lunibee 0.2.1 → 0.2.2

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.
@@ -1,6 +1,6 @@
1
- import type { APIEntitlement, APISoundboardSound } from "@lunibee/types";
1
+ import type { APIEntitlement, APISoundboardSound, APISticker } from "@lunibee/types";
2
2
  import type { APIAutoModerationActionExecution, APIAutoModerationRule, APIChannel, APIChannelPinsUpdate, APIGuild, APIGuildBanEvent, APIGuildEmojisUpdateEvent, APIGuildMember, APIGuildMembersChunk, APIGuildRoleDeleteEvent, APIGuildRoleEvent, APIGuildScheduledEvent, APIGuildScheduledEventUserEvent, APIGuildStickersUpdateEvent, APIInviteCreate, APIInviteDelete, APIMessageDeleteBulkEvent, APIMessageDeleteEvent, APIMessagePollVoteEvent, APIMessageReactionEvent, APIMessageReactionRemoveEmojiEvent, APIPresenceUpdate, APIStageInstance, APIThreadEvent, APIThreadListSync, APIThreadMember, APIThreadMembersUpdate, APITypingStart, APIVoiceServerUpdate, APIVoiceState, APIWebhooksUpdate, ClientUser } from "@lunibee/types";
3
- import type { Channel, Interaction, Message } from "@lunibee/structures";
3
+ import type { Channel, Emoji, Guild, GuildMember, Interaction, Message, Role } from "@lunibee/structures";
4
4
  /** Names of events emitted by a Lunibee client. */
5
5
  export declare enum ClientEvent {
6
6
  Ready = "ready",
@@ -107,7 +107,8 @@ export type ClientEvents = {
107
107
  messagePollVoteAdd: [data: APIMessagePollVoteEvent];
108
108
  messagePollVoteRemove: [data: APIMessagePollVoteEvent];
109
109
  guildCreate: [data: APIGuild];
110
- guildUpdate: [data: APIGuild];
110
+ /** `previous` is a copy of the cached guild before the update, or null when it was not cached. */
111
+ guildUpdate: [data: APIGuild, previous: Guild | null];
111
112
  guildDelete: [data: {
112
113
  id: string;
113
114
  unavailable?: boolean;
@@ -120,16 +121,27 @@ export type ClientEvents = {
120
121
  unavailable?: boolean;
121
122
  }];
122
123
  guildMemberAdd: [member: APIGuildMember];
123
- guildMemberUpdate: [member: APIGuildMember];
124
+ /** `previous` is a copy of the cached member before the update, or null when it was not cached. */
125
+ guildMemberUpdate: [member: APIGuildMember, previous: GuildMember | null];
124
126
  guildMemberRemove: [member: APIGuildMember];
125
127
  guildMembersChunk: [data: APIGuildMembersChunk];
126
128
  guildBanAdd: [data: APIGuildBanEvent];
127
129
  guildBanRemove: [data: APIGuildBanEvent];
128
130
  guildRoleCreate: [data: APIGuildRoleEvent];
129
- guildRoleUpdate: [data: APIGuildRoleEvent];
130
- guildRoleDelete: [data: APIGuildRoleDeleteEvent];
131
- guildEmojisUpdate: [data: APIGuildEmojisUpdateEvent];
132
- guildStickersUpdate: [data: APIGuildStickersUpdateEvent];
131
+ /** `previous` is a copy of the cached role before the update, or null when it was not cached. */
132
+ guildRoleUpdate: [data: APIGuildRoleEvent, previous: Role | null];
133
+ /** `removed` is the role that was cached, or null. */
134
+ guildRoleDelete: [data: APIGuildRoleDeleteEvent, removed: Role | null];
135
+ /** `previous` is the cached emoji list before the update, or null without the emoji cache. */
136
+ guildEmojisUpdate: [
137
+ data: APIGuildEmojisUpdateEvent,
138
+ previous: Emoji[] | null
139
+ ];
140
+ /** `previous` is the cached sticker list before the update (empty when none were cached). */
141
+ guildStickersUpdate: [
142
+ data: APIGuildStickersUpdateEvent,
143
+ previous: APISticker[]
144
+ ];
133
145
  entitlementCreate: [entitlement: APIEntitlement];
134
146
  entitlementUpdate: [entitlement: APIEntitlement];
135
147
  entitlementDelete: [entitlement: APIEntitlement];
@@ -158,12 +170,16 @@ export type ClientEvents = {
158
170
  autoModerationRuleDelete: [data: APIAutoModerationRule];
159
171
  autoModerationActionExecution: [data: APIAutoModerationActionExecution];
160
172
  channelCreate: [channel: Channel];
161
- channelUpdate: [channel: Channel];
162
- channelDelete: [data: APIChannel];
173
+ /** `previous` is a copy of the cached channel before the update, or null when it was not cached. */
174
+ channelUpdate: [channel: Channel, previous: Channel | null];
175
+ /** `removed` is the channel that was cached, or null. */
176
+ channelDelete: [data: APIChannel, removed: Channel | null];
163
177
  channelPinsUpdate: [data: APIChannelPinsUpdate];
164
178
  threadCreate: [channel: Channel];
165
- threadUpdate: [channel: Channel];
166
- threadDelete: [data: APIThreadEvent];
179
+ /** `previous` is a copy of the cached thread before the update, or null when it was not cached. */
180
+ threadUpdate: [channel: Channel, previous: Channel | null];
181
+ /** `removed` is the thread that was cached, or null. */
182
+ threadDelete: [data: APIThreadEvent, removed: Channel | null];
167
183
  threadListSync: [data: APIThreadListSync];
168
184
  threadMembersUpdate: [data: APIThreadMembersUpdate];
169
185
  threadMemberUpdate: [data: APIThreadMember];
@@ -1,4 +1,4 @@
1
- export { Permission, Permissions, PermissionFlagsBits, PermissionSet, PermissionsBitField, PermissionOverwriteType, computePermissions, type PermissionContext, type PermissionOverwrite, type PermissionRole, type PermissionName, } from "./permissions.js";
1
+ export { Permission, Permissions, PermissionFlagsBits, PermissionSet, PermissionsBitField, PermissionOverwriteEnum, PermissionOverwriteType, computePermissions, type PermissionContext, type PermissionOverwrite, type PermissionRole, type PermissionName, } from "./permissions.js";
2
2
  export { ClientEvent,
3
3
  /** Discord.js-familiar alias for {@link ClientEvent}. */
4
4
  ClientEvent as Events, type ClientEventName, type ClientEvents, type ClientListener, } from "./events.js";
@@ -1,10 +1,11 @@
1
1
  // @bun
2
2
  // packages/core/src/permissions.ts
3
- var PermissionOverwriteType;
4
- ((PermissionOverwriteType) => {
5
- PermissionOverwriteType[PermissionOverwriteType["Role"] = 0] = "Role";
6
- PermissionOverwriteType[PermissionOverwriteType["Member"] = 1] = "Member";
7
- })(PermissionOverwriteType ||= {});
3
+ var PermissionOverwriteEnum;
4
+ ((PermissionOverwriteEnum) => {
5
+ PermissionOverwriteEnum[PermissionOverwriteEnum["Role"] = 0] = "Role";
6
+ PermissionOverwriteEnum[PermissionOverwriteEnum["Member"] = 1] = "Member";
7
+ })(PermissionOverwriteEnum ||= {});
8
+ var PermissionOverwriteType = PermissionOverwriteEnum;
8
9
  var Permission = {
9
10
  createInstantInvite: 1n << 0n,
10
11
  kickMembers: 1n << 1n,
@@ -802,7 +803,7 @@ class IntentsBitField {
802
803
  }
803
804
  }
804
805
  // packages/types/src/index.ts
805
- var InteractionResponseType = {
806
+ var InteractionResponseEnum = {
806
807
  Pong: 1,
807
808
  ChannelMessage: 4,
808
809
  DeferredChannelMessage: 5,
@@ -1463,7 +1464,7 @@ class ResourceManager extends Manager {
1463
1464
  // packages/rest/package.json
1464
1465
  var package_default = {
1465
1466
  name: "@lunibee/rest",
1466
- version: "0.2.1",
1467
+ version: "0.2.2",
1467
1468
  type: "module",
1468
1469
  module: "./src/index.ts",
1469
1470
  types: "./src/index.ts",
@@ -2913,7 +2914,7 @@ class CommandOptions {
2913
2914
  }
2914
2915
  }
2915
2916
  // packages/structures/src/interactions.ts
2916
- var InteractionType = {
2917
+ var InteractionEnum = {
2917
2918
  Ping: 1,
2918
2919
  ApplicationCommand: 2,
2919
2920
  MessageComponent: 3,
@@ -2921,8 +2922,17 @@ var InteractionType = {
2921
2922
  ModalSubmit: 5
2922
2923
  };
2923
2924
  var EPHEMERAL = 64;
2925
+ var COMMAND_CHAT_INPUT = 1;
2926
+ var COMMAND_USER = 2;
2927
+ var COMMAND_MESSAGE = 3;
2924
2928
  var TOKEN_LIFETIME_MS = 15 * 60000;
2925
2929
  var DISCORD_EPOCH = 1420070400000n;
2930
+ function splitWithResponse(options) {
2931
+ if (typeof options === "string")
2932
+ return { withResponse: false, rest: options };
2933
+ const { withResponse, ...rest } = options;
2934
+ return { withResponse: withResponse === true, rest };
2935
+ }
2926
2936
  function toMessageData(options) {
2927
2937
  if (typeof options === "string")
2928
2938
  return { content: options };
@@ -2935,6 +2945,7 @@ function toMessageData(options) {
2935
2945
  class InteractionResponse {
2936
2946
  type;
2937
2947
  data;
2948
+ withResponse = false;
2938
2949
  constructor(type, data) {
2939
2950
  if (!Number.isFinite(type))
2940
2951
  throw new TypeError("Interaction response type must be finite.");
@@ -2945,13 +2956,13 @@ class InteractionResponse {
2945
2956
  return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
2946
2957
  }
2947
2958
  static message(options) {
2948
- return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
2959
+ return new InteractionResponse(InteractionResponseEnum.ChannelMessage, toMessageData(options));
2949
2960
  }
2950
2961
  static defer(ephemeral = false) {
2951
- return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
2962
+ return new InteractionResponse(InteractionResponseEnum.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
2952
2963
  }
2953
2964
  static pong() {
2954
- return new InteractionResponse(InteractionResponseType.Pong);
2965
+ return new InteractionResponse(InteractionResponseEnum.Pong);
2955
2966
  }
2956
2967
  }
2957
2968
 
@@ -2979,8 +2990,30 @@ class Interaction {
2979
2990
  this.type = data.type;
2980
2991
  this.data = data;
2981
2992
  }
2993
+ #commandType() {
2994
+ if (this.type !== InteractionEnum.ApplicationCommand)
2995
+ return 0;
2996
+ const type = this.data.data?.type;
2997
+ return typeof type === "number" ? type : COMMAND_CHAT_INPUT;
2998
+ }
2999
+ isCommand() {
3000
+ return this.type === InteractionEnum.ApplicationCommand;
3001
+ }
2982
3002
  isChatInputCommand() {
2983
- return this.type === InteractionType.ApplicationCommand;
3003
+ return this.#commandType() === COMMAND_CHAT_INPUT;
3004
+ }
3005
+ isContextMenuCommand() {
3006
+ const type = this.#commandType();
3007
+ return type === COMMAND_USER || type === COMMAND_MESSAGE;
3008
+ }
3009
+ isUserContextMenuCommand() {
3010
+ return this.#commandType() === COMMAND_USER;
3011
+ }
3012
+ isMessageContextMenuCommand() {
3013
+ return this.#commandType() === COMMAND_MESSAGE;
3014
+ }
3015
+ get resourceContext() {
3016
+ return this.#client.resourceContext;
2984
3017
  }
2985
3018
  awaitModalSubmit(options) {
2986
3019
  const collect = this.#client.resourceContext?.collectInteractions;
@@ -2997,13 +3030,13 @@ class Interaction {
2997
3030
  return collector.next();
2998
3031
  }
2999
3032
  isMessageComponent() {
3000
- return this.type === InteractionType.MessageComponent;
3033
+ return this.type === InteractionEnum.MessageComponent;
3001
3034
  }
3002
3035
  isModalSubmit() {
3003
- return this.type === InteractionType.ModalSubmit;
3036
+ return this.type === InteractionEnum.ModalSubmit;
3004
3037
  }
3005
3038
  isAutocomplete() {
3006
- return this.type === InteractionType.ApplicationCommandAutocomplete;
3039
+ return this.type === InteractionEnum.ApplicationCommandAutocomplete;
3007
3040
  }
3008
3041
  #componentType() {
3009
3042
  return this.isMessageComponent() ? this.data.data?.component_type ?? 0 : 0;
@@ -3088,12 +3121,24 @@ class Interaction {
3088
3121
  postResponse(response) {
3089
3122
  return this.#client.postInteractionResponse(this.id, this.token, response);
3090
3123
  }
3124
+ async acknowledgeWith(response, state, withResponse) {
3125
+ response.withResponse = withResponse;
3126
+ const result = await this.acknowledge(response, state);
3127
+ if (!withResponse)
3128
+ return result;
3129
+ const message = result?.resource?.message;
3130
+ return message ? new Message(message, this.#client.resourceContext) : null;
3131
+ }
3091
3132
  async reply(options) {
3092
- return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
3133
+ const { withResponse, rest } = splitWithResponse(options);
3134
+ return this.acknowledgeWith(InteractionResponse.message(toMessageData(rest)), "replied", withResponse);
3093
3135
  }
3094
3136
  async deferReply(options = false) {
3095
3137
  const ephemeral = typeof options === "boolean" ? options : options.ephemeral === true;
3096
- await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
3138
+ const withResponse = typeof options === "object" && options.withResponse === true;
3139
+ const result = await this.acknowledgeWith(InteractionResponse.defer(ephemeral), "deferred", withResponse);
3140
+ if (withResponse)
3141
+ return result;
3097
3142
  }
3098
3143
  editReply(options) {
3099
3144
  this.assertAcknowledged();
@@ -3107,11 +3152,12 @@ class Interaction {
3107
3152
  return this.#client.followUpInteraction(this.token, toMessageData(options));
3108
3153
  }
3109
3154
  async update(options) {
3110
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
3155
+ const { withResponse, rest } = splitWithResponse(options);
3156
+ return this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.MessageUpdate, toMessageData(rest)), "replied", withResponse);
3111
3157
  }
3112
3158
  async showModal(modal) {
3113
3159
  const data = "toJSON" in modal && typeof modal.toJSON === "function" ? modal.toJSON() : modal;
3114
- return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, data), "replied");
3160
+ return this.acknowledge(new InteractionResponse(InteractionResponseEnum.Modal, data), "replied");
3115
3161
  }
3116
3162
  }
3117
3163
 
@@ -3128,6 +3174,38 @@ class CommandInteraction extends Interaction {
3128
3174
  }
3129
3175
  }
3130
3176
 
3177
+ class ContextMenuCommandInteraction extends CommandInteraction {
3178
+ #resolved() {
3179
+ return this.data.data?.resolved ?? {};
3180
+ }
3181
+ get targetId() {
3182
+ const id = this.data.data?.target_id;
3183
+ return typeof id === "string" ? id : null;
3184
+ }
3185
+ get targetUser() {
3186
+ const id = this.targetId;
3187
+ const raw = id ? this.#resolved().users?.[id] : undefined;
3188
+ return raw ? new User(raw) : null;
3189
+ }
3190
+ get targetMember() {
3191
+ const id = this.targetId;
3192
+ const raw = id ? this.#resolved().members?.[id] : undefined;
3193
+ const user = id ? this.#resolved().users?.[id] : undefined;
3194
+ if (!raw || !user || !this.guildId)
3195
+ return null;
3196
+ return new GuildMember({
3197
+ ...raw,
3198
+ user,
3199
+ guild_id: this.guildId
3200
+ }, this.resourceContext);
3201
+ }
3202
+ get targetMessage() {
3203
+ const id = this.targetId;
3204
+ const raw = id ? this.#resolved().messages?.[id] : undefined;
3205
+ return raw ? new Message(raw, this.resourceContext) : null;
3206
+ }
3207
+ }
3208
+
3131
3209
  class ComponentInteraction extends Interaction {
3132
3210
  get customId() {
3133
3211
  return this.data?.data?.custom_id ?? "";
@@ -3141,11 +3219,11 @@ class ComponentInteraction extends Interaction {
3141
3219
  get values() {
3142
3220
  return this.data?.data?.values ?? [];
3143
3221
  }
3144
- async deferUpdate() {
3145
- await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
3146
- }
3147
- async update(options) {
3148
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
3222
+ async deferUpdate(options = {}) {
3223
+ const withResponse = options.withResponse === true;
3224
+ const result = await this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.DeferredMessageUpdate), "deferred", withResponse);
3225
+ if (withResponse)
3226
+ return result;
3149
3227
  }
3150
3228
  }
3151
3229
 
@@ -3187,7 +3265,7 @@ class AutocompleteInteraction extends Interaction {
3187
3265
  async respond(choices) {
3188
3266
  if (!Array.isArray(choices))
3189
3267
  throw new TypeError("Autocomplete choices must be an array.");
3190
- const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
3268
+ const response = new InteractionResponse(InteractionResponseEnum.Autocomplete, { choices });
3191
3269
  await this.acknowledge(response, "replied");
3192
3270
  }
3193
3271
  }
@@ -3205,13 +3283,15 @@ function findFocused(options) {
3205
3283
  }
3206
3284
  function createInteraction(client, data) {
3207
3285
  switch (data.type) {
3208
- case InteractionType.ApplicationCommand:
3209
- return new CommandInteraction(client, data);
3210
- case InteractionType.ApplicationCommandAutocomplete:
3286
+ case InteractionEnum.ApplicationCommand: {
3287
+ const commandType = data.data?.type;
3288
+ return commandType === COMMAND_USER || commandType === COMMAND_MESSAGE ? new ContextMenuCommandInteraction(client, data) : new CommandInteraction(client, data);
3289
+ }
3290
+ case InteractionEnum.ApplicationCommandAutocomplete:
3211
3291
  return new AutocompleteInteraction(client, data);
3212
- case InteractionType.MessageComponent:
3292
+ case InteractionEnum.MessageComponent:
3213
3293
  return new ComponentInteraction(client, data);
3214
- case InteractionType.ModalSubmit:
3294
+ case InteractionEnum.ModalSubmit:
3215
3295
  return new ModalSubmitInteraction(client, data);
3216
3296
  default:
3217
3297
  return new Interaction(client, data);
@@ -3240,6 +3320,9 @@ class Message extends BaseStructure {
3240
3320
  reference;
3241
3321
  components;
3242
3322
  referencedMessage;
3323
+ stickers;
3324
+ poll;
3325
+ messageSnapshots;
3243
3326
  member;
3244
3327
  #context;
3245
3328
  constructor(data, context) {
@@ -3261,6 +3344,13 @@ class Message extends BaseStructure {
3261
3344
  this.mentionEveryone = data.mention_everyone ?? false;
3262
3345
  this.type = data.type ?? 0;
3263
3346
  this.reference = data.message_reference;
3347
+ this.stickers = data.sticker_items ?? (data.stickers ?? []).map(({ id, name, format_type }) => ({
3348
+ id,
3349
+ name,
3350
+ format_type
3351
+ }));
3352
+ this.poll = data.poll ?? null;
3353
+ this.messageSnapshots = data.message_snapshots ?? [];
3264
3354
  this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
3265
3355
  this.#context = context;
3266
3356
  this.member = data.member && data.guild_id ? new GuildMember({
@@ -3395,8 +3485,10 @@ class Message extends BaseStructure {
3395
3485
  }
3396
3486
 
3397
3487
  // packages/managers/src/message.ts
3398
- function toRequest(options) {
3488
+ function toRequest(options, allowedMentions) {
3399
3489
  const { files, ...body } = options;
3490
+ if (allowedMentions !== undefined && body.allowed_mentions === undefined)
3491
+ body.allowed_mentions = allowedMentions;
3400
3492
  if (!files?.length)
3401
3493
  return body;
3402
3494
  return {
@@ -3415,9 +3507,11 @@ class MessageManager {
3415
3507
  #rest;
3416
3508
  #context;
3417
3509
  #channelId;
3418
- constructor(rest, context, channelId, cache) {
3510
+ #allowedMentions;
3511
+ constructor(rest, context, channelId, cache, allowedMentions) {
3419
3512
  if (!channelId)
3420
3513
  throw new TypeError("Channel ID is required.");
3514
+ this.#allowedMentions = allowedMentions;
3421
3515
  this.#rest = rest;
3422
3516
  this.#context = context;
3423
3517
  this.#channelId = channelId;
@@ -3431,7 +3525,7 @@ class MessageManager {
3431
3525
  return this.cache.get(messageId) ?? this.fetch(messageId);
3432
3526
  }
3433
3527
  async send(options) {
3434
- const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options));
3528
+ const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options, this.#allowedMentions));
3435
3529
  return this.upsert(data);
3436
3530
  }
3437
3531
  async fetch(messageId) {
@@ -4174,10 +4268,12 @@ class ChannelManager extends Manager {
4174
4268
  #context;
4175
4269
  #messageManagers = new Map;
4176
4270
  #messageCache;
4271
+ #allowedMentions;
4177
4272
  constructor(rest, options = {}) {
4178
4273
  super();
4179
4274
  this.#rest = rest;
4180
4275
  this.#messageCache = options.messageCache;
4276
+ this.#allowedMentions = options.allowedMentions;
4181
4277
  this.#context = {
4182
4278
  sendMessage: (channelId, options) => this.send(channelId, options),
4183
4279
  editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
@@ -4196,7 +4292,7 @@ class ChannelManager extends Manager {
4196
4292
  messages(channelId) {
4197
4293
  let manager = this.#messageManagers.get(channelId);
4198
4294
  if (!manager) {
4199
- manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
4295
+ manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache, this.#allowedMentions);
4200
4296
  this.#messageManagers.set(channelId, manager);
4201
4297
  }
4202
4298
  return manager;
@@ -4302,7 +4398,7 @@ class ChannelManager extends Manager {
4302
4398
  return this.messages(data.channel_id).upsert(data);
4303
4399
  }
4304
4400
  async editMessage(channelId, messageId, options) {
4305
- return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options)));
4401
+ return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options, this.#allowedMentions)));
4306
4402
  }
4307
4403
  async deleteMessage(channelId, messageId) {
4308
4404
  await this.#rest.delete(Routes.message(channelId, messageId));
@@ -5339,6 +5435,7 @@ class Gateway {
5339
5435
  #message(raw, token) {
5340
5436
  if (!this.#session.owns(token))
5341
5437
  return;
5438
+ this.#heartbeat.receivedMessage();
5342
5439
  const { sequence, action } = classifyFrame(raw);
5343
5440
  if (sequence !== null)
5344
5441
  this.#session.recordSequence(sequence, token);
@@ -5607,7 +5704,8 @@ class Client extends EventEmitter2 {
5607
5704
  this.users = new UserManager(this.rest);
5608
5705
  this.guilds = new GuildManager(this.rest);
5609
5706
  this.channels = new ChannelManager(this.rest, {
5610
- messageCache: options.messageCache
5707
+ messageCache: options.messageCache,
5708
+ allowedMentions: options.allowedMentions
5611
5709
  });
5612
5710
  this.stageInstances = new StageInstanceManager(this.rest);
5613
5711
  const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
@@ -5754,8 +5852,11 @@ class Client extends EventEmitter2 {
5754
5852
  this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
5755
5853
  });
5756
5854
  this.#gateway.on("GUILD_UPDATE", (data) => {
5757
- this.guilds.patch(data);
5758
- this.emit("guildUpdate" /* GuildUpdate */, data);
5855
+ const payload = data;
5856
+ const cached = this.guilds.get(payload.id);
5857
+ const previous = cached ? this.#snapshot(cached) : null;
5858
+ this.guilds.patch(payload);
5859
+ this.emit("guildUpdate" /* GuildUpdate */, payload, previous);
5759
5860
  });
5760
5861
  this.#gateway.on("GUILD_DELETE", (data) => {
5761
5862
  const payload = data;
@@ -5774,8 +5875,10 @@ class Client extends EventEmitter2 {
5774
5875
  });
5775
5876
  this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
5776
5877
  const member = data;
5878
+ const cached = this.#cache.members ? this.guilds.members(member.guild_id).get(member.user.id) : undefined;
5879
+ const previous = cached ? this.#snapshot(cached, new GuildMember({ user: member.user, guild_id: member.guild_id }, this.#resourceContext)) : null;
5777
5880
  this.#upsertMember(member.guild_id, member);
5778
- this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
5881
+ this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member, previous);
5779
5882
  });
5780
5883
  this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
5781
5884
  const member = data;
@@ -5810,18 +5913,24 @@ class Client extends EventEmitter2 {
5810
5913
  });
5811
5914
  this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
5812
5915
  const event = data;
5916
+ const cached = this.#cache.roles ? this.guilds.roles(event.guild_id).get(event.role.id) : undefined;
5917
+ const previous = cached ? this.#snapshot(cached) : null;
5813
5918
  this.#upsertRole(event.guild_id, event.role);
5814
- this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
5919
+ this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event, previous);
5815
5920
  });
5816
5921
  this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
5817
5922
  const event = data;
5818
- this.guilds.roles(event.guild_id).delete(event.role_id);
5819
- this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
5923
+ const roles = this.guilds.roles(event.guild_id);
5924
+ const removed = roles.get(event.role_id) ?? null;
5925
+ roles.delete(event.role_id);
5926
+ this.emit("guildRoleDelete" /* GuildRoleDelete */, event, removed);
5820
5927
  });
5821
5928
  this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
5822
5929
  const event = data;
5930
+ let previous = null;
5823
5931
  if (this.#cache.emojis) {
5824
5932
  const emojis = this.guilds.emojis(event.guild_id);
5933
+ previous = [...emojis.cache.values()].map((emoji) => this.#snapshot(emoji));
5825
5934
  const current = new Set(event.emojis.map((emoji) => emoji.id));
5826
5935
  for (const id of [...emojis.cache.keys()])
5827
5936
  if (!current.has(id))
@@ -5829,12 +5938,14 @@ class Client extends EventEmitter2 {
5829
5938
  for (const emoji of event.emojis)
5830
5939
  emojis.upsert(emoji);
5831
5940
  }
5832
- this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
5941
+ this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event, previous);
5833
5942
  });
5834
5943
  this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
5835
5944
  const event = data;
5836
- this.guilds.stickers(event.guild_id).sync(event.stickers);
5837
- this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
5945
+ const stickers = this.guilds.stickers(event.guild_id);
5946
+ const previous = [...stickers.cache.values()];
5947
+ stickers.sync(event.stickers);
5948
+ this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event, previous);
5838
5949
  });
5839
5950
  this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
5840
5951
  const sound = data;
@@ -5915,13 +6026,15 @@ class Client extends EventEmitter2 {
5915
6026
  this.emit("channelCreate" /* ChannelCreate */, channel);
5916
6027
  });
5917
6028
  this.#gateway.on("CHANNEL_UPDATE", (data) => {
6029
+ const previous = this.#previousChannel(data);
5918
6030
  const channel = this.channels.upsert(data);
5919
- this.emit("channelUpdate" /* ChannelUpdate */, channel);
6031
+ this.emit("channelUpdate" /* ChannelUpdate */, channel, previous);
5920
6032
  });
5921
6033
  this.#gateway.on("CHANNEL_DELETE", (data) => {
5922
6034
  const payload = data;
6035
+ const removed = this.channels.get(payload.id) ?? null;
5923
6036
  this.channels.delete(payload.id);
5924
- this.emit("channelDelete" /* ChannelDelete */, payload);
6037
+ this.emit("channelDelete" /* ChannelDelete */, payload, removed);
5925
6038
  });
5926
6039
  this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
5927
6040
  this.#gateway.on("THREAD_CREATE", (data) => {
@@ -5929,13 +6042,15 @@ class Client extends EventEmitter2 {
5929
6042
  this.emit("threadCreate" /* ThreadCreate */, channel);
5930
6043
  });
5931
6044
  this.#gateway.on("THREAD_UPDATE", (data) => {
6045
+ const previous = this.#previousChannel(data);
5932
6046
  const channel = this.channels.upsert(data);
5933
- this.emit("threadUpdate" /* ThreadUpdate */, channel);
6047
+ this.emit("threadUpdate" /* ThreadUpdate */, channel, previous);
5934
6048
  });
5935
6049
  this.#gateway.on("THREAD_DELETE", (data) => {
5936
6050
  const payload = data;
6051
+ const removed = this.channels.get(payload.id) ?? null;
5937
6052
  this.channels.delete(payload.id);
5938
- this.emit("threadDelete" /* ThreadDelete */, payload);
6053
+ this.emit("threadDelete" /* ThreadDelete */, payload, removed);
5939
6054
  });
5940
6055
  this.#gateway.on("THREAD_LIST_SYNC", (data) => {
5941
6056
  const sync = data;
@@ -6012,6 +6127,15 @@ class Client extends EventEmitter2 {
6012
6127
  return new Role(data);
6013
6128
  return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
6014
6129
  }
6130
+ #snapshot(cached, blank = Object.create(Object.getPrototypeOf(cached))) {
6131
+ return Object.assign(blank, cached);
6132
+ }
6133
+ #previousChannel(data) {
6134
+ const cached = this.channels.get(data.id);
6135
+ if (!cached)
6136
+ return null;
6137
+ return this.#snapshot(cached, createChannel({ id: cached.id, type: cached.type, guild_id: cached.guildId }, this.#resourceContext));
6138
+ }
6015
6139
  #merge(manager, id, next) {
6016
6140
  const existing = manager.get(id);
6017
6141
  if (!existing) {
@@ -6103,20 +6227,22 @@ class Client extends EventEmitter2 {
6103
6227
  }
6104
6228
  postInteractionResponse(id, token, response) {
6105
6229
  const json = response.toJSON();
6106
- const upload = json.data ? toRequest(json.data) : undefined;
6230
+ const callback = response.withResponse ? `${Routes.interactionCallback(id, token)}?with_response=true` : Routes.interactionCallback(id, token);
6231
+ const carriesMessage = json.type === 4 || json.type === 7;
6232
+ const upload = json.data ? toRequest(json.data, carriesMessage ? this.options.allowedMentions : undefined) : undefined;
6107
6233
  if (upload && typeof upload === "object" && "files" in upload) {
6108
6234
  const { body, files } = upload;
6109
- return this.rest.post(Routes.interactionCallback(id, token), {
6235
+ return this.rest.post(callback, {
6110
6236
  body: { ...json, data: body },
6111
6237
  files
6112
6238
  });
6113
6239
  }
6114
- return this.rest.post(Routes.interactionCallback(id, token), json);
6240
+ return this.rest.post(callback, upload === undefined ? json : { ...json, data: upload });
6115
6241
  }
6116
6242
  editInteractionReply(token, data) {
6117
6243
  if (!this.user)
6118
6244
  return Promise.reject(new Error("Client is unauthenticated."));
6119
- return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data));
6245
+ return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data, this.options.allowedMentions));
6120
6246
  }
6121
6247
  deleteInteractionReply(token) {
6122
6248
  if (!this.user)
@@ -6126,14 +6252,14 @@ class Client extends EventEmitter2 {
6126
6252
  followUpInteraction(token, data) {
6127
6253
  if (!this.user)
6128
6254
  return Promise.reject(new Error("Client is unauthenticated."));
6129
- return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data));
6255
+ return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data, this.options.allowedMentions));
6130
6256
  }
6131
6257
  interactionWebhookMessage(method, applicationId, token, messageId, data) {
6132
6258
  const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
6133
6259
  if (method === "GET")
6134
6260
  return this.rest.get(path);
6135
6261
  if (method === "PATCH")
6136
- return this.rest.patch(path, data);
6262
+ return this.rest.patch(path, data ? toRequest(data, this.options.allowedMentions) : data);
6137
6263
  return this.rest.delete(path);
6138
6264
  }
6139
6265
  fetchWebhook(id, token) {
@@ -6189,6 +6315,7 @@ export {
6189
6315
  IntentsBitField,
6190
6316
  Permission,
6191
6317
  PermissionFlagsBits,
6318
+ PermissionOverwriteEnum,
6192
6319
  PermissionOverwriteType,
6193
6320
  PermissionSet,
6194
6321
  Permissions,
@@ -6197,4 +6324,4 @@ export {
6197
6324
  resolveGatewayIntents
6198
6325
  };
6199
6326
 
6200
- //# debugId=C58DF09843ED07E364756E2164756E21
6327
+ //# debugId=A5606C420611230B64756E2164756E21