Compare commits

..

10 Commits

Author SHA1 Message Date
Vlad Frangu
53dbc96194 chore(builders): release @discordjs/builders@1.10.1 2025-02-11 00:51:35 +02:00
Almeida
49ef3a833e fix(EmbedBuilder): allow empty name and value on fields (#10747) 2025-02-10 23:55:17 +02:00
Jiralite
bffe8a423e build: bump undici to 6.21.1 2025-02-08 15:38:37 +00:00
Jiralite
5d896f7d4f build: bump discord-api-types to 0.37.119 2025-02-07 21:46:15 +00:00
Jiralite
f3a2fb8a68 build: bump discord-api-types to 0.37.118 2025-01-29 09:36:34 +00:00
Qjuh
fbc3d57828 feat(website): include reexported members in docs (#10518)
* feat(website): add re-exported members to docs site

* refactor(scripts): rewrite sourceURL for externals

* feat(website): add external badge

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-10 04:04:28 +00:00
Vlad Frangu
d6c7b8fe05 chore(builders): release @discordjs/builders@1.10.0 2025-01-01 23:24:11 +02:00
Vlad Frangu
e9d6046047 chore(formatters): release @discordjs/formatters@0.6.0 2025-01-01 23:23:37 +02:00
Jiralite
24e20d27a9 build: bump discord-api-types to 0.37.114 2024-12-24 12:07:58 +00:00
Jiralite
8760fde9ff build: bump discord-api-types to 0.37.113 2024-12-22 21:58:29 +00:00
124 changed files with 495 additions and 1987 deletions

View File

@@ -18,8 +18,9 @@ export async function Badges({ node }: { readonly node: any }) {
const isAbstract = node.isAbstract;
const isReadonly = node.isReadonly;
const isOptional = node.isOptional;
const isExternal = node.isExternal;
const isAny = isDeprecated || isProtected || isStatic || isAbstract || isReadonly || isOptional;
const isAny = isDeprecated || isProtected || isStatic || isAbstract || isReadonly || isOptional || isExternal;
return isAny ? (
<div className="mb-1 flex gap-3">
@@ -33,6 +34,7 @@ export async function Badges({ node }: { readonly node: any }) {
{isAbstract ? <Badge className="bg-cyan-500/20 text-cyan-500">abstract</Badge> : null}
{isReadonly ? <Badge className="bg-purple-500/20 text-purple-500">readonly</Badge> : null}
{isOptional ? <Badge className="bg-cyan-500/20 text-cyan-500">optional</Badge> : null}
{isExternal ? <Badge className="bg-purple-500/20 text-purple-500">external</Badge> : null}
</div>
) : null;
}

View File

@@ -20,7 +20,7 @@ export async function fetchDependencies({
return Object.entries<string>(parsedDependencies)
.filter(([key]) => key.startsWith('@discordjs/') && !key.includes('api-extractor'))
.map(([key, value]) => `${key.replace('@discordjs/', '').replaceAll('.', '-')}-${sanitizeVersion(value)}`);
.map(([key, value]) => `${key.replace('@discordjs/', '').replaceAll('.', '-')}-${value.replaceAll('.', '-')}`);
} catch {
return [];
}
@@ -36,12 +36,8 @@ export async function fetchDependencies({
return Object.entries<string>(parsedDependencies)
.filter(([key]) => key.startsWith('@discordjs/') && !key.includes('api-extractor'))
.map(([key, value]) => `${key.replace('@discordjs/', '').replaceAll('.', '-')}-${sanitizeVersion(value)}`);
.map(([key, value]) => `${key.replace('@discordjs/', '').replaceAll('.', '-')}-${value.replaceAll('.', '-')}`);
} catch {
return [];
}
}
function sanitizeVersion(version: string) {
return version.replaceAll('.', '-').replace(/^[\^~]/, '');
}

View File

@@ -49,7 +49,7 @@
"meilisearch": "^0.38.0",
"p-limit": "^6.1.0",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@types/node": "^18.19.45",

View File

@@ -114,7 +114,7 @@ interface DocgenEventJson {
}
interface DocgenParamJson {
default?: boolean | number | string;
default?: string;
description: string;
name: string;
nullable?: boolean;
@@ -155,7 +155,7 @@ interface DocgenMethodJson {
interface DocgenPropertyJson {
abstract?: boolean;
access?: DocgenAccess;
default?: boolean | number | string;
default?: string;
deprecated?: DocgenDeprecated;
description: string;
meta: DocgenMetaJson;
@@ -1264,7 +1264,7 @@ export class ApiModelGenerator {
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}${jsDoc.default ? ` (default: ${this._escapeSpecialChars(jsDoc.default)})` : ''}\n${
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
'deprecated' in jsDoc && jsDoc.deprecated
@@ -1342,7 +1342,7 @@ export class ApiModelGenerator {
const apiItemMetadata: ApiItemMetadata = this._collector.fetchApiItemMetadata(astDeclaration);
const docComment: tsdoc.DocComment | undefined = jsDoc
? this._tsDocParser.parseString(
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}${jsDoc.default ? ` (default: ${this._escapeSpecialChars(jsDoc.default)})` : ''}\n${
`/**\n * ${this._fixLinkTags(jsDoc.description) ?? ''}\n${
'see' in jsDoc ? jsDoc.see.map((see) => ` * @see ${see}\n`).join('') : ''
}${'readonly' in jsDoc && jsDoc.readonly ? ' * @readonly\n' : ''}${
'deprecated' in jsDoc && jsDoc.deprecated
@@ -1510,17 +1510,15 @@ export class ApiModelGenerator {
const excerptTokens: IExcerptToken[] = [
{
kind: ExcerptTokenKind.Content,
text: `public on(eventName: '${name}', listener: (${
jsDoc.params?.length
? `${jsDoc.params[0]?.name}${jsDoc.params[0]?.optional ? '?' : ''}: `
: ') => void): this;'
text: `on('${name}', (${
jsDoc.params?.length ? `${jsDoc.params[0]?.name}${jsDoc.params[0]?.nullable ? '?' : ''}: ` : ') => {})'
}`,
},
];
const parameters: IApiParameterOptions[] = [];
for (let index = 0; index < (jsDoc.params?.length ?? 0) - 1; index++) {
const parameter = jsDoc.params![index]!;
const newTokens = this._mapVarType(parameter.type, parameter.nullable);
const newTokens = this._mapVarType(parameter.type);
parameters.push({
parameterName: parameter.name,
parameterTypeTokenRange: {
@@ -1539,7 +1537,7 @@ export class ApiModelGenerator {
if (jsDoc.params?.length) {
const parameter = jsDoc.params![jsDoc.params.length - 1]!;
const newTokens = this._mapVarType(parameter.type, parameter.nullable);
const newTokens = this._mapVarType(parameter.type);
parameters.push({
parameterName: parameter.name,
parameterTypeTokenRange: {
@@ -1552,7 +1550,7 @@ export class ApiModelGenerator {
excerptTokens.push(...newTokens);
excerptTokens.push({
kind: ExcerptTokenKind.Content,
text: `) => void): this;`,
text: `) => {})`,
});
}
@@ -1748,14 +1746,6 @@ export class ApiModelGenerator {
return sourceLocation;
}
private _escapeSpecialChars(input: boolean | number | string) {
if (typeof input !== 'string') {
return input;
}
return input.replaceAll(/(?<char>[{}])/g, '\\$<char>');
}
private _fixLinkTags(input?: string): string | undefined {
return input
?.replaceAll(linkRegEx, (_match, _p1, _p2, _p3, _p4, _p5, _offset, _string, groups) => {
@@ -1775,7 +1765,7 @@ export class ApiModelGenerator {
.replaceAll('* ', '\n * * ');
}
private _mapVarType(typey: DocgenVarTypeJson, nullable?: boolean): IExcerptToken[] {
private _mapVarType(typey: DocgenVarTypeJson): IExcerptToken[] {
const mapper = Array.isArray(typey) ? typey : (typey.types ?? []);
const lookup: { [K in ts.SyntaxKind]?: string } = {
[ts.SyntaxKind.ClassDeclaration]: 'class',
@@ -1818,22 +1808,7 @@ export class ApiModelGenerator {
{ kind: ExcerptTokenKind.Content, text: symbol ?? '' },
];
}, []);
return index === 0
? mapper.length === 1 && (nullable || ('nullable' in typey && typey.nullable))
? [
...result,
{ kind: ExcerptTokenKind.Content, text: ' | ' },
{ kind: ExcerptTokenKind.Reference, text: 'null' },
]
: result
: index === mapper.length - 1 && (nullable || ('nullable' in typey && typey.nullable))
? [
{ kind: ExcerptTokenKind.Content, text: ' | ' },
...result,
{ kind: ExcerptTokenKind.Content, text: ' | ' },
{ kind: ExcerptTokenKind.Reference, text: 'null' },
]
: [{ kind: ExcerptTokenKind.Content, text: ' | ' }, ...result];
return index === 0 ? result : [{ kind: ExcerptTokenKind.Content, text: ' | ' }, ...result];
})
.filter((excerpt) => excerpt.text.length);
}
@@ -1848,7 +1823,7 @@ export class ApiModelGenerator {
isOptional: Boolean(prop.nullable),
isReadonly: Boolean(prop.readonly),
docComment: this._tsDocParser.parseString(
`/**\n * ${this._fixLinkTags(prop.description) ?? ''}${prop.default ? ` (default: ${this._escapeSpecialChars(prop.default)})` : ''}\n${
`/**\n * ${this._fixLinkTags(prop.description) ?? ''}\n${
prop.see?.map((see) => ` * @see ${see}\n`).join('') ?? ''
}${prop.readonly ? ' * @readonly\n' : ''} */`,
).docComment,

View File

@@ -23,7 +23,7 @@
## Installation
**Node.js 20 or newer is required.**
**Node.js 18 or newer is required.**
```sh
npm install @discordjs/brokers

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}

View File

@@ -89,7 +89,7 @@
"vitest": "^2.0.5"
},
"engines": {
"node": ">=20"
"node": ">=18"
},
"publishConfig": {
"access": "public",

View File

@@ -2,6 +2,12 @@
All notable changes to this project will be documented in this file.
# [@discordjs/builders@1.10.1](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.10.0...@discordjs/builders@1.10.1) - (2025-02-10)
## Bug Fixes
- **EmbedBuilder:** Allow empty `name` and `value` on fields (#10747) ([49ef3a8](https://github.com/discordjs/discord.js/commit/49ef3a833eab23d426d5c667e28aa493ddc9cb6c))
# [@discordjs/builders@1.9.0](https://github.com/discordjs/discord.js/compare/@discordjs/builders@1.8.2...@discordjs/builders@1.9.0) - (2024-09-01)
## Features

View File

@@ -23,7 +23,7 @@
## Installation
**Node.js 18 or newer is required.**
**Node.js 16.11.0 or newer is required.**
```sh
npm install @discordjs/builders

View File

@@ -166,7 +166,7 @@ describe('Context Menu Commands', () => {
});
describe('integration types', () => {
test('GIVEN a builder with valid integration types THEN does not throw an error', () => {
test('GIVEN a builder with valid integraton types THEN does not throw an error', () => {
expect(() =>
getBuilder().setIntegrationTypes([
ApplicationIntegrationType.GuildInstall,

View File

@@ -324,12 +324,16 @@ describe('Embed', () => {
test('GIVEN an embed using Embed#addFields THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.addFields({ name: 'foo', value: 'bar' });
embed.addFields([{ name: 'foo', value: 'bar' }]);
embed.addFields([
{ name: 'foo', value: 'bar' },
{ name: '', value: '' },
]);
expect(embed.toJSON()).toStrictEqual({
fields: [
{ name: 'foo', value: 'bar' },
{ name: 'foo', value: 'bar' },
{ name: '', value: '' },
],
});
});
@@ -381,38 +385,24 @@ describe('Embed', () => {
expect(() => embed.setFields(Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' })))).toThrowError();
});
describe('GIVEN invalid field amount THEN throws error', () => {
test('1', () => {
const embed = new EmbedBuilder();
test('GIVEN invalid field amount THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() =>
embed.addFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
});
expect(() =>
embed.addFields(...Array.from({ length: 26 }, () => ({ name: 'foo', value: 'bar' }))),
).toThrowError();
});
describe('GIVEN invalid field name THEN throws error', () => {
test('2', () => {
const embed = new EmbedBuilder();
test('GIVEN invalid field name length THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'bar' })).toThrowError();
});
expect(() => embed.addFields({ name: 'a'.repeat(257), value: 'bar' })).toThrowError();
});
describe('GIVEN invalid field name length THEN throws error', () => {
test('3', () => {
const embed = new EmbedBuilder();
test('GIVEN invalid field value length THEN throws error', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: 'a'.repeat(257), value: 'bar' })).toThrowError();
});
});
describe('GIVEN invalid field value length THEN throws error', () => {
test('4', () => {
const embed = new EmbedBuilder();
expect(() => embed.addFields({ name: '', value: 'a'.repeat(1_025) })).toThrowError();
});
expect(() => embed.addFields({ name: '', value: 'a'.repeat(1_025) })).toThrowError();
});
});
});

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@discordjs/builders",
"version": "1.9.0",
"version": "1.10.1",
"description": "A set of builders that you can use when creating your bot",
"scripts": {
"test": "vitest run",
@@ -68,7 +68,7 @@
"@discordjs/formatters": "workspace:^",
"@discordjs/util": "workspace:^",
"@sapphire/shapeshift": "^4.0.0",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.4",
"tslib": "^2.6.3"
@@ -91,7 +91,7 @@
"vitest": "^2.0.5"
},
"engines": {
"node": ">=18"
"node": ">=16.11.0"
},
"publishConfig": {
"access": "public",

View File

@@ -2,17 +2,9 @@ import { s } from '@sapphire/shapeshift';
import type { APIEmbedField } from 'discord-api-types/v10';
import { isValidationEnabled } from '../../util/validation.js';
export const fieldNamePredicate = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(256)
.setValidationEnabled(isValidationEnabled);
export const fieldNamePredicate = s.string().lengthLessThanOrEqual(256).setValidationEnabled(isValidationEnabled);
export const fieldValuePredicate = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(1_024)
.setValidationEnabled(isValidationEnabled);
export const fieldValuePredicate = s.string().lengthLessThanOrEqual(1_024).setValidationEnabled(isValidationEnabled);
export const fieldInlinePredicate = s.boolean().optional();
@@ -32,7 +24,10 @@ export function validateFieldLength(amountAdding: number, fields?: APIEmbedField
fieldLengthPredicate.parse((fields?.length ?? 0) + amountAdding);
}
export const authorNamePredicate = fieldNamePredicate.nullable().setValidationEnabled(isValidationEnabled);
export const authorNamePredicate = fieldNamePredicate
.lengthGreaterThanOrEqual(1)
.nullable()
.setValidationEnabled(isValidationEnabled);
export const imageURLPredicate = s
.string()
@@ -96,4 +91,7 @@ export const embedFooterPredicate = s
export const timestampPredicate = s.union([s.number(), s.date()]).nullable().setValidationEnabled(isValidationEnabled);
export const titlePredicate = fieldNamePredicate.nullable().setValidationEnabled(isValidationEnabled);
export const titlePredicate = fieldNamePredicate
.lengthGreaterThanOrEqual(1)
.nullable()
.setValidationEnabled(isValidationEnabled);

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}

View File

@@ -23,7 +23,7 @@
## Installation
**Node.js 20 or newer is required.**
**Node.js 18 or newer is required.**
```sh
npm install @discordjs/core

View File

@@ -1,5 +1,6 @@
{
"extends": "../../api-extractor.json",
"bundledPackages": ["discord-api-types"],
"docModel": {
"projectFolderUrl": "https://github.com/discordjs/discord.js/tree/main/packages/core"
}

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}

View File

@@ -70,7 +70,7 @@
"@discordjs/ws": "workspace:^",
"@sapphire/snowflake": "^3.5.3",
"@vladfrangu/async_event_emitter": "^2.4.6",
"discord-api-types": "^0.37.114"
"discord-api-types": "^0.37.119"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
@@ -90,7 +90,7 @@
"vitest": "^2.0.5"
},
"engines": {
"node": ">=20"
"node": ">=18"
},
"publishConfig": {
"access": "public",

View File

@@ -45,7 +45,7 @@ export class ChannelsAPI {
/**
* Sends a message in a channel
*
* @see {@link https://discord.com/developers/docs/resources/message#create-message}
* @see {@link https://discord.com/developers/docs/resources/channel#create-message}
* @param channelId - The id of the channel to send the message in
* @param body - The data for sending the message
* @param options - The options for sending the message
@@ -65,7 +65,7 @@ export class ChannelsAPI {
/**
* Edits a message
*
* @see {@link https://discord.com/developers/docs/resources/message#edit-message}
* @see {@link https://discord.com/developers/docs/resources/channel#edit-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to edit
* @param body - The data for editing the message
@@ -87,7 +87,7 @@ export class ChannelsAPI {
/**
* Fetches the reactions for a message
*
* @see {@link https://discord.com/developers/docs/resources/message#get-reactions}
* @see {@link https://discord.com/developers/docs/resources/channel#get-reactions}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to get the reactions for
* @param emoji - The emoji to get the reactions for
@@ -110,7 +110,7 @@ export class ChannelsAPI {
/**
* Deletes a reaction for the current user
*
* @see {@link https://discord.com/developers/docs/resources/message#delete-own-reaction}
* @see {@link https://discord.com/developers/docs/resources/channel#delete-own-reaction}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reaction for
* @param emoji - The emoji to delete the reaction for
@@ -130,7 +130,7 @@ export class ChannelsAPI {
/**
* Deletes a reaction for a user
*
* @see {@link https://discord.com/developers/docs/resources/message#delete-user-reaction}
* @see {@link https://discord.com/developers/docs/resources/channel#delete-user-reaction}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reaction for
* @param emoji - The emoji to delete the reaction for
@@ -152,7 +152,7 @@ export class ChannelsAPI {
/**
* Deletes all reactions for a message
*
* @see {@link https://discord.com/developers/docs/resources/message#delete-all-reactions}
* @see {@link https://discord.com/developers/docs/resources/channel#delete-all-reactions}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reactions for
* @param options - The options for deleting the reactions
@@ -168,7 +168,7 @@ export class ChannelsAPI {
/**
* Deletes all reactions of an emoji for a message
*
* @see {@link https://discord.com/developers/docs/resources/message#delete-all-reactions-for-emoji}
* @see {@link https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete the reactions for
* @param emoji - The emoji to delete the reactions for
@@ -186,7 +186,7 @@ export class ChannelsAPI {
/**
* Adds a reaction to a message
*
* @see {@link https://discord.com/developers/docs/resources/message#create-reaction}
* @see {@link https://discord.com/developers/docs/resources/channel#create-reaction}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to add the reaction to
* @param emoji - The emoji to add the reaction with
@@ -242,7 +242,7 @@ export class ChannelsAPI {
/**
* Fetches the messages of a channel
*
* @see {@link https://discord.com/developers/docs/resources/message#get-channel-messages}
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-messages}
* @param channelId - The id of the channel to fetch messages from
* @param query - The query options for fetching messages
* @param options - The options for fetching the messages
@@ -299,7 +299,7 @@ export class ChannelsAPI {
/**
* Deletes a message
*
* @see {@link https://discord.com/developers/docs/resources/message#delete-message}
* @see {@link https://discord.com/developers/docs/resources/channel#delete-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to delete
* @param options - The options for deleting the message
@@ -315,7 +315,7 @@ export class ChannelsAPI {
/**
* Bulk deletes messages
*
* @see {@link https://discord.com/developers/docs/resources/message#bulk-delete-messages}
* @see {@link https://discord.com/developers/docs/resources/channel#bulk-delete-messages}
* @param channelId - The id of the channel the messages are in
* @param messageIds - The ids of the messages to delete
* @param options - The options for deleting the messages
@@ -331,7 +331,7 @@ export class ChannelsAPI {
/**
* Fetches a message
*
* @see {@link https://discord.com/developers/docs/resources/message#get-channel-message}
* @see {@link https://discord.com/developers/docs/resources/channel#get-channel-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to fetch
* @param options - The options for fetching the message
@@ -345,7 +345,7 @@ export class ChannelsAPI {
/**
* Crossposts a message
*
* @see {@link https://discord.com/developers/docs/resources/message#crosspost-message}
* @see {@link https://discord.com/developers/docs/resources/channel#crosspost-message}
* @param channelId - The id of the channel the message is in
* @param messageId - The id of the message to crosspost
* @param options - The options for crossposting the message
@@ -452,7 +452,7 @@ export class ChannelsAPI {
/**
* Creates a new forum post
*
* @see {@link https://discord.com/developers/docs/resources/channel#start-thread-in-forum-or-media-channel}
* @see {@link https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel}
* @param channelId - The id of the forum channel to start the thread in
* @param body - The data for starting the thread
* @param options - The options for starting the thread

View File

@@ -258,7 +258,7 @@ export class InteractionsAPI {
* @param interactionId - The id of the interaction
* @param interactionToken - The token of the interaction
* @param options - The options for sending the premium required response
* @deprecated Sending a premium-style button is the new Discord behavior.
* @deprecated Sending a premium-style button is the new Discord behaviour.
*/
public async sendPremiumRequired(
interactionId: Snowflake,

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}

View File

@@ -2,41 +2,6 @@
All notable changes to this project will be documented in this file.
# [14.16.3](https://github.com/discordjs/discord.js/compare/14.16.2...14.16.3) - (2024-09-29)
## Bug Fixes
- **BaseInteraction:** Add missing props (#10517) ([6c77fee](https://github.com/discordjs/discord.js/commit/6c77fee41b1aabc243bff623debd157a4c7fad6a)) by @monbrey
- `GuildChannel#guildId` not being patched to `undefined` (#10505) ([2adee06](https://github.com/discordjs/discord.js/commit/2adee06b6e92b7854ebb1c2bfd04940aab68dd10)) by @Qjuh
## Typings
- **MessageEditOptions:** Omit `poll` (#10509) ([665bf14](https://github.com/discordjs/discord.js/commit/665bf1486aec62e9528f5f7b5a6910ae6b5a6c9c)) by @TAEMBO
# [14.16.2](https://github.com/discordjs/discord.js/compare/14.16.1...14.16.2) - (2024-09-12)
## Bug Fixes
- **ApplicationCommand:** Incorrect comparison in equals method (#10497) ([3c74aa2](https://github.com/discordjs/discord.js/commit/3c74aa204909323ff6d05991438bee2c583e838b)) by @monbrey
- Type guard for sendable text-based channels (#10482) ([dea6840](https://github.com/discordjs/discord.js/commit/dea68400a38edb90b8b4242d64be14968943130d)) by @vladfrangu
## Documentation
- Update discord documentation links (#10484) ([799fa54](https://github.com/discordjs/discord.js/commit/799fa54fa4434144855be2f7a0bbac6ff8ce9d0b)) by @sdanialraza
- **Message:** Mark `interaction` as deprecated (#10481) ([c13f18e](https://github.com/discordjs/discord.js/commit/c13f18e90eb6eb315397c095e948993856428757)) by @sdanialraza
- **ApplicationEmojiManager:** Fix fetch example (#10480) ([4594896](https://github.com/discordjs/discord.js/commit/4594896b5404c6a34e07544951c59ff8f3657184)) by @sdanialraza
## Typings
- Export GroupDM helper type (#10478) ([aff772c](https://github.com/discordjs/discord.js/commit/aff772c7aa3b3de58780a94588d1f3576a434f32)) by @Qjuh
# [14.16.1](https://github.com/discordjs/discord.js/compare/14.16.0...14.16.1) - (2024-09-02)
## Bug Fixes
- **Message:** Reacting returning undefined (#10475) ([9257a09](https://github.com/discordjs/discord.js/commit/9257a09abbf80558ed2d5d209a2f6bd2a4b3d799)) by @vladfrangu
- **Transformers:** Pass client to recursive call (#10474) ([4810f7c](https://github.com/discordjs/discord.js/commit/4810f7c8637dacf77d0442bd84e0d579e1f1d3bd)) by @SpaceEEC
# [14.16.0](https://github.com/discordjs/discord.js/compare/14.15.3...14.16.0) - (2024-09-01)
## Bug Fixes

View File

@@ -29,7 +29,7 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
## Installation
**Node.js 18 or newer is required.**
**Node.js 16.11.0 or newer is required.**
```sh
npm install discord.js
@@ -42,6 +42,7 @@ bun add discord.js
- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
- [@discordjs/voice](https://www.npmjs.com/package/@discordjs/voice) for interacting with the Discord Voice API (`npm install @discordjs/voice`)
## Example usage

View File

@@ -1,6 +1,14 @@
{
"extends": "../../api-extractor.json",
"mainEntryPointFilePath": "<projectFolder>/typings/index.d.ts",
"bundledPackages": [
"discord-api-types",
"@discordjs/builders",
"@discordjs/formatters",
"@discordjs/rest",
"@discordjs/util",
"@discordjs/ws"
],
"docModel": {
"projectFolderUrl": "https://github.com/discordjs/discord.js/tree/main/packages/discord.js"
}

View File

@@ -30,10 +30,8 @@ body = """
{{ commit.message | upper_first }} ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\
{% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
{% if commit.breaking %}\
{% for footer in commit.footers %}\
{% if footer.breaking %}\
\n{% raw %} {% endraw %}- **{{ footer.token }}{{ footer.separator }}** {{ footer.value }}\
{% endif %}\
{% for breakingChange in commit.footers %}\
\n{% raw %} {% endraw %}- **{{ breakingChange.token }}{{ breakingChange.separator }}** {{ breakingChange.value }}\
{% endfor %}\
{% endif %}\
{% endfor %}
@@ -69,7 +67,8 @@ commit_parsers = [
{ body = ".*security", group = "Security"},
]
filter_commits = true
tag_pattern = "^[0-9]+"
tag_pattern = "[0-9]*"
skip_tags = "v[0-9]*|@discordjs*"
ignore_tags = ""
topo_order = false
sort_commits = "newest"

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "discord.js",
"version": "14.16.3",
"version": "14.16.0",
"description": "A powerful library for interacting with the Discord API",
"scripts": {
"test": "pnpm run docs:test && pnpm run test:typescript",
@@ -65,18 +65,18 @@
"homepage": "https://discord.js.org",
"funding": "https://github.com/discordjs/discord.js?sponsor",
"dependencies": {
"@discordjs/builders": "^1.10.0",
"@discordjs/builders": "workspace:^",
"@discordjs/collection": "1.5.3",
"@discordjs/formatters": "^0.6.0",
"@discordjs/formatters": "workspace:^",
"@discordjs/rest": "workspace:^",
"@discordjs/util": "workspace:^",
"@discordjs/ws": "^1.1.1",
"@discordjs/ws": "1.1.1",
"@sapphire/snowflake": "3.5.3",
"discord-api-types": "^0.37.114",
"discord-api-types": "^0.37.119",
"fast-deep-equal": "3.1.3",
"lodash.snakecase": "4.1.1",
"tslib": "^2.6.3",
"undici": "6.19.8"
"undici": "6.21.1"
},
"devDependencies": {
"@discordjs/api-extractor": "workspace:^",
@@ -98,7 +98,7 @@
"typescript": "~5.5.4"
},
"engines": {
"node": ">=18"
"node": ">=16.11.0"
},
"publishConfig": {
"provenance": true

View File

@@ -107,20 +107,20 @@ class Client extends BaseClient {
: null;
/**
* The user manager of this client
* All of the {@link User} objects that have been cached at any point, mapped by their ids
* @type {UserManager}
*/
this.users = new UserManager(this);
/**
* A manager of all the guilds the client is currently handling -
* All of the guilds the client is currently handling, mapped by their ids -
* as long as sharding isn't being used, this will be *every* guild the bot is a member of
* @type {GuildManager}
*/
this.guilds = new GuildManager(this);
/**
* All of the {@link BaseChannel}s that the client is currently handling -
* All of the {@link BaseChannel}s that the client is currently handling, mapped by their ids -
* as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
* is a member of. Note that DM channels will not be initially cached, and thus not be present
* in the Manager without their explicit fetching or use.
@@ -174,7 +174,7 @@ class Client extends BaseClient {
}
/**
* A manager of all the custom emojis that the client has access to
* All custom emojis that the client has access to, mapped by their ids
* @type {BaseGuildEmojiManager}
* @readonly
*/

View File

@@ -111,10 +111,6 @@ class GenericAction {
getThreadMember(id, manager) {
return this.getPayload({ user_id: id }, manager, id, Partials.ThreadMember, false);
}
spreadInjectedData(data) {
return Object.fromEntries(Object.getOwnPropertySymbols(data).map(symbol => [symbol, data[symbol]]));
}
}
module.exports = GenericAction;

View File

@@ -6,11 +6,7 @@ const Events = require('../../util/Events');
class MessageCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = this.getChannel({
id: data.channel_id,
author: data.author,
...('guild_id' in data && { guild_id: data.guild_id }),
});
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id, author: data.author });
if (channel) {
if (!channel.isTextBased()) return {};

View File

@@ -6,7 +6,7 @@ const Events = require('../../util/Events');
class MessageDeleteAction extends Action {
handle(data) {
const client = this.client;
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
let message;
if (channel) {
if (!channel.isTextBased()) return {};

View File

@@ -5,7 +5,7 @@ const Events = require('../../util/Events');
class MessagePollVoteAddAction extends Action {
handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (!channel?.isTextBased()) return false;
const message = this.getMessage(data, channel);

View File

@@ -5,7 +5,7 @@ const Events = require('../../util/Events');
class MessagePollVoteRemoveAction extends Action {
handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (!channel?.isTextBased()) return false;
const message = this.getMessage(data, channel);

View File

@@ -23,13 +23,7 @@ class MessageReactionAdd extends Action {
if (!user) return false;
// Verify channel
const channel = this.getChannel({
id: data.channel_id,
...('guild_id' in data && { guild_id: data.guild_id }),
user_id: data.user_id,
...this.spreadInjectedData(data),
});
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id, user_id: data.user_id });
if (!channel?.isTextBased()) return false;
// Verify message
@@ -51,7 +45,6 @@ class MessageReactionAdd extends Action {
/**
* Provides additional information about altered reaction
* @typedef {Object} MessageReactionEventDetails
* @property {ReactionType} type The type of the reaction
* @property {boolean} burst Determines whether a super reaction was used
*/
/**
@@ -61,7 +54,7 @@ class MessageReactionAdd extends Action {
* @param {User} user The user that applied the guild or reaction emoji
* @param {MessageReactionEventDetails} details Details of adding the reaction
*/
this.client.emit(Events.MessageReactionAdd, reaction, user, { type: data.type, burst: data.burst });
this.client.emit(Events.MessageReactionAdd, reaction, user, { burst: data.burst });
return { message, reaction, user };
}

View File

@@ -19,11 +19,7 @@ class MessageReactionRemove extends Action {
if (!user) return false;
// Verify channel
const channel = this.getChannel({
id: data.channel_id,
...('guild_id' in data && { guild_id: data.guild_id }),
user_id: data.user_id,
});
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id, user_id: data.user_id });
if (!channel?.isTextBased()) return false;
// Verify message
@@ -41,7 +37,7 @@ class MessageReactionRemove extends Action {
* @param {User} user The user whose emoji or reaction emoji was removed
* @param {MessageReactionEventDetails} details Details of removing the reaction
*/
this.client.emit(Events.MessageReactionRemove, reaction, user, { type: data.type, burst: data.burst });
this.client.emit(Events.MessageReactionRemove, reaction, user, { burst: data.burst });
return { message, reaction, user };
}

View File

@@ -6,7 +6,7 @@ const Events = require('../../util/Events');
class MessageReactionRemoveAll extends Action {
handle(data) {
// Verify channel
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (!channel?.isTextBased()) return false;
// Verify message

View File

@@ -5,7 +5,7 @@ const Events = require('../../util/Events');
class MessageReactionRemoveEmoji extends Action {
handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (!channel?.isTextBased()) return false;
const message = this.getMessage(data, channel);

View File

@@ -4,7 +4,7 @@ const Action = require('./Action');
class MessageUpdateAction extends Action {
handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (channel) {
if (!channel.isTextBased()) return {};

View File

@@ -13,7 +13,7 @@ class ThreadListSyncAction extends Action {
if (data.channel_ids) {
for (const id of data.channel_ids) {
const channel = client.channels.cache.get(id);
const channel = client.channels.resolve(id);
if (channel) this.removeStale(channel);
}
} else {

View File

@@ -6,7 +6,7 @@ const Events = require('../../util/Events');
class TypingStart extends Action {
handle(data) {
const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
const channel = this.getChannel({ id: data.channel_id, guild_id: data.guild_id });
if (!channel) return;
if (!channel.isTextBased()) {

View File

@@ -1,14 +0,0 @@
'use strict';
const Events = require('../../../util/Events');
module.exports = (client, { d: data }) => {
const subscription = client.application.subscriptions._add(data);
/**
* Emitted whenever a subscription is created.
* @event Client#subscriptionCreate
* @param {Subscription} subscription The subscription that was created
*/
client.emit(Events.SubscriptionCreate, subscription);
};

View File

@@ -1,16 +0,0 @@
'use strict';
const Events = require('../../../util/Events');
module.exports = (client, { d: data }) => {
const subscription = client.application.subscriptions._add(data, false);
client.application.subscriptions.cache.delete(subscription.id);
/**
* Emitted whenever a subscription is deleted.
* @event Client#subscriptionDelete
* @param {Subscription} subscription The subscription that was deleted
*/
client.emit(Events.SubscriptionDelete, subscription);
};

View File

@@ -1,16 +0,0 @@
'use strict';
const Events = require('../../../util/Events');
module.exports = (client, { d: data }) => {
const oldSubscription = client.application.subscriptions.cache.get(data.id)?._clone() ?? null;
const newSubscription = client.application.subscriptions._add(data);
/**
* Emitted whenever a subscription is updated - i.e. when a user's subscription renews.
* @event Client#subscriptionUpdate
* @param {?Subscription} oldSubscription The subscription before the update
* @param {Subscription} newSubscription The subscription after the update
*/
client.emit(Events.SubscriptionUpdate, oldSubscription, newSubscription);
};

View File

@@ -1,16 +0,0 @@
'use strict';
const VoiceChannelEffect = require('../../../structures/VoiceChannelEffect');
const Events = require('../../../util/Events');
module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return;
/**
* Emitted when someone sends an effect, such as an emoji reaction, in a voice channel the client is connected to.
* @event Client#voiceChannelEffectSend
* @param {VoiceChannelEffect} voiceChannelEffect The sent voice channel effect
*/
client.emit(Events.VoiceChannelEffectSend, new VoiceChannelEffect(data, guild));
};

View File

@@ -53,9 +53,6 @@ const handlers = Object.fromEntries([
['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')],
['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')],
['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')],
['SUBSCRIPTION_CREATE', require('./SUBSCRIPTION_CREATE')],
['SUBSCRIPTION_DELETE', require('./SUBSCRIPTION_DELETE')],
['SUBSCRIPTION_UPDATE', require('./SUBSCRIPTION_UPDATE')],
['THREAD_CREATE', require('./THREAD_CREATE')],
['THREAD_DELETE', require('./THREAD_DELETE')],
['THREAD_LIST_SYNC', require('./THREAD_LIST_SYNC')],
@@ -64,7 +61,6 @@ const handlers = Object.fromEntries([
['THREAD_UPDATE', require('./THREAD_UPDATE')],
['TYPING_START', require('./TYPING_START')],
['USER_UPDATE', require('./USER_UPDATE')],
['VOICE_CHANNEL_EFFECT_SEND', require('./VOICE_CHANNEL_EFFECT_SEND')],
['VOICE_SERVER_UPDATE', require('./VOICE_SERVER_UPDATE')],
['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')],
['WEBHOOKS_UPDATE', require('./WEBHOOKS_UPDATE')],

View File

@@ -85,7 +85,6 @@ exports.ReactionManager = require('./managers/ReactionManager');
exports.ReactionUserManager = require('./managers/ReactionUserManager');
exports.RoleManager = require('./managers/RoleManager');
exports.StageInstanceManager = require('./managers/StageInstanceManager');
exports.SubscriptionManager = require('./managers/SubscriptionManager').SubscriptionManager;
exports.ThreadManager = require('./managers/ThreadManager');
exports.ThreadMemberManager = require('./managers/ThreadMemberManager');
exports.UserManager = require('./managers/UserManager');
@@ -147,9 +146,6 @@ exports.GuildScheduledEvent = require('./structures/GuildScheduledEvent').GuildS
exports.GuildTemplate = require('./structures/GuildTemplate');
exports.Integration = require('./structures/Integration');
exports.IntegrationApplication = require('./structures/IntegrationApplication');
exports.InteractionCallback = require('./structures/InteractionCallback');
exports.InteractionCallbackResource = require('./structures/InteractionCallbackResource');
exports.InteractionCallbackResponse = require('./structures/InteractionCallbackResponse');
exports.BaseInteraction = require('./structures/BaseInteraction');
exports.InteractionCollector = require('./structures/InteractionCollector');
exports.InteractionResponse = require('./structures/InteractionResponse');
@@ -206,7 +202,6 @@ exports.SKU = require('./structures/SKU').SKU;
exports.StringSelectMenuOptionBuilder = require('./structures/StringSelectMenuOptionBuilder');
exports.StageChannel = require('./structures/StageChannel');
exports.StageInstance = require('./structures/StageInstance').StageInstance;
exports.Subscription = require('./structures/Subscription').Subscription;
exports.Sticker = require('./structures/Sticker').Sticker;
exports.StickerPack = require('./structures/StickerPack');
exports.Team = require('./structures/Team');
@@ -220,7 +215,6 @@ exports.ThreadOnlyChannel = require('./structures/ThreadOnlyChannel');
exports.Typing = require('./structures/Typing');
exports.User = require('./structures/User');
exports.UserContextMenuCommandInteraction = require('./structures/UserContextMenuCommandInteraction');
exports.VoiceChannelEffect = require('./structures/VoiceChannelEffect');
exports.VoiceChannel = require('./structures/VoiceChannel');
exports.VoiceRegion = require('./structures/VoiceRegion');
exports.VoiceState = require('./structures/VoiceState');

View File

@@ -82,7 +82,7 @@ class ApplicationCommandManager extends CachedManager {
* Options used to fetch Application Commands from Discord
* @typedef {BaseFetchOptions} FetchApplicationCommandOptions
* @property {Snowflake} [guildId] The guild's id to fetch commands for, for when the guild is not cached
* @property {Locale} [locale] The locale to use when fetching this command
* @property {LocaleString} [locale] The locale to use when fetching this command
* @property {boolean} [withLocalizations] Whether to fetch all localization data
*/

View File

@@ -65,12 +65,12 @@ class ApplicationEmojiManager extends CachedManager {
* @returns {Promise<ApplicationEmoji|Collection<Snowflake, ApplicationEmoji>>}
* @example
* // Fetch all emojis from the application
* application.emojis.fetch()
* message.application.emojis.fetch()
* .then(emojis => console.log(`There are ${emojis.size} emojis.`))
* .catch(console.error);
* @example
* // Fetch a single emoji
* application.emojis.fetch('222078108977594368')
* message.application.emojis.fetch('222078108977594368')
* .then(emoji => console.log(`The emoji name is: ${emoji.name}`))
* .catch(console.error);
*/

View File

@@ -1,7 +1,6 @@
'use strict';
const CachedManager = require('./CachedManager');
const ApplicationEmoji = require('../structures/ApplicationEmoji');
const GuildEmoji = require('../structures/GuildEmoji');
const ReactionEmoji = require('../structures/ReactionEmoji');
const { parseEmoji } = require('../util/Util');
@@ -26,8 +25,7 @@ class BaseGuildEmojiManager extends CachedManager {
* * A Snowflake
* * A GuildEmoji object
* * A ReactionEmoji object
* * An ApplicationEmoji object
* @typedef {Snowflake|GuildEmoji|ReactionEmoji|ApplicationEmoji} EmojiResolvable
* @typedef {Snowflake|GuildEmoji|ReactionEmoji} EmojiResolvable
*/
/**
@@ -36,8 +34,7 @@ class BaseGuildEmojiManager extends CachedManager {
* @returns {?GuildEmoji}
*/
resolve(emoji) {
if (emoji instanceof ReactionEmoji) return super.cache.get(emoji.id) ?? null;
if (emoji instanceof ApplicationEmoji) return super.cache.get(emoji.id) ?? null;
if (emoji instanceof ReactionEmoji) return super.resolve(emoji.id);
return super.resolve(emoji);
}
@@ -48,7 +45,6 @@ class BaseGuildEmojiManager extends CachedManager {
*/
resolveId(emoji) {
if (emoji instanceof ReactionEmoji) return emoji.id;
if (emoji instanceof ApplicationEmoji) return emoji.id;
return super.resolveId(emoji);
}
@@ -69,7 +65,6 @@ class BaseGuildEmojiManager extends CachedManager {
const emojiResolvable = this.resolve(emoji);
if (emojiResolvable) return emojiResolvable.identifier;
if (emoji instanceof ReactionEmoji) return emoji.identifier;
if (emoji instanceof ApplicationEmoji) return emoji.identifier;
if (typeof emoji === 'string') {
const res = parseEmoji(emoji);
if (res?.name.length) {

View File

@@ -37,12 +37,6 @@ class EntitlementManager extends CachedManager {
* @typedef {SKU|Snowflake} SKUResolvable
*/
/**
* Options used to fetch an entitlement
* @typedef {BaseFetchOptions} FetchEntitlementOptions
* @property {EntitlementResolvable} entitlement The entitlement to fetch
*/
/**
* Options used to fetch entitlements
* @typedef {Object} FetchEntitlementsOptions
@@ -51,7 +45,6 @@ class EntitlementManager extends CachedManager {
* @property {UserResolvable} [user] The user to fetch entitlements for
* @property {SKUResolvable[]} [skus] The SKUs to fetch entitlements for
* @property {boolean} [excludeEnded] Whether to exclude ended entitlements
* @property {boolean} [excludeDeleted] Whether to exclude deleted entitlements
* @property {boolean} [cache=true] Whether to cache the fetched entitlements
* @property {Snowflake} [before] Consider only entitlements before this entitlement id
* @property {Snowflake} [after] Consider only entitlements after this entitlement id
@@ -60,49 +53,21 @@ class EntitlementManager extends CachedManager {
/**
* Fetches entitlements for this application
* @param {EntitlementResolvable|FetchEntitlementOptions|FetchEntitlementsOptions} [options]
* Options for fetching the entitlements
* @returns {Promise<Entitlement|Collection<Snowflake, Entitlement>>}
* @param {FetchEntitlementsOptions} [options={}] Options for fetching the entitlements
* @returns {Promise<Collection<Snowflake, Entitlement>>}
*/
async fetch(options) {
if (!options) return this._fetchMany(options);
const { entitlement, cache, force } = options;
const resolvedEntitlement = this.resolveId(entitlement ?? options);
if (resolvedEntitlement) {
return this._fetchSingle({ entitlement: resolvedEntitlement, cache, force });
}
return this._fetchMany(options);
}
async _fetchSingle({ entitlement, cache, force = false }) {
if (!force) {
const existing = this.cache.get(entitlement);
if (existing) {
return existing;
}
}
const data = await this.client.rest.get(Routes.entitlement(this.client.application.id, entitlement));
return this._add(data, cache);
}
async _fetchMany({ limit, guild, user, skus, excludeEnded, excludeDeleted, cache, before, after } = {}) {
async fetch({ limit, guild, user, skus, excludeEnded, cache = true, before, after } = {}) {
const query = makeURLSearchParams({
limit,
guild_id: guild && this.client.guilds.resolveId(guild),
user_id: user && this.client.users.resolveId(user),
sku_ids: skus?.map(sku => resolveSKUId(sku)).join(','),
exclude_ended: excludeEnded,
exclude_deleted: excludeDeleted,
before,
after,
});
const entitlements = await this.client.rest.get(Routes.entitlements(this.client.application.id), { query });
return entitlements.reduce(
(coll, entitlement) => coll.set(entitlement.id, this._add(entitlement, cache)),
new Collection(),

View File

@@ -175,7 +175,7 @@ class GuildBanManager extends CachedManager {
reason: options.reason,
});
if (user instanceof GuildMember) return user;
const _user = this.client.users.cache.get(id);
const _user = this.client.users.resolve(id);
if (_user) {
return this.guild.members.resolve(_user) ?? _user;
}

View File

@@ -84,7 +84,7 @@ class GuildChannelManager extends CachedManager {
* @returns {?(GuildChannel|ThreadChannel)}
*/
resolve(channel) {
if (channel instanceof ThreadChannel) return super.cache.get(channel.id) ?? null;
if (channel instanceof ThreadChannel) return super.resolve(channel.id);
return super.resolve(channel);
}
@@ -287,7 +287,7 @@ class GuildChannelManager extends CachedManager {
const resolvedChannel = this.resolve(channel);
if (!resolvedChannel) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'channel', 'GuildChannelResolvable');
const parentId = options.parent && this.client.channels.resolveId(options.parent);
const parent = options.parent && this.client.channels.resolveId(options.parent);
if (options.position !== undefined) {
await this.setPosition(resolvedChannel, options.position, { position: options.position, reason: options.reason });
@@ -298,8 +298,8 @@ class GuildChannelManager extends CachedManager {
);
if (options.lockPermissions) {
if (parentId) {
const newParent = this.cache.get(parentId);
if (parent) {
const newParent = this.guild.channels.resolve(parent);
if (newParent?.type === ChannelType.GuildCategory) {
permission_overwrites = newParent.permissionOverwrites.cache.map(overwrite =>
PermissionOverwrites.resolve(overwrite, this.guild),
@@ -322,7 +322,7 @@ class GuildChannelManager extends CachedManager {
user_limit: options.userLimit,
rtc_region: options.rtcRegion,
video_quality_mode: options.videoQualityMode,
parent_id: parentId,
parent_id: parent,
lock_permissions: options.lockPermissions,
rate_limit_per_user: options.rateLimitPerUser,
default_auto_archive_duration: options.defaultAutoArchiveDuration,

View File

@@ -55,7 +55,7 @@ class GuildMemberManager extends CachedManager {
const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable;
const userResolvable = this.client.users.resolveId(member);
if (userResolvable) return super.cache.get(userResolvable) ?? null;
if (userResolvable) return super.resolve(userResolvable);
return null;
}
@@ -144,7 +144,7 @@ class GuildMemberManager extends CachedManager {
*/
get me() {
return (
this.cache.get(this.client.user.id) ??
this.resolve(this.client.user.id) ??
(this.client.options.partials.includes(Partials.GuildMember)
? this._add({ user: { id: this.client.user.id } }, true)
: null)
@@ -535,7 +535,7 @@ class GuildMemberManager extends CachedManager {
*/
async addRole(options) {
const { user, role, reason } = options;
const userId = this.resolveId(user);
const userId = this.guild.members.resolveId(user);
const roleId = this.guild.roles.resolveId(role);
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });
@@ -549,7 +549,7 @@ class GuildMemberManager extends CachedManager {
*/
async removeRole(options) {
const { user, role, reason } = options;
const userId = this.resolveId(user);
const userId = this.guild.members.resolveId(user);
const roleId = this.guild.roles.resolveId(role);
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, userId, roleId), { reason });

View File

@@ -101,8 +101,6 @@ class GuildMemberRoleManager extends DataManager {
/**
* Adds a role (or multiple roles) to the member.
*
* <info>Uses the idempotent PUT route for singular roles, otherwise PATCHes the underlying guild member</info>
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to add
* @param {string} [reason] Reason for adding the role(s)
* @returns {Promise<GuildMember>}
@@ -140,8 +138,6 @@ class GuildMemberRoleManager extends DataManager {
/**
* Removes a role (or multiple roles) from the member.
*
* <info>Uses the idempotent DELETE route for singular roles, otherwise PATCHes the underlying guild member</info>
* @param {RoleResolvable|RoleResolvable[]|Collection<Snowflake, Role>} roleOrRoles The role or roles to remove
* @param {string} [reason] Reason for removing the role(s)
* @returns {Promise<GuildMember>}

View File

@@ -7,7 +7,6 @@ const CachedManager = require('./CachedManager');
const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../errors');
const { GuildScheduledEvent } = require('../structures/GuildScheduledEvent');
const { resolveImage } = require('../util/DataResolver');
const { _transformGuildScheduledEventRecurrenceRule } = require('../util/Transformers');
/**
* Manages API methods for GuildScheduledEvents and stores their cache.
@@ -37,21 +36,6 @@ class GuildScheduledEventManager extends CachedManager {
* @typedef {Snowflake|GuildScheduledEvent} GuildScheduledEventResolvable
*/
/**
* Options for setting a recurrence rule for a guild scheduled event.
* @typedef {Object} GuildScheduledEventRecurrenceRuleOptions
* @property {DateResolvable} startAt The time the recurrence rule interval starts at
* @property {?DateResolvable} endAt The time the recurrence rule interval ends at
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
* @property {number} interval The spacing between the events
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
* @property {?number[]} byMonthDay The days within a month to recur on
* @property {?number[]} byYearDay The days within a year to recur on
* @property {?number} count The total amount of times the event is allowed to recur before stopping
*/
/**
* Options used to create a guild scheduled event.
* @typedef {Object} GuildScheduledEventCreateOptions
@@ -70,8 +54,6 @@ class GuildScheduledEventManager extends CachedManager {
* <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.External}</warn>
* @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
* @property {string} [reason] The reason for creating the guild scheduled event
* @property {GuildScheduledEventRecurrenceRuleOptions} [recurrenceRule]
* The recurrence rule of the guild scheduled event
*/
/**
@@ -99,7 +81,6 @@ class GuildScheduledEventManager extends CachedManager {
entityMetadata,
reason,
image,
recurrenceRule,
} = options;
let entity_metadata, channel_id;
@@ -123,7 +104,6 @@ class GuildScheduledEventManager extends CachedManager {
entity_type: entityType,
entity_metadata,
image: image && (await resolveImage(image)),
recurrence_rule: recurrenceRule && _transformGuildScheduledEventRecurrenceRule(recurrenceRule),
},
reason,
});
@@ -173,7 +153,10 @@ class GuildScheduledEventManager extends CachedManager {
return data.reduce(
(coll, rawGuildScheduledEventData) =>
coll.set(rawGuildScheduledEventData.id, this._add(rawGuildScheduledEventData, options.cache)),
coll.set(
rawGuildScheduledEventData.id,
this.guild.scheduledEvents._add(rawGuildScheduledEventData, options.cache),
),
new Collection(),
);
}
@@ -195,8 +178,6 @@ class GuildScheduledEventManager extends CachedManager {
* {@link GuildScheduledEventEntityType.External}</warn>
* @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
* @property {string} [reason] The reason for editing the guild scheduled event
* @property {?GuildScheduledEventRecurrenceRuleOptions} [recurrenceRule]
* The recurrence rule of the guild scheduled event
*/
/**
@@ -222,7 +203,6 @@ class GuildScheduledEventManager extends CachedManager {
entityMetadata,
reason,
image,
recurrenceRule,
} = options;
let entity_metadata;
@@ -244,7 +224,6 @@ class GuildScheduledEventManager extends CachedManager {
status,
image: image && (await resolveImage(image)),
entity_metadata,
recurrence_rule: recurrenceRule && _transformGuildScheduledEventRecurrenceRule(recurrenceRule),
},
reason,
});

View File

@@ -38,8 +38,8 @@ class PresenceManager extends CachedManager {
resolve(presence) {
const presenceResolvable = super.resolve(presence);
if (presenceResolvable) return presenceResolvable;
const userId = this.client.users.resolveId(presence);
return super.cache.get(userId) ?? null;
const UserResolvable = this.client.users.resolveId(presence);
return super.resolve(UserResolvable);
}
/**
@@ -50,8 +50,8 @@ class PresenceManager extends CachedManager {
resolveId(presence) {
const presenceResolvable = super.resolveId(presence);
if (presenceResolvable) return presenceResolvable;
const userId = this.client.users.resolveId(presence);
return this.cache.has(userId) ? userId : null;
const userResolvable = this.client.users.resolveId(presence);
return this.cache.has(userResolvable) ? userResolvable : null;
}
}

View File

@@ -1,81 +0,0 @@
'use strict';
const { Collection } = require('@discordjs/collection');
const { makeURLSearchParams } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v10');
const CachedManager = require('./CachedManager');
const { DiscordjsTypeError, ErrorCodes } = require('../errors/index');
const { Subscription } = require('../structures/Subscription');
const { resolveSKUId } = require('../util/Util');
/**
* Manages API methods for subscriptions and stores their cache.
* @extends {CachedManager}
*/
class SubscriptionManager extends CachedManager {
constructor(client, iterable) {
super(client, Subscription, iterable);
}
/**
* The cache of this manager
* @type {Collection<Snowflake, Subscription>}
* @name SubscriptionManager#cache
*/
/**
* Options used to fetch a subscription
* @typedef {BaseFetchOptions} FetchSubscriptionOptions
* @property {SKUResolvable} sku The SKU to fetch the subscription for
* @property {Snowflake} subscriptionId The id of the subscription to fetch
*/
/**
* Options used to fetch subscriptions
* @typedef {Object} FetchSubscriptionsOptions
* @property {Snowflake} [after] Consider only subscriptions after this subscription id
* @property {Snowflake} [before] Consider only subscriptions before this subscription id
* @property {number} [limit] The maximum number of subscriptions to fetch
* @property {SKUResolvable} sku The SKU to fetch subscriptions for
* @property {UserResolvable} user The user to fetch entitlements for
* <warn>If both `before` and `after` are provided, only `before` is respected</warn>
*/
/**
* Fetches subscriptions for this application
* @param {FetchSubscriptionOptions|FetchSubscriptionsOptions} [options={}] Options for fetching the subscriptions
* @returns {Promise<Subscription|Collection<Snowflake, Subscription>>}
*/
async fetch(options = {}) {
if (typeof options !== 'object') throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true);
const { after, before, cache, limit, sku, subscriptionId, user } = options;
const skuId = resolveSKUId(sku);
if (!skuId) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'sku', 'SKUResolvable');
if (subscriptionId) {
const subscription = await this.client.rest.get(Routes.skuSubscription(skuId, subscriptionId));
return this._add(subscription, cache);
}
const query = makeURLSearchParams({
limit,
user_id: this.client.users.resolveId(user) ?? undefined,
sku_id: skuId,
before,
after,
});
const subscriptions = await this.client.rest.get(Routes.skuSubscriptions(skuId), { query });
return subscriptions.reduce(
(coll, subscription) => coll.set(subscription.id, this._add(subscription, cache)),
new Collection(),
);
}
}
exports.SubscriptionManager = SubscriptionManager;

View File

@@ -1,15 +1,11 @@
'use strict';
const process = require('node:process');
const { Collection } = require('@discordjs/collection');
const { makeURLSearchParams } = require('@discordjs/rest');
const { Routes } = require('discord-api-types/v10');
const CachedManager = require('./CachedManager');
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
const ThreadMember = require('../structures/ThreadMember');
const { emitDeprecationWarningForRemoveThreadMember } = require('../util/Util');
let deprecationEmittedForAdd = false;
/**
* Manages API methods for GuildMembers and stores their cache.
@@ -57,7 +53,7 @@ class ThreadMemberManager extends CachedManager {
* @readonly
*/
get me() {
return this.cache.get(this.client.user.id) ?? null;
return this.resolve(this.client.user.id);
}
/**
@@ -75,8 +71,8 @@ class ThreadMemberManager extends CachedManager {
resolve(member) {
const memberResolvable = super.resolve(member);
if (memberResolvable) return memberResolvable;
const userId = this.client.users.resolveId(member);
if (userId) return super.cache.get(userId) ?? null;
const userResolvable = this.client.users.resolveId(member);
if (userResolvable) return super.resolve(userResolvable);
return null;
}
@@ -96,20 +92,9 @@ class ThreadMemberManager extends CachedManager {
* Adds a member to the thread.
* @param {UserResolvable|'@me'} member The member to add
* @param {string} [reason] The reason for adding this member
* <warn>This parameter is **deprecated**. Reasons cannot be used.</warn>
* @returns {Promise<Snowflake>}
*/
async add(member, reason) {
if (reason !== undefined && !deprecationEmittedForAdd) {
process.emitWarning(
// eslint-disable-next-line max-len
'The reason parameter of ThreadMemberManager#add() is deprecated as Discord does not parse them. It will be removed in the next major version.',
'DeprecationWarning',
);
deprecationEmittedForAdd = true;
}
const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
await this.client.rest.put(Routes.threadMembers(this.thread.id, id), { reason });
@@ -120,14 +105,9 @@ class ThreadMemberManager extends CachedManager {
* Remove a user from the thread.
* @param {UserResolvable|'@me'} member The member to remove
* @param {string} [reason] The reason for removing this member from the thread
* <warn>This parameter is **deprecated**. Reasons cannot be used.</warn>
* @returns {Promise<Snowflake>}
*/
async remove(member, reason) {
if (reason !== undefined) {
emitDeprecationWarningForRemoveThreadMember(this.constructor.name);
}
const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'member', 'UserResolvable');
await this.client.rest.delete(Routes.threadMembers(this.thread.id, id), { reason });

View File

@@ -7,7 +7,6 @@ const { GuildMember } = require('../structures/GuildMember');
const { Message } = require('../structures/Message');
const ThreadMember = require('../structures/ThreadMember');
const User = require('../structures/User');
const { emitDeprecationWarningForUserFetchFlags } = require('../util/Util');
/**
* Manages API methods for users and stores their cache.
@@ -101,11 +100,8 @@ class UserManager extends CachedManager {
* @param {UserResolvable} user The UserResolvable to identify
* @param {BaseFetchOptions} [options] Additional options for this fetch
* @returns {Promise<UserFlagsBitField>}
* @deprecated <warn>This method is deprecated and will be removed in the next major version.
* Flags may still be retrieved via {@link UserManager#fetch}.</warn>
*/
async fetchFlags(user, options) {
emitDeprecationWarningForUserFetchFlags(this.constructor.name);
return (await this.fetch(user, options)).flags;
}

View File

@@ -8,7 +8,7 @@ const { makeError, makePlainError } = require('../util/Util');
/**
* Helper class for sharded clients spawned as a child process/worker, such as from a {@link ShardingManager}.
* Utilizes IPC to send and receive data to/from the master process and other shards.
* Utilises IPC to send and receive data to/from the master process and other shards.
*/
class ShardClientUtil {
constructor(client, mode) {

View File

@@ -14,7 +14,7 @@ const { fetchRecommendedShardCount } = require('../util/Util');
* This is a utility class that makes multi-process sharding of a bot an easy and painless experience.
* It works by spawning a self-contained {@link ChildProcess} or {@link Worker} for each individual shard, each
* containing its own instance of your bot's {@link Client}. They all have a line of communication with the master
* process, and there are several useful methods that utilize it in order to simplify tasks that are normally difficult
* process, and there are several useful methods that utilise it in order to simplify tasks that are normally difficult
* with sharding. It can spawn a specific number of shards or the amount that Discord suggests for the bot, and takes a
* path to your main bot script to launch for each one.
* @extends {EventEmitter}

View File

@@ -418,7 +418,7 @@ class ApplicationCommand extends Base {
command.descriptionLocalizations ?? command.description_localizations ?? {},
this.descriptionLocalizations ?? {},
) ||
!isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? []) ||
!isEqual(command.integrationTypes ?? command.integration_types ?? [], this.integrationTypes ?? {}) ||
!isEqual(command.contexts ?? [], this.contexts ?? [])
) {
return false;

View File

@@ -155,14 +155,6 @@ class BaseChannel extends Base {
return 'availableTags' in this;
}
/**
* Indicates whether this channel is sendable.
* @returns {boolean}
*/
isSendable() {
return 'send' in this;
}
toJSON(...props) {
return super.toJSON({ createdTimestamp: true }, ...props);
}

View File

@@ -107,21 +107,6 @@ class BaseInteraction extends Base {
(coll, entitlement) => coll.set(entitlement.id, this.client.application.entitlements._add(entitlement)),
new Collection(),
);
/* eslint-disable max-len */
/**
* Mapping of installation contexts that the interaction was authorized for the related user or guild ids
* @type {APIAuthorizingIntegrationOwnersMap}
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-authorizing-integration-owners-object}
*/
this.authorizingIntegrationOwners = data.authorizing_integration_owners;
/* eslint-enable max-len */
/**
* Context where the interaction was triggered from
* @type {?InteractionContextType}
*/
this.context = data.context ?? null;
}
/**

View File

@@ -9,7 +9,6 @@ const Application = require('./interfaces/Application');
const ApplicationCommandManager = require('../managers/ApplicationCommandManager');
const ApplicationEmojiManager = require('../managers/ApplicationEmojiManager');
const { EntitlementManager } = require('../managers/EntitlementManager');
const { SubscriptionManager } = require('../managers/SubscriptionManager');
const ApplicationFlagsBitField = require('../util/ApplicationFlagsBitField');
const { resolveImage } = require('../util/DataResolver');
const PermissionsBitField = require('../util/PermissionsBitField');
@@ -45,12 +44,6 @@ class ClientApplication extends Application {
* @type {EntitlementManager}
*/
this.entitlements = new EntitlementManager(this.client);
/**
* The subscription manager for this application
* @type {SubscriptionManager}
*/
this.subscriptions = new SubscriptionManager(this.client);
}
_patch(data) {
@@ -243,36 +236,6 @@ class ClientApplication extends Application {
this.roleConnectionsVerificationURL ??= null;
}
if ('event_webhooks_url' in data) {
/**
* This application's URL to receive event webhooks
* @type {?string}
*/
this.eventWebhooksURL = data.event_webhooks_url;
} else {
this.eventWebhooksURL ??= null;
}
if ('event_webhooks_status' in data) {
/**
* This application's event webhooks status
* @type {?ApplicationWebhookEventStatus}
*/
this.eventWebhooksStatus = data.event_webhooks_status;
} else {
this.eventWebhooksStatus ??= null;
}
if ('event_webhooks_types' in data) {
/**
* List of event webhooks types this application subscribes to
* @type {?ApplicationWebhookEventType[]}
*/
this.eventWebhooksTypes = data.event_webhooks_types;
} else {
this.eventWebhooksTypes ??= null;
}
/**
* The owner of this OAuth application
* @type {?(User|Team)}
@@ -314,10 +277,6 @@ class ClientApplication extends Application {
* @property {?(BufferResolvable|Base64Resolvable)} [icon] The application's icon
* @property {?(BufferResolvable|Base64Resolvable)} [coverImage] The application's cover image
* @property {string} [interactionsEndpointURL] The application's interaction endpoint URL
* @property {string} [eventWebhooksURL] The application's event webhooks URL
* @property {ApplicationWebhookEventStatus.Enabled|ApplicationWebhookEventStatus.Disabled} [eventWebhooksStatus]
* The application's event webhooks status.
* @property {ApplicationWebhookEventType[]} [eventWebhooksTypes] The application's event webhooks types
* @property {string[]} [tags] The application's tags
*/
@@ -335,9 +294,6 @@ class ClientApplication extends Application {
icon,
coverImage,
interactionsEndpointURL,
eventWebhooksURL,
eventWebhooksStatus,
eventWebhooksTypes,
tags,
} = {}) {
const data = await this.client.rest.patch(Routes.currentApplication(), {
@@ -350,9 +306,6 @@ class ClientApplication extends Application {
icon: icon && (await resolveImage(icon)),
cover_image: coverImage && (await resolveImage(coverImage)),
interactions_endpoint_url: interactionsEndpointURL,
event_webhooks_url: eventWebhooksURL,
event_webhooks_status: eventWebhooksStatus,
event_webhooks_types: eventWebhooksTypes,
tags,
},
});

View File

@@ -45,6 +45,21 @@ class CommandInteraction extends BaseInteraction {
*/
this.commandGuildId = data.data.guild_id ?? null;
/* eslint-disable max-len */
/**
* Mapping of installation contexts that the interaction was authorized for the related user or guild ids
* @type {APIAuthorizingIntegrationOwnersMap}
* @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-authorizing-integration-owners-object}
*/
this.authorizingIntegrationOwners = data.authorizing_integration_owners;
/* eslint-enable max-len */
/**
* Context where the interaction was triggered from
* @type {?InteractionContextType}
*/
this.context = data.context ?? null;
/**
* Whether the reply to this interaction has been deferred
* @type {boolean}

View File

@@ -73,9 +73,10 @@ class Entitlement extends Base {
if ('starts_at' in data) {
/**
* The timestamp at which this entitlement is valid
* <info>This is only `null` for test entitlements</info>
* @type {?number}
*/
this.startsTimestamp = data.starts_at ? Date.parse(data.starts_at) : null;
this.startsTimestamp = Date.parse(data.starts_at);
} else {
this.startsTimestamp ??= null;
}
@@ -83,9 +84,10 @@ class Entitlement extends Base {
if ('ends_at' in data) {
/**
* The timestamp at which this entitlement is no longer valid
* <info>This is only `null` for test entitlements</info>
* @type {?number}
*/
this.endsTimestamp = data.ends_at ? Date.parse(data.ends_at) : null;
this.endsTimestamp = Date.parse(data.ends_at);
} else {
this.endsTimestamp ??= null;
}
@@ -112,6 +114,7 @@ class Entitlement extends Base {
/**
* The start date at which this entitlement is valid
* <info>This is only `null` for test entitlements</info>
* @type {?Date}
*/
get startsAt() {
@@ -120,6 +123,7 @@ class Entitlement extends Base {
/**
* The end date at which this entitlement is no longer valid
* <info>This is only `null` for test entitlements</info>
* @type {?Date}
*/
get endsAt() {

View File

@@ -84,17 +84,6 @@ class GuildMember extends Base {
} else if (typeof this.avatar !== 'string') {
this.avatar = null;
}
if ('banner' in data) {
/**
* The guild member's banner hash.
* @type {?string}
*/
this.banner = data.banner;
} else {
this.banner ??= null;
}
if ('joined_at' in data) this.joinedTimestamp = Date.parse(data.joined_at);
if ('premium_since' in data) {
this.premiumSinceTimestamp = data.premium_since ? Date.parse(data.premium_since) : null;
@@ -166,15 +155,6 @@ 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 banner.
* @param {ImageURLOptions} [options={}] Options for the banner URL
* @returns {?string}
*/
bannerURL(options = {}) {
return this.banner && this.client.rest.cdn.guildMemberBanner(this.guild.id, this.id, this.banner, options);
}
/**
* A link to the member's guild avatar if they have one.
* Otherwise, a link to their {@link User#displayAvatarURL} will be returned.
@@ -185,16 +165,6 @@ class GuildMember extends Base {
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
}
/**
* A link to the member's guild banner if they have one.
* Otherwise, a link to their {@link User#bannerURL} will be returned.
* @param {ImageURLOptions} [options={}] Options for the image URL
* @returns {?string}
*/
displayBannerURL(options) {
return this.bannerURL(options) ?? this.user.bannerURL(options);
}
/**
* The time this member joined the guild
* @type {?Date}
@@ -228,7 +198,7 @@ class GuildMember extends Base {
* @readonly
*/
get presence() {
return this.guild.presences.cache.get(this.id) ?? null;
return this.guild.presences.resolve(this.id);
}
/**
@@ -494,7 +464,6 @@ class GuildMember extends Base {
this.joinedTimestamp === member.joinedTimestamp &&
this.nickname === member.nickname &&
this.avatar === member.avatar &&
this.banner === member.banner &&
this.pending === member.pending &&
this.communicationDisabledUntilTimestamp === member.communicationDisabledUntilTimestamp &&
this.flags.bitfield === member.flags.bitfield &&
@@ -522,9 +491,7 @@ class GuildMember extends Base {
roles: true,
});
json.avatarURL = this.avatarURL();
json.bannerURL = this.bannerURL();
json.displayAvatarURL = this.displayAvatarURL();
json.displayBannerURL = this.displayBannerURL();
return json;
}
}

View File

@@ -79,7 +79,7 @@ class GuildOnboardingPromptOption extends Base {
*/
get emoji() {
if (!this._emoji.id && !this._emoji.name) return null;
return this.client.emojis.cache.get(this._emoji.id) ?? new Emoji(this.client, this._emoji);
return this.client.emojis.resolve(this._emoji.id) ?? new Emoji(this.client, this._emoji);
}
}

View File

@@ -189,56 +189,6 @@ class GuildScheduledEvent extends Base {
} else {
this.image ??= null;
}
/**
* Represents the recurrence rule for a {@link GuildScheduledEvent}.
* @typedef {Object} GuildScheduledEventRecurrenceRule
* @property {number} startTimestamp The timestamp the recurrence rule interval starts at
* @property {Date} startAt The time the recurrence rule interval starts at
* @property {?number} endTimestamp The timestamp the recurrence rule interval ends at
* @property {?Date} endAt The time the recurrence rule interval ends at
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
* @property {number} interval The spacing between the events
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
* @property {?number[]} byMonthDay The days within a month to recur on
* @property {?number[]} byYearDay The days within a year to recur on
* @property {?number} count The total amount of times the event is allowed to recur before stopping
*/
/**
* @typedef {Object} GuildScheduledEventRecurrenceRuleNWeekday
* @property {number} n The week to recur on
* @property {GuildScheduledEventRecurrenceRuleWeekday} day The day within the week to recur on
*/
if ('recurrence_rule' in data) {
/**
* The recurrence rule for this scheduled event
* @type {?GuildScheduledEventRecurrenceRule}
*/
this.recurrenceRule = data.recurrence_rule && {
startTimestamp: Date.parse(data.recurrence_rule.start),
get startAt() {
return new Date(this.startTimestamp);
},
endTimestamp: data.recurrence_rule.end && Date.parse(data.recurrence_rule.end),
get endAt() {
return this.endTimestamp && new Date(this.endTimestamp);
},
frequency: data.recurrence_rule.frequency,
interval: data.recurrence_rule.interval,
byWeekday: data.recurrence_rule.by_weekday,
byNWeekday: data.recurrence_rule.by_n_weekday,
byMonth: data.recurrence_rule.by_month,
byMonthDay: data.recurrence_rule.by_month_day,
byYearDay: data.recurrence_rule.by_year_day,
count: data.recurrence_rule.count,
};
} else {
this.recurrenceRule ??= null;
}
}
/**

View File

@@ -1,74 +0,0 @@
'use strict';
const { DiscordSnowflake } = require('@sapphire/snowflake');
/**
* Represents an interaction callback response from Discord
*/
class InteractionCallback {
constructor(client, data) {
/**
* The client that instantiated this.
* @name InteractionCallback#client
* @type {Client}
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
/**
* The id of the original interaction response
* @type {Snowflake}
*/
this.id = data.id;
/**
* The type of the original interaction
* @type {InteractionType}
*/
this.type = data.type;
/**
* The instance id of the Activity if one was launched or joined
* @type {?string}
*/
this.activityInstanceId = data.activity_instance_id ?? null;
/**
* The id of the message that was created by the interaction
* @type {?Snowflake}
*/
this.responseMessageId = data.response_message_id ?? null;
/**
* Whether the message is in a loading state
* @type {?boolean}
*/
this.responseMessageLoading = data.response_message_loading ?? null;
/**
* Whether the response message was ephemeral
* @type {?boolean}
*/
this.responseMessageEphemeral = data.response_message_ephemeral ?? null;
}
/**
* The timestamp the original interaction was created at
* @type {number}
* @readonly
*/
get createdTimestamp() {
return DiscordSnowflake.timestampFrom(this.id);
}
/**
* The time the original interaction was created at
* @type {Date}
* @readonly
*/
get createdAt() {
return new Date(this.createdTimestamp);
}
}
module.exports = InteractionCallback;

View File

@@ -1,52 +0,0 @@
'use strict';
const { lazy } = require('@discordjs/util');
const getMessage = lazy(() => require('./Message').Message);
/**
* Represents the resource that was created by the interaction response.
*/
class InteractionCallbackResource {
constructor(client, data) {
/**
* The client that instantiated this
* @name InteractionCallbackResource#client
* @type {Client}
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
/**
* The interaction callback type
* @type {InteractionResponseType}
*/
this.type = data.type;
/**
* The Activity launched by an interaction
* @typedef {Object} ActivityInstance
* @property {string} id The instance id of the Activity
*/
/**
* Represents the Activity launched by this interaction
* @type {?ActivityInstance}
*/
this.activityInstance = data.activity_instance ?? null;
if ('message' in data) {
/**
* The message created by the interaction
* @type {?Message}
*/
this.message =
this.client.channels.cache.get(data.message.channel_id)?.messages._add(data.message) ??
new (getMessage())(client, data.message);
} else {
this.message = null;
}
}
}
module.exports = InteractionCallbackResource;

View File

@@ -1,33 +0,0 @@
'use strict';
const InteractionCallback = require('./InteractionCallback');
const InteractionCallbackResource = require('./InteractionCallbackResource');
/**
* Represents an interaction's response
*/
class InteractionCallbackResponse {
constructor(client, data) {
/**
* The client that instantiated this
* @name InteractionCallbackResponse#client
* @type {Client}
* @readonly
*/
Object.defineProperty(this, 'client', { value: client });
/**
* The interaction object associated with the interaction callback response
* @type {InteractionCallback}
*/
this.interaction = new InteractionCallback(client, data.interaction);
/**
* The resource that was created by the interaction response
* @type {?InteractionCallbackResource}
*/
this.resource = data.resource ? new InteractionCallbackResource(client, data.resource) : null;
}
}
module.exports = InteractionCallbackResponse;

View File

@@ -153,8 +153,8 @@ class InteractionCollector extends Collector {
if (this.messageId && interaction.message?.id !== this.messageId) return null;
if (
this.messageInteractionId &&
interaction.message?.interactionMetadata?.id &&
interaction.message.interactionMetadata.id !== this.messageInteractionId
interaction.message?.interaction?.id &&
interaction.message.interaction.id !== this.messageInteractionId
) {
return null;
}
@@ -180,8 +180,8 @@ class InteractionCollector extends Collector {
if (this.messageId && interaction.message?.id !== this.messageId) return null;
if (
this.messageInteractionId &&
interaction.message?.interactionMetadata?.id &&
interaction.message.interactionMetadata.id !== this.messageInteractionId
interaction.message?.interaction?.id &&
interaction.message.interaction.id !== this.messageInteractionId
) {
return null;
}
@@ -224,7 +224,7 @@ class InteractionCollector extends Collector {
this.stop('messageDelete');
}
if (message.interactionMetadata?.id === this.messageInteractionId) {
if (message.interaction?.id === this.messageInteractionId) {
this.stop('messageDelete');
}
}

View File

@@ -40,7 +40,7 @@ class Invite extends Base {
*/
this.guild ??= null;
if (data.guild) {
this.guild = this.client.guilds.cache.get(data.guild.id) ?? new InviteGuild(this.client, data.guild);
this.guild = this.client.guilds.resolve(data.guild.id) ?? new InviteGuild(this.client, data.guild);
}
if ('code' in data) {

View File

@@ -359,12 +359,11 @@ class Message extends Base {
* * {@link MessageType.ChannelFollowAdd}
* * {@link MessageType.Reply}
* * {@link MessageType.ThreadStarterMessage}
* @see {@link https://discord.com/developers/docs/resources/message#message-object-message-types}
* @see {@link https://discord.com/developers/docs/resources/channel#message-types}
* @typedef {Object} MessageReference
* @property {Snowflake} channelId The channel id that was referenced
* @property {Snowflake|undefined} guildId The guild id that was referenced
* @property {Snowflake|undefined} messageId The message id that was referenced
* @property {MessageReferenceType} type The type of message reference
*/
if ('message_reference' in data) {
@@ -376,7 +375,6 @@ class Message extends Base {
channelId: data.message_reference.channel_id,
guildId: data.message_reference.guild_id,
messageId: data.message_reference.message_id,
type: data.message_reference.type,
};
} else {
this.reference ??= null;
@@ -428,7 +426,6 @@ class Message extends Base {
/**
* Partial data of the interaction that this message is a reply to
* @type {?MessageInteraction}
* @deprecated Use {@link Message#interactionMetadata} instead.
*/
this.interaction = {
id: data.interaction.id,
@@ -450,29 +447,6 @@ class Message extends Base {
this.poll ??= null;
}
if (data.message_snapshots) {
/**
* The message associated with the message reference
* @type {Collection<Snowflake, Message>}
*/
this.messageSnapshots = data.message_snapshots.reduce((coll, snapshot) => {
const channel = this.client.channels.resolve(this.reference.channelId);
const snapshotData = {
...snapshot.message,
id: this.reference.messageId,
channel_id: this.reference.channelId,
guild_id: this.reference.guildId,
};
return coll.set(
this.reference.messageId,
channel ? channel.messages._add(snapshotData) : new this.constructor(this.client, snapshotData),
);
}, new Collection());
} else {
this.messageSnapshots ??= new Collection();
}
/**
* A call associated with a message
* @typedef {Object} MessageCall
@@ -570,7 +544,7 @@ class Message extends Base {
* @readonly
*/
get thread() {
return this.channel?.threads?.cache.get(this.id) ?? null;
return this.channel?.threads?.resolve(this.id) ?? null;
}
/**

View File

@@ -92,7 +92,6 @@ class MessagePayload {
* Whether or not the target is an {@link BaseInteraction} or an {@link InteractionWebhook}
* @type {boolean}
* @readonly
* @deprecated This will no longer serve a purpose in the next major version.
*/
get isInteraction() {
const BaseInteraction = getBaseInteraction();
@@ -165,12 +164,15 @@ class MessagePayload {
let flags;
if (
// eslint-disable-next-line eqeqeq
this.options.flags != null ||
this.options.flags !== undefined ||
(this.isMessage && this.options.reply === undefined) ||
this.isMessageManager
) {
flags = new MessageFlagsBitField(this.options.flags).bitfield;
flags =
// eslint-disable-next-line eqeqeq
this.options.flags != null
? new MessageFlagsBitField(this.options.flags).bitfield
: this.target.flags?.bitfield;
}
if (isInteraction && this.options.ephemeral) {

View File

@@ -1,7 +1,6 @@
'use strict';
const { Routes } = require('discord-api-types/v10');
const ApplicationEmoji = require('./ApplicationEmoji');
const GuildEmoji = require('./GuildEmoji');
const ReactionEmoji = require('./ReactionEmoji');
const ReactionUserManager = require('../managers/ReactionUserManager');
@@ -36,7 +35,7 @@ class MessageReaction {
* Whether the client has super-reacted using this emoji
* @type {boolean}
*/
this.meBurst = Boolean(data.me_burst);
this.meBurst = data.me_burst;
/**
* A manager of the users that have given this reaction
@@ -52,7 +51,7 @@ class MessageReaction {
}
_patch(data) {
if (data.burst_colors) {
if ('burst_colors' in data) {
/**
* Hexadecimal colors used for this super reaction
* @type {?string[]}
@@ -109,24 +108,16 @@ class MessageReaction {
}
/**
* The emoji of this reaction. Either a {@link GuildEmoji} object for known custom emojis,
* {@link ApplicationEmoji} for application emojis, or a {@link ReactionEmoji} object
* which has fewer properties. Whatever the prototype of the emoji, it will still have
* The emoji of this reaction. Either a {@link GuildEmoji} object for known custom emojis, or a {@link ReactionEmoji}
* object which has fewer properties. Whatever the prototype of the emoji, it will still have
* `name`, `id`, `identifier` and `toString()`
* @type {GuildEmoji|ReactionEmoji|ApplicationEmoji}
* @type {GuildEmoji|ReactionEmoji}
* @readonly
*/
get emoji() {
if (this._emoji instanceof GuildEmoji) return this._emoji;
if (this._emoji instanceof ApplicationEmoji) return this._emoji;
// Check to see if the emoji has become known to the client
if (this._emoji.id) {
const applicationEmojis = this.message.client.application.emojis.cache;
if (applicationEmojis.has(this._emoji.id)) {
const emoji = applicationEmojis.get(this._emoji.id);
this._emoji = emoji;
return emoji;
}
const emojis = this.message.client.emojis.cache;
if (emojis.has(this._emoji.id)) {
const emoji = emojis.get(this._emoji.id);

View File

@@ -180,7 +180,7 @@ class PermissionOverwrites extends Base {
};
}
const userOrRole = guild.roles.cache.get(overwrite.id) ?? guild.client.users.cache.get(overwrite.id);
const userOrRole = guild.roles.resolve(overwrite.id) ?? guild.client.users.resolve(overwrite.id);
if (!userOrRole) throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'parameter', 'User nor a Role');
const type = userOrRole instanceof Role ? OverwriteType.Role : OverwriteType.Member;

View File

@@ -61,7 +61,7 @@ class PollAnswer extends Base {
*/
get emoji() {
if (!this._emoji || (!this._emoji.id && !this._emoji.name)) return null;
return this.client.emojis.cache.get(this._emoji.id) ?? new Emoji(this.client, this._emoji);
return this.client.emojis.resolve(this._emoji.id) ?? new Emoji(this.client, this._emoji);
}
/**

View File

@@ -1,109 +0,0 @@
'use strict';
const Base = require('./Base');
/**
* Represents a Subscription
* @extends {Base}
*/
class Subscription extends Base {
constructor(client, data) {
super(client);
/**
* The id of the subscription
* @type {Snowflake}
*/
this.id = data.id;
/**
* The id of the user who subscribed
* @type {Snowflake}
*/
this.userId = data.user_id;
this._patch(data);
}
_patch(data) {
/**
* The SKU ids subscribed to
* @type {Snowflake[]}
*/
this.skuIds = data.sku_ids;
/**
* The entitlement ids granted for this subscription
* @type {Snowflake[]}
*/
this.entitlementIds = data.entitlement_ids;
/**
* The timestamp the current subscription period will start at
* @type {number}
*/
this.currentPeriodStartTimestamp = Date.parse(data.current_period_start);
/**
* The timestamp the current subscription period will end at
* @type {number}
*/
this.currentPeriodEndTimestamp = Date.parse(data.current_period_end);
/**
* The current status of the subscription
* @type {SubscriptionStatus}
*/
this.status = data.status;
if ('canceled_at' in data) {
/**
* The timestamp of when the subscription was canceled
* @type {?number}
*/
this.canceledTimestamp = data.canceled_at ? Date.parse(data.canceled_at) : null;
} else {
this.canceledTimestamp ??= null;
}
if ('country' in data) {
/**
* ISO 3166-1 alpha-2 country code of the payment source used to purchase the subscription.
* Missing unless queried with a private OAuth scope.
* @type {?string}
*/
this.country = data.country;
} else {
this.country ??= null;
}
}
/**
* The time the subscription was canceled
* @type {?Date}
* @readonly
*/
get canceledAt() {
return this.canceledTimestamp && new Date(this.canceledTimestamp);
}
/**
* The time the current subscription period will start at
* @type {Date}
* @readonly
*/
get currentPeriodStartAt() {
return new Date(this.currentPeriodStartTimestamp);
}
/**
* The time the current subscription period will end at
* @type {Date}
* @readonly
*/
get currentPeriodEndAt() {
return new Date(this.currentPeriodEndTimestamp);
}
}
exports.Subscription = Subscription;

View File

@@ -6,7 +6,7 @@ const { RESTJSONErrorCodes, ChannelFlags, ChannelType, PermissionFlagsBits, Rout
const { BaseChannel } = require('./BaseChannel');
const getThreadOnlyChannel = lazy(() => require('./ThreadOnlyChannel'));
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { DiscordjsRangeError, ErrorCodes } = require('../errors');
const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors');
const GuildMessageManager = require('../managers/GuildMessageManager');
const ThreadMemberManager = require('../managers/ThreadMemberManager');
const ChannelFlagsBitField = require('../util/ChannelFlagsBitField');
@@ -32,12 +32,6 @@ class ThreadChannel extends BaseChannel {
*/
this.guildId = guild?.id ?? data.guild_id;
/**
* The id of the member who created this thread
* @type {Snowflake}
*/
this.ownerId = data.owner_id;
/**
* A manager of the messages sent to this thread
* @type {GuildMessageManager}
@@ -128,6 +122,16 @@ class ThreadChannel extends BaseChannel {
this._createdTimestamp ??= this.type === ChannelType.PrivateThread ? super.createdTimestamp : null;
if ('owner_id' in data) {
/**
* The id of the member who created this thread
* @type {?Snowflake}
*/
this.ownerId = data.owner_id;
} else {
this.ownerId ??= null;
}
if ('last_message_id' in data) {
/**
* The last message id sent in this thread, if one was sent
@@ -284,19 +288,17 @@ class ThreadChannel extends BaseChannel {
return this.parent?.permissionsFor(memberOrRole, checkAdmin) ?? null;
}
/**
* Options used to fetch a thread owner.
* @typedef {BaseFetchOptions} FetchThreadOwnerOptions
* @property {boolean} [withMember] Whether to also return the guild member associated with this thread member
*/
/**
* Fetches the owner of this thread. If the thread member object isn't needed,
* use {@link ThreadChannel#ownerId} instead.
* @param {FetchThreadOwnerOptions} [options] Options for fetching the owner
* @param {BaseFetchOptions} [options] The options for fetching the member
* @returns {Promise<?ThreadMember>}
*/
async fetchOwner(options) {
if (!this.ownerId) {
throw new DiscordjsError(ErrorCodes.FetchOwnerId, 'thread');
}
// TODO: Remove that catch in the next major version
const member = await this.members._fetchSingle({ ...options, member: this.ownerId }).catch(error => {
if (error instanceof DiscordAPIError && error.code === RESTJSONErrorCodes.UnknownMember) {

View File

@@ -2,7 +2,6 @@
const Base = require('./Base');
const ThreadMemberFlagsBitField = require('../util/ThreadMemberFlagsBitField');
const { emitDeprecationWarningForRemoveThreadMember } = require('../util/Util');
/**
* Represents a Member for a Thread.
@@ -70,7 +69,7 @@ class ThreadMember extends Base {
* @readonly
*/
get guildMember() {
return this.member ?? this.thread.guild.members.cache.get(this.id) ?? null;
return this.member ?? this.thread.guild.members.resolve(this.id);
}
/**
@@ -88,7 +87,7 @@ class ThreadMember extends Base {
* @readonly
*/
get user() {
return this.client.users.cache.get(this.id) ?? null;
return this.client.users.resolve(this.id);
}
/**
@@ -103,14 +102,9 @@ class ThreadMember extends Base {
/**
* Removes this member from the thread.
* @param {string} [reason] Reason for removing the member
* <warn>This parameter is **deprecated**. Reasons cannot be used.</warn>
* @returns {Promise<ThreadMember>}
*/
async remove(reason) {
if (reason !== undefined) {
emitDeprecationWarningForRemoveThreadMember(this.constructor.name);
}
await this.thread.members.remove(this.id, reason);
return this;
}

View File

@@ -36,7 +36,7 @@ const { transformAPIGuildForumTag, transformAPIGuildDefaultReaction } = require(
*/
/**
* Represents symbols utilized by thread-only channels.
* Represents symbols utilised by thread-only channels.
* @extends {GuildChannel}
* @implements {TextBasedChannel}
* @abstract

View File

@@ -6,7 +6,6 @@ const { DiscordSnowflake } = require('@sapphire/snowflake');
const Base = require('./Base');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const UserFlagsBitField = require('../util/UserFlagsBitField');
const { emitDeprecationWarningForUserFetchFlags } = require('../util/Util');
/**
* Represents a user on Discord.
@@ -347,11 +346,8 @@ class User extends Base {
* Fetches this user's flags.
* @param {boolean} [force=false] Whether to skip the cache check and request the API
* @returns {Promise<UserFlagsBitField>}
* @deprecated <warn>This method is deprecated and will be removed in the next major version.
* Flags may still be retrieved via {@link User#fetch}.</warn>
*/
fetchFlags(force = false) {
emitDeprecationWarningForUserFetchFlags(this.constructor.name);
return this.client.users.fetchFlags(this.id, { force });
}

View File

@@ -1,69 +0,0 @@
'use strict';
const { Emoji } = require('./Emoji');
/**
* Represents an effect used in a {@link VoiceChannel}.
*/
class VoiceChannelEffect {
constructor(data, guild) {
/**
* The guild where the effect was sent from.
* @type {Guild}
*/
this.guild = guild;
/**
* The id of the channel the effect was sent in.
* @type {Snowflake}
*/
this.channelId = data.channel_id;
/**
* The id of the user that sent the effect.
* @type {Snowflake}
*/
this.userId = data.user_id;
/**
* The emoji of the effect.
* @type {?Emoji}
*/
this.emoji = data.emoji ? new Emoji(guild.client, data.emoji) : null;
/**
* The animation type of the effect.
* @type {?VoiceChannelEffectSendAnimationType}
*/
this.animationType = data.animation_type ?? null;
/**
* The animation id of the effect.
* @type {?number}
*/
this.animationId = data.animation_id ?? null;
/**
* The id of the soundboard sound for soundboard effects.
* @type {?(Snowflake|number)}
*/
this.soundId = data.sound_id ?? null;
/**
* The volume of the soundboard sound [0-1] for soundboard effects.
* @type {?number}
*/
this.soundVolume = data.sound_volume ?? null;
}
/**
* The channel the effect was sent in.
* @type {?VoiceChannel}
* @readonly
*/
get channel() {
return this.guild.channels.cache.get(this.channelId) ?? null;
}
}
module.exports = VoiceChannelEffect;

View File

@@ -108,7 +108,7 @@ class Webhook {
* The source guild of the webhook
* @type {?(Guild|APIGuild)}
*/
this.sourceGuild = this.client.guilds?.cache.get(data.source_guild.id) ?? data.source_guild;
this.sourceGuild = this.client.guilds?.resolve(data.source_guild.id) ?? data.source_guild;
} else {
this.sourceGuild ??= null;
}
@@ -118,7 +118,7 @@ class Webhook {
* The source channel of the webhook
* @type {?(NewsChannel|APIChannel)}
*/
this.sourceChannel = this.client.channels?.cache.get(data.source_channel?.id) ?? data.source_channel;
this.sourceChannel = this.client.channels?.resolve(data.source_channel?.id) ?? data.source_channel;
} else {
this.sourceChannel ??= null;
}
@@ -126,7 +126,7 @@ class Webhook {
/**
* Options that can be passed into send.
* @typedef {BaseMessageOptionsWithPoll} WebhookMessageCreateOptions
* @typedef {BaseMessageOptions} WebhookMessageCreateOptions
* @property {boolean} [tts=false] Whether the message should be spoken aloud
* @property {MessageFlags} [flags] Which flags to set for the message.
* <info>Only the {@link MessageFlags.SuppressEmbeds} flag can be set.</info>

View File

@@ -53,7 +53,7 @@ class WelcomeChannel extends Base {
* @type {GuildEmoji|Emoji}
*/
get emoji() {
return this.client.emojis.cache.get(this._emoji.id) ?? new Emoji(this.client, this._emoji);
return this.client.emojis.resolve(this._emoji.id) ?? new Emoji(this.client, this._emoji);
}
}

View File

@@ -1,20 +1,14 @@
'use strict';
const process = require('node:process');
const { deprecate } = require('node:util');
const { makeURLSearchParams } = require('@discordjs/rest');
const { isJSONEncodable } = require('@discordjs/util');
const { InteractionResponseType, MessageFlags, Routes, InteractionType } = require('discord-api-types/v10');
const { DiscordjsError, ErrorCodes } = require('../../errors');
const MessageFlagsBitField = require('../../util/MessageFlagsBitField');
const InteractionCallbackResponse = require('../InteractionCallbackResponse');
const InteractionCollector = require('../InteractionCollector');
const InteractionResponse = require('../InteractionResponse');
const MessagePayload = require('../MessagePayload');
let deprecationEmittedForEphemeralOption = false;
let deprecationEmittedForFetchReplyOption = false;
/**
* @typedef {Object} ModalComponentData
* @property {string} title The title of the modal
@@ -30,33 +24,23 @@ class InteractionResponses {
/**
* Options for deferring the reply to an {@link BaseInteraction}.
* @typedef {Object} InteractionDeferReplyOptions
* @property {boolean} [ephemeral] Whether the reply should be ephemeral.
* <warn>This option is deprecated. Use `flags` instead.</warn>
* @property {MessageFlagsResolvable} [flags] Flags for the reply.
* <info>Only `MessageFlags.Ephemeral` can be set.</info>
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
* @property {boolean} [ephemeral] Whether the reply should be ephemeral
* @property {boolean} [fetchReply] Whether to fetch the reply
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
*/
/**
* Options for deferring and updating the reply to a {@link MessageComponentInteraction}.
* @typedef {Object} InteractionDeferUpdateOptions
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
* @property {boolean} [fetchReply] Whether to fetch the reply
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
*/
/**
* Options for a reply to a {@link BaseInteraction}.
* @typedef {BaseMessageOptionsWithPoll} InteractionReplyOptions
* @property {boolean} [ephemeral] Whether the reply should be ephemeral.
* <warn>This option is deprecated. Use `flags` instead.</warn>
* @typedef {BaseMessageOptions} InteractionReplyOptions
* @property {boolean} [tts=false] Whether the message should be spoken aloud
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
* @property {boolean} [ephemeral] Whether the reply should be ephemeral
* @property {boolean} [fetchReply] Whether to fetch the reply
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
* @property {MessageFlagsResolvable} [flags] Which flags to set for the message.
* @property {MessageFlags} [flags] Which flags to set for the message.
* <info>Only `MessageFlags.Ephemeral`, `MessageFlags.SuppressEmbeds`, and `MessageFlags.SuppressNotifications`
* can be set.</info>
*/
@@ -64,21 +48,13 @@ class InteractionResponses {
/**
* Options for updating the message received from a {@link MessageComponentInteraction}.
* @typedef {MessageEditOptions} InteractionUpdateOptions
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
* @property {boolean} [fetchReply] Whether to fetch the reply
* <warn>This option is deprecated. Use `withResponse` or fetch the response instead.</warn>
*/
/**
* Options for showing a modal in response to a {@link BaseInteraction}
* @typedef {Object} ShowModalOptions
* @property {boolean} [withResponse] Whether to return an {@link InteractionCallbackResponse} as the response
*/
/**
* Defers the reply to this interaction.
* @param {InteractionDeferReplyOptions} [options] Options for deferring the reply to this interaction
* @returns {Promise<InteractionCallbackResponse|Message|InteractionResponse>}
* @returns {Promise<Message|InteractionResponse>}
* @example
* // Defer the reply to this interaction
* interaction.deferReply()
@@ -86,129 +62,67 @@ class InteractionResponses {
* .catch(console.error)
* @example
* // Defer to send an ephemeral reply later
* interaction.deferReply({ flags: MessageFlags.Ephemeral })
* interaction.deferReply({ ephemeral: true })
* .then(console.log)
* .catch(console.error);
*/
async deferReply(options = {}) {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
if ('ephemeral' in options) {
if (!deprecationEmittedForEphemeralOption) {
process.emitWarning(
`Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.`,
);
deprecationEmittedForEphemeralOption = true;
}
}
if ('fetchReply' in options) {
if (!deprecationEmittedForFetchReplyOption) {
process.emitWarning(
// eslint-disable-next-line max-len
`Supplying "fetchReply" for interaction response options is deprecated. Utilize "withResponse" instead or fetch the response after using the method.`,
);
deprecationEmittedForFetchReplyOption = true;
}
}
const flags = new MessageFlagsBitField(options.flags);
if (options.ephemeral) {
flags.add(MessageFlags.Ephemeral);
}
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
this.ephemeral = options.ephemeral ?? false;
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
body: {
type: InteractionResponseType.DeferredChannelMessageWithSource,
data: {
flags: flags.bitfield,
flags: options.ephemeral ? MessageFlags.Ephemeral : undefined,
},
},
auth: false,
query: makeURLSearchParams({ with_response: options.withResponse ?? false }),
});
this.deferred = true;
this.ephemeral = flags.has(MessageFlags.Ephemeral);
return options.withResponse
? new InteractionCallbackResponse(this.client, response)
: options.fetchReply
? this.fetchReply()
: new InteractionResponse(this);
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this);
}
/**
* Creates a reply to this interaction.
* <info>Use the `withResponse` option to get the interaction callback response.</info>
* <info>Use the `fetchReply` option to get the bot's reply message.</info>
* @param {string|MessagePayload|InteractionReplyOptions} options The options for the reply
* @returns {Promise<InteractionCallbackResponse|Message|InteractionResponse>}
* @returns {Promise<Message|InteractionResponse>}
* @example
* // Reply to the interaction and fetch the response
* interaction.reply({ content: 'Pong!', withResponse: true })
* .then((response) => console.log(`Reply sent with content ${response.resource.message.content}`))
* interaction.reply({ content: 'Pong!', fetchReply: true })
* .then((message) => console.log(`Reply sent with content ${message.content}`))
* .catch(console.error);
* @example
* // Create an ephemeral reply with an embed
* const embed = new EmbedBuilder().setDescription('Pong!');
*
* interaction.reply({ embeds: [embed], flags: MessageFlags.Ephemeral })
* interaction.reply({ embeds: [embed], ephemeral: true })
* .then(() => console.log('Reply sent.'))
* .catch(console.error);
*/
async reply(options) {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
if (typeof options !== 'string') {
if ('fetchReply' in options) {
if (!deprecationEmittedForEphemeralOption) {
process.emitWarning(
`Supplying "ephemeral" for interaction response options is deprecated. Utilize flags instead.`,
);
deprecationEmittedForEphemeralOption = true;
}
}
if ('fetchReply' in options) {
if (!deprecationEmittedForFetchReplyOption) {
process.emitWarning(
// eslint-disable-next-line max-len
`Supplying "fetchReply" for interaction response options is deprecated. Utilize "withResponse" instead or fetch the response after using the method.`,
);
deprecationEmittedForFetchReplyOption = true;
}
}
}
let messagePayload;
if (options instanceof MessagePayload) messagePayload = options;
else messagePayload = MessagePayload.create(this, options);
const { body: data, files } = await messagePayload.resolveBody().resolveFiles();
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
this.ephemeral = new MessageFlagsBitField(data.flags).has(MessageFlags.Ephemeral);
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
body: {
type: InteractionResponseType.ChannelMessageWithSource,
data,
},
files,
auth: false,
query: makeURLSearchParams({ with_response: options.withResponse ?? false }),
});
this.ephemeral = Boolean(data.flags & MessageFlags.Ephemeral);
this.replied = true;
return options.withResponse
? new InteractionCallbackResponse(this.client, response)
: options.fetchReply
? this.fetchReply()
: new InteractionResponse(this);
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this);
}
/**
@@ -262,8 +176,6 @@ class InteractionResponses {
* .catch(console.error);
*/
async deleteReply(message = '@original') {
if (!this.deferred && !this.replied) throw new DiscordjsError(ErrorCodes.InteractionNotReplied);
await this.webhook.deleteMessage(message);
}
@@ -280,7 +192,7 @@ class InteractionResponses {
/**
* Defers an update to the message to which the component was attached.
* @param {InteractionDeferUpdateOptions} [options] Options for deferring the update to this interaction
* @returns {Promise<InteractionCallbackResponse|Message|InteractionResponse>}
* @returns {Promise<Message|InteractionResponse>}
* @example
* // Defer updating and reset the component's loading state
* interaction.deferUpdate()
@@ -289,38 +201,21 @@ class InteractionResponses {
*/
async deferUpdate(options = {}) {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
if ('fetchReply' in options) {
if (!deprecationEmittedForFetchReplyOption) {
process.emitWarning(
// eslint-disable-next-line max-len
`Supplying "fetchReply" for interaction response options is deprecated. Utilize "withResponse" instead or fetch the response after using the method.`,
);
deprecationEmittedForFetchReplyOption = true;
}
}
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
body: {
type: InteractionResponseType.DeferredMessageUpdate,
},
auth: false,
query: makeURLSearchParams({ with_response: options.withResponse ?? false }),
});
this.deferred = true;
return options.withResponse
? new InteractionCallbackResponse(this.client, response)
: options.fetchReply
? this.fetchReply()
: new InteractionResponse(this, this.message?.interactionMetadata?.id);
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this, this.message?.interaction?.id);
}
/**
* Updates the original message of the component on which the interaction was received on.
* @param {string|MessagePayload|InteractionUpdateOptions} options The options for the updated message
* @returns {Promise<InteractionCallbackResponse|Message|void>}
* @returns {Promise<Message|void>}
* @example
* // Remove the components from the message
* interaction.update({
@@ -333,60 +228,40 @@ class InteractionResponses {
async update(options) {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
if (typeof options !== 'string' && 'fetchReply' in options) {
if (!deprecationEmittedForFetchReplyOption) {
process.emitWarning(
// eslint-disable-next-line max-len
`Supplying "fetchReply" for interaction response options is deprecated. Utilize "withResponse" instead or fetch the response after using the method.`,
);
deprecationEmittedForFetchReplyOption = true;
}
}
let messagePayload;
if (options instanceof MessagePayload) messagePayload = options;
else messagePayload = MessagePayload.create(this, options);
const { body: data, files } = await messagePayload.resolveBody().resolveFiles();
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
body: {
type: InteractionResponseType.UpdateMessage,
data,
},
files,
auth: false,
query: makeURLSearchParams({ with_response: options.withResponse ?? false }),
});
this.replied = true;
return options.withResponse
? new InteractionCallbackResponse(this.client, response)
: options.fetchReply
? this.fetchReply()
: new InteractionResponse(this, this.message.interactionMetadata?.id);
return options.fetchReply ? this.fetchReply() : new InteractionResponse(this, this.message.interaction?.id);
}
/**
* Shows a modal component
* @param {ModalBuilder|ModalComponentData|APIModalInteractionResponseCallbackData} modal The modal to show
* @param {ShowModalOptions} [options={}] The options for sending this interaction response
* @returns {Promise<InteractionCallbackResponse|undefined>}
* @returns {Promise<void>}
*/
async showModal(modal, options = {}) {
async showModal(modal) {
if (this.deferred || this.replied) throw new DiscordjsError(ErrorCodes.InteractionAlreadyReplied);
const response = await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
await this.client.rest.post(Routes.interactionCallback(this.id, this.token), {
body: {
type: InteractionResponseType.Modal,
data: isJSONEncodable(modal) ? modal.toJSON() : this.client.options.jsonTransformer(modal),
},
auth: false,
query: makeURLSearchParams({ with_response: options.withResponse ?? false }),
});
this.replied = true;
return options.withResponse ? new InteractionCallbackResponse(this.client, response) : undefined;
}
/**

View File

@@ -75,16 +75,11 @@ class TextBasedChannel {
* @property {?string} [content=''] The content for the message. This can only be `null` when editing a message.
* @property {Array<(EmbedBuilder|Embed|APIEmbed)>} [embeds] The embeds for the message
* @property {MessageMentionOptions} [allowedMentions] Which mentions should be parsed from the message content
* (see [here](https://discord.com/developers/docs/resources/message#allowed-mentions-object) for more details)
* (see [here](https://discord.com/developers/docs/resources/channel#allowed-mentions-object) for more details)
* @property {Array<(AttachmentBuilder|Attachment|AttachmentPayload|BufferResolvable)>} [files]
* The files to send with the message.
* @property {Array<(ActionRowBuilder|ActionRow|APIActionRowComponent)>} [components]
* Action rows containing interactive components for the message (buttons, select menus)
*/
/**
* The base message options for messages including a poll.
* @typedef {BaseMessageOptions} BaseMessageOptionsWithPoll
* @property {PollData} [poll] The poll to send with the message
*/
@@ -98,7 +93,7 @@ class TextBasedChannel {
/**
* The options for sending a message.
* @typedef {BaseMessageOptionsWithPoll} BaseMessageCreateOptions
* @typedef {BaseMessageOptions} BaseMessageCreateOptions
* @property {boolean} [tts=false] Whether the message should be spoken aloud
* @property {string} [nonce] The nonce for the message
* <info>This property is required if `enforceNonce` set to `true`.</info>

View File

@@ -100,11 +100,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildMember}
*/
/**
* @external APIGuildScheduledEventRecurrenceRule
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildScheduledEventRecurrenceRule}
*/
/**
* @external APIInteraction
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIInteraction}
@@ -255,16 +250,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationRoleConnectionMetadataType}
*/
/**
* @external ApplicationWebhookEventStatus
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationWebhookEventStatus}
*/
/**
* @external ApplicationWebhookEventType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ApplicationWebhookEventType}
*/
/**
* @external AttachmentFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/AttachmentFlags}
@@ -405,21 +390,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventPrivacyLevel}
*/
/**
* @external GuildScheduledEventRecurrenceRuleFrequency
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleFrequency}
*/
/**
* @external GuildScheduledEventRecurrenceRuleMonth
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleMonth}
*/
/**
* @external GuildScheduledEventRecurrenceRuleWeekday
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleWeekday}
*/
/**
* @external GuildScheduledEventStatus
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventStatus}
@@ -472,7 +442,12 @@
/**
* @external Locale
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/Locale}
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common/enum/Locale}
*/
/**
* @external LocaleString
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common#LocaleString}
*/
/**
@@ -480,11 +455,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageActivityType}
*/
/**
* @external MessageReferenceType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageReferenceType}
*/
/**
* @external MessageType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageType}
@@ -507,7 +477,7 @@
/**
* @external PermissionFlagsBits
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#PermissionFlagsBits}
* @see {@link https://discord-api-types.dev/api/discord-api-types-payloads/common#PermissionFlagsBits}
*/
/**
@@ -515,11 +485,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/PollLayoutType}
*/
/**
* @external ReactionType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ReactionType}
*/
/**
* @external RoleFlags
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/RoleFlags}
@@ -532,7 +497,7 @@
/**
* @external RESTJSONErrorCodes
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/RESTJSONErrorCodes}
* @see {@link https://discord-api-types.dev/api/discord-api-types-rest/common/enum/RESTJSONErrorCodes}
*/
/**
@@ -595,11 +560,6 @@
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/VideoQualityMode}
*/
/**
* @external VoiceChannelEffectSendAnimationType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/VoiceChannelEffectSendAnimationType}
*/
/**
* @external WebhookType
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/WebhookType}

View File

@@ -117,24 +117,9 @@ exports.GuildTextBasedChannelTypes = [
* * {@link ChannelType.PrivateThread}
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* * {@link ChannelType.GroupDM}
* @typedef {ChannelType[]} TextBasedChannelTypes
*/
exports.TextBasedChannelTypes = [...exports.GuildTextBasedChannelTypes, ChannelType.DM, ChannelType.GroupDM];
/**
* The types of channels that are text-based and can have messages sent into. The available types are:
* * {@link ChannelType.DM}
* * {@link ChannelType.GuildText}
* * {@link ChannelType.GuildAnnouncement}
* * {@link ChannelType.AnnouncementThread}
* * {@link ChannelType.PublicThread}
* * {@link ChannelType.PrivateThread}
* * {@link ChannelType.GuildVoice}
* * {@link ChannelType.GuildStageVoice}
* @typedef {ChannelType[]} SendableChannels
*/
exports.SendableChannels = [...exports.GuildTextBasedChannelTypes, ChannelType.DM];
exports.TextBasedChannelTypes = [...exports.GuildTextBasedChannelTypes, ChannelType.DM];
/**
* The types of channels that are threads. The available types are:

View File

@@ -69,9 +69,6 @@
* @property {string} StageInstanceCreate stageInstanceCreate
* @property {string} StageInstanceDelete stageInstanceDelete
* @property {string} StageInstanceUpdate stageInstanceUpdate
* @property {string} SubscriptionCreate subscriptionCreate
* @property {string} SubscriptionUpdate subscriptionUpdate
* @property {string} SubscriptionDelete subscriptionDelete
* @property {string} ThreadCreate threadCreate
* @property {string} ThreadDelete threadDelete
* @property {string} ThreadListSync threadListSync
@@ -80,7 +77,6 @@
* @property {string} ThreadUpdate threadUpdate
* @property {string} TypingStart typingStart
* @property {string} UserUpdate userUpdate
* @property {string} VoiceChannelEffectSend voiceChannelEffectSend
* @property {string} VoiceServerUpdate voiceServerUpdate
* @property {string} VoiceStateUpdate voiceStateUpdate
* @property {string} Warn warn
@@ -161,9 +157,6 @@ module.exports = {
StageInstanceCreate: 'stageInstanceCreate',
StageInstanceDelete: 'stageInstanceDelete',
StageInstanceUpdate: 'stageInstanceUpdate',
SubscriptionCreate: 'subscriptionCreate',
SubscriptionUpdate: 'subscriptionUpdate',
SubscriptionDelete: 'subscriptionDelete',
ThreadCreate: 'threadCreate',
ThreadDelete: 'threadDelete',
ThreadListSync: 'threadListSync',
@@ -172,7 +165,6 @@ module.exports = {
ThreadUpdate: 'threadUpdate',
TypingStart: 'typingStart',
UserUpdate: 'userUpdate',
VoiceChannelEffectSend: 'voiceChannelEffectSend',
VoiceServerUpdate: 'voiceServerUpdate',
VoiceStateUpdate: 'voiceStateUpdate',
Warn: 'warn',

View File

@@ -23,15 +23,6 @@ class MessageFlagsBitField extends BitField {
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
*/
/**
* Data that can be resolved to give a message flags bit field. This can be:
* * A string (see {@link MessageFlagsBitField.Flags})
* * A message flag
* * An instance of {@link MessageFlagsBitField}
* * An array of `MessageFlagsResolvable`
* @typedef {string|number|MessageFlagsBitField|MessageFlagsResolvable[]} MessageFlagsResolvable
*/
/**
* Bitfield of the packed bits
* @type {number}

View File

@@ -49,36 +49,9 @@ function _transformAPIMessageInteractionMetadata(client, messageInteractionMetad
originalResponseMessageId: messageInteractionMetadata.original_response_message_id ?? null,
interactedMessageId: messageInteractionMetadata.interacted_message_id ?? null,
triggeringInteractionMetadata: messageInteractionMetadata.triggering_interaction_metadata
? _transformAPIMessageInteractionMetadata(client, messageInteractionMetadata.triggering_interaction_metadata)
? _transformAPIMessageInteractionMetadata(messageInteractionMetadata.triggering_interaction_metadata)
: null,
};
}
/**
* Transforms a guild scheduled event recurrence rule object to a snake-cased variant.
* @param {GuildScheduledEventRecurrenceRuleOptions} recurrenceRule The recurrence rule to transform
* @returns {APIGuildScheduledEventRecurrenceRule}
* @ignore
*/
function _transformGuildScheduledEventRecurrenceRule(recurrenceRule) {
return {
start: new Date(recurrenceRule.startAt).toISOString(),
// eslint-disable-next-line eqeqeq
end: recurrenceRule.endAt != null ? new Date(recurrenceRule.endAt).toISOString() : recurrenceRule.endAt,
frequency: recurrenceRule.frequency,
interval: recurrenceRule.interval,
by_weekday: recurrenceRule.byWeekday,
by_n_weekday: recurrenceRule.byNWeekday,
by_month: recurrenceRule.byMonth,
by_month_day: recurrenceRule.byMonthDay,
by_year_day: recurrenceRule.byYearDay,
count: recurrenceRule.count,
};
}
module.exports = {
toSnakeCase,
_transformAPIAutoModerationAction,
_transformAPIMessageInteractionMetadata,
_transformGuildScheduledEventRecurrenceRule,
};
module.exports = { toSnakeCase, _transformAPIAutoModerationAction, _transformAPIMessageInteractionMetadata };

View File

@@ -1,7 +1,6 @@
'use strict';
const { parse } = require('node:path');
const process = require('node:process');
const { Collection } = require('@discordjs/collection');
const { ChannelType, RouteBases, Routes } = require('discord-api-types/v10');
const { fetch } = require('undici');
@@ -9,9 +8,6 @@ const Colors = require('./Colors');
const { DiscordjsError, DiscordjsRangeError, DiscordjsTypeError, ErrorCodes } = require('../errors');
const isObject = d => typeof d === 'object' && d !== null;
let deprecationEmittedForUserFetchFlags = false;
let deprecationEmittedForRemoveThreadMember = false;
/**
* Flatten an object. Any properties that are collections will get converted to an array of keys.
* @param {Object} obj The object to flatten.
@@ -503,32 +499,6 @@ function resolveSKUId(resolvable) {
return null;
}
/**
* Deprecation function for fetching user flags.
* @param {string} name Name of the class
* @private
*/
function emitDeprecationWarningForUserFetchFlags(name) {
if (deprecationEmittedForUserFetchFlags) return;
process.emitWarning(`${name}#fetchFlags() is deprecated. Use ${name}#fetch() instead.`);
deprecationEmittedForUserFetchFlags = true;
}
/**
* Deprecation function for the reason parameter of removing thread members.
* @param {string} name Name of the class
* @private
*/
function emitDeprecationWarningForRemoveThreadMember(name) {
if (deprecationEmittedForRemoveThreadMember) return;
process.emitWarning(
`The reason parameter of ${name}#remove() is deprecated as Discord does not parse them. It will be removed in the next major version.`,
);
deprecationEmittedForRemoveThreadMember = true;
}
module.exports = {
flatten,
fetchRecommendedShardCount,
@@ -548,8 +518,6 @@ module.exports = {
parseWebhookURL,
transformResolved,
resolveSKUId,
emitDeprecationWarningForUserFetchFlags,
emitDeprecationWarningForRemoveThreadMember,
};
// Fixes Circular

View File

@@ -2,7 +2,7 @@
'use strict';
const { token, owner } = require('./auth.js');
const { token } = require('./auth.js');
const { Client } = require('../src');
const { ChannelType, GatewayIntentBits } = require('discord-api-types/v10');
@@ -14,7 +14,6 @@ const client = new Client({
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.MessageContent,
],
});
@@ -187,7 +186,7 @@ client.on('messageCreate', msg => {
msg.channel.send(`\`\`\`${msg.content}\`\`\``);
}
if (msg.content.startsWith('#eval') && msg.author.id === owner) {
if (msg.content.startsWith('#eval') && msg.author.id === '66564597481480192') {
try {
const com = eval(msg.content.split(' ').slice(1).join(' '));
msg.channel.send(`\`\`\`\n${com}\`\`\``);

View File

@@ -126,6 +126,7 @@ import {
APIEmbedImage,
VideoQualityMode,
LocalizationMap,
LocaleString,
MessageActivityType,
APIAttachment,
APIChannel,
@@ -184,25 +185,6 @@ import {
InviteType,
ReactionType,
APIAuthorizingIntegrationOwnersMap,
MessageReferenceType,
GuildScheduledEventRecurrenceRuleWeekday,
GuildScheduledEventRecurrenceRuleMonth,
GuildScheduledEventRecurrenceRuleFrequency,
APISubscription,
SubscriptionStatus,
ApplicationWebhookEventStatus,
ApplicationWebhookEventType,
GatewaySendPayload,
GatewayDispatchPayload,
RESTPostAPIInteractionCallbackWithResponseResult,
RESTAPIInteractionCallbackObject,
RESTAPIInteractionCallbackResourceObject,
InteractionResponseType,
RESTAPIInteractionCallbackActivityInstanceResource,
VoiceChannelEffectSendAnimationType,
GatewayVoiceChannelEffectSendDispatchData,
APIChatInputApplicationCommandInteractionData,
APIContextMenuInteractionData,
} from 'discord-api-types/v10';
import { ChildProcess } from 'node:child_process';
import { EventEmitter } from 'node:events';
@@ -565,6 +547,7 @@ export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
export type BooleanCache<Cached extends CacheType> = Cached extends 'cached' ? true : false;
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends BaseInteraction<Cached> {
public authorizingIntegrationOwners: APIAuthorizingIntegrationOwnersMap;
public type: InteractionType.ApplicationCommand;
public get command(): ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
public options: Omit<
@@ -589,6 +572,7 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
public commandName: string;
public commandType: ApplicationCommandType;
public commandGuildId: Snowflake | null;
public context: InteractionContextType | null;
public deferred: boolean;
public ephemeral: boolean | null;
public replied: boolean;
@@ -596,10 +580,6 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
public inGuild(): this is CommandInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is CommandInteraction<'cached'>;
public inRawGuild(): this is CommandInteraction<'raw'>;
public deferReply(
options: InteractionDeferReplyOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
public deferReply(
options: InteractionDeferReplyOptions & { fetchReply: true },
): Promise<Message<BooleanCache<Cached>>>;
@@ -610,8 +590,6 @@ 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>;
/** @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,
@@ -621,22 +599,7 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options: ShowModalOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
public showModal(
modal:
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options?: ShowModalOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
public showModal(
modal:
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options?: ShowModalOptions,
): Promise<undefined>;
): Promise<void>;
/** @deprecated Sending a premium-style button is the new Discord behaviour. */
public sendPremiumRequired(): Promise<void>;
public awaitModalSubmit(
@@ -644,10 +607,8 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
): Promise<ModalSubmitInteraction<Cached>>;
private transformOption(
option: APIApplicationCommandOption,
resolved: Extract<
APIApplicationCommandInteractionData,
APIChatInputApplicationCommandInteractionData | APIContextMenuInteractionData
>['resolved'],
// @ts-expect-error builders/1.x.
resolved: APIApplicationCommandInteractionData['resolved'],
): CommandInteractionOption<Cached>;
}
@@ -1015,7 +976,6 @@ export abstract class BaseChannel extends Base {
public isDMBased(): this is PartialGroupDMChannel | DMChannel | PartialDMChannel;
public isVoiceBased(): this is VoiceBasedChannel;
public isThreadOnly(): this is ThreadOnlyChannel;
public isSendable(): this is SendableChannels;
public toString(): ChannelMention | UserMention;
}
@@ -1117,7 +1077,6 @@ export class ClientApplication extends Application {
public commands: ApplicationCommandManager;
public emojis: ApplicationEmojiManager;
public entitlements: EntitlementManager;
public subscriptions: SubscriptionManager;
public guildId: Snowflake | null;
public get guild(): Guild | null;
public cover: string | null;
@@ -1131,9 +1090,6 @@ export class ClientApplication extends Application {
public owner: User | Team | null;
public get partial(): boolean;
public interactionsEndpointURL: string | null;
public eventWebhooksURL: string | null;
public eventWebhooksStatus: ApplicationWebhookEventStatus | null;
public eventWebhooksTypes: ApplicationWebhookEventType[] | null;
public roleConnectionsVerificationURL: string | null;
public rpcOrigins: string[];
public edit(options: ClientApplicationEditOptions): Promise<ClientApplication>;
@@ -1652,7 +1608,7 @@ export abstract class GuildChannel extends BaseChannel {
public get permissionsLocked(): boolean | null;
public get position(): number;
public rawPosition: number;
public type: GuildChannelTypes;
public type: Exclude<ChannelType, ChannelType.DM | ChannelType.GroupDM>;
public get viewable(): boolean;
public clone(options?: GuildChannelCloneOptions): Promise<this>;
public delete(reason?: string): Promise<this>;
@@ -1700,7 +1656,6 @@ export class GuildMember extends Base {
private constructor(client: Client<true>, data: RawGuildMemberData, guild: Guild);
private _roles: Snowflake[];
public avatar: string | null;
public banner: string | null;
public get bannable(): boolean;
public get dmChannel(): DMChannel | null;
public get displayColor(): number;
@@ -1727,7 +1682,6 @@ export class GuildMember extends Base {
public user: User;
public get voice(): VoiceState;
public avatarURL(options?: ImageURLOptions): string | null;
public bannerURL(options?: ImageURLOptions): string | null;
public ban(options?: BanOptions): Promise<GuildMember>;
public disableCommunicationUntil(timeout: DateResolvable | null, reason?: string): Promise<GuildMember>;
public timeout(timeout: number | null, reason?: string): Promise<GuildMember>;
@@ -1735,7 +1689,6 @@ export class GuildMember extends Base {
public createDM(force?: boolean): Promise<DMChannel>;
public deleteDM(): Promise<DMChannel>;
public displayAvatarURL(options?: ImageURLOptions): string;
public displayBannerURL(options?: ImageURLOptions): string | null;
public edit(options: GuildMemberEditOptions): Promise<GuildMember>;
public isCommunicationDisabled(): this is GuildMember & {
communicationDisabledUntilTimestamp: number;
@@ -1827,7 +1780,6 @@ export class GuildScheduledEvent<Status extends GuildScheduledEventStatus = Guil
public entityMetadata: GuildScheduledEventEntityMetadata | null;
public userCount: number | null;
public creator: User | null;
public recurrenceRule: GuildScheduledEventRecurrenceRule | null;
public get createdTimestamp(): number;
public get createdAt(): Date;
public get scheduledStartAt(): Date | null;
@@ -1866,26 +1818,6 @@ export class GuildScheduledEvent<Status extends GuildScheduledEventStatus = Guil
public isScheduled(): this is GuildScheduledEvent<GuildScheduledEventStatus.Scheduled>;
}
export interface GuildScheduledEventRecurrenceRule {
startTimestamp: number;
get startAt(): Date;
endTimestamp: number | null;
get endAt(): Date | null;
frequency: GuildScheduledEventRecurrenceRuleFrequency;
interval: number;
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[] | null;
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[] | null;
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[] | null;
byMonthDay: readonly number[] | null;
byYearDay: readonly number[] | null;
count: number | null;
}
export interface GuildScheduledEventRecurrenceRuleNWeekday {
n: number;
day: GuildScheduledEventRecurrenceRuleWeekday;
}
export class GuildTemplate extends Base {
private constructor(client: Client<true>, data: RawGuildTemplateData);
public createdTimestamp: number;
@@ -1993,7 +1925,6 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
private readonly _cacheType: Cached;
protected constructor(client: Client<true>, data: RawInteractionData);
public applicationId: Snowflake;
public authorizingIntegrationOwners: APIAuthorizingIntegrationOwnersMap;
public get channel(): CacheTypeReducer<
Cached,
GuildTextBasedChannel | null,
@@ -2002,7 +1933,6 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
TextBasedChannel | null
>;
public channelId: Snowflake | null;
public context: InteractionContextType | null;
public get createdAt(): Date;
public get createdTimestamp(): number;
public get guild(): CacheTypeReducer<Cached, Guild, null>;
@@ -2041,33 +1971,6 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
public isRepliable(): this is RepliableInteraction<Cached>;
}
export class InteractionCallback {
private constructor(client: Client<true>, data: RESTAPIInteractionCallbackObject);
public activityInstanceId: string | null;
public readonly client: Client<true>;
public get createdAt(): Date;
public get createdTimestamp(): number;
public id: Snowflake;
public responseMessageEphemeral: boolean | null;
public responseMessageId: Snowflake | null;
public responseMessageLoading: boolean | null;
public type: InteractionType;
}
export class InteractionCallbackResponse {
private constructor(client: Client<true>, data: RESTPostAPIInteractionCallbackWithResponseResult);
public readonly client: Client<true>;
public interaction: InteractionCallback;
public resource: InteractionCallbackResource | null;
}
export class InteractionCallbackResource {
private constructor(client: Client<true>, data: RESTAPIInteractionCallbackResourceObject);
public activityInstance: RESTAPIInteractionCallbackActivityInstanceResource | null;
public message: Message | null;
public type: InteractionResponseType;
}
export class InteractionCollector<Interaction extends CollectedInteraction> extends Collector<
Snowflake,
Interaction,
@@ -2183,13 +2086,7 @@ export interface MessageCall {
participants: readonly Snowflake[];
}
export type MessageComponentType =
| ComponentType.Button
| ComponentType.ChannelSelect
| ComponentType.MentionableSelect
| ComponentType.RoleSelect
| ComponentType.StringSelect
| ComponentType.UserSelect;
export type MessageComponentType = Exclude<ComponentType, ComponentType.TextInput | ComponentType.ActionRow>;
export interface MessageCollectorOptionsParams<
ComponentType extends MessageComponentType,
@@ -2288,7 +2185,6 @@ export class Message<InGuild extends boolean = boolean> extends Base {
public webhookId: Snowflake | null;
public flags: Readonly<MessageFlagsBitField>;
public reference: MessageReference | null;
public messageSnapshots: Collection<Snowflake, MessageSnapshot>;
public awaitMessageComponent<ComponentType extends MessageComponentType>(
options?: AwaitMessageCollectorOptionsParams<ComponentType, InGuild>,
): Promise<MappedInteractionTypes<InGuild>[ComponentType]>;
@@ -2297,27 +2193,27 @@ export class Message<InGuild extends boolean = boolean> extends Base {
public createMessageComponentCollector<ComponentType extends MessageComponentType>(
options?: MessageCollectorOptionsParams<ComponentType, InGuild>,
): InteractionCollector<MappedInteractionTypes<InGuild>[ComponentType]>;
public delete(): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public delete(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public edit(
content: string | MessageEditOptions | MessagePayload,
): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public equals(message: Message, rawData: unknown): boolean;
public fetchReference(): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public fetchReference(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public fetchWebhook(): Promise<Webhook>;
public crosspost(): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public fetch(force?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public pin(reason?: string): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public crosspost(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public fetch(force?: boolean): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public pin(reason?: string): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
public removeAttachments(): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public removeAttachments(): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public reply(
options: string | MessagePayload | MessageReplyOptions,
): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public resolveComponent(customId: string): MessageActionRowComponent | null;
public startThread(options: StartThreadOptions): Promise<PublicThreadChannel<false>>;
public suppressEmbeds(suppress?: boolean): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public suppressEmbeds(suppress?: boolean): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public toJSON(): unknown;
public toString(): string;
public unpin(reason?: string): Promise<OmitPartialGroupDMChannel<Message<InGuild>>>;
public unpin(reason?: string): Promise<NonPartialGroupDMChannel<Message<InGuild>>>;
public inGuild(): this is Message<true>;
}
@@ -2382,11 +2278,11 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
public get component(): CacheTypeReducer<
Cached,
MessageActionRowComponent,
APIMessageActionRowComponent,
MessageActionRowComponent | APIMessageActionRowComponent,
MessageActionRowComponent | APIMessageActionRowComponent
Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>,
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>,
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent<APIMessageActionRowComponent>>
>;
public componentType: MessageComponentType;
public componentType: Exclude<ComponentType, ComponentType.ActionRow | ComponentType.TextInput>;
public customId: string;
public channelId: Snowflake;
public deferred: boolean;
@@ -2397,18 +2293,10 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
public inGuild(): this is MessageComponentInteraction<'raw' | 'cached'>;
public inCachedGuild(): this is MessageComponentInteraction<'cached'>;
public inRawGuild(): this is MessageComponentInteraction<'raw'>;
public deferReply(
options: InteractionDeferReplyOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
public deferReply(
options: InteractionDeferReplyOptions & { fetchReply: true },
): Promise<Message<BooleanCache<Cached>>>;
public deferReply(options?: InteractionDeferReplyOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
public deferUpdate(
options: InteractionDeferUpdateOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
public deferUpdate(
options: InteractionDeferUpdateOptions & { fetchReply: true },
): Promise<Message<BooleanCache<Cached>>>;
@@ -2419,14 +2307,10 @@ 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>;
/** @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>;
/** @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,
@@ -2436,22 +2320,7 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options: ShowModalOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
public showModal(
modal:
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options?: ShowModalOptions,
): Promise<undefined>;
public showModal(
modal:
| JSONEncodable<APIModalInteractionResponseCallbackData>
| ModalComponentData
| APIModalInteractionResponseCallbackData,
options?: ShowModalOptions,
): Promise<undefined>;
): Promise<void>;
/** @deprecated Sending a premium-style button is the new Discord behaviour. */
public sendPremiumRequired(): Promise<void>;
public awaitModalSubmit(
@@ -2488,11 +2357,9 @@ export type MessageFlagsString = keyof typeof MessageFlags;
export class MessageFlagsBitField extends BitField<MessageFlagsString> {
public static Flags: typeof MessageFlags;
public static resolve(bit?: MessageFlagsResolvable): number;
public static resolve(bit?: BitFieldResolvable<MessageFlagsString, number>): number;
}
export type MessageFlagsResolvable = BitFieldResolvable<MessageFlagsString, number>;
export class MessageMentions<InGuild extends boolean = boolean> {
private constructor(
message: Message,
@@ -2542,7 +2409,6 @@ export class MessagePayload {
public get isWebhook(): boolean;
public get isMessage(): boolean;
public get isMessageManager(): boolean;
/** @deprecated This will no longer serve a purpose in the next major version. */
public get isInteraction(): boolean;
public files: RawFile[] | null;
public options: MessagePayloadOption;
@@ -2564,13 +2430,13 @@ export class MessagePayload {
export class MessageReaction {
private constructor(client: Client<true>, data: RawMessageReactionData, message: Message);
private _emoji: GuildEmoji | ReactionEmoji | ApplicationEmoji;
private _emoji: GuildEmoji | ReactionEmoji;
public burstColors: string[] | null;
public readonly client: Client<true>;
public count: number;
public countDetails: ReactionCountDetailsData;
public get emoji(): GuildEmoji | ReactionEmoji | ApplicationEmoji;
public get emoji(): GuildEmoji | ReactionEmoji;
public me: boolean;
public meBurst: boolean;
public message: Message | PartialMessage;
@@ -2584,7 +2450,6 @@ export class MessageReaction {
}
export interface MessageReactionEventDetails {
type: ReactionType;
burst: boolean;
}
@@ -2625,8 +2490,6 @@ export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = C
extends ModalSubmitInteraction<Cached> {
message: Message<BooleanCache<Cached>>;
channelId: Snowflake;
update(options: InteractionUpdateOptions & { withResponse: true }): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<Message>;
update(
options: string | MessagePayload | InteractionUpdateOptions,
@@ -2647,8 +2510,6 @@ 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>;
/** @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,
@@ -2657,20 +2518,12 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
public editReply(
options: string | MessagePayload | InteractionEditReplyOptions,
): Promise<Message<BooleanCache<Cached>>>;
public deferReply(
options: InteractionDeferReplyOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
public deferReply(
options: InteractionDeferReplyOptions & { fetchReply: true },
): Promise<Message<BooleanCache<Cached>>>;
public deferReply(options?: InteractionDeferReplyOptions): Promise<InteractionResponse<BooleanCache<Cached>>>;
public fetchReply(message?: Snowflake | '@original'): Promise<Message<BooleanCache<Cached>>>;
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<Message<BooleanCache<Cached>>>;
public deferUpdate(
options: InteractionDeferUpdateOptions & { withResponse: true },
): Promise<InteractionCallbackResponse>;
/** @deprecated `fetchReply` is deprecated. Use `withResponse` instead or fetch the response after using the method. */
public deferUpdate(
options: InteractionDeferUpdateOptions & { fetchReply: true },
): Promise<Message<BooleanCache<Cached>>>;
@@ -3235,22 +3088,6 @@ export class SKUFlagsBitField extends BitField<SKUFlagsString> {
public static resolve(bit?: BitFieldResolvable<SKUFlagsString, number>): number;
}
export class Subscription extends Base {
private constructor(client: Client<true>, data: APISubscription);
public id: Snowflake;
public userId: Snowflake;
public skuIds: Snowflake[];
public entitlementIds: Snowflake[];
public currentPeriodStartTimestamp: number;
public currentPeriodEndTimestamp: number;
public status: SubscriptionStatus;
public canceledTimestamp: number | null;
public country: string | null;
public get canceledAt(): Date | null;
public get currentPeriodStartAt(): Date;
public get currentPeriodEndAt(): Date;
}
export class StageChannel extends BaseGuildVoiceChannel {
public get stageInstance(): StageInstance | null;
public topic: string | null;
@@ -3487,7 +3324,7 @@ export class ThreadChannel<ThreadOnly extends boolean = boolean> extends BaseCha
public totalMessageSent: number | null;
public members: ThreadMemberManager;
public name: string;
public ownerId: Snowflake;
public ownerId: Snowflake | null;
public get parent(): If<ThreadOnly, ForumChannel | MediaChannel, TextChannel | NewsChannel> | null;
public parentId: Snowflake | null;
public rateLimitPerUser: number | null;
@@ -3502,7 +3339,7 @@ export class ThreadChannel<ThreadOnly extends boolean = boolean> extends BaseCha
memberOrRole: GuildMemberResolvable | RoleResolvable,
checkAdmin?: boolean,
): Readonly<PermissionsBitField> | null;
public fetchOwner(options?: FetchThreadOwnerOptions): Promise<ThreadMember | null>;
public fetchOwner(options?: BaseFetchOptions): Promise<ThreadMember | null>;
public fetchStarterMessage(options?: BaseFetchOptions): Promise<Message<true> | null>;
public setArchived(archived?: boolean, reason?: string): Promise<this>;
public setAutoArchiveDuration(autoArchiveDuration: ThreadAutoArchiveDuration, reason?: string): Promise<this>;
@@ -3528,11 +3365,7 @@ export class ThreadMember<HasMemberData extends boolean = boolean> extends Base
public thread: AnyThreadChannel;
public get user(): User | null;
public get partial(): false;
/* tslint:disable:unified-signatures */
public remove(): Promise<ThreadMember>;
/** @deprecated The `reason` parameter is deprecated as Discord does not parse them. */
public remove(reason?: string): Promise<ThreadMember>;
/* tslint:enable:unified-signatures */
}
export type ThreadMemberFlagsString = keyof typeof ThreadMemberFlags;
@@ -3596,7 +3429,6 @@ export class User extends Base {
public displayAvatarURL(options?: ImageURLOptions): string;
public equals(user: User): boolean;
public fetch(force?: boolean): Promise<User>;
/** @deprecated This method is deprecated and will be removed in the next major version. Flags may still be retrieved via {@link User.fetch} */
public fetchFlags(force?: boolean): Promise<UserFlagsBitField>;
public toString(): UserMention;
}
@@ -3676,10 +3508,8 @@ export function parseWebhookURL(url: string): WebhookClientDataIdWithToken | nul
/** @internal */
export function transformResolved<Cached extends CacheType>(
supportingData: SupportingInteractionResolvedData,
data?: Extract<
APIApplicationCommandInteractionData,
APIChatInputApplicationCommandInteractionData | APIContextMenuInteractionData
>['resolved'],
// @ts-expect-error builders/1.x.
data?: APIApplicationCommandInteractionData['resolved'],
): CommandInteractionResolvedData<Cached>;
export function resolveSKUId(resolvable: SKUResolvable): Snowflake | null;
@@ -3790,19 +3620,6 @@ export class VoiceChannel extends BaseGuildVoiceChannel {
public type: ChannelType.GuildVoice;
}
export class VoiceChannelEffect {
private constructor(data: GatewayVoiceChannelEffectSendDispatchData, guild: Guild);
public guild: Guild;
public channelId: Snowflake;
public userId: Snowflake;
public emoji: Emoji | null;
public animationType: VoiceChannelEffectSendAnimationType | null;
public animationId: number | null;
public soundId: Snowflake | number | null;
public soundVolume: number | null;
public get channel(): VoiceChannel | null;
}
export class VoiceRegion {
private constructor(data: RawVoiceRegionData);
public custom: boolean;
@@ -4052,7 +3869,6 @@ export const Constants: {
SweeperKeys: SweeperKey[];
NonSystemMessageTypes: NonSystemMessageType[];
TextBasedChannelTypes: TextBasedChannelTypes[];
SendableChannels: SendableChannelTypes[];
GuildTextBasedChannelTypes: GuildTextBasedChannelTypes[];
ThreadChannelTypes: ThreadChannelType[];
VoiceBasedChannelTypes: VoiceBasedChannelTypes[];
@@ -4430,7 +4246,6 @@ export class ChannelManager extends CachedManager<Snowflake, Channel, ChannelRes
export type EntitlementResolvable = Snowflake | Entitlement;
export type SKUResolvable = Snowflake | SKU;
export type SubscriptionResolvable = Snowflake | Subscription;
export interface GuildEntitlementCreateOptions {
sku: SKUResolvable;
@@ -4442,17 +4257,12 @@ export interface UserEntitlementCreateOptions {
user: UserResolvable;
}
export interface FetchEntitlementOptions extends BaseFetchOptions {
entitlement: EntitlementResolvable;
}
export interface FetchEntitlementsOptions {
limit?: number;
guild?: GuildResolvable;
user?: UserResolvable;
skus?: readonly SKUResolvable[];
excludeEnded?: boolean;
excludeDeleted?: boolean;
cache?: boolean;
before?: Snowflake;
after?: Snowflake;
@@ -4460,32 +4270,12 @@ export interface FetchEntitlementsOptions {
export class EntitlementManager extends CachedManager<Snowflake, Entitlement, EntitlementResolvable> {
private constructor(client: Client<true>, iterable: Iterable<APIEntitlement>);
public fetch(options: EntitlementResolvable | FetchEntitlementOptions): Promise<Entitlement>;
public fetch(options?: FetchEntitlementsOptions): Promise<Collection<Snowflake, Entitlement>>;
public createTest(options: GuildEntitlementCreateOptions | UserEntitlementCreateOptions): Promise<Entitlement>;
public deleteTest(entitlement: EntitlementResolvable): Promise<void>;
public consume(entitlementId: Snowflake): Promise<void>;
}
export interface FetchSubscriptionOptions extends BaseFetchOptions {
sku: SKUResolvable;
subscriptionId: Snowflake;
}
export interface FetchSubscriptionsOptions {
after?: Snowflake;
before?: Snowflake;
limit?: number;
sku: SKUResolvable;
user: UserResolvable;
}
export class SubscriptionManager extends CachedManager<Snowflake, Subscription, SubscriptionResolvable> {
private constructor(client: Client<true>, iterable?: Iterable<APISubscription>);
public fetch(options: FetchSubscriptionOptions): Promise<Subscription>;
public fetch(options: FetchSubscriptionsOptions): Promise<Collection<Snowflake, Subscription>>;
}
export interface FetchGuildApplicationCommandFetchOptions extends Omit<FetchApplicationCommandOptions, 'guildId'> {}
export class GuildApplicationCommandManager extends ApplicationCommandManager<ApplicationCommand, {}, Guild> {
@@ -4848,12 +4638,7 @@ export class ThreadMemberManager extends CachedManager<Snowflake, ThreadMember,
private constructor(thread: ThreadChannel, iterable?: Iterable<RawThreadMemberData>);
public thread: AnyThreadChannel;
public get me(): ThreadMember | null;
/* tslint:disable:unified-signatures */
public add(member: UserResolvable | '@me'): Promise<Snowflake>;
/** @deprecated The `reason` parameter is deprecated as Discord does not parse them. */
public add(member: UserResolvable | '@me', reason?: string): Promise<Snowflake>;
/* tslint:enable:unified-signatures */
public fetch(
options: ThreadMember<true> | ((FetchThreadMemberOptions & { withMember: true }) | { member: ThreadMember<true> }),
@@ -4867,12 +4652,7 @@ export class ThreadMemberManager extends CachedManager<Snowflake, ThreadMember,
public fetch(options?: FetchThreadMembersWithoutGuildMemberDataOptions): Promise<Collection<Snowflake, ThreadMember>>;
public fetchMe(options?: BaseFetchOptions): Promise<ThreadMember>;
/* tslint:disable:unified-signatures */
public remove(member: UserResolvable | '@me'): Promise<Snowflake>;
/** @deprecated The `reason` parameter is deprecated as Discord does not parse them. */
public remove(member: UserResolvable | '@me', reason?: string): Promise<Snowflake>;
/* tslint:enable:unified-signatures */
}
export class UserManager extends CachedManager<Snowflake, User, UserResolvable> {
@@ -4881,7 +4661,6 @@ export class UserManager extends CachedManager<Snowflake, User, UserResolvable>
public createDM(user: UserResolvable, options?: BaseFetchOptions): Promise<DMChannel>;
public deleteDM(user: UserResolvable): Promise<DMChannel>;
public fetch(user: UserResolvable, options?: BaseFetchOptions): Promise<User>;
/** @deprecated This method is deprecated and will be removed in the next major version. Flags may still be retrieved via {@link UserManager.fetch} */
public fetchFlags(user: UserResolvable, options?: BaseFetchOptions): Promise<UserFlagsBitField>;
public send(user: UserResolvable, options: string | MessagePayload | MessageCreateOptions): Promise<Message>;
}
@@ -5384,20 +5163,18 @@ export type BitFieldResolvable<Flags extends string, Type extends number | bigin
export type BufferResolvable = Buffer | string;
export interface Caches {
ApplicationCommandManager: [manager: typeof ApplicationCommandManager, holds: typeof ApplicationCommand];
ApplicationEmojiManager: [manager: typeof ApplicationEmojiManager, holds: typeof ApplicationEmoji];
AutoModerationRuleManager: [manager: typeof AutoModerationRuleManager, holds: typeof AutoModerationRule];
ApplicationCommandManager: [manager: typeof ApplicationCommandManager, holds: typeof ApplicationCommand];
BaseGuildEmojiManager: [manager: typeof BaseGuildEmojiManager, holds: typeof GuildEmoji];
// TODO: ChannelManager: [manager: typeof ChannelManager, holds: typeof Channel];
DMMessageManager: [manager: typeof MessageManager, holds: typeof Message<false>];
EntitlementManager: [manager: typeof EntitlementManager, holds: typeof Entitlement];
GuildBanManager: [manager: typeof GuildBanManager, holds: typeof GuildBan];
// TODO: GuildChannelManager: [manager: typeof GuildChannelManager, holds: typeof GuildChannel];
GuildEmojiManager: [manager: typeof GuildEmojiManager, holds: typeof GuildEmoji];
GuildForumThreadManager: [manager: typeof GuildForumThreadManager, holds: typeof ThreadChannel<true>];
GuildInviteManager: [manager: typeof GuildInviteManager, holds: typeof Invite];
// TODO: ChannelManager: [manager: typeof ChannelManager, holds: typeof Channel];
// TODO: GuildChannelManager: [manager: typeof GuildChannelManager, holds: typeof GuildChannel];
// TODO: GuildManager: [manager: typeof GuildManager, holds: typeof Guild];
GuildMemberManager: [manager: typeof GuildMemberManager, holds: typeof GuildMember];
GuildBanManager: [manager: typeof GuildBanManager, holds: typeof GuildBan];
GuildForumThreadManager: [manager: typeof GuildForumThreadManager, holds: typeof ThreadChannel<true>];
GuildInviteManager: [manager: typeof GuildInviteManager, holds: typeof Invite];
GuildMessageManager: [manager: typeof GuildMessageManager, holds: typeof Message<true>];
GuildScheduledEventManager: [manager: typeof GuildScheduledEventManager, holds: typeof GuildScheduledEvent];
GuildStickerManager: [manager: typeof GuildStickerManager, holds: typeof Sticker];
@@ -5495,7 +5272,7 @@ export interface GuildMembersChunk {
nonce: string | undefined;
}
export type OmitPartialGroupDMChannel<Structure extends { channel: Channel }> = Structure & {
type NonPartialGroupDMChannel<Structure extends { channel: Channel }> = Structure & {
channel: Exclude<Structure['channel'], PartialGroupDMChannel>;
};
@@ -5541,17 +5318,17 @@ export interface ClientEvents {
guildUpdate: [oldGuild: Guild, newGuild: Guild];
inviteCreate: [invite: Invite];
inviteDelete: [invite: Invite];
messageCreate: [message: OmitPartialGroupDMChannel<Message>];
messageDelete: [message: OmitPartialGroupDMChannel<Message | PartialMessage>];
messageCreate: [message: NonPartialGroupDMChannel<Message>];
messageDelete: [message: NonPartialGroupDMChannel<Message | PartialMessage>];
messagePollVoteAdd: [pollAnswer: PollAnswer, userId: Snowflake];
messagePollVoteRemove: [pollAnswer: PollAnswer, userId: Snowflake];
messageReactionRemoveAll: [
message: OmitPartialGroupDMChannel<Message | PartialMessage>,
message: NonPartialGroupDMChannel<Message | PartialMessage>,
reactions: ReadonlyCollection<string | Snowflake, MessageReaction>,
];
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
messageDeleteBulk: [
messages: ReadonlyCollection<Snowflake, OmitPartialGroupDMChannel<Message | PartialMessage>>,
messages: ReadonlyCollection<Snowflake, NonPartialGroupDMChannel<Message | PartialMessage>>,
channel: GuildTextBasedChannel,
];
messageReactionAdd: [
@@ -5564,10 +5341,7 @@ export interface ClientEvents {
user: User | PartialUser,
details: MessageReactionEventDetails,
];
messageUpdate: [
oldMessage: OmitPartialGroupDMChannel<Message | PartialMessage>,
newMessage: OmitPartialGroupDMChannel<Message>,
];
messageUpdate: [oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage];
presenceUpdate: [oldPresence: Presence | null, newPresence: Presence];
ready: [client: Client<true>];
invalidated: [];
@@ -5586,7 +5360,6 @@ export interface ClientEvents {
threadUpdate: [oldThread: AnyThreadChannel, newThread: AnyThreadChannel];
typingStart: [typing: Typing];
userUpdate: [oldUser: User | PartialUser, newUser: User];
voiceChannelEffectSend: [voiceChannelEffect: VoiceChannelEffect];
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
/** @deprecated Use {@link ClientEvents.webhooksUpdate} instead. */
webhookUpdate: ClientEvents['webhooksUpdate'];
@@ -5603,9 +5376,6 @@ export interface ClientEvents {
stickerCreate: [sticker: Sticker];
stickerDelete: [sticker: Sticker];
stickerUpdate: [oldSticker: Sticker, newSticker: Sticker];
subscriptionCreate: [subscription: Subscription];
subscriptionDelete: [subscription: Subscription];
subscriptionUpdate: [oldSubscription: Subscription | null, newSubscription: Subscription];
guildScheduledEventCreate: [guildScheduledEvent: GuildScheduledEvent];
guildScheduledEventUpdate: [
oldGuildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent | null,
@@ -5801,7 +5571,6 @@ export enum Events {
ThreadMembersUpdate = 'threadMembersUpdate',
UserUpdate = 'userUpdate',
PresenceUpdate = 'presenceUpdate',
VoiceChannelEffectSend = 'voiceChannelEffectSend',
VoiceServerUpdate = 'voiceServerUpdate',
VoiceStateUpdate = 'voiceStateUpdate',
TypingStart = 'typingStart',
@@ -5821,9 +5590,6 @@ export enum Events {
StageInstanceCreate = 'stageInstanceCreate',
StageInstanceUpdate = 'stageInstanceUpdate',
StageInstanceDelete = 'stageInstanceDelete',
SubscriptionCreate = 'subscriptionCreate',
SubscriptionUpdate = 'subscriptionUpdate',
SubscriptionDelete = 'subscriptionDelete',
GuildStickerCreate = 'stickerCreate',
GuildStickerDelete = 'stickerDelete',
GuildStickerUpdate = 'stickerUpdate',
@@ -5911,11 +5677,11 @@ export type EmojiIdentifierResolvable =
| `<${'' | 'a'}:${string}:${Snowflake}>`
| string;
export type EmojiResolvable = Snowflake | GuildEmoji | ReactionEmoji | ApplicationEmoji;
export type EmojiResolvable = Snowflake | GuildEmoji | ReactionEmoji;
export interface FetchApplicationCommandOptions extends BaseFetchOptions {
guildId?: Snowflake;
locale?: Locale;
locale?: LocaleString;
withLocalizations?: boolean;
}
@@ -6029,10 +5795,6 @@ export interface FetchThreadMemberOptions extends BaseFetchOptions {
withMember?: boolean;
}
export interface FetchThreadOwnerOptions extends BaseFetchOptions {
withMember?: boolean;
}
export interface FetchThreadMembersWithGuildMemberDataOptions {
withMember: true;
after?: Snowflake;
@@ -6403,29 +6165,14 @@ export interface GuildScheduledEventCreateOptions {
entityMetadata?: GuildScheduledEventEntityMetadataOptions;
image?: BufferResolvable | Base64Resolvable | null;
reason?: string;
recurrenceRule?: GuildScheduledEventRecurrenceRuleOptions;
}
export interface GuildScheduledEventRecurrenceRuleOptions {
startAt: DateResolvable;
endAt: DateResolvable;
frequency: GuildScheduledEventRecurrenceRuleFrequency;
interval: number;
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[];
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[];
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[];
byMonthDay: readonly number[];
byYearDay: readonly number[];
count: number;
}
export interface GuildScheduledEventEditOptions<
Status extends GuildScheduledEventStatus,
AcceptableStatus extends GuildScheduledEventSetStatusArg<Status>,
> extends Omit<Partial<GuildScheduledEventCreateOptions>, 'channel' | 'recurrenceRule'> {
> extends Omit<Partial<GuildScheduledEventCreateOptions>, 'channel'> {
channel?: GuildVoiceChannelResolvable | null;
status?: AcceptableStatus;
recurrenceRule?: GuildScheduledEventRecurrenceRuleOptions | null;
}
export interface GuildScheduledEventEntityMetadata {
@@ -6538,29 +6285,15 @@ export interface InteractionCollectorOptions<
}
export interface InteractionDeferReplyOptions {
/** @deprecated Use {@link InteractionDeferReplyOptions.flags} instead. */
ephemeral?: boolean;
flags?: BitFieldResolvable<
Extract<MessageFlagsString, 'Ephemeral' | 'SuppressEmbeds' | 'SuppressNotifications'>,
MessageFlags.Ephemeral | MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications
>;
withResponse?: boolean;
/** @deprecated Use {@link InteractionDeferReplyOptions.withResponse} instead. */
fetchReply?: boolean;
}
export interface InteractionDeferUpdateOptions {
withResponse?: boolean;
/** @deprecated Use {@link InteractionDeferUpdateOptions.withResponse} instead. */
fetchReply?: boolean;
}
export interface InteractionDeferUpdateOptions extends Omit<InteractionDeferReplyOptions, 'ephemeral'> {}
export interface InteractionReplyOptions extends BaseMessageOptionsWithPoll {
/** @deprecated Use {@link InteractionReplyOptions.flags} instead. */
ephemeral?: boolean;
export interface InteractionReplyOptions extends BaseMessageOptions {
tts?: boolean;
withResponse?: boolean;
/** @deprecated Use {@link InteractionReplyOptions.withResponse} instead. */
ephemeral?: boolean;
fetchReply?: boolean;
flags?: BitFieldResolvable<
Extract<MessageFlagsString, 'Ephemeral' | 'SuppressEmbeds' | 'SuppressNotifications'>,
@@ -6569,8 +6302,6 @@ export interface InteractionReplyOptions extends BaseMessageOptionsWithPoll {
}
export interface InteractionUpdateOptions extends MessageEditOptions {
withResponse?: boolean;
/** @deprecated Use {@link InteractionUpdateOptions.withResponse} instead. */
fetchReply?: boolean;
}
@@ -6687,7 +6418,6 @@ export interface MessageInteractionMetadata {
triggeringInteractionMetadata: MessageInteractionMetadata | null;
}
/** @deprecated Use {@link MessageInteractionMetadata} instead. */
export interface MessageInteraction {
id: Snowflake;
type: InteractionType;
@@ -6711,26 +6441,6 @@ export interface MessageMentionOptions {
export type MessageMentionTypes = 'roles' | 'users' | 'everyone';
export interface MessageSnapshot
extends Partialize<
Message,
null,
Exclude<
keyof Message,
| 'attachments'
| 'client'
| 'components'
| 'content'
| 'createdTimestamp'
| 'editedTimestamp'
| 'embeds'
| 'flags'
| 'mentions'
| 'stickers'
| 'type'
>
> {}
export interface BaseMessageOptions {
content?: string;
embeds?: readonly (JSONEncodable<APIEmbed> | APIEmbed)[];
@@ -6748,13 +6458,10 @@ export interface BaseMessageOptions {
| ActionRowData<MessageActionRowComponentData | MessageActionRowComponentBuilder>
| APIActionRowComponent<APIMessageActionRowComponent>
)[];
}
export interface BaseMessageOptionsWithPoll extends BaseMessageOptions {
poll?: PollData;
}
export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
export interface MessageCreateOptions extends BaseMessageOptions {
tts?: boolean;
nonce?: string | number;
enforceNonce?: boolean;
@@ -6767,7 +6474,7 @@ export interface MessageCreateOptions extends BaseMessageOptionsWithPoll {
}
export interface GuildForumThreadMessageCreateOptions
extends BaseMessageOptions,
extends Omit<BaseMessageOptions, 'poll'>,
Pick<MessageCreateOptions, 'flags' | 'stickers'> {}
export interface MessageEditAttachmentData {
@@ -6786,7 +6493,6 @@ export interface MessageReference {
channelId: Snowflake;
guildId: Snowflake | undefined;
messageId: Snowflake | undefined;
type: MessageReferenceType;
}
export type MessageResolvable = Message | Snowflake;
@@ -7082,10 +6788,6 @@ export interface ShardingManagerOptions {
execArgv?: readonly string[];
}
export interface ShowModalOptions {
withResponse?: boolean;
}
export { Snowflake };
export type StageInstanceResolvable = StageInstance | Snowflake;
@@ -7178,15 +6880,11 @@ export type Channel =
export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, ForumChannel | MediaChannel>;
export type SendableChannels = Extract<Channel, { send: (...args: any[]) => any }>;
export type TextBasedChannels = TextBasedChannel;
export type TextBasedChannelTypes = TextBasedChannel['type'];
export type GuildTextBasedChannelTypes = Exclude<TextBasedChannelTypes, ChannelType.DM | ChannelType.GroupDM>;
export type SendableChannelTypes = SendableChannels['type'];
export type GuildTextBasedChannelTypes = Exclude<TextBasedChannelTypes, ChannelType.DM>;
export type VoiceBasedChannel = Extract<Channel, { bitrate: number }>;
@@ -7278,9 +6976,7 @@ export interface WebhookMessageEditOptions extends Omit<MessageEditOptions, 'fla
threadId?: Snowflake;
}
export interface InteractionEditReplyOptions
extends WebhookMessageEditOptions,
Pick<BaseMessageOptionsWithPoll, 'poll'> {
export interface InteractionEditReplyOptions extends WebhookMessageEditOptions {
message?: MessageResolvable | '@original';
}
@@ -7334,9 +7030,6 @@ export interface ClientApplicationEditOptions {
icon?: BufferResolvable | Base64Resolvable | null;
coverImage?: BufferResolvable | Base64Resolvable | null;
interactionsEndpointURL?: string;
eventWebhooksURL?: string;
eventWebhooksStatus?: ApplicationWebhookEventStatus.Enabled | ApplicationWebhookEventStatus.Disabled;
eventWebhooksTypes?: readonly ApplicationWebhookEventType[];
tags?: readonly string[];
}

View File

@@ -209,20 +209,8 @@ import {
ApplicationEmoji,
ApplicationEmojiManager,
StickerPack,
GuildScheduledEventManager,
SendableChannels,
PollData,
UserManager,
InteractionCallbackResponse,
} from '.';
import {
expectAssignable,
expectDeprecated,
expectNotAssignable,
expectNotDeprecated,
expectNotType,
expectType,
} from 'tsd';
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
import { ReadonlyCollection } from '@discordjs/collection';
@@ -446,7 +434,6 @@ 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 }));
const buttonCollector = message.createMessageComponentCollector({ componentType: ComponentType.Button });
expectType<InteractionCollector<ButtonInteraction<'cached'>>>(buttonCollector);
@@ -1761,19 +1748,6 @@ declare const threadMemberManager: ThreadMemberManager;
threadMemberManager.fetch({ cache: true, force: false });
// @ts-expect-error `withMember` needs to be `true` to receive paginated results.
threadMemberManager.fetch({ withMember: false, limit: 5, after: '12345678901234567' });
expectNotDeprecated(threadMemberManager.add('1234678'));
expectDeprecated(threadMemberManager.add('1234678', 'reason'));
expectNotDeprecated(threadMemberManager.remove('1234678'));
expectDeprecated(threadMemberManager.remove('1234678', 'reason'));
expectNotDeprecated(threadMemberWithGuildMember.remove());
expectDeprecated(threadMemberWithGuildMember.remove('reason'));
}
declare const userManager: UserManager;
{
expectDeprecated(userManager.fetchFlags('1234567890'));
expectDeprecated(user.fetchFlags());
}
declare const typing: Typing;
@@ -1814,14 +1788,10 @@ 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<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<Message<true>>>(interaction.followUp({ content: 'a' }));
} else if (interaction.inRawGuild()) {
expectAssignable<MessageComponentInteraction>(interaction);
@@ -1830,14 +1800,10 @@ 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<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<Message<false>>>(interaction.followUp({ content: 'a' }));
} else if (interaction.inGuild()) {
expectAssignable<MessageComponentInteraction>(interaction);
@@ -1846,14 +1812,10 @@ client.on('interactionCreate', async interaction => {
expectType<Guild | null>(interaction.guild);
expectType<Promise<Message>>(interaction.reply({ content: 'a', fetchReply: true }));
expectType<Promise<Message>>(interaction.deferReply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message>>(interaction.fetchReply());
expectType<Promise<Message>>(interaction.update({ content: 'a', fetchReply: true }));
expectType<Promise<Message>>(interaction.deferUpdate({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.update({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
}
}
@@ -1889,8 +1851,6 @@ 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<Message<true>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<true>>>(interaction.fetchReply());
expectType<Promise<Message<true>>>(interaction.followUp({ content: 'a' }));
@@ -1899,8 +1859,6 @@ 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<Message<false>>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message<false>>>(interaction.fetchReply());
expectType<Promise<Message<false>>>(interaction.followUp({ content: 'a' }));
@@ -1909,8 +1867,6 @@ client.on('interactionCreate', async interaction => {
expectType<Guild | null>(interaction.guild);
expectType<Promise<Message>>(interaction.reply({ content: 'a', fetchReply: true }));
expectType<Promise<Message>>(interaction.deferReply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message>>(interaction.fetchReply());
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
@@ -1965,21 +1921,18 @@ 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 }));
} 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 }));
} else if (interaction.inGuild()) {
expectAssignable<ButtonInteraction>(interaction);
expectType<ButtonComponent | APIButtonComponent>(interaction.component);
expectType<Message>(interaction.message);
expectAssignable<Guild | null>(interaction.guild);
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
}
}
@@ -1996,21 +1949,18 @@ 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 }));
} 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 }));
} else if (interaction.inGuild()) {
expectAssignable<StringSelectMenuInteraction>(interaction);
expectType<SelectMenuComponent | APIStringSelectComponent>(interaction.component);
expectType<Message>(interaction.message);
expectType<Guild | null>(interaction.guild);
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
}
}
@@ -2023,7 +1973,6 @@ 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<APIInteractionDataResolvedGuildMember | null>(interaction.options.getMember('test'));
expectType<APIInteractionDataResolvedChannel>(interaction.options.getChannel('test', true));
@@ -2038,7 +1987,6 @@ 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<GuildBasedChannel>(interaction.options.getChannel('test', true));
expectType<Role>(interaction.options.getRole('test', true));
@@ -2061,9 +2009,10 @@ client.on('interactionCreate', async interaction => {
);
expectType<MediaChannel>(interaction.options.getChannel('test', true, [ChannelType.GuildMedia]));
} else {
// @ts-expect-error
consumeCachedCommand(interaction);
expectType<ChatInputCommandInteraction>(interaction);
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ withResponse: true }));
expectType<APIInteractionDataResolvedGuildMember | GuildMember | null>(interaction.options.getMember('test'));
expectType<GuildBasedChannel | APIInteractionDataResolvedChannel>(interaction.options.getChannel('test', true));
@@ -2119,36 +2068,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<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<Message<true>>>(interaction.followUp({ content: 'a' }));
} 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<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<Message<false>>>(interaction.followUp({ content: 'a' }));
} else if (interaction.inGuild()) {
expectAssignable<ModalSubmitInteraction>(interaction);
expectType<Guild | null>(interaction.guild);
expectType<Promise<Message>>(interaction.reply({ content: 'a', fetchReply: true }));
expectType<Promise<Message>>(interaction.deferReply({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.reply({ content: 'a', withResponse: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferReply({ withResponse: true }));
expectType<Promise<Message>>(interaction.editReply({ content: 'a' }));
expectType<Promise<Message>>(interaction.fetchReply());
expectType<Promise<Message>>(interaction.deferUpdate({ fetchReply: true }));
expectType<Promise<InteractionCallbackResponse>>(interaction.deferUpdate({ withResponse: true }));
expectType<Promise<Message>>(interaction.followUp({ content: 'a' }));
}
}
@@ -2635,8 +2575,6 @@ await textChannel.send({
});
declare const poll: Poll;
declare const message: Message;
declare const pollData: PollData;
{
expectType<Message>(await poll.end());
@@ -2650,32 +2588,8 @@ declare const pollData: PollData;
messageId: snowflake,
answerId: 1,
});
await message.edit({
// @ts-expect-error
poll: pollData,
});
await chatInputInteraction.editReply({ poll: pollData });
}
expectType<Collection<Snowflake, StickerPack>>(await client.fetchStickerPacks());
expectType<Collection<Snowflake, StickerPack>>(await client.fetchStickerPacks({}));
expectType<StickerPack>(await client.fetchStickerPacks({ packId: snowflake }));
client.on('interactionCreate', interaction => {
if (!interaction.channel) {
return;
}
// @ts-expect-error
interaction.channel.send();
if (interaction.channel.isSendable()) {
expectType<SendableChannels>(interaction.channel);
interaction.channel.send({ embeds: [] });
}
});
declare const guildScheduledEventManager: GuildScheduledEventManager;
await guildScheduledEventManager.edit(snowflake, { recurrenceRule: null });

View File

@@ -23,7 +23,7 @@
## Installation
**Node.js 18 or newer is required.**
**Node.js 16.11.0 or newer is required.**
```sh
npm install @discordjs/formatters

Some files were not shown because too many files have changed in this diff Show More