lunibee 0.2.1 → 0.2.3

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 (49) hide show
  1. package/README.md +6 -6
  2. package/dist/builders/attachment.d.ts +5 -1
  3. package/dist/builders/commands.d.ts +136 -47
  4. package/dist/builders/components.d.ts +164 -45
  5. package/dist/builders/embed.d.ts +5 -1
  6. package/dist/builders/index.d.ts +9 -4
  7. package/dist/builders/index.js +206 -105
  8. package/dist/builders/index.js.map +8 -8
  9. package/dist/core/events.d.ts +28 -12
  10. package/dist/core/index.d.ts +2 -1
  11. package/dist/core/index.js +377 -150
  12. package/dist/core/index.js.map +25 -25
  13. package/dist/core/permissions.d.ts +6 -2
  14. package/dist/index.d.ts +5 -4
  15. package/dist/index.js +662 -268
  16. package/dist/index.js.map +33 -32
  17. package/dist/managers/base.d.ts +4 -0
  18. package/dist/managers/emoji.d.ts +7 -1
  19. package/dist/managers/guild-resources.d.ts +11 -3
  20. package/dist/managers/guild.d.ts +13 -5
  21. package/dist/managers/index.d.ts +31 -14
  22. package/dist/managers/index.js +167 -80
  23. package/dist/managers/index.js.map +18 -18
  24. package/dist/managers/member.d.ts +5 -3
  25. package/dist/managers/message.d.ts +7 -3
  26. package/dist/managers/role.d.ts +13 -1
  27. package/dist/rest/error-codes.d.ts +48 -0
  28. package/dist/rest/errors.d.ts +1 -0
  29. package/dist/rest/index.d.ts +1 -0
  30. package/dist/rest/index.js +53 -3
  31. package/dist/rest/index.js.map +7 -6
  32. package/dist/rest/routes.d.ts +4 -2
  33. package/dist/sharding/index.js +7 -6
  34. package/dist/sharding/index.js.map +6 -6
  35. package/dist/structures/base.d.ts +18 -9
  36. package/dist/structures/index.d.ts +15 -9
  37. package/dist/structures/index.js +198 -68
  38. package/dist/structures/index.js.map +12 -12
  39. package/dist/structures/interactions.d.ts +85 -11
  40. package/dist/structures/resources.d.ts +11 -1
  41. package/dist/types/gateway.d.ts +14 -0
  42. package/dist/types/index.d.ts +204 -16
  43. package/dist/types/index.js +37 -10
  44. package/dist/types/index.js.map +4 -4
  45. package/dist/voice/index.js +4 -3
  46. package/dist/voice/index.js.map +3 -3
  47. package/dist/ws/index.js +2 -1
  48. package/dist/ws/index.js.map +5 -5
  49. package/package.json +15 -15
@@ -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,
@@ -1362,6 +1363,11 @@ class Collection extends Map {
1362
1363
  }
1363
1364
 
1364
1365
  // packages/managers/src/base.ts
1366
+ function splitReason(options) {
1367
+ const { reason, ...payload } = options;
1368
+ return [payload, reason];
1369
+ }
1370
+
1365
1371
  class Manager {
1366
1372
  cache = new Collection;
1367
1373
  get(id) {
@@ -1463,12 +1469,15 @@ class ResourceManager extends Manager {
1463
1469
  // packages/rest/package.json
1464
1470
  var package_default = {
1465
1471
  name: "@lunibee/rest",
1466
- version: "0.2.1",
1472
+ version: "0.2.3",
1467
1473
  type: "module",
1468
1474
  module: "./src/index.ts",
1469
1475
  types: "./src/index.ts",
1470
1476
  exports: {
1471
1477
  ".": "./src/index.ts"
1478
+ },
1479
+ dependencies: {
1480
+ "@lunibee/types": "workspace:*"
1472
1481
  }
1473
1482
  };
1474
1483
 
@@ -1543,6 +1552,10 @@ function kindFromStatus(status) {
1543
1552
  function redactPath(path) {
1544
1553
  return path.replace(/^(\/webhooks\/[^/?]+\/)[^/?]+/, "$1:token").replace(/^(\/interactions\/[^/?]+\/)[^/?]+/, "$1:token");
1545
1554
  }
1555
+ var HINTS = {
1556
+ 50001: "The bot cannot see this resource: check that it is in the guild and has View Channel there.",
1557
+ 50013: "The bot lacks a permission for this action, or the target role or member is at or above the bot's highest role."
1558
+ };
1546
1559
 
1547
1560
  class RESTError extends Error {
1548
1561
  kind;
@@ -1551,12 +1564,14 @@ class RESTError extends Error {
1551
1564
  errors;
1552
1565
  method;
1553
1566
  path;
1567
+ hint;
1554
1568
  constructor(message, status, code, errors, options = {}) {
1555
1569
  super(message, options.cause === undefined ? undefined : { cause: options.cause });
1556
1570
  this.name = "RESTError";
1557
1571
  this.status = status;
1558
1572
  this.kind = options.kind ?? kindFromStatus(status);
1559
1573
  this.code = code;
1574
+ this.hint = code === undefined ? undefined : HINTS[code];
1560
1575
  this.errors = errors;
1561
1576
  this.method = options.method;
1562
1577
  this.path = options.path === undefined ? undefined : redactPath(options.path);
@@ -1865,6 +1880,8 @@ var Routes = {
1865
1880
  crosspostMessage: (channelId, messageId) => `${Routes.message(channelId, messageId)}/crosspost`,
1866
1881
  messageReactions: (channelId, messageId, emoji) => `${Routes.message(channelId, messageId)}/reactions/${encodeURIComponent(emoji)}`,
1867
1882
  messageReactionsAll: (channelId, messageId) => `${Routes.message(channelId, messageId)}/reactions`,
1883
+ channelMessagesPins: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/pins`,
1884
+ channelMessagesPin: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/pins/${snowflake(messageId, "Message ID")}`,
1868
1885
  channelPins: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/pins`,
1869
1886
  channelPin: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/pins/${snowflake(messageId, "Message ID")}`,
1870
1887
  messageThread: (channelId, messageId) => `${Routes.message(channelId, messageId)}/threads`,
@@ -1927,7 +1944,7 @@ function snowflake(value, field) {
1927
1944
  // packages/rest/src/index.ts
1928
1945
  var LIBRARY_VERSION = package_default.version;
1929
1946
  var LIBRARY_URL = "https://github.com/Ekretos/lunibee";
1930
- var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${package_default.version})`;
1947
+ var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${LIBRARY_VERSION})`;
1931
1948
  var REQUEST_DATA_KEYS = new Set([
1932
1949
  "body",
1933
1950
  "files",
@@ -2250,13 +2267,13 @@ class Channel extends BaseStructure {
2250
2267
  this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
2251
2268
  this.#context = context;
2252
2269
  }
2253
- sendMessage(options) {
2270
+ send(options) {
2254
2271
  if (!this.#context)
2255
2272
  throw new Error("This channel is not attached to a client.");
2256
2273
  return this.#context.sendMessage(this.id, options);
2257
2274
  }
2258
- send(options) {
2259
- return this.sendMessage(options);
2275
+ sendMessage(options) {
2276
+ return this.send(options);
2260
2277
  }
2261
2278
  edit(options) {
2262
2279
  if (!this.#context?.editChannel)
@@ -2279,10 +2296,10 @@ class Channel extends BaseStructure {
2279
2296
  editParent(parentId) {
2280
2297
  return this.edit({ parent_id: parentId });
2281
2298
  }
2282
- delete() {
2299
+ delete(reason) {
2283
2300
  if (!this.#context?.deleteChannel)
2284
2301
  throw new Error("This channel is not attached to a client.");
2285
- return this.#context.deleteChannel(this.id);
2302
+ return this.#context.deleteChannel(this.id, reason);
2286
2303
  }
2287
2304
  update(options) {
2288
2305
  return this.edit(options);
@@ -2329,6 +2346,15 @@ class Guild extends BaseStructure {
2329
2346
  mfaLevel;
2330
2347
  explicitContentFilter;
2331
2348
  defaultMessageNotifications;
2349
+ afkChannelId;
2350
+ afkTimeout;
2351
+ widgetEnabled;
2352
+ widgetChannelId;
2353
+ applicationId;
2354
+ publicUpdatesChannelId;
2355
+ safetyAlertsChannelId;
2356
+ maxPresences;
2357
+ maxVideoChannelUsers;
2332
2358
  constructor(data) {
2333
2359
  super(data.id);
2334
2360
  if (!data.name)
@@ -2350,14 +2376,22 @@ class Guild extends BaseStructure {
2350
2376
  this.vanityUrlCode = data.vanity_url_code ?? null;
2351
2377
  this.nsfwLevel = data.nsfw_level ?? 0;
2352
2378
  this.discoverySplash = data.discovery_splash ?? null;
2353
- const d = data;
2354
- this.rulesChannelId = d.rules_channel_id ?? null;
2355
- this.systemChannelId = d.system_channel_id ?? null;
2356
- this.systemChannelFlags = d.system_channel_flags ?? 0;
2357
- this.maxMembers = d.max_members ?? 0;
2358
- this.mfaLevel = d.mfa_level ?? 0;
2359
- this.explicitContentFilter = d.explicit_content_filter ?? 0;
2360
- this.defaultMessageNotifications = d.default_message_notifications ?? 0;
2379
+ this.rulesChannelId = data.rules_channel_id ?? null;
2380
+ this.systemChannelId = data.system_channel_id ?? null;
2381
+ this.systemChannelFlags = data.system_channel_flags ?? 0;
2382
+ this.maxMembers = data.max_members ?? 0;
2383
+ this.mfaLevel = data.mfa_level ?? 0;
2384
+ this.explicitContentFilter = data.explicit_content_filter ?? 0;
2385
+ this.defaultMessageNotifications = data.default_message_notifications ?? 0;
2386
+ this.afkChannelId = data.afk_channel_id ?? null;
2387
+ this.afkTimeout = data.afk_timeout;
2388
+ this.widgetEnabled = data.widget_enabled ?? false;
2389
+ this.widgetChannelId = data.widget_channel_id ?? null;
2390
+ this.applicationId = data.application_id ?? null;
2391
+ this.publicUpdatesChannelId = data.public_updates_channel_id ?? null;
2392
+ this.safetyAlertsChannelId = data.safety_alerts_channel_id ?? null;
2393
+ this.maxPresences = data.max_presences ?? null;
2394
+ this.maxVideoChannelUsers = data.max_video_channel_users;
2361
2395
  }
2362
2396
  iconURL(options = {}) {
2363
2397
  if (!this.icon)
@@ -2752,6 +2786,13 @@ var OptionType = {
2752
2786
  class CommandOptions {
2753
2787
  #options;
2754
2788
  #resolved;
2789
+ #lookup(kind, id) {
2790
+ const group = this.#resolved?.[kind];
2791
+ if (typeof group !== "object" || group === null)
2792
+ return;
2793
+ const entry = group[id];
2794
+ return typeof entry === "object" && entry !== null ? entry : undefined;
2795
+ }
2755
2796
  constructor(options, resolved = {}) {
2756
2797
  let currentOptions = options;
2757
2798
  let group = null;
@@ -2840,7 +2881,7 @@ class CommandOptions {
2840
2881
  return null;
2841
2882
  }
2842
2883
  const userId = String(opt.value);
2843
- const resolved = this.#resolved?.users?.[userId] ?? null;
2884
+ const resolved = this.#lookup("users", userId) ?? null;
2844
2885
  if (!resolved && required)
2845
2886
  throw new TypeError(`Resolved user for option "${name}" is missing.`);
2846
2887
  return resolved;
@@ -2853,7 +2894,7 @@ class CommandOptions {
2853
2894
  return null;
2854
2895
  }
2855
2896
  const channelId = String(opt.value);
2856
- const resolved = this.#resolved?.channels?.[channelId] ?? null;
2897
+ const resolved = this.#lookup("channels", channelId) ?? null;
2857
2898
  if (!resolved && required)
2858
2899
  throw new TypeError(`Resolved channel for option "${name}" is missing.`);
2859
2900
  return resolved;
@@ -2866,7 +2907,7 @@ class CommandOptions {
2866
2907
  return null;
2867
2908
  }
2868
2909
  const roleId = String(opt.value);
2869
- const resolved = this.#resolved?.roles?.[roleId] ?? null;
2910
+ const resolved = this.#lookup("roles", roleId) ?? null;
2870
2911
  if (!resolved && required)
2871
2912
  throw new TypeError(`Resolved role for option "${name}" is missing.`);
2872
2913
  return resolved;
@@ -2879,7 +2920,7 @@ class CommandOptions {
2879
2920
  return null;
2880
2921
  }
2881
2922
  const id = String(opt.value);
2882
- const resolved = this.#resolved?.users?.[id] ?? this.#resolved?.roles?.[id] ?? null;
2923
+ const resolved = this.#lookup("users", id) ?? this.#lookup("roles", id) ?? null;
2883
2924
  if (!resolved && required)
2884
2925
  throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
2885
2926
  return resolved;
@@ -2889,9 +2930,9 @@ class CommandOptions {
2889
2930
  if (!opt || opt.type !== OptionType.Mentionable)
2890
2931
  return null;
2891
2932
  const id = String(opt.value);
2892
- if (this.#resolved?.users?.[id])
2933
+ if (this.#lookup("users", id))
2893
2934
  return "user";
2894
- if (this.#resolved?.roles?.[id])
2935
+ if (this.#lookup("roles", id))
2895
2936
  return "role";
2896
2937
  return null;
2897
2938
  }
@@ -2903,7 +2944,7 @@ class CommandOptions {
2903
2944
  return null;
2904
2945
  }
2905
2946
  const attachmentId = String(opt.value);
2906
- const resolved = this.#resolved?.attachments?.[attachmentId] ?? null;
2947
+ const resolved = this.#lookup("attachments", attachmentId) ?? null;
2907
2948
  if (!resolved && required)
2908
2949
  throw new TypeError(`Resolved attachment for option "${name}" is missing.`);
2909
2950
  return resolved;
@@ -2913,7 +2954,7 @@ class CommandOptions {
2913
2954
  }
2914
2955
  }
2915
2956
  // packages/structures/src/interactions.ts
2916
- var InteractionType = {
2957
+ var InteractionEnum = {
2917
2958
  Ping: 1,
2918
2959
  ApplicationCommand: 2,
2919
2960
  MessageComponent: 3,
@@ -2921,8 +2962,17 @@ var InteractionType = {
2921
2962
  ModalSubmit: 5
2922
2963
  };
2923
2964
  var EPHEMERAL = 64;
2965
+ var COMMAND_CHAT_INPUT = 1;
2966
+ var COMMAND_USER = 2;
2967
+ var COMMAND_MESSAGE = 3;
2924
2968
  var TOKEN_LIFETIME_MS = 15 * 60000;
2925
2969
  var DISCORD_EPOCH = 1420070400000n;
2970
+ function splitWithResponse(options) {
2971
+ if (typeof options === "string")
2972
+ return { withResponse: false, rest: options };
2973
+ const { withResponse, ...rest } = options;
2974
+ return { withResponse: withResponse === true, rest };
2975
+ }
2926
2976
  function toMessageData(options) {
2927
2977
  if (typeof options === "string")
2928
2978
  return { content: options };
@@ -2935,6 +2985,7 @@ function toMessageData(options) {
2935
2985
  class InteractionResponse {
2936
2986
  type;
2937
2987
  data;
2988
+ withResponse = false;
2938
2989
  constructor(type, data) {
2939
2990
  if (!Number.isFinite(type))
2940
2991
  throw new TypeError("Interaction response type must be finite.");
@@ -2945,13 +2996,13 @@ class InteractionResponse {
2945
2996
  return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
2946
2997
  }
2947
2998
  static message(options) {
2948
- return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
2999
+ return new InteractionResponse(InteractionResponseEnum.ChannelMessage, toMessageData(options));
2949
3000
  }
2950
3001
  static defer(ephemeral = false) {
2951
- return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
3002
+ return new InteractionResponse(InteractionResponseEnum.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
2952
3003
  }
2953
3004
  static pong() {
2954
- return new InteractionResponse(InteractionResponseType.Pong);
3005
+ return new InteractionResponse(InteractionResponseEnum.Pong);
2955
3006
  }
2956
3007
  }
2957
3008
 
@@ -2979,8 +3030,30 @@ class Interaction {
2979
3030
  this.type = data.type;
2980
3031
  this.data = data;
2981
3032
  }
3033
+ #commandType() {
3034
+ if (this.type !== InteractionEnum.ApplicationCommand)
3035
+ return 0;
3036
+ const type = this.data.data?.type;
3037
+ return typeof type === "number" ? type : COMMAND_CHAT_INPUT;
3038
+ }
3039
+ isCommand() {
3040
+ return this.type === InteractionEnum.ApplicationCommand;
3041
+ }
2982
3042
  isChatInputCommand() {
2983
- return this.type === InteractionType.ApplicationCommand;
3043
+ return this.#commandType() === COMMAND_CHAT_INPUT;
3044
+ }
3045
+ isContextMenuCommand() {
3046
+ const type = this.#commandType();
3047
+ return type === COMMAND_USER || type === COMMAND_MESSAGE;
3048
+ }
3049
+ isUserContextMenuCommand() {
3050
+ return this.#commandType() === COMMAND_USER;
3051
+ }
3052
+ isMessageContextMenuCommand() {
3053
+ return this.#commandType() === COMMAND_MESSAGE;
3054
+ }
3055
+ get resourceContext() {
3056
+ return this.#client.resourceContext;
2984
3057
  }
2985
3058
  awaitModalSubmit(options) {
2986
3059
  const collect = this.#client.resourceContext?.collectInteractions;
@@ -2997,13 +3070,13 @@ class Interaction {
2997
3070
  return collector.next();
2998
3071
  }
2999
3072
  isMessageComponent() {
3000
- return this.type === InteractionType.MessageComponent;
3073
+ return this.type === InteractionEnum.MessageComponent;
3001
3074
  }
3002
3075
  isModalSubmit() {
3003
- return this.type === InteractionType.ModalSubmit;
3076
+ return this.type === InteractionEnum.ModalSubmit;
3004
3077
  }
3005
3078
  isAutocomplete() {
3006
- return this.type === InteractionType.ApplicationCommandAutocomplete;
3079
+ return this.type === InteractionEnum.ApplicationCommandAutocomplete;
3007
3080
  }
3008
3081
  #componentType() {
3009
3082
  return this.isMessageComponent() ? this.data.data?.component_type ?? 0 : 0;
@@ -3088,12 +3161,24 @@ class Interaction {
3088
3161
  postResponse(response) {
3089
3162
  return this.#client.postInteractionResponse(this.id, this.token, response);
3090
3163
  }
3164
+ async acknowledgeWith(response, state, withResponse) {
3165
+ response.withResponse = withResponse;
3166
+ const result = await this.acknowledge(response, state);
3167
+ if (!withResponse)
3168
+ return result;
3169
+ const message = result?.resource?.message;
3170
+ return message ? new Message(message, this.#client.resourceContext) : null;
3171
+ }
3091
3172
  async reply(options) {
3092
- return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
3173
+ const { withResponse, rest } = splitWithResponse(options);
3174
+ return this.acknowledgeWith(InteractionResponse.message(toMessageData(rest)), "replied", withResponse);
3093
3175
  }
3094
3176
  async deferReply(options = false) {
3095
3177
  const ephemeral = typeof options === "boolean" ? options : options.ephemeral === true;
3096
- await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
3178
+ const withResponse = typeof options === "object" && options.withResponse === true;
3179
+ const result = await this.acknowledgeWith(InteractionResponse.defer(ephemeral), "deferred", withResponse);
3180
+ if (withResponse)
3181
+ return result;
3097
3182
  }
3098
3183
  editReply(options) {
3099
3184
  this.assertAcknowledged();
@@ -3107,11 +3192,12 @@ class Interaction {
3107
3192
  return this.#client.followUpInteraction(this.token, toMessageData(options));
3108
3193
  }
3109
3194
  async update(options) {
3110
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
3195
+ const { withResponse, rest } = splitWithResponse(options);
3196
+ return this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.MessageUpdate, toMessageData(rest)), "replied", withResponse);
3111
3197
  }
3112
3198
  async showModal(modal) {
3113
3199
  const data = "toJSON" in modal && typeof modal.toJSON === "function" ? modal.toJSON() : modal;
3114
- return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, data), "replied");
3200
+ return this.acknowledge(new InteractionResponse(InteractionResponseEnum.Modal, data), "replied");
3115
3201
  }
3116
3202
  }
3117
3203
 
@@ -3128,33 +3214,69 @@ class CommandInteraction extends Interaction {
3128
3214
  }
3129
3215
  }
3130
3216
 
3217
+ class ContextMenuCommandInteraction extends CommandInteraction {
3218
+ #resolved() {
3219
+ return this.data.data?.resolved ?? {};
3220
+ }
3221
+ get targetId() {
3222
+ const id = this.data.data?.target_id;
3223
+ return typeof id === "string" ? id : null;
3224
+ }
3225
+ get targetUser() {
3226
+ const id = this.targetId;
3227
+ const raw = id ? this.#resolved().users?.[id] : undefined;
3228
+ return raw ? new User(raw) : null;
3229
+ }
3230
+ get targetMember() {
3231
+ const id = this.targetId;
3232
+ const raw = id ? this.#resolved().members?.[id] : undefined;
3233
+ const user = id ? this.#resolved().users?.[id] : undefined;
3234
+ if (!raw || !user || !this.guildId)
3235
+ return null;
3236
+ return new GuildMember({
3237
+ ...raw,
3238
+ user,
3239
+ guild_id: this.guildId
3240
+ }, this.resourceContext);
3241
+ }
3242
+ get targetMessage() {
3243
+ const id = this.targetId;
3244
+ const raw = id ? this.#resolved().messages?.[id] : undefined;
3245
+ return raw ? new Message(raw, this.resourceContext) : null;
3246
+ }
3247
+ }
3248
+
3131
3249
  class ComponentInteraction extends Interaction {
3132
3250
  get customId() {
3133
- return this.data?.data?.custom_id ?? "";
3251
+ const id = this.data.data?.custom_id;
3252
+ return typeof id === "string" ? id : "";
3134
3253
  }
3135
3254
  get messageId() {
3136
- return this.data?.message?.id;
3255
+ return this.data.message?.id;
3137
3256
  }
3138
3257
  get componentType() {
3139
- return this.data?.data?.component_type ?? 0;
3258
+ const type = this.data.data?.component_type;
3259
+ return typeof type === "number" ? type : 0;
3140
3260
  }
3141
3261
  get values() {
3142
- return this.data?.data?.values ?? [];
3143
- }
3144
- async deferUpdate() {
3145
- await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
3262
+ const values = this.data.data?.values;
3263
+ return Array.isArray(values) ? values : [];
3146
3264
  }
3147
- async update(options) {
3148
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
3265
+ async deferUpdate(options = {}) {
3266
+ const withResponse = options.withResponse === true;
3267
+ const result = await this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.DeferredMessageUpdate), "deferred", withResponse);
3268
+ if (withResponse)
3269
+ return result;
3149
3270
  }
3150
3271
  }
3151
3272
 
3152
3273
  class ModalSubmitInteraction extends Interaction {
3153
3274
  get customId() {
3154
- return this.data?.data?.custom_id ?? "";
3275
+ const id = this.data.data?.custom_id;
3276
+ return typeof id === "string" ? id : "";
3155
3277
  }
3156
3278
  getInputValue(customId) {
3157
- const rows = this.data?.data?.components ?? [];
3279
+ const rows = this.data.data?.components ?? [];
3158
3280
  for (const row of rows) {
3159
3281
  for (const comp of row.components ?? []) {
3160
3282
  if (comp.custom_id === customId)
@@ -3178,16 +3300,17 @@ class AutocompleteInteraction extends Interaction {
3178
3300
  this.options = new CommandOptions(data.data?.options ?? []);
3179
3301
  }
3180
3302
  get commandName() {
3181
- return this.data?.data?.name ?? "";
3303
+ const name = this.data.data?.name;
3304
+ return typeof name === "string" ? name : "";
3182
3305
  }
3183
3306
  get focusedOption() {
3184
- const options = this.data?.data?.options ?? [];
3185
- return findFocused(options);
3307
+ const options = this.data.data?.options;
3308
+ return findFocused(Array.isArray(options) ? options : []);
3186
3309
  }
3187
3310
  async respond(choices) {
3188
3311
  if (!Array.isArray(choices))
3189
3312
  throw new TypeError("Autocomplete choices must be an array.");
3190
- const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
3313
+ const response = new InteractionResponse(InteractionResponseEnum.Autocomplete, { choices });
3191
3314
  await this.acknowledge(response, "replied");
3192
3315
  }
3193
3316
  }
@@ -3205,13 +3328,15 @@ function findFocused(options) {
3205
3328
  }
3206
3329
  function createInteraction(client, data) {
3207
3330
  switch (data.type) {
3208
- case InteractionType.ApplicationCommand:
3209
- return new CommandInteraction(client, data);
3210
- case InteractionType.ApplicationCommandAutocomplete:
3331
+ case InteractionEnum.ApplicationCommand: {
3332
+ const commandType = data.data?.type;
3333
+ return commandType === COMMAND_USER || commandType === COMMAND_MESSAGE ? new ContextMenuCommandInteraction(client, data) : new CommandInteraction(client, data);
3334
+ }
3335
+ case InteractionEnum.ApplicationCommandAutocomplete:
3211
3336
  return new AutocompleteInteraction(client, data);
3212
- case InteractionType.MessageComponent:
3337
+ case InteractionEnum.MessageComponent:
3213
3338
  return new ComponentInteraction(client, data);
3214
- case InteractionType.ModalSubmit:
3339
+ case InteractionEnum.ModalSubmit:
3215
3340
  return new ModalSubmitInteraction(client, data);
3216
3341
  default:
3217
3342
  return new Interaction(client, data);
@@ -3240,6 +3365,9 @@ class Message extends BaseStructure {
3240
3365
  reference;
3241
3366
  components;
3242
3367
  referencedMessage;
3368
+ stickers;
3369
+ poll;
3370
+ messageSnapshots;
3243
3371
  member;
3244
3372
  #context;
3245
3373
  constructor(data, context) {
@@ -3261,6 +3389,13 @@ class Message extends BaseStructure {
3261
3389
  this.mentionEveryone = data.mention_everyone ?? false;
3262
3390
  this.type = data.type ?? 0;
3263
3391
  this.reference = data.message_reference;
3392
+ this.stickers = data.sticker_items ?? (data.stickers ?? []).map(({ id, name, format_type }) => ({
3393
+ id,
3394
+ name,
3395
+ format_type
3396
+ }));
3397
+ this.poll = data.poll ?? null;
3398
+ this.messageSnapshots = data.message_snapshots ?? [];
3264
3399
  this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
3265
3400
  this.#context = context;
3266
3401
  this.member = data.member && data.guild_id ? new GuildMember({
@@ -3287,10 +3422,10 @@ class Message extends BaseStructure {
3287
3422
  update(options) {
3288
3423
  return this.edit(options);
3289
3424
  }
3290
- delete() {
3425
+ delete(reason) {
3291
3426
  if (!this.#context)
3292
3427
  throw new Error("This message is not attached to a client.");
3293
- return this.#context.deleteMessage(this.channelId, this.id);
3428
+ return this.#context.deleteMessage(this.channelId, this.id, reason);
3294
3429
  }
3295
3430
  reply(options) {
3296
3431
  if (!this.#context)
@@ -3337,15 +3472,15 @@ class Message extends BaseStructure {
3337
3472
  throw new Error("This message is not attached to a client.");
3338
3473
  return this.#context.removeAllReactions(this.channelId, this.id);
3339
3474
  }
3340
- pin() {
3475
+ pin(reason) {
3341
3476
  if (!this.#context?.pinMessage)
3342
3477
  throw new Error("This message is not attached to a client.");
3343
- return this.#context.pinMessage(this.channelId, this.id);
3478
+ return this.#context.pinMessage(this.channelId, this.id, reason);
3344
3479
  }
3345
- unpin() {
3480
+ unpin(reason) {
3346
3481
  if (!this.#context?.unpinMessage)
3347
3482
  throw new Error("This message is not attached to a client.");
3348
- return this.#context.unpinMessage(this.channelId, this.id);
3483
+ return this.#context.unpinMessage(this.channelId, this.id, reason);
3349
3484
  }
3350
3485
  get isEphemeral() {
3351
3486
  return (this.flags & 64) !== 0;
@@ -3395,8 +3530,10 @@ class Message extends BaseStructure {
3395
3530
  }
3396
3531
 
3397
3532
  // packages/managers/src/message.ts
3398
- function toRequest(options) {
3533
+ function toRequest(options, allowedMentions) {
3399
3534
  const { files, ...body } = options;
3535
+ if (allowedMentions !== undefined && body.allowed_mentions === undefined)
3536
+ body.allowed_mentions = allowedMentions;
3400
3537
  if (!files?.length)
3401
3538
  return body;
3402
3539
  return {
@@ -3415,9 +3552,11 @@ class MessageManager {
3415
3552
  #rest;
3416
3553
  #context;
3417
3554
  #channelId;
3418
- constructor(rest, context, channelId, cache) {
3555
+ #allowedMentions;
3556
+ constructor(rest, context, channelId, cache, allowedMentions) {
3419
3557
  if (!channelId)
3420
3558
  throw new TypeError("Channel ID is required.");
3559
+ this.#allowedMentions = allowedMentions;
3421
3560
  this.#rest = rest;
3422
3561
  this.#context = context;
3423
3562
  this.#channelId = channelId;
@@ -3431,7 +3570,7 @@ class MessageManager {
3431
3570
  return this.cache.get(messageId) ?? this.fetch(messageId);
3432
3571
  }
3433
3572
  async send(options) {
3434
- const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options));
3573
+ const data = await this.#rest.post(Routes.channelMessages(this.#channelId), toRequest(options, this.#allowedMentions));
3435
3574
  return this.upsert(data);
3436
3575
  }
3437
3576
  async fetch(messageId) {
@@ -3520,15 +3659,22 @@ class EmojiManager extends Manager {
3520
3659
  return data.map((item) => this.upsert(item));
3521
3660
  }
3522
3661
  async create(options) {
3523
- return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
3662
+ const [payload, reason] = splitReason(options);
3663
+ return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), payload, { reason }));
3524
3664
  }
3525
3665
  async edit(emojiId, options) {
3526
- return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
3666
+ const [payload, reason] = splitReason(options);
3667
+ return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), payload, { reason }));
3527
3668
  }
3528
- async deleteEmoji(emojiId) {
3529
- await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
3669
+ async remove(emojiId, reason) {
3670
+ await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId), {
3671
+ reason
3672
+ });
3530
3673
  this.delete(emojiId);
3531
3674
  }
3675
+ deleteEmoji(emojiId) {
3676
+ return this.remove(emojiId);
3677
+ }
3532
3678
  upsert(data) {
3533
3679
  const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
3534
3680
  return this.#merge(key, new Emoji(data));
@@ -3732,11 +3878,16 @@ class GuildMemberManager extends ResourceManager {
3732
3878
  await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
3733
3879
  this.delete(userId);
3734
3880
  }
3735
- async unban(userId) {
3736
- await this.#rest.delete(Routes.guildBan(this.guildId, userId));
3881
+ async unban(userId, reason) {
3882
+ await this.#rest.delete(Routes.guildBan(this.guildId, userId), {
3883
+ reason
3884
+ });
3737
3885
  }
3738
3886
  async edit(userId, options, reason) {
3739
- const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options, { reason });
3887
+ const [payload, optionsReason] = splitReason(options);
3888
+ const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), payload, {
3889
+ reason: optionsReason ?? reason
3890
+ });
3740
3891
  const member = new GuildMember({ ...data, guild_id: this.guildId }, this.#context());
3741
3892
  this.set(member.user.id, member);
3742
3893
  return member;
@@ -3775,7 +3926,7 @@ class RoleManager extends ResourceManager {
3775
3926
  const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
3776
3927
  ...payload,
3777
3928
  permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
3778
- });
3929
+ }, { reason });
3779
3930
  const role = new Role(data);
3780
3931
  this.set(role.id, role);
3781
3932
  return role;
@@ -3785,15 +3936,28 @@ class RoleManager extends ResourceManager {
3785
3936
  const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
3786
3937
  ...payload,
3787
3938
  permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
3788
- });
3939
+ }, { reason });
3789
3940
  const role = new Role(data);
3790
3941
  this.set(role.id, role);
3791
3942
  return role;
3792
3943
  }
3793
- async deleteRole(roleId) {
3794
- await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
3944
+ async remove(roleId, reason) {
3945
+ await this.#rest.delete(Routes.guildRole(this.guildId, roleId), {
3946
+ reason
3947
+ });
3795
3948
  this.delete(roleId);
3796
3949
  }
3950
+ async setPositions(positions, reason) {
3951
+ const data = await this.#rest.patch(Routes.guildRoles(this.guildId), positions.map(({ id, position }) => ({ id, position })), { reason });
3952
+ return data.map((item) => {
3953
+ const role = new Role(item);
3954
+ this.set(role.id, role);
3955
+ return role;
3956
+ });
3957
+ }
3958
+ deleteRole(roleId) {
3959
+ return this.remove(roleId);
3960
+ }
3797
3961
  }
3798
3962
 
3799
3963
  // packages/managers/src/guild-resources.ts
@@ -3865,13 +4029,15 @@ class GuildScheduledEventManager extends Manager {
3865
4029
  return events.map((event) => this.#store(event));
3866
4030
  }
3867
4031
  async create(options, reason) {
3868
- return this.#store(await this.#rest.post(Routes.guildScheduledEvents(this.guildId), options, { reason }));
4032
+ const [payload, optionsReason] = splitReason(options);
4033
+ return this.#store(await this.#rest.post(Routes.guildScheduledEvents(this.guildId), payload, { reason: optionsReason ?? reason }));
3869
4034
  }
3870
4035
  async edit(eventId, options, reason) {
3871
- return this.#store(await this.#rest.patch(Routes.guildScheduledEvent(this.guildId, eventId), options, { reason }));
4036
+ const [payload, optionsReason] = splitReason(options);
4037
+ return this.#store(await this.#rest.patch(Routes.guildScheduledEvent(this.guildId, eventId), payload, { reason: optionsReason ?? reason }));
3872
4038
  }
3873
- async remove(eventId) {
3874
- await this.#rest.delete(Routes.guildScheduledEvent(this.guildId, eventId));
4039
+ async remove(eventId, reason) {
4040
+ await this.#rest.delete(Routes.guildScheduledEvent(this.guildId, eventId), { reason });
3875
4041
  this.delete(eventId);
3876
4042
  }
3877
4043
  async fetchSubscribers(eventId, options = {}) {
@@ -3902,13 +4068,13 @@ class StageInstanceManager extends Manager {
3902
4068
  privacy_level: options.privacyLevel,
3903
4069
  send_start_notification: options.sendStartNotification,
3904
4070
  guild_scheduled_event_id: options.guildScheduledEventId
3905
- }, { reason }));
4071
+ }, { reason: options.reason ?? reason }));
3906
4072
  }
3907
4073
  async fetch(channelId) {
3908
4074
  return this.#store(await this.#rest.get(Routes.stageInstanceByChannel(channelId)));
3909
4075
  }
3910
4076
  async edit(channelId, options, reason) {
3911
- return this.#store(await this.#rest.patch(Routes.stageInstanceByChannel(channelId), { topic: options.topic, privacy_level: options.privacyLevel }, { reason }));
4077
+ return this.#store(await this.#rest.patch(Routes.stageInstanceByChannel(channelId), { topic: options.topic, privacy_level: options.privacyLevel }, { reason: options.reason ?? reason }));
3912
4078
  }
3913
4079
  async remove(channelId, reason) {
3914
4080
  await this.#rest.delete(Routes.stageInstanceByChannel(channelId), {
@@ -3945,7 +4111,7 @@ class PermissionOverwriteManager {
3945
4111
  type: options.type,
3946
4112
  allow: BigInt(options.allow ?? 0).toString(),
3947
4113
  deny: BigInt(options.deny ?? 0).toString()
3948
- }, { reason });
4114
+ }, { reason: options.reason ?? reason });
3949
4115
  }
3950
4116
  async remove(overwriteId, reason) {
3951
4117
  await this.#rest.delete(Routes.channelPermission(this.channelId, overwriteId), { reason });
@@ -4063,12 +4229,16 @@ class GuildManager extends ResourceManager {
4063
4229
  return this.upsert(new Guild(data));
4064
4230
  }
4065
4231
  async edit(id, options) {
4066
- const data = await this.#rest.patch(Routes.guild(id), options);
4232
+ const [payload, reason] = splitReason(options);
4233
+ const data = await this.#rest.patch(Routes.guild(id), payload, { reason });
4067
4234
  return this.upsert(new Guild(data));
4068
4235
  }
4069
- async deleteGuild(id) {
4236
+ async remove(id) {
4070
4237
  await this.#rest.delete(Routes.guild(id));
4071
4238
  }
4239
+ deleteGuild(id) {
4240
+ return this.remove(id);
4241
+ }
4072
4242
  async fetchPreview(id) {
4073
4243
  return this.#rest.get(Routes.guildPreview(id));
4074
4244
  }
@@ -4112,15 +4282,17 @@ class GuildManager extends ResourceManager {
4112
4282
  return new AutoModerationRule(rule);
4113
4283
  }
4114
4284
  async createAutoModerationRule(guildId, options) {
4115
- const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), options);
4285
+ const [payload, reason] = splitReason(options);
4286
+ const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), payload, { reason });
4116
4287
  return new AutoModerationRule(rule);
4117
4288
  }
4118
4289
  async editAutoModerationRule(guildId, ruleId, options) {
4119
- const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), options);
4290
+ const [payload, reason] = splitReason(options);
4291
+ const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), payload, { reason });
4120
4292
  return new AutoModerationRule(rule);
4121
4293
  }
4122
- async deleteAutoModerationRule(guildId, ruleId) {
4123
- await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId));
4294
+ async deleteAutoModerationRule(guildId, ruleId, reason) {
4295
+ await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId), { reason });
4124
4296
  }
4125
4297
  }
4126
4298
  // packages/managers/src/application.ts
@@ -4174,29 +4346,31 @@ class ChannelManager extends Manager {
4174
4346
  #context;
4175
4347
  #messageManagers = new Map;
4176
4348
  #messageCache;
4349
+ #allowedMentions;
4177
4350
  constructor(rest, options = {}) {
4178
4351
  super();
4179
4352
  this.#rest = rest;
4180
4353
  this.#messageCache = options.messageCache;
4354
+ this.#allowedMentions = options.allowedMentions;
4181
4355
  this.#context = {
4182
4356
  sendMessage: (channelId, options) => this.send(channelId, options),
4183
4357
  editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
4184
- deleteMessage: (channelId, messageId) => this.deleteMessage(channelId, messageId),
4358
+ deleteMessage: (channelId, messageId, reason) => this.deleteMessage(channelId, messageId, reason),
4185
4359
  crosspostMessage: (channelId, messageId) => this.crosspostMessage(channelId, messageId),
4186
4360
  editChannel: (channelId, options) => this.edit(channelId, options),
4187
- deleteChannel: (channelId) => this.deleteChannel(channelId),
4361
+ deleteChannel: (channelId, reason) => this.remove(channelId, reason),
4188
4362
  addReaction: (channelId, messageId, emoji) => this.addReaction(channelId, messageId, emoji),
4189
4363
  removeOwnReaction: (channelId, messageId, emoji) => this.removeOwnReaction(channelId, messageId, emoji),
4190
4364
  removeReaction: (channelId, messageId, emoji, userId) => this.removeReaction(channelId, messageId, emoji, userId),
4191
4365
  removeAllReactions: (channelId, messageId) => this.removeAllReactions(channelId, messageId),
4192
- pinMessage: (channelId, messageId) => this.pinMessage(channelId, messageId),
4193
- unpinMessage: (channelId, messageId) => this.unpinMessage(channelId, messageId)
4366
+ pinMessage: (channelId, messageId, reason) => this.pinMessage(channelId, messageId, reason),
4367
+ unpinMessage: (channelId, messageId, reason) => this.unpinMessage(channelId, messageId, reason)
4194
4368
  };
4195
4369
  }
4196
4370
  messages(channelId) {
4197
4371
  let manager = this.#messageManagers.get(channelId);
4198
4372
  if (!manager) {
4199
- manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
4373
+ manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache, this.#allowedMentions);
4200
4374
  this.#messageManagers.set(channelId, manager);
4201
4375
  }
4202
4376
  return manager;
@@ -4260,15 +4434,20 @@ class ChannelManager extends Manager {
4260
4434
  return this.#messageManagers.get(channelId);
4261
4435
  }
4262
4436
  async create(guildId, options) {
4263
- return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
4437
+ const [payload, reason] = splitReason(options);
4438
+ return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), payload, { reason }));
4264
4439
  }
4265
4440
  async edit(channelId, options) {
4266
- return this.upsert(await this.#rest.patch(Routes.channel(channelId), options));
4441
+ const [payload, reason] = splitReason(options);
4442
+ return this.upsert(await this.#rest.patch(Routes.channel(channelId), payload, { reason }));
4267
4443
  }
4268
- async deleteChannel(channelId) {
4269
- await this.#rest.delete(Routes.channel(channelId));
4444
+ async remove(channelId, reason) {
4445
+ await this.#rest.delete(Routes.channel(channelId), { reason });
4270
4446
  this.delete(channelId);
4271
4447
  }
4448
+ deleteChannel(channelId) {
4449
+ return this.remove(channelId);
4450
+ }
4272
4451
  delete(channelId) {
4273
4452
  this.#messageManagers.delete(channelId);
4274
4453
  return super.delete(channelId);
@@ -4302,10 +4481,12 @@ class ChannelManager extends Manager {
4302
4481
  return this.messages(data.channel_id).upsert(data);
4303
4482
  }
4304
4483
  async editMessage(channelId, messageId, options) {
4305
- return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options)));
4484
+ return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), toRequest(options, this.#allowedMentions)));
4306
4485
  }
4307
- async deleteMessage(channelId, messageId) {
4308
- await this.#rest.delete(Routes.message(channelId, messageId));
4486
+ async deleteMessage(channelId, messageId, reason) {
4487
+ await this.#rest.delete(Routes.message(channelId, messageId), {
4488
+ reason
4489
+ });
4309
4490
  this.messages(channelId).delete(messageId);
4310
4491
  }
4311
4492
  deleteCachedMessage(channelId, messageId) {
@@ -4314,19 +4495,17 @@ class ChannelManager extends Manager {
4314
4495
  async crosspostMessage(channelId, messageId) {
4315
4496
  return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
4316
4497
  }
4317
- async bulkDeleteMessages(channelId, messageIds) {
4498
+ async bulkDeleteMessages(channelId, messageIds, reason) {
4318
4499
  const ids = [...new Set(messageIds)];
4319
4500
  if (ids.length < 1 || ids.length > 100)
4320
4501
  throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
4321
4502
  if (ids.length === 1)
4322
- return this.deleteMessage(channelId, ids[0]);
4503
+ return this.deleteMessage(channelId, ids[0], reason);
4323
4504
  const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
4324
4505
  const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
4325
4506
  if (tooOld.length)
4326
4507
  throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
4327
- await this.#rest.post(Routes.channelBulkDelete(channelId), {
4328
- messages: ids
4329
- });
4508
+ await this.#rest.post(Routes.channelBulkDelete(channelId), { messages: ids }, { reason });
4330
4509
  for (const id of ids)
4331
4510
  this.messages(channelId).delete(id);
4332
4511
  }
@@ -4369,14 +4548,20 @@ class ChannelManager extends Manager {
4369
4548
  await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));
4370
4549
  }
4371
4550
  async fetchPinnedMessages(channelId) {
4372
- const data = await this.#rest.get(Routes.channelPins(channelId));
4373
- return data.map((item) => this.messages(channelId).upsert(item));
4551
+ const data = await this.#rest.get(Routes.channelMessagesPins(channelId));
4552
+ return data.items.map((item) => this.messages(channelId).upsert(item.message));
4374
4553
  }
4375
- async pinMessage(channelId, messageId) {
4376
- await this.#rest.put(Routes.channelPin(channelId, messageId));
4554
+ async pinMessage(channelId, messageId, reason) {
4555
+ await this.#rest.put(Routes.channelMessagesPin(channelId, messageId), undefined, { reason });
4377
4556
  }
4378
- async unpinMessage(channelId, messageId) {
4379
- await this.#rest.delete(Routes.channelPin(channelId, messageId));
4557
+ async unpinMessage(channelId, messageId, reason) {
4558
+ await this.#rest.delete(Routes.channelMessagesPin(channelId, messageId), { reason });
4559
+ }
4560
+ async createWebhook(channelId, options) {
4561
+ const [payload, reason] = splitReason(options);
4562
+ return this.#rest.post(Routes.channelWebhooks(channelId), payload, {
4563
+ reason
4564
+ });
4380
4565
  }
4381
4566
  createThreadFromMessage(channelId, messageId, options) {
4382
4567
  return this.threads(channelId).createFromMessage(messageId, options);
@@ -4394,7 +4579,7 @@ class ChannelManager extends Manager {
4394
4579
  hasMore: messages.length === limit
4395
4580
  };
4396
4581
  }
4397
- async bulkDelete(channelId, messageIds) {
4582
+ bulkDelete(channelId, messageIds) {
4398
4583
  return this.bulkDeleteMessages(channelId, messageIds);
4399
4584
  }
4400
4585
  clear() {
@@ -5339,6 +5524,7 @@ class Gateway {
5339
5524
  #message(raw, token) {
5340
5525
  if (!this.#session.owns(token))
5341
5526
  return;
5527
+ this.#heartbeat.receivedMessage();
5342
5528
  const { sequence, action } = classifyFrame(raw);
5343
5529
  if (sequence !== null)
5344
5530
  this.#session.recordSequence(sequence, token);
@@ -5536,18 +5722,31 @@ class EventEmitter2 {
5536
5722
  return true;
5537
5723
  }
5538
5724
  #handleError(event, error) {
5539
- if (event === "error" /* Error */)
5540
- return;
5541
5725
  const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
5542
- for (const listener of [
5726
+ const listeners = event === "error" /* Error */ ? [] : [
5543
5727
  ...this.#listeners.get("error" /* Error */) ?? []
5544
- ]) {
5728
+ ];
5729
+ if (listeners.length === 0)
5730
+ return warnListenerError(event, normalized);
5731
+ for (const listener of listeners) {
5545
5732
  try {
5546
- listener(normalized);
5547
- } catch {}
5733
+ const result = listener(normalized);
5734
+ if (result && typeof result.then === "function")
5735
+ Promise.resolve(result).catch((failure) => warnListenerError("error" /* Error */, failure));
5736
+ } catch (failure) {
5737
+ warnListenerError("error" /* Error */, failure);
5738
+ }
5548
5739
  }
5549
5740
  }
5550
5741
  }
5742
+ function warnListenerError(event, error) {
5743
+ const failure = error instanceof Error ? error : new Error(String(error));
5744
+ process.emitWarning(`A "${String(event)}" listener threw and no error listener handled it: ${failure.message}`, {
5745
+ type: "LunibeeWarning",
5746
+ code: "LUNIBEE_UNHANDLED_LISTENER_ERROR",
5747
+ detail: failure.stack
5748
+ });
5749
+ }
5551
5750
 
5552
5751
  class Client extends EventEmitter2 {
5553
5752
  options;
@@ -5607,7 +5806,8 @@ class Client extends EventEmitter2 {
5607
5806
  this.users = new UserManager(this.rest);
5608
5807
  this.guilds = new GuildManager(this.rest);
5609
5808
  this.channels = new ChannelManager(this.rest, {
5610
- messageCache: options.messageCache
5809
+ messageCache: options.messageCache,
5810
+ allowedMentions: options.allowedMentions
5611
5811
  });
5612
5812
  this.stageInstances = new StageInstanceManager(this.rest);
5613
5813
  const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
@@ -5615,16 +5815,16 @@ class Client extends EventEmitter2 {
5615
5815
  this.#resourceContext = {
5616
5816
  sendMessage: (channelId, options) => this.channels.send(channelId, options),
5617
5817
  editMessage: (channelId, messageId, options) => this.channels.editMessage(channelId, messageId, options),
5618
- deleteMessage: (channelId, messageId) => this.channels.deleteMessage(channelId, messageId),
5818
+ deleteMessage: (channelId, messageId, reason) => this.channels.deleteMessage(channelId, messageId, reason),
5619
5819
  crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId),
5620
5820
  editChannel: (channelId, options) => this.channels.edit(channelId, options),
5621
- deleteChannel: (channelId) => this.channels.deleteChannel(channelId),
5821
+ deleteChannel: (channelId, reason) => this.channels.remove(channelId, reason),
5622
5822
  addReaction: (channelId, messageId, emoji) => this.channels.addReaction(channelId, messageId, emoji),
5623
5823
  removeOwnReaction: (channelId, messageId, emoji) => this.channels.removeOwnReaction(channelId, messageId, emoji),
5624
5824
  removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
5625
5825
  removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
5626
- pinMessage: (channelId, messageId) => this.channels.pinMessage(channelId, messageId),
5627
- unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId),
5826
+ pinMessage: (channelId, messageId, reason) => this.channels.pinMessage(channelId, messageId, reason),
5827
+ unpinMessage: (channelId, messageId, reason) => this.channels.unpinMessage(channelId, messageId, reason),
5628
5828
  collectInteractions: (options) => this.createCollector("interactionCreate" /* InteractionCreate */, options),
5629
5829
  memberPermissions: (guildId, memberId, roleIds, channelId) => this.#memberPermissions(guildId, memberId, roleIds, channelId),
5630
5830
  kickMember: (guildId, userId, reason) => this.guilds.members(guildId).kick(userId, reason),
@@ -5754,8 +5954,11 @@ class Client extends EventEmitter2 {
5754
5954
  this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
5755
5955
  });
5756
5956
  this.#gateway.on("GUILD_UPDATE", (data) => {
5757
- this.guilds.patch(data);
5758
- this.emit("guildUpdate" /* GuildUpdate */, data);
5957
+ const payload = data;
5958
+ const cached = this.guilds.get(payload.id);
5959
+ const previous = cached ? this.#snapshot(cached) : null;
5960
+ this.guilds.patch(payload);
5961
+ this.emit("guildUpdate" /* GuildUpdate */, payload, previous);
5759
5962
  });
5760
5963
  this.#gateway.on("GUILD_DELETE", (data) => {
5761
5964
  const payload = data;
@@ -5774,8 +5977,10 @@ class Client extends EventEmitter2 {
5774
5977
  });
5775
5978
  this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
5776
5979
  const member = data;
5980
+ const cached = this.#cache.members ? this.guilds.members(member.guild_id).get(member.user.id) : undefined;
5981
+ const previous = cached ? this.#snapshot(cached, new GuildMember({ user: member.user, guild_id: member.guild_id }, this.#resourceContext)) : null;
5777
5982
  this.#upsertMember(member.guild_id, member);
5778
- this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
5983
+ this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member, previous);
5779
5984
  });
5780
5985
  this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
5781
5986
  const member = data;
@@ -5810,18 +6015,24 @@ class Client extends EventEmitter2 {
5810
6015
  });
5811
6016
  this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
5812
6017
  const event = data;
6018
+ const cached = this.#cache.roles ? this.guilds.roles(event.guild_id).get(event.role.id) : undefined;
6019
+ const previous = cached ? this.#snapshot(cached) : null;
5813
6020
  this.#upsertRole(event.guild_id, event.role);
5814
- this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event);
6021
+ this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event, previous);
5815
6022
  });
5816
6023
  this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
5817
6024
  const event = data;
5818
- this.guilds.roles(event.guild_id).delete(event.role_id);
5819
- this.emit("guildRoleDelete" /* GuildRoleDelete */, event);
6025
+ const roles = this.guilds.roles(event.guild_id);
6026
+ const removed = roles.get(event.role_id) ?? null;
6027
+ roles.delete(event.role_id);
6028
+ this.emit("guildRoleDelete" /* GuildRoleDelete */, event, removed);
5820
6029
  });
5821
6030
  this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
5822
6031
  const event = data;
6032
+ let previous = null;
5823
6033
  if (this.#cache.emojis) {
5824
6034
  const emojis = this.guilds.emojis(event.guild_id);
6035
+ previous = [...emojis.cache.values()].map((emoji) => this.#snapshot(emoji));
5825
6036
  const current = new Set(event.emojis.map((emoji) => emoji.id));
5826
6037
  for (const id of [...emojis.cache.keys()])
5827
6038
  if (!current.has(id))
@@ -5829,12 +6040,14 @@ class Client extends EventEmitter2 {
5829
6040
  for (const emoji of event.emojis)
5830
6041
  emojis.upsert(emoji);
5831
6042
  }
5832
- this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event);
6043
+ this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event, previous);
5833
6044
  });
5834
6045
  this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
5835
6046
  const event = data;
5836
- this.guilds.stickers(event.guild_id).sync(event.stickers);
5837
- this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event);
6047
+ const stickers = this.guilds.stickers(event.guild_id);
6048
+ const previous = [...stickers.cache.values()];
6049
+ stickers.sync(event.stickers);
6050
+ this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event, previous);
5838
6051
  });
5839
6052
  this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
5840
6053
  const sound = data;
@@ -5915,13 +6128,15 @@ class Client extends EventEmitter2 {
5915
6128
  this.emit("channelCreate" /* ChannelCreate */, channel);
5916
6129
  });
5917
6130
  this.#gateway.on("CHANNEL_UPDATE", (data) => {
6131
+ const previous = this.#previousChannel(data);
5918
6132
  const channel = this.channels.upsert(data);
5919
- this.emit("channelUpdate" /* ChannelUpdate */, channel);
6133
+ this.emit("channelUpdate" /* ChannelUpdate */, channel, previous);
5920
6134
  });
5921
6135
  this.#gateway.on("CHANNEL_DELETE", (data) => {
5922
6136
  const payload = data;
6137
+ const removed = this.channels.get(payload.id) ?? null;
5923
6138
  this.channels.delete(payload.id);
5924
- this.emit("channelDelete" /* ChannelDelete */, payload);
6139
+ this.emit("channelDelete" /* ChannelDelete */, payload, removed);
5925
6140
  });
5926
6141
  this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
5927
6142
  this.#gateway.on("THREAD_CREATE", (data) => {
@@ -5929,13 +6144,15 @@ class Client extends EventEmitter2 {
5929
6144
  this.emit("threadCreate" /* ThreadCreate */, channel);
5930
6145
  });
5931
6146
  this.#gateway.on("THREAD_UPDATE", (data) => {
6147
+ const previous = this.#previousChannel(data);
5932
6148
  const channel = this.channels.upsert(data);
5933
- this.emit("threadUpdate" /* ThreadUpdate */, channel);
6149
+ this.emit("threadUpdate" /* ThreadUpdate */, channel, previous);
5934
6150
  });
5935
6151
  this.#gateway.on("THREAD_DELETE", (data) => {
5936
6152
  const payload = data;
6153
+ const removed = this.channels.get(payload.id) ?? null;
5937
6154
  this.channels.delete(payload.id);
5938
- this.emit("threadDelete" /* ThreadDelete */, payload);
6155
+ this.emit("threadDelete" /* ThreadDelete */, payload, removed);
5939
6156
  });
5940
6157
  this.#gateway.on("THREAD_LIST_SYNC", (data) => {
5941
6158
  const sync = data;
@@ -6012,6 +6229,15 @@ class Client extends EventEmitter2 {
6012
6229
  return new Role(data);
6013
6230
  return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));
6014
6231
  }
6232
+ #snapshot(cached, blank = Object.create(Object.getPrototypeOf(cached))) {
6233
+ return Object.assign(blank, cached);
6234
+ }
6235
+ #previousChannel(data) {
6236
+ const cached = this.channels.get(data.id);
6237
+ if (!cached)
6238
+ return null;
6239
+ return this.#snapshot(cached, createChannel({ id: cached.id, type: cached.type, guild_id: cached.guildId }, this.#resourceContext));
6240
+ }
6015
6241
  #merge(manager, id, next) {
6016
6242
  const existing = manager.get(id);
6017
6243
  if (!existing) {
@@ -6103,20 +6329,22 @@ class Client extends EventEmitter2 {
6103
6329
  }
6104
6330
  postInteractionResponse(id, token, response) {
6105
6331
  const json = response.toJSON();
6106
- const upload = json.data ? toRequest(json.data) : undefined;
6332
+ const callback = response.withResponse ? `${Routes.interactionCallback(id, token)}?with_response=true` : Routes.interactionCallback(id, token);
6333
+ const carriesMessage = json.type === 4 || json.type === 7;
6334
+ const upload = json.data ? toRequest(json.data, carriesMessage ? this.options.allowedMentions : undefined) : undefined;
6107
6335
  if (upload && typeof upload === "object" && "files" in upload) {
6108
6336
  const { body, files } = upload;
6109
- return this.rest.post(Routes.interactionCallback(id, token), {
6337
+ return this.rest.post(callback, {
6110
6338
  body: { ...json, data: body },
6111
6339
  files
6112
6340
  });
6113
6341
  }
6114
- return this.rest.post(Routes.interactionCallback(id, token), json);
6342
+ return this.rest.post(callback, upload === undefined ? json : { ...json, data: upload });
6115
6343
  }
6116
6344
  editInteractionReply(token, data) {
6117
6345
  if (!this.user)
6118
6346
  return Promise.reject(new Error("Client is unauthenticated."));
6119
- return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data));
6347
+ return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), toRequest(data, this.options.allowedMentions));
6120
6348
  }
6121
6349
  deleteInteractionReply(token) {
6122
6350
  if (!this.user)
@@ -6126,14 +6354,14 @@ class Client extends EventEmitter2 {
6126
6354
  followUpInteraction(token, data) {
6127
6355
  if (!this.user)
6128
6356
  return Promise.reject(new Error("Client is unauthenticated."));
6129
- return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data));
6357
+ return this.rest.post(`/webhooks/${this.user.id}/${token}`, toRequest(data, this.options.allowedMentions));
6130
6358
  }
6131
6359
  interactionWebhookMessage(method, applicationId, token, messageId, data) {
6132
6360
  const path = messageId === "@original" ? Routes.interactionOriginalResponse(applicationId, token) : Routes.webhookMessage(applicationId, token, messageId);
6133
6361
  if (method === "GET")
6134
6362
  return this.rest.get(path);
6135
6363
  if (method === "PATCH")
6136
- return this.rest.patch(path, data);
6364
+ return this.rest.patch(path, data ? toRequest(data, this.options.allowedMentions) : data);
6137
6365
  return this.rest.delete(path);
6138
6366
  }
6139
6367
  fetchWebhook(id, token) {
@@ -6149,8 +6377,6 @@ class Client extends EventEmitter2 {
6149
6377
  const query = new URLSearchParams;
6150
6378
  if (options?.withCounts)
6151
6379
  query.set("with_counts", "true");
6152
- if (options?.withExpiration)
6153
- query.set("with_expiration", "true");
6154
6380
  if (options?.guildScheduledEventId)
6155
6381
  query.set("guild_scheduled_event_id", options.guildScheduledEventId);
6156
6382
  const qs = query.toString();
@@ -6189,6 +6415,7 @@ export {
6189
6415
  IntentsBitField,
6190
6416
  Permission,
6191
6417
  PermissionFlagsBits,
6418
+ PermissionOverwriteEnum,
6192
6419
  PermissionOverwriteType,
6193
6420
  PermissionSet,
6194
6421
  Permissions,
@@ -6197,4 +6424,4 @@ export {
6197
6424
  resolveGatewayIntents
6198
6425
  };
6199
6426
 
6200
- //# debugId=C58DF09843ED07E364756E2164756E21
6427
+ //# debugId=A8C0111D9C7EBB3664756E2164756E21