mirror of
https://github.com/discordjs/discord.js.git
synced 2026-05-23 03:50:09 +00:00
Compare commits
15 Commits
@discordjs
...
@discordjs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8065b80cea | ||
|
|
3b26680672 | ||
|
|
c4dbd7ee9f | ||
|
|
72771b79aa | ||
|
|
63dbe48055 | ||
|
|
67c8953a10 | ||
|
|
30e35d909e | ||
|
|
6a5707c786 | ||
|
|
9b821e5dfc | ||
|
|
a04172325a | ||
|
|
154c00ded9 | ||
|
|
3b927449ae | ||
|
|
fcce0d95bb | ||
|
|
93e0f4cd10 | ||
|
|
abaae4ff16 |
@@ -2,6 +2,14 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [@discordjs/core@2.3.0](https://github.com/discordjs/discord.js/compare/@discordjs/core@2.2.2...@discordjs/core@2.3.0) - (2025-10-08)
|
||||
|
||||
## Features
|
||||
|
||||
- Add `{add,remove}GroupDMRecipient` methods (#11135) ([72771b7](https://github.com/discordjs/discord.js/commit/72771b79aa3a78967be92ea2e4c523755d0d2ec0))
|
||||
- **guild:** Support incident actions (#11131) ([63dbe48](https://github.com/discordjs/discord.js/commit/63dbe48055347413ec70f36bce4f645688776413))
|
||||
- Add gateway endpoints (#11130) ([a041723](https://github.com/discordjs/discord.js/commit/a04172325af5a3a9880253bb8dc7c057a0426d83))
|
||||
|
||||
# [@discordjs/core@2.2.2](https://github.com/discordjs/discord.js/compare/@discordjs/core@2.2.1...@discordjs/core@2.2.2) - (2025-09-10)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@discordjs/core",
|
||||
"version": "2.2.2",
|
||||
"version": "2.3.0",
|
||||
"description": "A thinly abstracted wrapper around the rest API, and gateway.",
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
@@ -70,7 +70,7 @@
|
||||
"@discordjs/ws": "workspace:^",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.24"
|
||||
"discord-api-types": "^0.38.29"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@discordjs/api-extractor": "workspace:^",
|
||||
|
||||
34
packages/core/scripts/check-routes.mjs
Normal file
34
packages/core/scripts/check-routes.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Routes } from 'discord-api-types/v10';
|
||||
import { glob, readFile } from 'node:fs/promises';
|
||||
|
||||
const usedRoutes = new Set();
|
||||
|
||||
const ignoredRoutes = new Set([
|
||||
// Deprecated
|
||||
'channelPins',
|
||||
'channelPin',
|
||||
'guilds',
|
||||
'guildCurrentMemberNickname',
|
||||
'guildMFA',
|
||||
'nitroStickerPacks',
|
||||
]);
|
||||
|
||||
for await (const file of glob('src/api/*.ts')) {
|
||||
const content = await readFile(file, 'utf-8');
|
||||
|
||||
const routes = content.matchAll(/Routes\.([\w\d_]+)/g);
|
||||
for (const route of routes) {
|
||||
usedRoutes.add(route[1]);
|
||||
}
|
||||
}
|
||||
|
||||
const unusedRoutes = Object.keys(Routes).filter((route) => !usedRoutes.has(route) && !ignoredRoutes.has(route));
|
||||
|
||||
if (unusedRoutes.length > 0) {
|
||||
console.warn('The following routes are not implemented:');
|
||||
for (const route of unusedRoutes) {
|
||||
console.warn(` - ${route}`);
|
||||
}
|
||||
} else {
|
||||
console.log('No missing routes.');
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
/* eslint-disable jsdoc/check-param-names */
|
||||
|
||||
import { makeURLSearchParams, type RawFile, type REST, type RequestData } from '@discordjs/rest';
|
||||
import { makeURLSearchParams, type RawFile, type RequestData, type REST } from '@discordjs/rest';
|
||||
import {
|
||||
Routes,
|
||||
type RESTPostAPIChannelWebhookJSONBody,
|
||||
type RESTPostAPIChannelWebhookResult,
|
||||
type APIThreadChannel,
|
||||
type RESTDeleteAPIChannelResult,
|
||||
type RESTGetAPIChannelInvitesResult,
|
||||
type RESTGetAPIChannelMessageReactionUsersQuery,
|
||||
@@ -17,8 +16,8 @@ import {
|
||||
type RESTGetAPIChannelThreadsArchivedQuery,
|
||||
type RESTGetAPIChannelUsersThreadsArchivedResult,
|
||||
type RESTGetAPIChannelWebhooksResult,
|
||||
type RESTPatchAPIChannelMessageJSONBody,
|
||||
type RESTPatchAPIChannelJSONBody,
|
||||
type RESTPatchAPIChannelMessageJSONBody,
|
||||
type RESTPatchAPIChannelMessageResult,
|
||||
type RESTPatchAPIChannelResult,
|
||||
type RESTPostAPIChannelFollowersResult,
|
||||
@@ -27,12 +26,14 @@ import {
|
||||
type RESTPostAPIChannelMessageCrosspostResult,
|
||||
type RESTPostAPIChannelMessageJSONBody,
|
||||
type RESTPostAPIChannelMessageResult,
|
||||
type RESTPutAPIChannelPermissionJSONBody,
|
||||
type Snowflake,
|
||||
type RESTPostAPIChannelThreadsJSONBody,
|
||||
type RESTPostAPIChannelThreadsResult,
|
||||
type APIThreadChannel,
|
||||
type RESTPostAPIChannelWebhookJSONBody,
|
||||
type RESTPostAPIChannelWebhookResult,
|
||||
type RESTPostAPIGuildForumThreadsJSONBody,
|
||||
type RESTPutAPIChannelPermissionJSONBody,
|
||||
type RESTPutAPIChannelRecipientJSONBody,
|
||||
type Snowflake,
|
||||
} from 'discord-api-types/v10';
|
||||
|
||||
export interface StartForumThreadOptions extends RESTPostAPIGuildForumThreadsJSONBody {
|
||||
@@ -593,4 +594,43 @@ export class ChannelsAPI {
|
||||
signal,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a recipient to a group DM channel
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#group-dm-add-recipient}
|
||||
* @param channelId - The id of the channel to add the recipient to
|
||||
* @param userId - The id of the user to add as a recipient
|
||||
* @param body - The data for adding the recipient
|
||||
* @param options - The options for adding the recipient
|
||||
*/
|
||||
public async addGroupDMRecipient(
|
||||
channelId: Snowflake,
|
||||
userId: Snowflake,
|
||||
body: RESTPutAPIChannelRecipientJSONBody,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
await this.rest.put(Routes.channelRecipient(channelId, userId), {
|
||||
body,
|
||||
signal,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a recipient from a group DM channel
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient}
|
||||
* @param channelId - The id of the channel to remove the recipient from
|
||||
* @param userId - The id of the user to remove as a recipient
|
||||
* @param options - The options for removing the recipient
|
||||
*/
|
||||
public async removeGroupDMRecipient(
|
||||
channelId: Snowflake,
|
||||
userId: Snowflake,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
await this.rest.delete(Routes.channelRecipient(channelId, userId), {
|
||||
signal,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
31
packages/core/src/api/gateway.ts
Normal file
31
packages/core/src/api/gateway.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/* eslint-disable jsdoc/check-param-names */
|
||||
|
||||
import type { RequestData, REST } from '@discordjs/rest';
|
||||
import { Routes, type RESTGetAPIGatewayBotResult, type RESTGetAPIGatewayResult } from 'discord-api-types/v10';
|
||||
|
||||
export class GatewayAPI {
|
||||
public constructor(private readonly rest: REST) {}
|
||||
|
||||
/**
|
||||
* Gets gateway information.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/events/gateway#get-gateway}
|
||||
* @param options - The options for fetching the gateway information
|
||||
*/
|
||||
public async get({ signal }: Pick<RequestData, 'signal'> = {}) {
|
||||
return this.rest.get(Routes.gateway(), {
|
||||
auth: false,
|
||||
signal,
|
||||
}) as Promise<RESTGetAPIGatewayResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets gateway information with additional metadata.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/events/gateway#get-gateway-bot}
|
||||
* @param options - The options for fetching the gateway information
|
||||
*/
|
||||
public async getBot({ signal }: Pick<RequestData, 'signal'> = {}) {
|
||||
return this.rest.get(Routes.gatewayBot(), { signal }) as Promise<RESTGetAPIGatewayBotResult>;
|
||||
}
|
||||
}
|
||||
@@ -95,6 +95,8 @@ import {
|
||||
type RESTPostAPIGuildsMFAResult,
|
||||
type RESTPostAPIGuildsResult,
|
||||
type RESTPutAPIGuildBanJSONBody,
|
||||
type RESTPutAPIGuildIncidentActionsJSONBody,
|
||||
type RESTPutAPIGuildIncidentActionsResult,
|
||||
type RESTPutAPIGuildMemberJSONBody,
|
||||
type RESTPutAPIGuildMemberResult,
|
||||
type RESTPutAPIGuildOnboardingJSONBody,
|
||||
@@ -1359,4 +1361,23 @@ export class GuildsAPI {
|
||||
signal,
|
||||
}) as Promise<RESTPutAPIGuildOnboardingResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies incident actions for a guild.
|
||||
*
|
||||
* @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions}
|
||||
* @param guildId - The id of the guild
|
||||
* @param body - The data for modifying guild incident actions
|
||||
* @param options - The options for modifying guild incident actions
|
||||
*/
|
||||
public async editIncidentActions(
|
||||
guildId: Snowflake,
|
||||
body: RESTPutAPIGuildIncidentActionsJSONBody,
|
||||
{ signal }: Pick<RequestData, 'signal'> = {},
|
||||
) {
|
||||
return this.rest.put(Routes.guildIncidentActions(guildId), {
|
||||
body,
|
||||
signal,
|
||||
}) as Promise<RESTPutAPIGuildIncidentActionsResult>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { REST } from '@discordjs/rest';
|
||||
import { ApplicationCommandsAPI } from './applicationCommands.js';
|
||||
import { ApplicationsAPI } from './applications.js';
|
||||
import { ChannelsAPI } from './channel.js';
|
||||
import { GatewayAPI } from './gateway.js';
|
||||
import { GuildsAPI } from './guild.js';
|
||||
import { InteractionsAPI } from './interactions.js';
|
||||
import { InvitesAPI } from './invite.js';
|
||||
@@ -19,6 +20,7 @@ import { WebhooksAPI } from './webhook.js';
|
||||
export * from './applicationCommands.js';
|
||||
export * from './applications.js';
|
||||
export * from './channel.js';
|
||||
export * from './gateway.js';
|
||||
export * from './guild.js';
|
||||
export * from './interactions.js';
|
||||
export * from './invite.js';
|
||||
@@ -40,6 +42,8 @@ export class API {
|
||||
|
||||
public readonly channels: ChannelsAPI;
|
||||
|
||||
public readonly gateway: GatewayAPI;
|
||||
|
||||
public readonly guilds: GuildsAPI;
|
||||
|
||||
public readonly interactions: InteractionsAPI;
|
||||
@@ -70,6 +74,7 @@ export class API {
|
||||
this.applicationCommands = new ApplicationCommandsAPI(rest);
|
||||
this.applications = new ApplicationsAPI(rest);
|
||||
this.channels = new ChannelsAPI(rest);
|
||||
this.gateway = new GatewayAPI(rest);
|
||||
this.guilds = new GuildsAPI(rest);
|
||||
this.invites = new InvitesAPI(rest);
|
||||
this.monetization = new MonetizationAPI(rest);
|
||||
|
||||
@@ -2,6 +2,38 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
# [14.23.0](https://github.com/discordjs/discord.js/compare/14.22.1...14.23.0) - (2025-10-08)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **ThreadMemberFlagsBitField:** Use `ThreadMemberFlags` enum in `Flags` (#11118) ([154c00d](https://github.com/discordjs/discord.js/commit/154c00ded932109c59ff0759609424fcb95140a0))
|
||||
- Backport in operator fix from main (#11127) ([fcce0d9](https://github.com/discordjs/discord.js/commit/fcce0d95bb6cd415f40f9f7a052e01ddcf625ed0))
|
||||
- Ensure discriminator detection respects webhooks too (#11062) ([d8ad181](https://github.com/discordjs/discord.js/commit/d8ad181c191e3a908e3c8e133ccb1d961d9d79e0))
|
||||
|
||||
## Documentation
|
||||
|
||||
- Use LocalizationMap where applicable (#11117) ([3b92744](https://github.com/discordjs/discord.js/commit/3b927449ae728175f04d67376642b20ba4a93069))
|
||||
- **GuildEditOptions:** Deprecate owner property ([fe025c0](https://github.com/discordjs/discord.js/commit/fe025c0a9f722c6225fff6501e9b3981cfe134ba))
|
||||
- Deprecate API related to guild ownership (#11054) ([3dd57c2](https://github.com/discordjs/discord.js/commit/3dd57c2eaf220b08f2b6f6562c34acf8524b5b17))
|
||||
- Deprecate setting owner ([740da4c](https://github.com/discordjs/discord.js/commit/740da4ce5e189391c7a0904da32a96fe1c8534e6))
|
||||
|
||||
## Features
|
||||
|
||||
- Bump builders in v14 (and fix runtime crashes) (#11153) ([67c8953](https://github.com/discordjs/discord.js/commit/67c8953a10d150074ba848cd8bfb30961d46b662))
|
||||
- **GuildMemberManager:** Add new modify self fields (#11112) ([9b821e5](https://github.com/discordjs/discord.js/commit/9b821e5dfcfb92a9d23ef96dd947c0bd11ee7b86))
|
||||
- Text display and more selects in modal for v14 (#11096) ([93e0f4c](https://github.com/discordjs/discord.js/commit/93e0f4cd10af6d85ccdcb6a6aeae3e1a9f14a8fe))
|
||||
- Guest invites (#11079) ([79d999e](https://github.com/discordjs/discord.js/commit/79d999e4c10e36330ee897065987ad99d558edca))
|
||||
- Polls overhaul (#11058) ([4a8aeb6](https://github.com/discordjs/discord.js/commit/4a8aeb6aee78b23a25e8d5be1309cc7c64b066fb))
|
||||
|
||||
## Refactor
|
||||
|
||||
- **ActionsManager:** Register actions without using class name (#11080) ([0dff969](https://github.com/discordjs/discord.js/commit/0dff969e16a8879a0fc889567bd540cb1b82a682))
|
||||
|
||||
## Typings
|
||||
|
||||
- **ClientEventTypes:** Fix `messageDeleteBulk` event arg (#11122) ([30e35d9](https://github.com/discordjs/discord.js/commit/30e35d909e0058db701c82744b13da26ddefcf0e))
|
||||
- **Webhook:** Specify message type (#11142) ([6a5707c](https://github.com/discordjs/discord.js/commit/6a5707c78669bb65d03ae76ab591e053787891f1))
|
||||
|
||||
# [14.22.1](https://github.com/discordjs/discord.js/compare/14.22.0...14.22.1) - (2025-08-22)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "discord.js",
|
||||
"version": "14.22.1",
|
||||
"version": "14.23.0",
|
||||
"description": "A powerful library for interacting with the Discord API",
|
||||
"scripts": {
|
||||
"test": "pnpm run docs:test && pnpm run test:typescript",
|
||||
@@ -66,14 +66,14 @@
|
||||
"homepage": "https://discord.js.org",
|
||||
"funding": "https://github.com/discordjs/discord.js?sponsor",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.11.2",
|
||||
"@discordjs/builders": "^1.12.0",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.6.1",
|
||||
"@discordjs/rest": "workspace:^",
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@discordjs/ws": "^1.2.3",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "^0.38.24",
|
||||
"discord-api-types": "^0.38.29",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
|
||||
@@ -168,6 +168,8 @@
|
||||
|
||||
* @property {'ModalSubmitInteractionFieldNotFound'} ModalSubmitInteractionFieldNotFound
|
||||
* @property {'ModalSubmitInteractionFieldType'} ModalSubmitInteractionFieldType
|
||||
* @property {'ModalSubmitInteractionFieldEmpty'} ModalSubmitInteractionFieldEmpty
|
||||
* @property {'ModalSubmitInteractionFieldInvalidChannelType'} ModalSubmitInteractionFieldInvalidChannelType
|
||||
|
||||
* @property {'InvalidMissingScopes'} InvalidMissingScopes
|
||||
* @property {'InvalidScopesWithPermissions'} InvalidScopesWithPermissions
|
||||
@@ -327,6 +329,8 @@ const keys = [
|
||||
|
||||
'ModalSubmitInteractionFieldNotFound',
|
||||
'ModalSubmitInteractionFieldType',
|
||||
'ModalSubmitInteractionFieldEmpty',
|
||||
'ModalSubmitInteractionFieldInvalidChannelType',
|
||||
|
||||
'InvalidMissingScopes',
|
||||
'InvalidScopesWithPermissions',
|
||||
|
||||
@@ -161,6 +161,10 @@ const Messages = {
|
||||
`Required field with custom id "${customId}" not found.`,
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldType]: (customId, type, expected) =>
|
||||
`Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldEmpty]: (customId, type) =>
|
||||
`Required field with custom id "${customId}" is of type: ${type}; expected a non-empty value.`,
|
||||
[DjsErrorCodes.ModalSubmitInteractionFieldInvalidChannelType]: (customId, type, expected) =>
|
||||
`The type of channel of the field with custom id "${customId}" is: ${type}; expected ${expected}.`,
|
||||
|
||||
[DjsErrorCodes.InvalidMissingScopes]: 'At least one valid scope must be provided for the invite',
|
||||
[DjsErrorCodes.InvalidScopesWithPermissions]: 'Permissions cannot be set without the bot scope.',
|
||||
|
||||
@@ -162,6 +162,7 @@ exports.InteractionWebhook = require('./structures/InteractionWebhook');
|
||||
exports.Invite = require('./structures/Invite');
|
||||
exports.InviteStageInstance = require('./structures/InviteStageInstance');
|
||||
exports.InviteGuild = require('./structures/InviteGuild');
|
||||
exports.LabelComponent = require('./structures/LabelComponent');
|
||||
exports.Message = require('./structures/Message').Message;
|
||||
exports.Attachment = require('./structures/Attachment');
|
||||
exports.AttachmentBuilder = require('./structures/AttachmentBuilder');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { process } = require('node:process');
|
||||
const { setTimeout, clearTimeout } = require('node:timers');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { makeURLSearchParams } = require('@discordjs/rest');
|
||||
@@ -10,10 +11,13 @@ const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } =
|
||||
const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
|
||||
const { GuildMember } = require('../structures/GuildMember');
|
||||
const { Role } = require('../structures/Role');
|
||||
const { resolveImage } = require('../util/DataResolver');
|
||||
const Events = require('../util/Events');
|
||||
const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField');
|
||||
const Partials = require('../util/Partials');
|
||||
|
||||
let deprecatedEmittedForEditSoleNickname = false;
|
||||
|
||||
/**
|
||||
* Manages API methods for GuildMembers and stores their cache.
|
||||
* @extends {CachedManager}
|
||||
@@ -336,8 +340,8 @@ class GuildMemberManager extends CachedManager {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits a member of the guild.
|
||||
* <info>The user must be a member of the guild</info>
|
||||
* Edits a member of a guild.
|
||||
*
|
||||
* @param {UserResolvable} user The member to edit
|
||||
* @param {GuildMemberEditOptions} options The options to provide
|
||||
* @returns {Promise<GuildMember>}
|
||||
@@ -372,13 +376,30 @@ class GuildMemberManager extends CachedManager {
|
||||
}
|
||||
|
||||
let endpoint;
|
||||
|
||||
if (id === this.client.user.id) {
|
||||
const keys = Object.keys(options);
|
||||
if (keys.length === 1 && keys[0] === 'nick') endpoint = Routes.guildMember(this.guild.id);
|
||||
else endpoint = Routes.guildMember(this.guild.id, id);
|
||||
} else {
|
||||
endpoint = Routes.guildMember(this.guild.id, id);
|
||||
|
||||
if (keys.length === 1 && keys[0] === 'nick') {
|
||||
// For modifying the current application's nickname only, we use the /guilds/{guild.id}/members/@me endpoint.
|
||||
// This endpoint only requires the CHANGE_NICKNAME permission.
|
||||
// The other endpoint would require the MANAGE_NICKNAMES permission.
|
||||
// In v15, this will be split out, so emit a deprecation.
|
||||
endpoint = Routes.guildMember(this.guild.id, '@me');
|
||||
|
||||
if (!deprecatedEmittedForEditSoleNickname) {
|
||||
process.emitWarning(
|
||||
// eslint-disable-next-line max-len
|
||||
"You should use GuildMemberManager#editMe() when changing your nickname. Due to Discord's API changes, GuildMemberManager#edit() will end up requiring MANAGE_NICKNAMES in v15.",
|
||||
'DeprecationWarning',
|
||||
);
|
||||
|
||||
deprecatedEmittedForEditSoleNickname = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endpoint ??= Routes.guildMember(this.guild.id, id);
|
||||
const d = await this.client.rest.patch(endpoint, { body: options, reason });
|
||||
|
||||
const clone = this.cache.get(id)?._clone();
|
||||
@@ -386,6 +407,38 @@ class GuildMemberManager extends CachedManager {
|
||||
return clone ?? this._add(d, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data for editing the current application's guild member.
|
||||
*
|
||||
* @typedef {Object} GuildMemberEditMeOptions
|
||||
* @property {?string} [nick] The nickname to set
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [banner] The banner to set
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [avatar] The avatar to set
|
||||
* @property {?string} [bio] The bio to set
|
||||
* @property {string} [reason] The reason to use
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edits the current application's guild member in a guild.
|
||||
*
|
||||
* @param {GuildMemberEditMeOptions} options The options to provide
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
async editMe({ reason, ...options }) {
|
||||
const data = await this.client.rest.patch(Routes.guildMember(this.guild.id, '@me'), {
|
||||
body: {
|
||||
...options,
|
||||
banner: options.banner && (await resolveImage(options.banner)),
|
||||
avatar: options.avatar && (await resolveImage(options.avatar)),
|
||||
},
|
||||
reason,
|
||||
});
|
||||
|
||||
const clone = this.me?._clone();
|
||||
clone?._patch(data);
|
||||
return clone ?? this._add(data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used for pruning guild members.
|
||||
* <info>It's recommended to set {@link GuildPruneMembersOptions#count options.count}
|
||||
|
||||
@@ -73,7 +73,7 @@ class ApplicationCommand extends Base {
|
||||
if ('name_localizations' in data) {
|
||||
/**
|
||||
* The name localizations for this command
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.nameLocalizations = data.name_localizations;
|
||||
} else {
|
||||
@@ -101,7 +101,7 @@ class ApplicationCommand extends Base {
|
||||
if ('description_localizations' in data) {
|
||||
/**
|
||||
* The description localizations for this command
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.descriptionLocalizations = data.description_localizations;
|
||||
} else {
|
||||
@@ -227,11 +227,11 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandData
|
||||
* @property {string} name The name of the command, must be in all lowercase if type is
|
||||
* {@link ApplicationCommandType.ChatInput}
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
|
||||
* @property {LocalizationMap} [nameLocalizations] The localizations for the command name
|
||||
* @property {string} description The description of the command,
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {boolean} [nsfw] Whether the command is age-restricted
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description,
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The localizations for the command description,
|
||||
* if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
|
||||
* @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
|
||||
* @property {ApplicationCommandOptionData[]} [options] Options for the command
|
||||
@@ -253,9 +253,9 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandOptionData
|
||||
* @property {ApplicationCommandOptionType} type The type of the option
|
||||
* @property {string} name The name of the option
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The name localizations for the option
|
||||
* @property {LocalizationMap} [nameLocalizations] The name localizations for the option
|
||||
* @property {string} description The description of the option
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The description localizations for the option
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The description localizations for the option
|
||||
* @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
|
||||
* {@link ApplicationCommandOptionType.String}, {@link ApplicationCommandOptionType.Integer} or
|
||||
* {@link ApplicationCommandOptionType.Number} option
|
||||
@@ -277,7 +277,7 @@ class ApplicationCommand extends Base {
|
||||
/**
|
||||
* @typedef {Object} ApplicationCommandOptionChoiceData
|
||||
* @property {string} name The name of the choice
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localized names for this choice
|
||||
* @property {LocalizationMap} [nameLocalizations] The localized names for this choice
|
||||
* @property {string|number} value The value of the choice
|
||||
*/
|
||||
|
||||
@@ -308,7 +308,7 @@ class ApplicationCommand extends Base {
|
||||
|
||||
/**
|
||||
* Edits the localized names of this ApplicationCommand
|
||||
* @param {Object<Locale, string>} nameLocalizations The new localized names for the command
|
||||
* @param {LocalizationMap} nameLocalizations The new localized names for the command
|
||||
* @returns {Promise<ApplicationCommand>}
|
||||
* @example
|
||||
* // Edit the name localizations of this command
|
||||
@@ -334,7 +334,7 @@ class ApplicationCommand extends Base {
|
||||
|
||||
/**
|
||||
* Edits the localized descriptions of this ApplicationCommand
|
||||
* @param {Object<Locale, string>} descriptionLocalizations The new localized descriptions for the command
|
||||
* @param {LocalizationMap} descriptionLocalizations The new localized descriptions for the command
|
||||
* @returns {Promise<ApplicationCommand>}
|
||||
* @example
|
||||
* // Edit the description localizations of this command
|
||||
@@ -550,10 +550,10 @@ class ApplicationCommand extends Base {
|
||||
* @typedef {Object} ApplicationCommandOption
|
||||
* @property {ApplicationCommandOptionType} type The type of the option
|
||||
* @property {string} name The name of the option
|
||||
* @property {Object<Locale, string>} [nameLocalizations] The localizations for the option name
|
||||
* @property {LocalizationMap} [nameLocalizations] The localizations for the option name
|
||||
* @property {string} [nameLocalized] The localized name for this option
|
||||
* @property {string} description The description of the option
|
||||
* @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the option description
|
||||
* @property {LocalizationMap} [descriptionLocalizations] The localizations for the option description
|
||||
* @property {string} [descriptionLocalized] The localized description for this option
|
||||
* @property {boolean} [required] Whether the option is required
|
||||
* @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
|
||||
|
||||
@@ -13,7 +13,7 @@ class ApplicationRoleConnectionMetadata {
|
||||
|
||||
/**
|
||||
* The name localizations for this metadata field
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.nameLocalizations = data.name_localizations ?? null;
|
||||
|
||||
@@ -25,7 +25,7 @@ class ApplicationRoleConnectionMetadata {
|
||||
|
||||
/**
|
||||
* The description localizations for this metadata field
|
||||
* @type {?Object<Locale, string>}
|
||||
* @type {?LocalizationMap}
|
||||
*/
|
||||
this.descriptionLocalizations = data.description_localizations ?? null;
|
||||
|
||||
|
||||
@@ -375,9 +375,9 @@ class ClientApplication extends Application {
|
||||
* Data for creating or editing an application role connection metadata.
|
||||
* @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
|
||||
* @property {string} name The name of the metadata field
|
||||
* @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
|
||||
* @property {?LocalizationMap} [nameLocalizations] The name localizations for the metadata field
|
||||
* @property {string} description The description of the metadata field
|
||||
* @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
|
||||
* @property {?LocalizationMap} [descriptionLocalizations] The description localizations for the metadata field
|
||||
* @property {string} key The dictionary key of the metadata field
|
||||
* @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
|
||||
*/
|
||||
|
||||
@@ -80,12 +80,17 @@ class CommandInteraction extends BaseInteraction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the resolved data of a received command interaction.
|
||||
* @typedef {Object} CommandInteractionResolvedData
|
||||
* @typedef {Object} BaseInteractionResolvedData
|
||||
* @property {Collection<Snowflake, User>} [users] The resolved users
|
||||
* @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
|
||||
* @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
|
||||
* @property {Collection<Snowflake, BaseChannel|APIChannel>} [channels] The resolved channels
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the resolved data of a received command interaction.
|
||||
*
|
||||
* @typedef {BaseInteractionResolvedData} CommandInteractionResolvedData
|
||||
* @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
|
||||
* @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
|
||||
*/
|
||||
|
||||
@@ -422,7 +422,9 @@ class GuildMember extends Base {
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setNickname(nick, reason) {
|
||||
return this.edit({ nick, reason });
|
||||
return this.user.id === this.client.user.id
|
||||
? this.guild.members.editMe({ nick, reason })
|
||||
: this.edit({ nick, reason });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
54
packages/discord.js/src/structures/LabelComponent.js
Normal file
54
packages/discord.js/src/structures/LabelComponent.js
Normal file
@@ -0,0 +1,54 @@
|
||||
'use strict';
|
||||
|
||||
const Component = require('./Component');
|
||||
const { createComponent } = require('../util/Components');
|
||||
|
||||
/**
|
||||
* Represents a label component
|
||||
*
|
||||
* @extends {Component}
|
||||
*/
|
||||
class LabelComponent extends Component {
|
||||
constructor({ component, ...data }) {
|
||||
super(data);
|
||||
|
||||
/**
|
||||
* The component in this label
|
||||
*
|
||||
* @type {Component}
|
||||
* @readonly
|
||||
*/
|
||||
this.component = createComponent(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* The label of the component
|
||||
*
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
get label() {
|
||||
return this.data.label;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of this component
|
||||
*
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get description() {
|
||||
return this.data.description ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the API-compatible JSON for this component
|
||||
*
|
||||
* @returns {APILabelComponent}
|
||||
*/
|
||||
toJSON() {
|
||||
return { ...this.data, component: this.component.toJSON() };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LabelComponent;
|
||||
@@ -623,7 +623,7 @@ class Message extends Base {
|
||||
* Similar to createReactionCollector but in promise form.
|
||||
* Resolves with a collection of reactions that pass the specified filter.
|
||||
* @param {AwaitReactionsOptions} [options={}] Optional options to pass to the internal collector
|
||||
* @returns {Promise<Collection<string | Snowflake, MessageReaction>>}
|
||||
* @returns {Promise<Collection<string|Snowflake, MessageReaction>>}
|
||||
* @example
|
||||
* // Create a reaction collector
|
||||
* const filter = (reaction, user) => reaction.emoji.name === '👌' && user.id === 'someId'
|
||||
|
||||
@@ -4,23 +4,48 @@ const { Collection } = require('@discordjs/collection');
|
||||
const { ComponentType } = require('discord-api-types/v10');
|
||||
const { DiscordjsTypeError, ErrorCodes } = require('../errors');
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModalSelectedMentionables
|
||||
* @property {Collection<Snowflake, User>} users The selected users
|
||||
* @property {Collection<Snowflake, GuildMember | APIGuildMember>} members The selected members
|
||||
* @property {Collection<Snowflake, Role | APIRole>} roles The selected roles
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the serialized fields from a modal submit interaction
|
||||
*/
|
||||
class ModalSubmitFields {
|
||||
constructor(components) {
|
||||
constructor(components, resolved) {
|
||||
/**
|
||||
* The components within the modal
|
||||
* @type {ActionRowModalData[]}
|
||||
*
|
||||
* @type {Array<ActionRowModalData|LabelModalData|TextDisplayModalData>}
|
||||
*/
|
||||
this.components = components;
|
||||
|
||||
/**
|
||||
* The interaction resolved data
|
||||
*
|
||||
* @name ModalSubmitFields#resolved
|
||||
* @type {?Readonly<BaseInteractionResolvedData>}
|
||||
*/
|
||||
Object.defineProperty(this, 'resolved', { value: resolved ? Object.freeze(resolved) : null });
|
||||
|
||||
/**
|
||||
* The extracted fields from the modal
|
||||
* @type {Collection<string, ModalData>}
|
||||
*/
|
||||
this.fields = components.reduce((accumulator, next) => {
|
||||
next.components.forEach(component => accumulator.set(component.customId, component));
|
||||
// For legacy support of action rows
|
||||
if ('components' in next) {
|
||||
for (const component of next.components) accumulator.set(component.customId, component);
|
||||
}
|
||||
|
||||
// For label components
|
||||
if ('component' in next) {
|
||||
accumulator.set(next.component.customId, next.component);
|
||||
}
|
||||
|
||||
return accumulator;
|
||||
}, new Collection());
|
||||
}
|
||||
@@ -42,13 +67,154 @@ class ModalSubmitFields {
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a component by custom id and property and checks its type.
|
||||
*
|
||||
* @param {string} customId The custom id of the component.
|
||||
* @param {ComponentType[]} allowedTypes The allowed types of the component.
|
||||
* @param {string[]} properties The properties to check for for `required`.
|
||||
* @param {boolean} required Whether to throw an error if the component value(s) are not found.
|
||||
* @returns {ModalData} The option, if found.
|
||||
* @private
|
||||
*/
|
||||
_getTypedComponent(customId, allowedTypes, properties, required) {
|
||||
const component = this.getField(customId);
|
||||
if (!allowedTypes.includes(component.type)) {
|
||||
throw new DiscordjsTypeError(
|
||||
ErrorCodes.ModalSubmitInteractionFieldNotFound,
|
||||
customId,
|
||||
component.type,
|
||||
allowedTypes.join(', '),
|
||||
);
|
||||
} else if (required && properties.every(prop => component[prop] === null || component[prop] === undefined)) {
|
||||
throw new DiscordjsTypeError(ErrorCodes.ModalSubmitInteractionFieldEmpty, customId, component.type);
|
||||
}
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a text input component given a custom id
|
||||
* @param {string} customId The custom id of the text input component
|
||||
* @returns {string}
|
||||
*/
|
||||
getTextInputValue(customId) {
|
||||
return this.getField(customId, ComponentType.TextInput).value;
|
||||
return this._getTypedComponent(customId, [ComponentType.TextInput]).value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the values of a string select component given a custom id
|
||||
*
|
||||
* @param {string} customId The custom id of the string select component
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getStringSelectValues(customId) {
|
||||
return this._getTypedComponent(customId, [ComponentType.StringSelect]).values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets users component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?Collection<Snowflake, User>} The selected users, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedUsers(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.UserSelect, ComponentType.MentionableSelect],
|
||||
['users'],
|
||||
required,
|
||||
);
|
||||
return component.users ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets roles component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?Collection<Snowflake, Role|APIRole>} The selected roles, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedRoles(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.RoleSelect, ComponentType.MentionableSelect],
|
||||
['roles'],
|
||||
required,
|
||||
);
|
||||
return component.roles ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channels component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @param {ChannelType[]} [channelTypes=[]] The allowed types of channels. If empty, all channel types are allowed.
|
||||
* @returns {?Collection<Snowflake, GuildChannel|ThreadChannel|APIChannel>} The selected channels,
|
||||
* or null if none were selected and not required
|
||||
*/
|
||||
getSelectedChannels(customId, required = false, channelTypes = []) {
|
||||
const component = this._getTypedComponent(customId, [ComponentType.ChannelSelect], ['channels'], required);
|
||||
const channels = component.channels;
|
||||
if (channels && channelTypes.length > 0) {
|
||||
for (const channel of channels.values()) {
|
||||
if (!channelTypes.includes(channel.type)) {
|
||||
throw new DiscordjsTypeError(
|
||||
ErrorCodes.ModalSubmitInteractionComponentInvalidChannelType,
|
||||
customId,
|
||||
channel.type,
|
||||
channelTypes.join(', '),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return channels ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets members component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @returns {?Collection<Snowflake, GuildMember|APIGuildMember>} The selected members,
|
||||
* or null if none were selected or the users were not present in the guild
|
||||
*/
|
||||
getSelectedMembers(customId) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.UserSelect, ComponentType.MentionableSelect],
|
||||
['members'],
|
||||
false,
|
||||
);
|
||||
return component.members ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets mentionables component
|
||||
*
|
||||
* @param {string} customId The custom id of the component
|
||||
* @param {boolean} [required=false] Whether to throw an error if the component value is not found or empty
|
||||
* @returns {?ModalSelectedMentionables} The selected mentionables, or null if none were selected and not required
|
||||
*/
|
||||
getSelectedMentionables(customId, required = false) {
|
||||
const component = this._getTypedComponent(
|
||||
customId,
|
||||
[ComponentType.MentionableSelect],
|
||||
['users', 'members', 'roles'],
|
||||
required,
|
||||
);
|
||||
|
||||
if (component.users || component.members || component.roles) {
|
||||
return {
|
||||
users: component.users ?? new Collection(),
|
||||
members: component.members ?? new Collection(),
|
||||
roles: component.roles ?? new Collection(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,53 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { lazy } = require('@discordjs/util');
|
||||
const BaseInteraction = require('./BaseInteraction');
|
||||
const InteractionWebhook = require('./InteractionWebhook');
|
||||
const ModalSubmitFields = require('./ModalSubmitFields');
|
||||
const InteractionResponses = require('./interfaces/InteractionResponses');
|
||||
const { transformResolved } = require('../util/Util');
|
||||
|
||||
const getMessage = lazy(() => require('./Message').Message);
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModalData
|
||||
* @property {string} value The value of the field
|
||||
* @typedef {Object} BaseModalData
|
||||
* @property {ComponentType} type The component type of the field
|
||||
* @property {string} customId The custom id of the field
|
||||
* @property {number} id The id of the field
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ActionRowModalData
|
||||
* @property {ModalData[]} components The components of this action row
|
||||
* @property {ComponentType} type The component type of the action row
|
||||
* @typedef {BaseModalData} TextInputModalData
|
||||
* @property {string} customId The custom id of the field
|
||||
* @property {string} value The value of the field
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} SelectMenuModalData
|
||||
* @property {string} customId The custom id of the field
|
||||
* @property {string[]} values The values of the field
|
||||
* @property {Collection<string, GuildMember|APIGuildMember>} [members] The resolved members
|
||||
* @property {Collection<string, User|APIUser>} [users] The resolved users
|
||||
* @property {Collection<string, Role|APIRole>} [roles] The resolved roles
|
||||
* @property {Collection<string, BaseChannel|APIChannel>} [channels] The resolved channels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} TextDisplayModalData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {SelectMenuModalData|TextInputModalData} ModalData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} LabelModalData
|
||||
* @property {ModalData} component The component within the label
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseModalData} ActionRowModalData
|
||||
* @property {TextInputModalData[]} components The components of this action row
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -47,15 +76,21 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
|
||||
/**
|
||||
* The components within the modal
|
||||
* @type {ActionRowModalData[]}
|
||||
*
|
||||
* @type {Array<ActionRowModalData | LabelModalData | TextDisplayModalData>}
|
||||
*/
|
||||
this.components = data.data.components?.map(component => ModalSubmitInteraction.transformComponent(component));
|
||||
this.components = data.data.components?.map(component =>
|
||||
ModalSubmitInteraction.transformComponent(component, data.data.resolved),
|
||||
);
|
||||
|
||||
/**
|
||||
* The fields within the modal
|
||||
* @type {ModalSubmitFields}
|
||||
*/
|
||||
this.fields = new ModalSubmitFields(this.components);
|
||||
this.fields = new ModalSubmitFields(
|
||||
this.components,
|
||||
transformResolved({ client: this.client, guild: this.guild, channel: this.channel }, data.data.resolved),
|
||||
);
|
||||
|
||||
/**
|
||||
* Whether the reply to this interaction has been deferred
|
||||
@@ -85,19 +120,68 @@ class ModalSubmitInteraction extends BaseInteraction {
|
||||
/**
|
||||
* Transforms component data to discord.js-compatible data
|
||||
* @param {*} rawComponent The data to transform
|
||||
* @param {APIInteractionDataResolved} [resolved] The resolved data for the interaction
|
||||
* @returns {ModalData[]}
|
||||
*/
|
||||
static transformComponent(rawComponent) {
|
||||
return rawComponent.components
|
||||
? {
|
||||
type: rawComponent.type,
|
||||
components: rawComponent.components.map(component => this.transformComponent(component)),
|
||||
}
|
||||
: {
|
||||
value: rawComponent.value,
|
||||
type: rawComponent.type,
|
||||
customId: rawComponent.custom_id,
|
||||
static transformComponent(rawComponent, resolved) {
|
||||
if ('components' in rawComponent) {
|
||||
return {
|
||||
type: rawComponent.type,
|
||||
id: rawComponent.id,
|
||||
components: rawComponent.components.map(component => this.transformComponent(component, resolved)),
|
||||
};
|
||||
}
|
||||
|
||||
if ('component' in rawComponent) {
|
||||
return {
|
||||
type: rawComponent.type,
|
||||
id: rawComponent.id,
|
||||
component: this.transformComponent(rawComponent.component, resolved),
|
||||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
type: rawComponent.type,
|
||||
id: rawComponent.id,
|
||||
};
|
||||
|
||||
// Text display components do not have custom ids.
|
||||
if ('custom_id' in rawComponent) data.customId = rawComponent.custom_id;
|
||||
|
||||
if ('value' in rawComponent) data.value = rawComponent.value;
|
||||
|
||||
if (rawComponent.values) {
|
||||
data.values = rawComponent.values;
|
||||
if (resolved) {
|
||||
const resolveCollection = (resolvedData, resolver) => {
|
||||
const collection = new Collection();
|
||||
for (const value of data.values) {
|
||||
if (resolvedData?.[value]) {
|
||||
collection.set(value, resolver(resolvedData[value]));
|
||||
}
|
||||
}
|
||||
|
||||
return collection.size ? collection : null;
|
||||
};
|
||||
|
||||
const users = resolveCollection(resolved.users, user => this.client.users._add(user));
|
||||
if (users) data.users = users;
|
||||
|
||||
const channels = resolveCollection(
|
||||
resolved.channels,
|
||||
channel => this.client.channels._add(channel, this.guild) ?? channel,
|
||||
);
|
||||
if (channels) data.channels = channels;
|
||||
|
||||
const members = resolveCollection(resolved.members, member => this.guild?.members._add(member) ?? member);
|
||||
if (members) data.members = members;
|
||||
|
||||
const roles = resolveCollection(resolved.roles, role => this.guild?.roles._add(role) ?? role);
|
||||
if (roles) data.roles = roles;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,13 +15,6 @@ const MessagePayload = require('../MessagePayload');
|
||||
let deprecationEmittedForEphemeralOption = false;
|
||||
let deprecationEmittedForFetchReplyOption = false;
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModalComponentData
|
||||
* @property {string} title The title of the modal
|
||||
* @property {string} customId The custom id of the modal
|
||||
* @property {ActionRow[]} components The components within this modal
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for classes that support shared interaction response types.
|
||||
* @interface
|
||||
|
||||
@@ -245,6 +245,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISelectMenuOption}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APISelectMenuDefaultValue
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISelectMenuDefaultValue}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APISticker
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APISticker}
|
||||
@@ -535,6 +540,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/Locale}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external LocalizationMap
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#LocalizationMap}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external MessageActivityType
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/MessageActivityType}
|
||||
@@ -650,6 +660,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ThreadAutoArchiveDuration}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external ThreadMemberFlags
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/ThreadMemberFlags}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external UserFlags
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/UserFlags}
|
||||
|
||||
@@ -14,6 +14,25 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
* @property {ComponentData[]} components The components in this action row
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ModalComponentData
|
||||
* @property {string} title The title of the modal
|
||||
* @property {string} customId The custom id of the modal
|
||||
* @property {Array<ActionRow|TextDisplayComponentData|LabelData>} components The components within this modal
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {StringSelectMenuComponentData|TextInputComponentData|UserSelectMenuComponentData|
|
||||
* RoleSelectMenuComponentData|MentionableSelectMenuComponentData|ChannelSelectMenuComponentData} ComponentInLabelData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} LabelData
|
||||
* @property {string} label The label to use
|
||||
* @property {string} [description] The optional description for the label
|
||||
* @property {ComponentInLabelData} component The component within the label
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} ButtonComponentData
|
||||
* @property {ButtonStyle} style The style of the button
|
||||
@@ -24,6 +43,42 @@ const { ComponentType } = require('discord-api-types/v10');
|
||||
* @property {string} [url] The URL of the button
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseComponentData} BaseSelectMenuComponentData
|
||||
* @property {string} customId The custom id of the select menu
|
||||
* @property {boolean} [disabled] Whether the select menu is disabled or not
|
||||
* @property {number} [maxValues] The maximum amount of options that can be selected
|
||||
* @property {number} [minValues] The minimum amount of options that can be selected
|
||||
* @property {string} [placeholder] The placeholder of the select menu
|
||||
* @property {boolean} [required] Whether this component is required in modals
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} StringSelectMenuComponentData
|
||||
* @property {SelectMenuComponentOptionData[]} [options] The options in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} UserSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} RoleSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} MentionableSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {BaseSelectMenuComponentData} ChannelSelectMenuComponentData
|
||||
* @property {APISelectMenuDefaultValue[]} [defaultValues] The default selected values in this select menu
|
||||
* @property {ChannelType[]} [channelTypes] The types of channels that can be selected
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} SelectMenuComponentOptionData
|
||||
* @property {string} label The label of the option
|
||||
@@ -199,6 +254,7 @@ const ChannelSelectMenuComponent = require('../structures/ChannelSelectMenuCompo
|
||||
const Component = require('../structures/Component');
|
||||
const ContainerComponent = require('../structures/ContainerComponent');
|
||||
const FileComponent = require('../structures/FileComponent');
|
||||
const LabelComponent = require('../structures/LabelComponent');
|
||||
const MediaGalleryComponent = require('../structures/MediaGalleryComponent');
|
||||
const MentionableSelectMenuBuilder = require('../structures/MentionableSelectMenuBuilder');
|
||||
const MentionableSelectMenuComponent = require('../structures/MentionableSelectMenuComponent');
|
||||
@@ -231,6 +287,7 @@ const ComponentTypeToComponent = {
|
||||
[ComponentType.Section]: SectionComponent,
|
||||
[ComponentType.Separator]: SeparatorComponent,
|
||||
[ComponentType.Thumbnail]: ThumbnailComponent,
|
||||
[ComponentType.Label]: LabelComponent,
|
||||
};
|
||||
|
||||
const ComponentTypeToBuilder = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { InviteFlags } = require('discord-api-types/v10');
|
||||
const { BitField } = require('./BitField.js');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link GuildInvite#flags} bit field.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { ThreadMemberFlags } = require('discord-api-types/v10');
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
@@ -9,10 +10,10 @@ const BitField = require('./BitField');
|
||||
class ThreadMemberFlagsBitField extends BitField {
|
||||
/**
|
||||
* Numeric thread member flags. There are currently no bitflags relevant to bots for this.
|
||||
* @type {Object<string, number>}
|
||||
* @type {ThreadMemberFlags}
|
||||
* @memberof ThreadMemberFlagsBitField
|
||||
*/
|
||||
static Flags = {};
|
||||
static Flags = ThreadMemberFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
191
packages/discord.js/typings/index.d.ts
vendored
191
packages/discord.js/typings/index.d.ts
vendored
@@ -37,7 +37,15 @@ import {
|
||||
} from '@discordjs/formatters';
|
||||
import { Awaitable, JSONEncodable } from '@discordjs/util';
|
||||
import { Collection, ReadonlyCollection } from '@discordjs/collection';
|
||||
import { BaseImageURLOptions, EmojiURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||
import {
|
||||
BaseImageURLOptions,
|
||||
EmojiURLOptions,
|
||||
ImageURLOptions,
|
||||
RawFile,
|
||||
REST,
|
||||
RESTOptions,
|
||||
ImageSize,
|
||||
} from '@discordjs/rest';
|
||||
import {
|
||||
WebSocketManager as WSWebSocketManager,
|
||||
IShardingStrategy,
|
||||
@@ -55,6 +63,7 @@ import {
|
||||
APIInteractionDataResolvedChannel,
|
||||
APIInteractionDataResolvedGuildMember,
|
||||
APIInteractionGuildMember,
|
||||
APILabelComponent,
|
||||
APIMessage,
|
||||
APIMessageComponent,
|
||||
APIOverwrite,
|
||||
@@ -352,6 +361,21 @@ export class ActionRowBuilder<
|
||||
): ActionRowBuilder<ComponentType>;
|
||||
}
|
||||
|
||||
export type ComponentInLabelData =
|
||||
| StringSelectMenuComponentData
|
||||
| TextInputComponentData
|
||||
| UserSelectMenuComponentData
|
||||
| ChannelSelectMenuComponentData
|
||||
| RoleSelectMenuComponentData
|
||||
| MentionableSelectMenuComponentData;
|
||||
|
||||
export interface LabelComponentData extends BaseComponentData {
|
||||
type: ComponentType.Label;
|
||||
component: ComponentInLabelData;
|
||||
description?: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export type MessageActionRowComponent =
|
||||
| ButtonComponent
|
||||
| StringSelectMenuComponent
|
||||
@@ -912,6 +936,12 @@ export class TextInputComponent extends Component<APITextInputComponent> {
|
||||
public get value(): string;
|
||||
}
|
||||
|
||||
export class LabelComponent extends Component<APILabelComponent> {
|
||||
public component: StringSelectMenuComponent | TextInputComponent;
|
||||
public get label(): string;
|
||||
public get description(): string | null;
|
||||
}
|
||||
|
||||
export class BaseSelectMenuComponent<Data extends APISelectMenuComponent> extends Component<Data> {
|
||||
protected constructor(data: Data);
|
||||
public get placeholder(): string | null;
|
||||
@@ -2757,33 +2787,119 @@ export interface ModalComponentData {
|
||||
customId: string;
|
||||
title: string;
|
||||
components: readonly (
|
||||
| JSONEncodable<APIActionRowComponent<APIComponentInModalActionRow>>
|
||||
| JSONEncodable<APIActionRowComponent<APIComponentInModalActionRow> | APILabelComponent>
|
||||
| ActionRowData<ModalActionRowComponentData>
|
||||
| LabelComponentData
|
||||
| TextDisplayComponentData
|
||||
)[];
|
||||
}
|
||||
|
||||
export interface BaseModalData {
|
||||
customId: string;
|
||||
type: ComponentType;
|
||||
export interface BaseModalData<Type extends ComponentType> {
|
||||
id: number;
|
||||
type: Type;
|
||||
}
|
||||
|
||||
export interface TextInputModalData extends BaseModalData {
|
||||
type: ComponentType.TextInput;
|
||||
export interface TextInputModalData extends BaseModalData<ComponentType.TextInput> {
|
||||
customId: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ActionRowModalData {
|
||||
type: ComponentType.ActionRow;
|
||||
export interface SelectMenuModalData<Cached extends CacheType = CacheType>
|
||||
extends BaseModalData<
|
||||
| ComponentType.ChannelSelect
|
||||
| ComponentType.MentionableSelect
|
||||
| ComponentType.RoleSelect
|
||||
| ComponentType.StringSelect
|
||||
| ComponentType.UserSelect
|
||||
> {
|
||||
channels?: ReadonlyCollection<
|
||||
Snowflake,
|
||||
CacheTypeReducer<Cached, GuildBasedChannel, APIInteractionDataResolvedChannel>
|
||||
>;
|
||||
customId: string;
|
||||
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
|
||||
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
values: readonly string[];
|
||||
}
|
||||
|
||||
export type ModalData = SelectMenuModalData | TextInputModalData;
|
||||
|
||||
export interface LabelModalData extends BaseModalData<ComponentType.Label> {
|
||||
component: readonly ModalData[];
|
||||
}
|
||||
export interface ActionRowModalData extends BaseModalData<ComponentType.ActionRow> {
|
||||
components: readonly TextInputModalData[];
|
||||
}
|
||||
|
||||
export class ModalSubmitFields {
|
||||
private constructor(components: readonly (readonly ModalActionRowComponent[])[]);
|
||||
public components: ActionRowModalData[];
|
||||
public fields: Collection<string, TextInputModalData>;
|
||||
public getField<Type extends ComponentType>(customId: string, type: Type): { type: Type } & TextInputModalData;
|
||||
public getField(customId: string, type?: ComponentType): TextInputModalData;
|
||||
export interface TextDisplayModalData extends BaseModalData<ComponentType.TextDisplay> {}
|
||||
|
||||
export interface ModalSelectedMentionables<Cached extends CacheType = CacheType> {
|
||||
members: NonNullable<SelectMenuModalData<Cached>['members']>;
|
||||
roles: NonNullable<SelectMenuModalData<Cached>['roles']>;
|
||||
users: NonNullable<SelectMenuModalData<Cached>['users']>;
|
||||
}
|
||||
|
||||
export class ModalSubmitFields<Cached extends CacheType = CacheType> {
|
||||
private constructor(
|
||||
components: readonly (ActionRowModalData | LabelModalData | TextDisplayModalData)[],
|
||||
resolved?: BaseInteractionResolvedData,
|
||||
);
|
||||
public components: (ActionRowModalData | LabelModalData | TextDisplayModalData)[];
|
||||
public resolved: Readonly<BaseInteractionResolvedData<Cached>> | null;
|
||||
public fields: Collection<string, ModalData>;
|
||||
public getField<Type extends ComponentType>(customId: string, type: Type): Extract<ModalData, { type: Type }>;
|
||||
public getField(customId: string, type?: ComponentType): ModalData;
|
||||
private _getTypedComponent(
|
||||
customId: string,
|
||||
allowedTypes: readonly ComponentType[],
|
||||
properties: string,
|
||||
required: boolean,
|
||||
): ModalData;
|
||||
public getTextInputValue(customId: string): string;
|
||||
public getStringSelectValues(customId: string): readonly string[];
|
||||
public getSelectedUsers(customId: string, required: true): ReadonlyCollection<Snowflake, User>;
|
||||
public getSelectedUsers(customId: string, required?: boolean): ReadonlyCollection<Snowflake, User> | null;
|
||||
public getSelectedMembers(customId: string): NonNullable<SelectMenuModalData<Cached>['members']> | null;
|
||||
public getSelectedChannels<const Type extends ChannelType = ChannelType>(
|
||||
customId: string,
|
||||
required: true,
|
||||
channelTypes?: readonly Type[],
|
||||
): ReadonlyCollection<
|
||||
Snowflake,
|
||||
Extract<
|
||||
NonNullable<CommandInteractionOption<Cached>['channel']>,
|
||||
{
|
||||
type: Type extends ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
? ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
: Type;
|
||||
}
|
||||
>
|
||||
>;
|
||||
public getSelectedChannels<const Type extends ChannelType = ChannelType>(
|
||||
customId: string,
|
||||
required?: boolean,
|
||||
channelTypes?: readonly Type[],
|
||||
): ReadonlyCollection<
|
||||
Snowflake,
|
||||
Extract<
|
||||
NonNullable<CommandInteractionOption<Cached>['channel']>,
|
||||
{
|
||||
type: Type extends ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
? ChannelType.AnnouncementThread | ChannelType.PublicThread
|
||||
: Type;
|
||||
}
|
||||
>
|
||||
> | null;
|
||||
|
||||
public getSelectedRoles(customId: string, required: true): NonNullable<SelectMenuModalData<Cached>['roles']>;
|
||||
public getSelectedRoles(
|
||||
customId: string,
|
||||
required?: boolean,
|
||||
): NonNullable<SelectMenuModalData<Cached>['roles']> | null;
|
||||
|
||||
public getSelectedMentionables(customId: string, required: true): ModalSelectedMentionables<Cached>;
|
||||
public getSelectedMentionables(customId: string, required?: boolean): ModalSelectedMentionables<Cached> | null;
|
||||
}
|
||||
|
||||
export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = CacheType>
|
||||
@@ -2807,8 +2923,8 @@ export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extend
|
||||
private constructor(client: Client<true>, data: APIModalSubmitInteraction);
|
||||
public type: InteractionType.ModalSubmit;
|
||||
public readonly customId: string;
|
||||
public readonly components: ActionRowModalData[];
|
||||
public readonly fields: ModalSubmitFields;
|
||||
public readonly components: (ActionRowModalData | LabelModalData)[];
|
||||
public readonly fields: ModalSubmitFields<Cached>;
|
||||
public deferred: boolean;
|
||||
public ephemeral: boolean | null;
|
||||
public message: Message<BooleanCache<Cached>> | null;
|
||||
@@ -4036,6 +4152,8 @@ export class Formatters extends null {
|
||||
export type ComponentData =
|
||||
| MessageActionRowComponentData
|
||||
| ModalActionRowComponentData
|
||||
| LabelComponentData
|
||||
| ComponentInLabelData
|
||||
| ComponentInContainerData
|
||||
| ContainerComponentData
|
||||
| ThumbnailComponentData;
|
||||
@@ -4135,9 +4253,9 @@ export class Webhook<Type extends WebhookType = WebhookType> {
|
||||
public editMessage(
|
||||
message: MessageResolvable,
|
||||
options: string | MessagePayload | WebhookMessageEditOptions,
|
||||
): Promise<Message>;
|
||||
public fetchMessage(message: Snowflake, options?: WebhookFetchMessageOptions): Promise<Message>;
|
||||
public send(options: string | MessagePayload | WebhookMessageCreateOptions): Promise<Message>;
|
||||
): Promise<Message<true>>;
|
||||
public fetchMessage(message: Snowflake, options?: WebhookFetchMessageOptions): Promise<Message<true>>;
|
||||
public send(options: string | MessagePayload | WebhookMessageCreateOptions): Promise<Message<true>>;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line no-empty-interface
|
||||
@@ -4523,6 +4641,8 @@ export enum DiscordjsErrorCodes {
|
||||
|
||||
ModalSubmitInteractionFieldNotFound = 'ModalSubmitInteractionFieldNotFound',
|
||||
ModalSubmitInteractionFieldType = 'ModalSubmitInteractionFieldType',
|
||||
ModalSubmitInteractionFieldEmpty = 'ModalSubmitInteractionComponentEmpty',
|
||||
ModalSubmitInteractionFieldInvalidChannelType = 'ModalSubmitInteractionFieldInvalidChannelType',
|
||||
|
||||
InvalidMissingScopes = 'InvalidMissingScopes',
|
||||
InvalidScopesWithPermissions = 'InvalidScopesWithPermissions',
|
||||
@@ -4906,6 +5026,7 @@ export class GuildMemberManager extends CachedManager<Snowflake, GuildMember, Gu
|
||||
options?: BulkBanOptions,
|
||||
): Promise<BulkBanResult>;
|
||||
public edit(user: UserResolvable, options: GuildMemberEditOptions): Promise<GuildMember>;
|
||||
public editMe(options: GuildMemberEditMeOptions): Promise<GuildMember>;
|
||||
public fetch(
|
||||
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
|
||||
): Promise<GuildMember>;
|
||||
@@ -5915,7 +6036,7 @@ export interface ClientEvents {
|
||||
];
|
||||
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
|
||||
messageDeleteBulk: [
|
||||
messages: ReadonlyCollection<Snowflake, OmitPartialGroupDMChannel<Message | PartialMessage>>,
|
||||
messages: ReadonlyCollection<Snowflake, Message<true> | PartialMessage<true>>,
|
||||
channel: GuildTextBasedChannel,
|
||||
];
|
||||
messageReactionAdd: [
|
||||
@@ -6062,13 +6183,17 @@ export interface CommandInteractionOption<Cached extends CacheType = CacheType>
|
||||
message?: Message<BooleanCache<Cached>>;
|
||||
}
|
||||
|
||||
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType> {
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
export interface BaseInteractionResolvedData<Cached extends CacheType = CacheType> {
|
||||
channels?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
|
||||
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
|
||||
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
channels?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
|
||||
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
|
||||
users?: ReadonlyCollection<Snowflake, User>;
|
||||
}
|
||||
|
||||
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType>
|
||||
extends BaseInteractionResolvedData<Cached> {
|
||||
attachments?: ReadonlyCollection<Snowflake, Attachment>;
|
||||
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
|
||||
}
|
||||
|
||||
export interface AutocompleteFocusedOption extends Pick<CommandInteractionOption, 'name'> {
|
||||
@@ -6760,6 +6885,14 @@ export interface GuildMemberEditOptions {
|
||||
|
||||
export type GuildMemberResolvable = GuildMember | UserResolvable;
|
||||
|
||||
export interface GuildMemberEditMeOptions {
|
||||
avatar?: Base64Resolvable | BufferResolvable | null;
|
||||
banner?: Base64Resolvable | BufferResolvable | null;
|
||||
bio?: string | null;
|
||||
nick?: string | null;
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
export type GuildResolvable = Guild | NonThreadGuildBasedChannel | GuildMember | GuildEmoji | Invite | Role | Snowflake;
|
||||
|
||||
export interface GuildPruneMembersOptions {
|
||||
@@ -7233,6 +7366,7 @@ export interface BaseSelectMenuComponentData extends BaseComponentData {
|
||||
maxValues?: number;
|
||||
minValues?: number;
|
||||
placeholder?: string;
|
||||
required?: true;
|
||||
}
|
||||
|
||||
export interface StringSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
@@ -7398,8 +7532,8 @@ export interface PartialDMChannel extends Partialize<DMChannel, null, null, 'las
|
||||
|
||||
export interface PartialGuildMember extends Partialize<GuildMember, 'joinedAt' | 'joinedTimestamp' | 'pending'> {}
|
||||
|
||||
export interface PartialMessage
|
||||
extends Partialize<Message, 'type' | 'system' | 'pinned' | 'tts', 'content' | 'cleanContent' | 'author'> {}
|
||||
export interface PartialMessage<InGuild extends boolean = boolean>
|
||||
extends Partialize<Message<InGuild>, 'type' | 'system' | 'pinned' | 'tts', 'content' | 'cleanContent' | 'author'> {}
|
||||
|
||||
export interface PartialMessageReaction extends Partialize<MessageReaction, 'count'> {}
|
||||
|
||||
@@ -7878,3 +8012,6 @@ export * from '@discordjs/formatters';
|
||||
export * from '@discordjs/rest';
|
||||
export * from '@discordjs/util';
|
||||
export * from '@discordjs/ws';
|
||||
|
||||
// Solve TS compile error
|
||||
export type { ImageSize };
|
||||
|
||||
@@ -2566,6 +2566,59 @@ chatInputInteraction.showModal({
|
||||
],
|
||||
});
|
||||
|
||||
chatInputInteraction.showModal({
|
||||
title: 'abc',
|
||||
customId: 'abc',
|
||||
components: [
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
label: 'label',
|
||||
component: {
|
||||
customId: 'aa',
|
||||
type: ComponentType.TextInput,
|
||||
style: TextInputStyle.Short,
|
||||
label: 'label',
|
||||
},
|
||||
},
|
||||
{
|
||||
components: [
|
||||
{
|
||||
customId: 'aa',
|
||||
label: 'label',
|
||||
style: TextInputStyle.Short,
|
||||
type: ComponentType.TextInput,
|
||||
},
|
||||
],
|
||||
type: ComponentType.ActionRow,
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
label: 'Lll',
|
||||
component: {
|
||||
customId: 'aa',
|
||||
type: ComponentType.UserSelect,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
label: 'Lll',
|
||||
component: {
|
||||
customId: 'aa',
|
||||
type: ComponentType.ChannelSelect,
|
||||
channelTypes: [ChannelType.GuildText, ChannelType.GuildVoice],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: ComponentType.Label,
|
||||
label: 'Lll',
|
||||
component: {
|
||||
customId: 'aa',
|
||||
type: ComponentType.RoleSelect,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
declare const stringSelectMenuData: APIStringSelectComponent;
|
||||
StringSelectMenuBuilder.from(stringSelectMenuData);
|
||||
|
||||
@@ -2649,9 +2702,9 @@ declare const webhookClient: WebhookClient;
|
||||
declare const interactionWebhook: InteractionWebhook;
|
||||
declare const snowflake: Snowflake;
|
||||
|
||||
expectType<Promise<Message>>(webhook.send('content'));
|
||||
expectType<Promise<Message>>(webhook.editMessage(snowflake, 'content'));
|
||||
expectType<Promise<Message>>(webhook.fetchMessage(snowflake));
|
||||
expectType<Promise<Message<true>>>(webhook.send('content'));
|
||||
expectType<Promise<Message<true>>>(webhook.editMessage(snowflake, 'content'));
|
||||
expectType<Promise<Message<true>>>(webhook.fetchMessage(snowflake));
|
||||
expectType<Promise<Webhook>>(webhook.edit({ name: 'name' }));
|
||||
|
||||
expectType<Promise<APIMessage>>(webhookClient.send('content'));
|
||||
|
||||
31
pnpm-lock.yaml
generated
31
pnpm-lock.yaml
generated
@@ -816,8 +816,8 @@ importers:
|
||||
specifier: ^2.4.6
|
||||
version: 2.4.6
|
||||
discord-api-types:
|
||||
specifier: ^0.38.24
|
||||
version: 0.38.24
|
||||
specifier: ^0.38.29
|
||||
version: 0.38.29
|
||||
devDependencies:
|
||||
'@discordjs/api-extractor':
|
||||
specifier: workspace:^
|
||||
@@ -932,8 +932,8 @@ importers:
|
||||
packages/discord.js:
|
||||
dependencies:
|
||||
'@discordjs/builders':
|
||||
specifier: ^1.11.2
|
||||
version: 1.11.2
|
||||
specifier: ^1.12.0
|
||||
version: 1.12.0
|
||||
'@discordjs/collection':
|
||||
specifier: 1.5.3
|
||||
version: 1.5.3
|
||||
@@ -953,8 +953,8 @@ importers:
|
||||
specifier: 3.5.3
|
||||
version: 3.5.3
|
||||
discord-api-types:
|
||||
specifier: ^0.38.24
|
||||
version: 0.38.24
|
||||
specifier: ^0.38.29
|
||||
version: 0.38.29
|
||||
fast-deep-equal:
|
||||
specifier: 3.1.3
|
||||
version: 3.1.3
|
||||
@@ -2789,8 +2789,8 @@ packages:
|
||||
resolution: {integrity: sha512-4JINx4Rttha29f50PBsJo48xZXx/He5yaIWJRwVarhYAN947+S84YciHl+AIhQNRPAFkg8+5qFngEGtKxQDWXA==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
|
||||
'@discordjs/builders@1.11.2':
|
||||
resolution: {integrity: sha512-F1WTABdd8/R9D1icJzajC4IuLyyS8f3rTOz66JsSI3pKvpCAtsMBweu8cyNYsIyvcrKAVn9EPK+Psoymq+XC0A==}
|
||||
'@discordjs/builders@1.12.0':
|
||||
resolution: {integrity: sha512-jQ0m/fVOg6j3w2Rrzrg5VfqPpkslYNnpdTAyQzQXQ7S/5y0iScBnMlVZfu/AFLP9C34shQ4I+EpTGZV1VlN7RQ==}
|
||||
engines: {node: '>=16.11.0'}
|
||||
|
||||
'@discordjs/collection@1.5.3':
|
||||
@@ -8360,6 +8360,9 @@ packages:
|
||||
discord-api-types@0.38.24:
|
||||
resolution: {integrity: sha512-P7/DkcFIiIoaBogStnhhcGRX7KR+gIFp0SpmwsZUIM0bgDkYMEUx+8l+t3quYc/KSgg92wvE9w/4mabO57EMug==}
|
||||
|
||||
discord-api-types@0.38.29:
|
||||
resolution: {integrity: sha512-+5BfrjLJN1hrrcK0MxDQli6NSv5lQH7Y3/qaOfk9+k7itex8RkA/UcevVMMLe8B4IKIawr4ITBTb2fBB2vDORg==}
|
||||
|
||||
dlv@1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
|
||||
@@ -16318,12 +16321,12 @@ snapshots:
|
||||
tar-stream: 3.1.7
|
||||
which: 4.0.0
|
||||
|
||||
'@discordjs/builders@1.11.2':
|
||||
'@discordjs/builders@1.12.0':
|
||||
dependencies:
|
||||
'@discordjs/formatters': 0.6.1
|
||||
'@discordjs/util': 1.1.1
|
||||
'@sapphire/shapeshift': 4.0.0
|
||||
discord-api-types: 0.38.24
|
||||
discord-api-types: 0.38.29
|
||||
fast-deep-equal: 3.1.3
|
||||
ts-mixer: 6.0.4
|
||||
tslib: 2.8.1
|
||||
@@ -16334,7 +16337,7 @@ snapshots:
|
||||
|
||||
'@discordjs/formatters@0.6.1':
|
||||
dependencies:
|
||||
discord-api-types: 0.38.24
|
||||
discord-api-types: 0.38.29
|
||||
|
||||
'@discordjs/rest@2.5.1':
|
||||
dependencies:
|
||||
@@ -16343,7 +16346,7 @@ snapshots:
|
||||
'@sapphire/async-queue': 1.5.3
|
||||
'@sapphire/snowflake': 3.5.3
|
||||
'@vladfrangu/async_event_emitter': 2.4.6
|
||||
discord-api-types: 0.38.24
|
||||
discord-api-types: 0.38.29
|
||||
magic-bytes.js: 1.10.0
|
||||
tslib: 2.8.1
|
||||
undici: 6.21.3
|
||||
@@ -16358,7 +16361,7 @@ snapshots:
|
||||
'@sapphire/async-queue': 1.5.3
|
||||
'@types/ws': 8.5.12
|
||||
'@vladfrangu/async_event_emitter': 2.4.6
|
||||
discord-api-types: 0.38.24
|
||||
discord-api-types: 0.38.29
|
||||
tslib: 2.8.1
|
||||
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
transitivePeerDependencies:
|
||||
@@ -23713,6 +23716,8 @@ snapshots:
|
||||
|
||||
discord-api-types@0.38.24: {}
|
||||
|
||||
discord-api-types@0.38.29: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
|
||||
dmd@6.2.3:
|
||||
|
||||
Reference in New Issue
Block a user