discord.js 14.22.1 → 14.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/package.json +5 -5
  2. package/src/client/actions/Action.js +20 -1
  3. package/src/client/actions/ActionsManager.js +66 -66
  4. package/src/client/actions/MessagePollVoteAdd.js +9 -2
  5. package/src/client/actions/MessagePollVoteRemove.js +8 -3
  6. package/src/client/websocket/handlers/index.js +5 -5
  7. package/src/errors/ErrorCodes.js +4 -0
  8. package/src/errors/Messages.js +4 -0
  9. package/src/index.js +3 -0
  10. package/src/managers/GuildManager.js +1 -0
  11. package/src/managers/GuildMemberManager.js +59 -6
  12. package/src/managers/PollAnswerVoterManager.js +50 -0
  13. package/src/structures/ApplicationCommand.js +11 -11
  14. package/src/structures/ApplicationRoleConnectionMetadata.js +2 -2
  15. package/src/structures/ClientApplication.js +2 -2
  16. package/src/structures/CommandInteraction.js +7 -2
  17. package/src/structures/Guild.js +4 -11
  18. package/src/structures/GuildMember.js +3 -1
  19. package/src/structures/GuildTemplate.js +1 -0
  20. package/src/structures/Invite.js +12 -0
  21. package/src/structures/LabelComponent.js +54 -0
  22. package/src/structures/Message.js +10 -6
  23. package/src/structures/ModalSubmitFields.js +170 -4
  24. package/src/structures/ModalSubmitInteraction.js +114 -18
  25. package/src/structures/Poll.js +104 -38
  26. package/src/structures/PollAnswer.js +39 -14
  27. package/src/structures/User.js +6 -2
  28. package/src/structures/interfaces/InteractionResponses.js +0 -7
  29. package/src/util/APITypes.js +20 -0
  30. package/src/util/Components.js +57 -0
  31. package/src/util/InviteFlagsBitField.js +28 -0
  32. package/src/util/Partials.js +4 -0
  33. package/src/util/ThreadMemberFlagsBitField.js +3 -2
  34. package/typings/index.d.mts +226 -36
  35. package/typings/index.d.ts +226 -36
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "discord.js",
4
- "version": "14.22.1",
4
+ "version": "14.23.1",
5
5
  "description": "A powerful library for interacting with the Discord API",
6
6
  "main": "./src/index.js",
7
7
  "types": "./typings/index.d.ts",
@@ -53,19 +53,19 @@
53
53
  "homepage": "https://discord.js.org",
54
54
  "funding": "https://github.com/discordjs/discord.js?sponsor",
55
55
  "dependencies": {
56
- "@discordjs/builders": "^1.11.2",
56
+ "@discordjs/builders": "^1.12.1",
57
57
  "@discordjs/collection": "1.5.3",
58
58
  "@discordjs/formatters": "^0.6.1",
59
59
  "@discordjs/ws": "^1.2.3",
60
60
  "@sapphire/snowflake": "3.5.3",
61
- "discord-api-types": "^0.38.16",
61
+ "discord-api-types": "^0.38.29",
62
62
  "fast-deep-equal": "3.1.3",
63
63
  "lodash.snakecase": "4.1.1",
64
64
  "magic-bytes.js": "^1.10.0",
65
65
  "tslib": "^2.6.3",
66
66
  "undici": "6.21.3",
67
- "@discordjs/util": "^1.1.1",
68
- "@discordjs/rest": "^2.6.0"
67
+ "@discordjs/rest": "^2.6.0",
68
+ "@discordjs/util": "^1.1.1"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@favware/cliff-jumper": "^4.1.0",
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const Partials = require('../../util/Partials');
3
+ const { Poll } = require('../../structures/Poll.js');
4
+ const { PollAnswer } = require('../../structures/PollAnswer.js');
5
+ const Partials = require('../../util/Partials.js');
4
6
 
5
7
  /*
6
8
 
@@ -63,6 +65,23 @@ class GenericAction {
63
65
  );
64
66
  }
65
67
 
68
+ getPoll(data, message, channel) {
69
+ const includePollPartial = this.client.options.partials.includes(Partials.Poll);
70
+ const includePollAnswerPartial = this.client.options.partials.includes(Partials.PollAnswer);
71
+ if (message.partial && (!includePollPartial || !includePollAnswerPartial)) return null;
72
+
73
+ if (!message.poll && includePollPartial) {
74
+ message.poll = new Poll(this.client, data, message, channel);
75
+ }
76
+
77
+ if (message.poll && !message.poll.answers.has(data.answer_id) && includePollAnswerPartial) {
78
+ const pollAnswer = new PollAnswer(this.client, data, message.poll);
79
+ message.poll.answers.set(data.answer_id, pollAnswer);
80
+ }
81
+
82
+ return message.poll;
83
+ }
84
+
66
85
  getReaction(data, message, user) {
67
86
  const id = data.emoji.id ?? decodeURIComponent(data.emoji.name);
68
87
  return this.getPayload(
@@ -11,74 +11,74 @@ class ActionsManager {
11
11
  constructor(client) {
12
12
  this.client = client;
13
13
 
14
- this.register(require('./ApplicationCommandPermissionsUpdate'));
15
- this.register(require('./AutoModerationActionExecution'));
16
- this.register(require('./AutoModerationRuleCreate'));
17
- this.register(require('./AutoModerationRuleDelete'));
18
- this.register(require('./AutoModerationRuleUpdate'));
19
- this.register(require('./ChannelCreate'));
20
- this.register(require('./ChannelDelete'));
21
- this.register(require('./ChannelUpdate'));
22
- this.register(require('./EntitlementCreate'));
23
- this.register(require('./EntitlementDelete'));
24
- this.register(require('./EntitlementUpdate'));
25
- this.register(require('./GuildAuditLogEntryCreate'));
26
- this.register(require('./GuildBanAdd'));
27
- this.register(require('./GuildBanRemove'));
28
- this.register(require('./GuildChannelsPositionUpdate'));
29
- this.register(require('./GuildDelete'));
30
- this.register(require('./GuildEmojiCreate'));
31
- this.register(require('./GuildEmojiDelete'));
32
- this.register(require('./GuildEmojiUpdate'));
33
- this.register(require('./GuildEmojisUpdate'));
34
- this.register(require('./GuildIntegrationsUpdate'));
35
- this.register(require('./GuildMemberRemove'));
36
- this.register(require('./GuildMemberUpdate'));
37
- this.register(require('./GuildRoleCreate'));
38
- this.register(require('./GuildRoleDelete'));
39
- this.register(require('./GuildRoleUpdate'));
40
- this.register(require('./GuildRolesPositionUpdate'));
41
- this.register(require('./GuildScheduledEventCreate'));
42
- this.register(require('./GuildScheduledEventDelete'));
43
- this.register(require('./GuildScheduledEventUpdate'));
44
- this.register(require('./GuildScheduledEventUserAdd'));
45
- this.register(require('./GuildScheduledEventUserRemove'));
46
- this.register(require('./GuildSoundboardSoundDelete.js'));
47
- this.register(require('./GuildStickerCreate'));
48
- this.register(require('./GuildStickerDelete'));
49
- this.register(require('./GuildStickerUpdate'));
50
- this.register(require('./GuildStickersUpdate'));
51
- this.register(require('./GuildUpdate'));
52
- this.register(require('./InteractionCreate'));
53
- this.register(require('./InviteCreate'));
54
- this.register(require('./InviteDelete'));
55
- this.register(require('./MessageCreate'));
56
- this.register(require('./MessageDelete'));
57
- this.register(require('./MessageDeleteBulk'));
58
- this.register(require('./MessagePollVoteAdd'));
59
- this.register(require('./MessagePollVoteRemove'));
60
- this.register(require('./MessageReactionAdd'));
61
- this.register(require('./MessageReactionRemove'));
62
- this.register(require('./MessageReactionRemoveAll'));
63
- this.register(require('./MessageReactionRemoveEmoji'));
64
- this.register(require('./MessageUpdate'));
65
- this.register(require('./PresenceUpdate'));
66
- this.register(require('./StageInstanceCreate'));
67
- this.register(require('./StageInstanceDelete'));
68
- this.register(require('./StageInstanceUpdate'));
69
- this.register(require('./ThreadCreate'));
70
- this.register(require('./ThreadDelete'));
71
- this.register(require('./ThreadListSync'));
72
- this.register(require('./ThreadMemberUpdate'));
73
- this.register(require('./ThreadMembersUpdate'));
74
- this.register(require('./TypingStart'));
75
- this.register(require('./UserUpdate'));
76
- this.register(require('./VoiceStateUpdate'));
77
- this.register(require('./WebhooksUpdate'));
14
+ this.ApplicationCommandPermissionsUpdate = this.load(require('./ApplicationCommandPermissionsUpdate.js'));
15
+ this.AutoModerationActionExecution = this.load(require('./AutoModerationActionExecution.js'));
16
+ this.AutoModerationRuleCreate = this.load(require('./AutoModerationRuleCreate.js'));
17
+ this.AutoModerationRuleDelete = this.load(require('./AutoModerationRuleDelete.js'));
18
+ this.AutoModerationRuleUpdate = this.load(require('./AutoModerationRuleUpdate.js'));
19
+ this.ChannelCreate = this.load(require('./ChannelCreate.js'));
20
+ this.ChannelDelete = this.load(require('./ChannelDelete.js'));
21
+ this.ChannelUpdate = this.load(require('./ChannelUpdate.js'));
22
+ this.EntitlementCreate = this.load(require('./EntitlementCreate.js'));
23
+ this.EntitlementDelete = this.load(require('./EntitlementDelete.js'));
24
+ this.EntitlementUpdate = this.load(require('./EntitlementUpdate.js'));
25
+ this.GuildAuditLogEntryCreate = this.load(require('./GuildAuditLogEntryCreate.js'));
26
+ this.GuildBanAdd = this.load(require('./GuildBanAdd.js'));
27
+ this.GuildBanRemove = this.load(require('./GuildBanRemove.js'));
28
+ this.GuildChannelsPositionUpdate = this.load(require('./GuildChannelsPositionUpdate.js'));
29
+ this.GuildDelete = this.load(require('./GuildDelete.js'));
30
+ this.GuildEmojiCreate = this.load(require('./GuildEmojiCreate.js'));
31
+ this.GuildEmojiDelete = this.load(require('./GuildEmojiDelete.js'));
32
+ this.GuildEmojiUpdate = this.load(require('./GuildEmojiUpdate.js'));
33
+ this.GuildEmojisUpdate = this.load(require('./GuildEmojisUpdate.js'));
34
+ this.GuildIntegrationsUpdate = this.load(require('./GuildIntegrationsUpdate.js'));
35
+ this.GuildMemberRemove = this.load(require('./GuildMemberRemove.js'));
36
+ this.GuildMemberUpdate = this.load(require('./GuildMemberUpdate.js'));
37
+ this.GuildRoleCreate = this.load(require('./GuildRoleCreate.js'));
38
+ this.GuildRoleDelete = this.load(require('./GuildRoleDelete.js'));
39
+ this.GuildRoleUpdate = this.load(require('./GuildRoleUpdate.js'));
40
+ this.GuildRolesPositionUpdate = this.load(require('./GuildRolesPositionUpdate.js'));
41
+ this.GuildScheduledEventCreate = this.load(require('./GuildScheduledEventCreate.js'));
42
+ this.GuildScheduledEventDelete = this.load(require('./GuildScheduledEventDelete.js'));
43
+ this.GuildScheduledEventUpdate = this.load(require('./GuildScheduledEventUpdate.js'));
44
+ this.GuildScheduledEventUserAdd = this.load(require('./GuildScheduledEventUserAdd.js'));
45
+ this.GuildScheduledEventUserRemove = this.load(require('./GuildScheduledEventUserRemove.js'));
46
+ this.GuildSoundboardSoundDelete = this.load(require('./GuildSoundboardSoundDelete.js'));
47
+ this.GuildStickerCreate = this.load(require('./GuildStickerCreate.js'));
48
+ this.GuildStickerDelete = this.load(require('./GuildStickerDelete.js'));
49
+ this.GuildStickerUpdate = this.load(require('./GuildStickerUpdate.js'));
50
+ this.GuildStickersUpdate = this.load(require('./GuildStickersUpdate.js'));
51
+ this.GuildUpdate = this.load(require('./GuildUpdate.js'));
52
+ this.InteractionCreate = this.load(require('./InteractionCreate.js'));
53
+ this.InviteCreate = this.load(require('./InviteCreate.js'));
54
+ this.InviteDelete = this.load(require('./InviteDelete.js'));
55
+ this.MessageCreate = this.load(require('./MessageCreate.js'));
56
+ this.MessageDelete = this.load(require('./MessageDelete.js'));
57
+ this.MessageDeleteBulk = this.load(require('./MessageDeleteBulk.js'));
58
+ this.MessagePollVoteAdd = this.load(require('./MessagePollVoteAdd.js'));
59
+ this.MessagePollVoteRemove = this.load(require('./MessagePollVoteRemove.js'));
60
+ this.MessageReactionAdd = this.load(require('./MessageReactionAdd.js'));
61
+ this.MessageReactionRemove = this.load(require('./MessageReactionRemove.js'));
62
+ this.MessageReactionRemoveAll = this.load(require('./MessageReactionRemoveAll.js'));
63
+ this.MessageReactionRemoveEmoji = this.load(require('./MessageReactionRemoveEmoji.js'));
64
+ this.MessageUpdate = this.load(require('./MessageUpdate.js'));
65
+ this.PresenceUpdate = this.load(require('./PresenceUpdate.js'));
66
+ this.StageInstanceCreate = this.load(require('./StageInstanceCreate.js'));
67
+ this.StageInstanceDelete = this.load(require('./StageInstanceDelete.js'));
68
+ this.StageInstanceUpdate = this.load(require('./StageInstanceUpdate.js'));
69
+ this.ThreadCreate = this.load(require('./ThreadCreate.js'));
70
+ this.ThreadDelete = this.load(require('./ThreadDelete.js'));
71
+ this.ThreadListSync = this.load(require('./ThreadListSync.js'));
72
+ this.ThreadMemberUpdate = this.load(require('./ThreadMemberUpdate.js'));
73
+ this.ThreadMembersUpdate = this.load(require('./ThreadMembersUpdate.js'));
74
+ this.TypingStart = this.load(require('./TypingStart.js'));
75
+ this.UserUpdate = this.load(require('./UserUpdate.js'));
76
+ this.VoiceStateUpdate = this.load(require('./VoiceStateUpdate.js'));
77
+ this.WebhooksUpdate = this.load(require('./WebhooksUpdate.js'));
78
78
  }
79
79
 
80
- register(Action) {
81
- this[Action.name.replace(/Action$/, '')] = new Action(this.client);
80
+ load(Action) {
81
+ return new Action(this.client);
82
82
  }
83
83
  }
84
84
 
@@ -11,11 +11,18 @@ class MessagePollVoteAddAction extends Action {
11
11
  const message = this.getMessage(data, channel);
12
12
  if (!message) return false;
13
13
 
14
- const { poll } = message;
14
+ const poll = this.getPoll(data, message, channel);
15
+ if (!poll) return false;
15
16
 
16
- const answer = poll?.answers.get(data.answer_id);
17
+ const answer = poll.answers.get(data.answer_id);
17
18
  if (!answer) return false;
18
19
 
20
+ const user = this.getUser(data);
21
+
22
+ if (user) {
23
+ answer.voters._add(user);
24
+ }
25
+
19
26
  answer.voteCount++;
20
27
 
21
28
  /**
@@ -11,12 +11,17 @@ class MessagePollVoteRemoveAction extends Action {
11
11
  const message = this.getMessage(data, channel);
12
12
  if (!message) return false;
13
13
 
14
- const { poll } = message;
14
+ const poll = this.getPoll(data, message, channel);
15
+ if (!poll) return false;
15
16
 
16
- const answer = poll?.answers.get(data.answer_id);
17
+ const answer = poll.answers.get(data.answer_id);
17
18
  if (!answer) return false;
18
19
 
19
- answer.voteCount--;
20
+ answer.voters.cache.delete(data.user_id);
21
+
22
+ if (answer.voteCount > 0) {
23
+ answer.voteCount--;
24
+ }
20
25
 
21
26
  /**
22
27
  * Emitted whenever a user removes their vote in a poll.
@@ -32,10 +32,10 @@ const handlers = Object.fromEntries([
32
32
  ['GUILD_SCHEDULED_EVENT_UPDATE', require('./GUILD_SCHEDULED_EVENT_UPDATE')],
33
33
  ['GUILD_SCHEDULED_EVENT_USER_ADD', require('./GUILD_SCHEDULED_EVENT_USER_ADD')],
34
34
  ['GUILD_SCHEDULED_EVENT_USER_REMOVE', require('./GUILD_SCHEDULED_EVENT_USER_REMOVE')],
35
- ['GUILD_SOUNDBOARD_SOUNDS_UPDATE', require('./GUILD_SOUNDBOARD_SOUNDS_UPDATE.js')],
36
- ['GUILD_SOUNDBOARD_SOUND_CREATE', require('./GUILD_SOUNDBOARD_SOUND_CREATE.js')],
37
- ['GUILD_SOUNDBOARD_SOUND_DELETE', require('./GUILD_SOUNDBOARD_SOUND_DELETE.js')],
38
- ['GUILD_SOUNDBOARD_SOUND_UPDATE', require('./GUILD_SOUNDBOARD_SOUND_UPDATE.js')],
35
+ ['GUILD_SOUNDBOARD_SOUNDS_UPDATE', require('./GUILD_SOUNDBOARD_SOUNDS_UPDATE')],
36
+ ['GUILD_SOUNDBOARD_SOUND_CREATE', require('./GUILD_SOUNDBOARD_SOUND_CREATE')],
37
+ ['GUILD_SOUNDBOARD_SOUND_DELETE', require('./GUILD_SOUNDBOARD_SOUND_DELETE')],
38
+ ['GUILD_SOUNDBOARD_SOUND_UPDATE', require('./GUILD_SOUNDBOARD_SOUND_UPDATE')],
39
39
  ['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')],
40
40
  ['GUILD_UPDATE', require('./GUILD_UPDATE')],
41
41
  ['INTERACTION_CREATE', require('./INTERACTION_CREATE')],
@@ -54,7 +54,7 @@ const handlers = Object.fromEntries([
54
54
  ['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')],
55
55
  ['READY', require('./READY')],
56
56
  ['RESUMED', require('./RESUMED')],
57
- ['SOUNDBOARD_SOUNDS', require('./SOUNDBOARD_SOUNDS.js')],
57
+ ['SOUNDBOARD_SOUNDS', require('./SOUNDBOARD_SOUNDS')],
58
58
  ['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')],
59
59
  ['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')],
60
60
  ['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')],
@@ -168,6 +168,8 @@
168
168
 
169
169
  * @property {'ModalSubmitInteractionFieldNotFound'} ModalSubmitInteractionFieldNotFound
170
170
  * @property {'ModalSubmitInteractionFieldType'} ModalSubmitInteractionFieldType
171
+ * @property {'ModalSubmitInteractionFieldEmpty'} ModalSubmitInteractionFieldEmpty
172
+ * @property {'ModalSubmitInteractionFieldInvalidChannelType'} ModalSubmitInteractionFieldInvalidChannelType
171
173
 
172
174
  * @property {'InvalidMissingScopes'} InvalidMissingScopes
173
175
  * @property {'InvalidScopesWithPermissions'} InvalidScopesWithPermissions
@@ -327,6 +329,8 @@ const keys = [
327
329
 
328
330
  'ModalSubmitInteractionFieldNotFound',
329
331
  'ModalSubmitInteractionFieldType',
332
+ 'ModalSubmitInteractionFieldEmpty',
333
+ 'ModalSubmitInteractionFieldInvalidChannelType',
330
334
 
331
335
  'InvalidMissingScopes',
332
336
  'InvalidScopesWithPermissions',
@@ -161,6 +161,10 @@ const Messages = {
161
161
  `Required field with custom id "${customId}" not found.`,
162
162
  [DjsErrorCodes.ModalSubmitInteractionFieldType]: (customId, type, expected) =>
163
163
  `Field with custom id "${customId}" is of type: ${type}; expected ${expected}.`,
164
+ [DjsErrorCodes.ModalSubmitInteractionFieldEmpty]: (customId, type) =>
165
+ `Required field with custom id "${customId}" is of type: ${type}; expected a non-empty value.`,
166
+ [DjsErrorCodes.ModalSubmitInteractionFieldInvalidChannelType]: (customId, type, expected) =>
167
+ `The type of channel of the field with custom id "${customId}" is: ${type}; expected ${expected}.`,
164
168
 
165
169
  [DjsErrorCodes.InvalidMissingScopes]: 'At least one valid scope must be provided for the invite',
166
170
  [DjsErrorCodes.InvalidScopesWithPermissions]: 'Permissions cannot be set without the bot scope.',
package/src/index.js CHANGED
@@ -33,6 +33,7 @@ exports.Events = require('./util/Events');
33
33
  exports.Formatters = require('./util/Formatters');
34
34
  exports.GuildMemberFlagsBitField = require('./util/GuildMemberFlagsBitField').GuildMemberFlagsBitField;
35
35
  exports.IntentsBitField = require('./util/IntentsBitField');
36
+ exports.InviteFlagsBitField = require('./util/InviteFlagsBitField.js').InviteFlagsBitField;
36
37
  exports.LimitedCollection = require('./util/LimitedCollection');
37
38
  exports.MessageFlagsBitField = require('./util/MessageFlagsBitField');
38
39
  exports.Options = require('./util/Options');
@@ -80,6 +81,7 @@ exports.GuildStickerManager = require('./managers/GuildStickerManager');
80
81
  exports.GuildTextThreadManager = require('./managers/GuildTextThreadManager');
81
82
  exports.MessageManager = require('./managers/MessageManager');
82
83
  exports.PermissionOverwriteManager = require('./managers/PermissionOverwriteManager');
84
+ exports.PollAnswerVoterManager = require('./managers/PollAnswerVoterManager.js').PollAnswerVoterManager;
83
85
  exports.PresenceManager = require('./managers/PresenceManager');
84
86
  exports.ReactionManager = require('./managers/ReactionManager');
85
87
  exports.ReactionUserManager = require('./managers/ReactionUserManager');
@@ -160,6 +162,7 @@ exports.InteractionWebhook = require('./structures/InteractionWebhook');
160
162
  exports.Invite = require('./structures/Invite');
161
163
  exports.InviteStageInstance = require('./structures/InviteStageInstance');
162
164
  exports.InviteGuild = require('./structures/InviteGuild');
165
+ exports.LabelComponent = require('./structures/LabelComponent');
163
166
  exports.Message = require('./structures/Message').Message;
164
167
  exports.Attachment = require('./structures/Attachment');
165
168
  exports.AttachmentBuilder = require('./structures/AttachmentBuilder');
@@ -163,6 +163,7 @@ class GuildManager extends CachedManager {
163
163
  * Creates a guild.
164
164
  * <warn>This is only available to bots in fewer than 10 guilds.</warn>
165
165
  * @param {GuildCreateOptions} options Options for creating the guild
166
+ * @deprecated API related to guild ownership may no longer be used.
166
167
  * @returns {Promise<Guild>} The guild that was created
167
168
  */
168
169
  async create({
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const { process } = require('node:process');
3
4
  const { setTimeout, clearTimeout } = require('node:timers');
4
5
  const { Collection } = require('@discordjs/collection');
5
6
  const { makeURLSearchParams } = require('@discordjs/rest');
@@ -10,10 +11,13 @@ const { DiscordjsError, DiscordjsTypeError, DiscordjsRangeError, ErrorCodes } =
10
11
  const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
11
12
  const { GuildMember } = require('../structures/GuildMember');
12
13
  const { Role } = require('../structures/Role');
14
+ const { resolveImage } = require('../util/DataResolver');
13
15
  const Events = require('../util/Events');
14
16
  const { GuildMemberFlagsBitField } = require('../util/GuildMemberFlagsBitField');
15
17
  const Partials = require('../util/Partials');
16
18
 
19
+ let deprecatedEmittedForEditSoleNickname = false;
20
+
17
21
  /**
18
22
  * Manages API methods for GuildMembers and stores their cache.
19
23
  * @extends {CachedManager}
@@ -336,8 +340,8 @@ class GuildMemberManager extends CachedManager {
336
340
  */
337
341
 
338
342
  /**
339
- * Edits a member of the guild.
340
- * <info>The user must be a member of the guild</info>
343
+ * Edits a member of a guild.
344
+ *
341
345
  * @param {UserResolvable} user The member to edit
342
346
  * @param {GuildMemberEditOptions} options The options to provide
343
347
  * @returns {Promise<GuildMember>}
@@ -372,13 +376,30 @@ class GuildMemberManager extends CachedManager {
372
376
  }
373
377
 
374
378
  let endpoint;
379
+
375
380
  if (id === this.client.user.id) {
376
381
  const keys = Object.keys(options);
377
- if (keys.length === 1 && keys[0] === 'nick') endpoint = Routes.guildMember(this.guild.id);
378
- else endpoint = Routes.guildMember(this.guild.id, id);
379
- } else {
380
- endpoint = Routes.guildMember(this.guild.id, id);
382
+
383
+ if (keys.length === 1 && keys[0] === 'nick') {
384
+ // For modifying the current application's nickname only, we use the /guilds/{guild.id}/members/@me endpoint.
385
+ // This endpoint only requires the CHANGE_NICKNAME permission.
386
+ // The other endpoint would require the MANAGE_NICKNAMES permission.
387
+ // In v15, this will be split out, so emit a deprecation.
388
+ endpoint = Routes.guildMember(this.guild.id, '@me');
389
+
390
+ if (!deprecatedEmittedForEditSoleNickname) {
391
+ process.emitWarning(
392
+ // eslint-disable-next-line max-len
393
+ "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.",
394
+ 'DeprecationWarning',
395
+ );
396
+
397
+ deprecatedEmittedForEditSoleNickname = true;
398
+ }
399
+ }
381
400
  }
401
+
402
+ endpoint ??= Routes.guildMember(this.guild.id, id);
382
403
  const d = await this.client.rest.patch(endpoint, { body: options, reason });
383
404
 
384
405
  const clone = this.cache.get(id)?._clone();
@@ -386,6 +407,38 @@ class GuildMemberManager extends CachedManager {
386
407
  return clone ?? this._add(d, false);
387
408
  }
388
409
 
410
+ /**
411
+ * The data for editing the current application's guild member.
412
+ *
413
+ * @typedef {Object} GuildMemberEditMeOptions
414
+ * @property {?string} [nick] The nickname to set
415
+ * @property {?(BufferResolvable|Base64Resolvable)} [banner] The banner to set
416
+ * @property {?(BufferResolvable|Base64Resolvable)} [avatar] The avatar to set
417
+ * @property {?string} [bio] The bio to set
418
+ * @property {string} [reason] The reason to use
419
+ */
420
+
421
+ /**
422
+ * Edits the current application's guild member in a guild.
423
+ *
424
+ * @param {GuildMemberEditMeOptions} options The options to provide
425
+ * @returns {Promise<GuildMember>}
426
+ */
427
+ async editMe({ reason, ...options }) {
428
+ const data = await this.client.rest.patch(Routes.guildMember(this.guild.id, '@me'), {
429
+ body: {
430
+ ...options,
431
+ banner: options.banner && (await resolveImage(options.banner)),
432
+ avatar: options.avatar && (await resolveImage(options.avatar)),
433
+ },
434
+ reason,
435
+ });
436
+
437
+ const clone = this.me?._clone();
438
+ clone?._patch(data);
439
+ return clone ?? this._add(data, false);
440
+ }
441
+
389
442
  /**
390
443
  * Options used for pruning guild members.
391
444
  * <info>It's recommended to set {@link GuildPruneMembersOptions#count options.count}
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ const { Collection } = require('@discordjs/collection');
4
+ const { makeURLSearchParams } = require('@discordjs/rest');
5
+ const { Routes } = require('discord-api-types/v10');
6
+ const CachedManager = require('./CachedManager.js');
7
+ const User = require('../structures/User.js');
8
+
9
+ /**
10
+ * Manages API methods for users who voted on a poll and stores their cache.
11
+ * @extends {CachedManager}
12
+ */
13
+ class PollAnswerVoterManager extends CachedManager {
14
+ constructor(answer) {
15
+ super(answer.client, User);
16
+
17
+ /**
18
+ * The poll answer that this manager belongs to
19
+ * @type {PollAnswer}
20
+ */
21
+ this.answer = answer;
22
+ }
23
+
24
+ /**
25
+ * The cache of this manager
26
+ * @type {Collection<Snowflake, User>}
27
+ * @name PollAnswerVoterManager#cache
28
+ */
29
+
30
+ /**
31
+ * Fetches the users that voted on this poll answer. Resolves with a collection of users, mapped by their ids.
32
+ * @param {BaseFetchPollAnswerVotersOptions} [options={}] Options for fetching the users
33
+ * @returns {Promise<Collection<Snowflake, User>>}
34
+ */
35
+ async fetch({ after, limit } = {}) {
36
+ const poll = this.answer.poll;
37
+ const query = makeURLSearchParams({ limit, after });
38
+ const data = await this.client.rest.get(Routes.pollAnswerVoters(poll.channelId, poll.messageId, this.answer.id), {
39
+ query,
40
+ });
41
+
42
+ return data.users.reduce((coll, rawUser) => {
43
+ const user = this.client.users._add(rawUser);
44
+ this.cache.set(user.id, user);
45
+ return coll.set(user.id, user);
46
+ }, new Collection());
47
+ }
48
+ }
49
+
50
+ exports.PollAnswerVoterManager = PollAnswerVoterManager;
@@ -73,7 +73,7 @@ class ApplicationCommand extends Base {
73
73
  if ('name_localizations' in data) {
74
74
  /**
75
75
  * The name localizations for this command
76
- * @type {?Object<Locale, string>}
76
+ * @type {?LocalizationMap}
77
77
  */
78
78
  this.nameLocalizations = data.name_localizations;
79
79
  } else {
@@ -101,7 +101,7 @@ class ApplicationCommand extends Base {
101
101
  if ('description_localizations' in data) {
102
102
  /**
103
103
  * The description localizations for this command
104
- * @type {?Object<Locale, string>}
104
+ * @type {?LocalizationMap}
105
105
  */
106
106
  this.descriptionLocalizations = data.description_localizations;
107
107
  } else {
@@ -227,11 +227,11 @@ class ApplicationCommand extends Base {
227
227
  * @typedef {Object} ApplicationCommandData
228
228
  * @property {string} name The name of the command, must be in all lowercase if type is
229
229
  * {@link ApplicationCommandType.ChatInput}
230
- * @property {Object<Locale, string>} [nameLocalizations] The localizations for the command name
230
+ * @property {LocalizationMap} [nameLocalizations] The localizations for the command name
231
231
  * @property {string} description The description of the command,
232
232
  * if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
233
233
  * @property {boolean} [nsfw] Whether the command is age-restricted
234
- * @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the command description,
234
+ * @property {LocalizationMap} [descriptionLocalizations] The localizations for the command description,
235
235
  * if type is {@link ApplicationCommandType.ChatInput} or {@link ApplicationCommandType.PrimaryEntryPoint}
236
236
  * @property {ApplicationCommandType} [type=ApplicationCommandType.ChatInput] The type of the command
237
237
  * @property {ApplicationCommandOptionData[]} [options] Options for the command
@@ -253,9 +253,9 @@ class ApplicationCommand extends Base {
253
253
  * @typedef {Object} ApplicationCommandOptionData
254
254
  * @property {ApplicationCommandOptionType} type The type of the option
255
255
  * @property {string} name The name of the option
256
- * @property {Object<Locale, string>} [nameLocalizations] The name localizations for the option
256
+ * @property {LocalizationMap} [nameLocalizations] The name localizations for the option
257
257
  * @property {string} description The description of the option
258
- * @property {Object<Locale, string>} [descriptionLocalizations] The description localizations for the option
258
+ * @property {LocalizationMap} [descriptionLocalizations] The description localizations for the option
259
259
  * @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
260
260
  * {@link ApplicationCommandOptionType.String}, {@link ApplicationCommandOptionType.Integer} or
261
261
  * {@link ApplicationCommandOptionType.Number} option
@@ -277,7 +277,7 @@ class ApplicationCommand extends Base {
277
277
  /**
278
278
  * @typedef {Object} ApplicationCommandOptionChoiceData
279
279
  * @property {string} name The name of the choice
280
- * @property {Object<Locale, string>} [nameLocalizations] The localized names for this choice
280
+ * @property {LocalizationMap} [nameLocalizations] The localized names for this choice
281
281
  * @property {string|number} value The value of the choice
282
282
  */
283
283
 
@@ -308,7 +308,7 @@ class ApplicationCommand extends Base {
308
308
 
309
309
  /**
310
310
  * Edits the localized names of this ApplicationCommand
311
- * @param {Object<Locale, string>} nameLocalizations The new localized names for the command
311
+ * @param {LocalizationMap} nameLocalizations The new localized names for the command
312
312
  * @returns {Promise<ApplicationCommand>}
313
313
  * @example
314
314
  * // Edit the name localizations of this command
@@ -334,7 +334,7 @@ class ApplicationCommand extends Base {
334
334
 
335
335
  /**
336
336
  * Edits the localized descriptions of this ApplicationCommand
337
- * @param {Object<Locale, string>} descriptionLocalizations The new localized descriptions for the command
337
+ * @param {LocalizationMap} descriptionLocalizations The new localized descriptions for the command
338
338
  * @returns {Promise<ApplicationCommand>}
339
339
  * @example
340
340
  * // Edit the description localizations of this command
@@ -550,10 +550,10 @@ class ApplicationCommand extends Base {
550
550
  * @typedef {Object} ApplicationCommandOption
551
551
  * @property {ApplicationCommandOptionType} type The type of the option
552
552
  * @property {string} name The name of the option
553
- * @property {Object<Locale, string>} [nameLocalizations] The localizations for the option name
553
+ * @property {LocalizationMap} [nameLocalizations] The localizations for the option name
554
554
  * @property {string} [nameLocalized] The localized name for this option
555
555
  * @property {string} description The description of the option
556
- * @property {Object<Locale, string>} [descriptionLocalizations] The localizations for the option description
556
+ * @property {LocalizationMap} [descriptionLocalizations] The localizations for the option description
557
557
  * @property {string} [descriptionLocalized] The localized description for this option
558
558
  * @property {boolean} [required] Whether the option is required
559
559
  * @property {boolean} [autocomplete] Whether the autocomplete interaction is enabled for a
@@ -13,7 +13,7 @@ class ApplicationRoleConnectionMetadata {
13
13
 
14
14
  /**
15
15
  * The name localizations for this metadata field
16
- * @type {?Object<Locale, string>}
16
+ * @type {?LocalizationMap}
17
17
  */
18
18
  this.nameLocalizations = data.name_localizations ?? null;
19
19
 
@@ -25,7 +25,7 @@ class ApplicationRoleConnectionMetadata {
25
25
 
26
26
  /**
27
27
  * The description localizations for this metadata field
28
- * @type {?Object<Locale, string>}
28
+ * @type {?LocalizationMap}
29
29
  */
30
30
  this.descriptionLocalizations = data.description_localizations ?? null;
31
31
 
@@ -375,9 +375,9 @@ class ClientApplication extends Application {
375
375
  * Data for creating or editing an application role connection metadata.
376
376
  * @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
377
377
  * @property {string} name The name of the metadata field
378
- * @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
378
+ * @property {?LocalizationMap} [nameLocalizations] The name localizations for the metadata field
379
379
  * @property {string} description The description of the metadata field
380
- * @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
380
+ * @property {?LocalizationMap} [descriptionLocalizations] The description localizations for the metadata field
381
381
  * @property {string} key The dictionary key of the metadata field
382
382
  * @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
383
383
  */
@@ -80,12 +80,17 @@ class CommandInteraction extends BaseInteraction {
80
80
  }
81
81
 
82
82
  /**
83
- * Represents the resolved data of a received command interaction.
84
- * @typedef {Object} CommandInteractionResolvedData
83
+ * @typedef {Object} BaseInteractionResolvedData
85
84
  * @property {Collection<Snowflake, User>} [users] The resolved users
86
85
  * @property {Collection<Snowflake, GuildMember|APIGuildMember>} [members] The resolved guild members
87
86
  * @property {Collection<Snowflake, Role|APIRole>} [roles] The resolved roles
88
87
  * @property {Collection<Snowflake, BaseChannel|APIChannel>} [channels] The resolved channels
88
+ */
89
+
90
+ /**
91
+ * Represents the resolved data of a received command interaction.
92
+ *
93
+ * @typedef {BaseInteractionResolvedData} CommandInteractionResolvedData
89
94
  * @property {Collection<Snowflake, Message|APIMessage>} [messages] The resolved messages
90
95
  * @property {Collection<Snowflake, Attachment>} [attachments] The resolved attachments
91
96
  */