lunibee 0.2.0 → 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.
Files changed (45) hide show
  1. package/README.md +6 -6
  2. package/dist/builders/attachment.d.ts +5 -1
  3. package/dist/builders/commands.d.ts +131 -45
  4. package/dist/builders/components.d.ts +183 -41
  5. package/dist/builders/embed.d.ts +12 -8
  6. package/dist/builders/index.d.ts +9 -4
  7. package/dist/builders/index.js +234 -110
  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 +5 -3
  11. package/dist/core/index.js +414 -78
  12. package/dist/core/index.js.map +18 -18
  13. package/dist/core/permissions.d.ts +6 -2
  14. package/dist/index.d.ts +5 -4
  15. package/dist/index.js +869 -194
  16. package/dist/index.js.map +25 -24
  17. package/dist/managers/guild-resources.d.ts +22 -2
  18. package/dist/managers/guild.d.ts +3 -1
  19. package/dist/managers/index.d.ts +7 -3
  20. package/dist/managers/index.js +167 -33
  21. package/dist/managers/index.js.map +13 -13
  22. package/dist/managers/member.d.ts +13 -12
  23. package/dist/managers/message.d.ts +16 -4
  24. package/dist/rest/index.js +2 -2
  25. package/dist/rest/index.js.map +1 -1
  26. package/dist/sharding/index.js +3 -2
  27. package/dist/sharding/index.js.map +4 -4
  28. package/dist/structures/base.d.ts +36 -0
  29. package/dist/structures/index.d.ts +38 -3
  30. package/dist/structures/index.js +240 -34
  31. package/dist/structures/index.js.map +11 -11
  32. package/dist/structures/interactions.d.ts +110 -12
  33. package/dist/structures/options.d.ts +2 -0
  34. package/dist/structures/resources.d.ts +40 -4
  35. package/dist/types/gateway.d.ts +14 -0
  36. package/dist/types/index.d.ts +185 -10
  37. package/dist/types/index.js +37 -10
  38. package/dist/types/index.js.map +4 -4
  39. package/dist/utils/args.d.ts +79 -0
  40. package/dist/utils/index.d.ts +1 -0
  41. package/dist/utils/index.js +190 -2
  42. package/dist/utils/index.js.map +5 -4
  43. package/dist/ws/index.js +2 -1
  44. package/dist/ws/index.js.map +4 -4
  45. package/package.json +14 -14
@@ -1,8 +1,16 @@
1
1
  /** Resource structures for Discord messages and related entities. */
2
2
  import { BaseStructure, Channel, User } from "./base.js";
3
+ import { GuildMember } from "./resources.js";
4
+ import type { ComponentInteraction } from "./interactions.js";
5
+ import type { Collector, CollectorOptions } from "@lunibee/core";
6
+ /** Options for {@link Message.createComponentCollector}. */
7
+ export interface ComponentCollectorOptions extends CollectorOptions<ComponentInteraction> {
8
+ /** Only this component type (2 button, 3 string select...). */
9
+ componentType?: number;
10
+ }
3
11
  import type { ResourceContext } from "./base.js";
4
- export { BaseStructure, Channel, Guild, User } from "./base.js";
5
- export type { ResourceContext } from "./base.js";
12
+ export { BaseStructure, Channel, Guild, User, CDN_BASE, cdnURL, } from "./base.js";
13
+ export type { ResourceContext, ImageURLOptions } from "./base.js";
6
14
  export declare class Message extends BaseStructure {
7
15
  #private;
8
16
  content: string;
@@ -23,6 +31,18 @@ export declare class Message extends BaseStructure {
23
31
  readonly reference?: import("@lunibee/types").APIMessageReference;
24
32
  readonly components: import("@lunibee/types").APIMessageComponent[];
25
33
  readonly referencedMessage?: Message | null;
34
+ /** Stickers sent with the message (`sticker_items`). */
35
+ readonly stickers: import("@lunibee/types").APIStickerItem[];
36
+ /** The poll, when the message is one. */
37
+ readonly poll: import("@lunibee/types").APIPoll | null;
38
+ /** For a forwarded message, the snapshot of the original. */
39
+ readonly messageSnapshots: import("@lunibee/types").APIMessageSnapshot[];
40
+ /**
41
+ * The author as a guild member, on guild messages from the Gateway. Its
42
+ * `permissions` are computed from the cached roles; `member.kick()` and the
43
+ * other member actions work when the message came from a client.
44
+ */
45
+ member: GuildMember | null;
26
46
  /** Creates a message structure from Discord message data. */
27
47
  constructor(data: import("@lunibee/types").APIMessage, context?: ResourceContext);
28
48
  /** Whether embeds are suppressed on this message. */
@@ -49,6 +69,21 @@ export declare class Message extends BaseStructure {
49
69
  })): Promise<Message>;
50
70
  /** Crossposts this message. @returns The resulting message. @throws {Error} If the message is not attached to a client. */
51
71
  crosspost(): Promise<Message>;
72
+ /**
73
+ * Collects clicks and picks on this message's components. It always ends:
74
+ * after `time`, or 15 minutes (an interaction token's life) when neither
75
+ * `time` nor `idle` is set.
76
+ * @example
77
+ * const collector = message.createComponentCollector({ filter: (i) => i.user?.id === authorId, time: 60_000 });
78
+ * collector.on("collect", (i) => i.update({ content: `Picked ${i.customId}` }));
79
+ */
80
+ createComponentCollector(options?: ComponentCollectorOptions): Collector<string, ComponentInteraction>;
81
+ /**
82
+ * Waits for the next click or pick on this message's components.
83
+ * @param options `time` (default 15 minutes), `filter`, `componentType`.
84
+ * @returns The interaction. @throws {Error} When time runs out first.
85
+ */
86
+ awaitComponent(options?: Omit<ComponentCollectorOptions, "max">): Promise<ComponentInteraction>;
52
87
  /** Adds a reaction to this message. @param emoji Emoji identifier. @returns A promise fulfilled when the reaction is added. @throws {Error} If reactions are unavailable. */
53
88
  react(emoji: string): Promise<void>;
54
89
  /** Removes a reaction from this message. @param emoji Emoji identifier. @param userId User whose reaction should be removed; omit to remove the current user's reaction. @returns A promise fulfilled when the reaction is removed. @throws {Error} If reaction operations are unavailable. */
@@ -80,7 +115,7 @@ export declare class Message extends BaseStructure {
80
115
  /** Returns a plain-object snapshot of all message fields. */
81
116
  toJSON(): Record<string, unknown>;
82
117
  }
83
- export { GuildMember, Role, TextChannel, Invite, Webhook, WebhookType, Emoji, AutoModerationRule, WelcomeScreenChannel, GuildWelcomeScreen, OnboardingPromptOption, OnboardingPrompt, GuildOnboarding, } from "./resources.js";
118
+ export { GuildMember, Role, TextChannel, Invite, Webhook, WebhookEnum, WebhookType, Emoji, AutoModerationRule, WelcomeScreenChannel, GuildWelcomeScreen, OnboardingPromptOption, OnboardingPrompt, GuildOnboarding, } from "./resources.js";
84
119
  export { NewsChannel, DMChannel, VoiceChannel, StageChannel, CategoryChannel, ThreadChannel, ForumChannel, MediaChannel, createChannel, } from "./channels.js";
85
120
  export * from "./interactions.js";
86
121
  export { Embed } from "./embed.js";
@@ -109,6 +109,11 @@ class Channel extends BaseStructure {
109
109
  editTopic(topic) {
110
110
  return this.edit({ topic });
111
111
  }
112
+ editPermissionOverwrite(targetId, changes, options) {
113
+ if (!this.#context?.editPermissionOverwrite)
114
+ throw new Error("This channel is not attached to a client.");
115
+ return this.#context.editPermissionOverwrite(this.id, targetId, changes, options);
116
+ }
112
117
  editParent(parentId) {
113
118
  return this.edit({ parent_id: parentId });
114
119
  }
@@ -243,6 +248,7 @@ class Guild extends BaseStructure {
243
248
  return this.name;
244
249
  }
245
250
  }
251
+
246
252
  // packages/core/src/permissions.ts
247
253
  var Permission = {
248
254
  createInstantInvite: 1n << 0n,
@@ -635,6 +641,11 @@ class PermissionSet {
635
641
  toArray() {
636
642
  return Object.keys(Permission).filter((permission) => this.has(permission));
637
643
  }
644
+ static #renamed = {
645
+ ManageEmojisAndStickers: "ManageGuildExpressions",
646
+ ManageEmojis: "ManageGuildExpressions",
647
+ UseSlashCommands: "UseApplicationCommands"
648
+ };
638
649
  #resolve(permission) {
639
650
  if (typeof permission === "bigint")
640
651
  return permission;
@@ -649,6 +660,9 @@ class PermissionSet {
649
660
  return bit;
650
661
  }
651
662
  if (typeof permission === "string") {
663
+ const renamed = PermissionSet.#renamed[permission];
664
+ if (renamed)
665
+ return this.#resolve(renamed);
652
666
  if (permission in Permission)
653
667
  return Permission[permission];
654
668
  if (permission in Permissions)
@@ -725,7 +739,7 @@ var IntentBits = {
725
739
  directMessagePolls: 1 << 25
726
740
  };
727
741
  // packages/types/src/index.ts
728
- var InteractionResponseType = {
742
+ var InteractionResponseEnum = {
729
743
  Pong: 1,
730
744
  ChannelMessage: 4,
731
745
  DeferredChannelMessage: 5,
@@ -734,10 +748,11 @@ var InteractionResponseType = {
734
748
  Autocomplete: 8,
735
749
  Modal: 9
736
750
  };
751
+ var InteractionResponseType = InteractionResponseEnum;
737
752
  // packages/rest/package.json
738
753
  var package_default = {
739
754
  name: "@lunibee/rest",
740
- version: "0.2.0",
755
+ version: "0.2.2",
741
756
  type: "module",
742
757
  module: "./src/index.ts",
743
758
  types: "./src/index.ts",
@@ -808,13 +823,15 @@ class GuildMember {
808
823
  roleIds;
809
824
  pending;
810
825
  joinedAt;
811
- permissions;
812
826
  avatarHash;
813
827
  premiumSince;
814
828
  timedOutUntil;
815
829
  flags;
816
- constructor(data) {
830
+ #suppliedPermissions;
831
+ #context;
832
+ constructor(data, context) {
817
833
  this.user = new User(data.user);
834
+ this.#context = context;
818
835
  if (!/^\d{1,20}$/.test(data.guild_id))
819
836
  throw new TypeError("Member guild_id must be a valid snowflake.");
820
837
  this.guildId = data.guild_id;
@@ -824,12 +841,53 @@ class GuildMember {
824
841
  this.joinedAt = data.joined_at ? new Date(data.joined_at) : undefined;
825
842
  if (this.joinedAt?.toString() === "Invalid Date")
826
843
  throw new RangeError("Member joined_at must be a valid date.");
827
- this.permissions = new PermissionsBitField(data.permissions ?? 0n);
844
+ if (data.permissions !== undefined)
845
+ this.#suppliedPermissions = new PermissionsBitField(data.permissions);
828
846
  this.avatarHash = data.avatar ?? null;
829
847
  this.premiumSince = toDateOrNull(data.premium_since);
830
848
  this.timedOutUntil = toDateOrNull(data.communication_disabled_until);
831
849
  this.flags = data.flags ?? 0;
832
850
  }
851
+ get permissions() {
852
+ if (this.#suppliedPermissions)
853
+ return this.#suppliedPermissions;
854
+ return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds) ?? 0n);
855
+ }
856
+ permissionsIn(channelId) {
857
+ const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId);
858
+ return computed ? new PermissionsBitField(computed) : null;
859
+ }
860
+ #action(name) {
861
+ const action = this.#context?.[name];
862
+ if (!action)
863
+ throw new Error("This member is not attached to a client.");
864
+ return action;
865
+ }
866
+ kick(reason) {
867
+ return this.#action("kickMember")(this.guildId, this.user.id, reason);
868
+ }
869
+ ban(options = {}) {
870
+ return this.#action("banMember")(this.guildId, this.user.id, options);
871
+ }
872
+ edit(options, reason) {
873
+ return this.#action("editMember")(this.guildId, this.user.id, options, reason);
874
+ }
875
+ timeout(milliseconds, reason) {
876
+ if (milliseconds !== null && !(milliseconds > 0))
877
+ throw new RangeError("Timeout length must be a positive number of milliseconds.");
878
+ return this.edit({
879
+ communication_disabled_until: milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString()
880
+ }, reason);
881
+ }
882
+ setNickname(nickname, reason) {
883
+ return this.edit({ nick: nickname }, reason);
884
+ }
885
+ addRole(roleId, reason) {
886
+ return this.#action("addMemberRole")(this.guildId, this.user.id, roleId, reason);
887
+ }
888
+ removeRole(roleId, reason) {
889
+ return this.#action("removeMemberRole")(this.guildId, this.user.id, roleId, reason);
890
+ }
833
891
  get displayName() {
834
892
  return this.nickname ?? this.user.displayName;
835
893
  }
@@ -932,7 +990,7 @@ class Invite {
932
990
  return this.url;
933
991
  }
934
992
  }
935
- var WebhookType = {
993
+ var WebhookEnum = {
936
994
  Incoming: 1,
937
995
  ChannelFollower: 2,
938
996
  Application: 3
@@ -948,7 +1006,7 @@ class Webhook extends BaseStructure {
948
1006
  token;
949
1007
  constructor(data) {
950
1008
  super(data.id);
951
- this.type = data.type ?? WebhookType.Incoming;
1009
+ this.type = data.type ?? WebhookEnum.Incoming;
952
1010
  this.name = data.name ?? null;
953
1011
  this.avatarHash = data.avatar ?? null;
954
1012
  this.channelId = data.channel_id ?? null;
@@ -1113,6 +1171,7 @@ class GuildOnboarding2 extends BaseStructure {
1113
1171
  this.mode = data.mode;
1114
1172
  }
1115
1173
  }
1174
+ var WebhookType = WebhookEnum;
1116
1175
  // packages/structures/src/channels.ts
1117
1176
  class NewsChannel extends TextChannel {
1118
1177
  }
@@ -1363,6 +1422,17 @@ class CommandOptions {
1363
1422
  throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
1364
1423
  return resolved;
1365
1424
  }
1425
+ getMentionableType(name) {
1426
+ const opt = this.#get(name);
1427
+ if (!opt || opt.type !== OptionType.Mentionable)
1428
+ return null;
1429
+ const id = String(opt.value);
1430
+ if (this.#resolved?.users?.[id])
1431
+ return "user";
1432
+ if (this.#resolved?.roles?.[id])
1433
+ return "role";
1434
+ return null;
1435
+ }
1366
1436
  getAttachment(name, required = false) {
1367
1437
  const opt = this.#get(name);
1368
1438
  if (!opt || opt.type !== OptionType.Attachment) {
@@ -1381,7 +1451,7 @@ class CommandOptions {
1381
1451
  }
1382
1452
  }
1383
1453
  // packages/structures/src/interactions.ts
1384
- var InteractionType = {
1454
+ var InteractionEnum = {
1385
1455
  Ping: 1,
1386
1456
  ApplicationCommand: 2,
1387
1457
  MessageComponent: 3,
@@ -1389,8 +1459,17 @@ var InteractionType = {
1389
1459
  ModalSubmit: 5
1390
1460
  };
1391
1461
  var EPHEMERAL = 64;
1462
+ var COMMAND_CHAT_INPUT = 1;
1463
+ var COMMAND_USER = 2;
1464
+ var COMMAND_MESSAGE = 3;
1392
1465
  var TOKEN_LIFETIME_MS = 15 * 60000;
1393
1466
  var DISCORD_EPOCH = 1420070400000n;
1467
+ function splitWithResponse(options) {
1468
+ if (typeof options === "string")
1469
+ return { withResponse: false, rest: options };
1470
+ const { withResponse, ...rest } = options;
1471
+ return { withResponse: withResponse === true, rest };
1472
+ }
1394
1473
  function toMessageData(options) {
1395
1474
  if (typeof options === "string")
1396
1475
  return { content: options };
@@ -1403,6 +1482,7 @@ function toMessageData(options) {
1403
1482
  class InteractionResponse {
1404
1483
  type;
1405
1484
  data;
1485
+ withResponse = false;
1406
1486
  constructor(type, data) {
1407
1487
  if (!Number.isFinite(type))
1408
1488
  throw new TypeError("Interaction response type must be finite.");
@@ -1413,13 +1493,13 @@ class InteractionResponse {
1413
1493
  return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
1414
1494
  }
1415
1495
  static message(options) {
1416
- return new InteractionResponse(InteractionResponseType.ChannelMessage, toMessageData(options));
1496
+ return new InteractionResponse(InteractionResponseEnum.ChannelMessage, toMessageData(options));
1417
1497
  }
1418
1498
  static defer(ephemeral = false) {
1419
- return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
1499
+ return new InteractionResponse(InteractionResponseEnum.DeferredChannelMessage, ephemeral ? { flags: EPHEMERAL } : undefined);
1420
1500
  }
1421
1501
  static pong() {
1422
- return new InteractionResponse(InteractionResponseType.Pong);
1502
+ return new InteractionResponse(InteractionResponseEnum.Pong);
1423
1503
  }
1424
1504
  }
1425
1505
 
@@ -1447,17 +1527,53 @@ class Interaction {
1447
1527
  this.type = data.type;
1448
1528
  this.data = data;
1449
1529
  }
1530
+ #commandType() {
1531
+ if (this.type !== InteractionEnum.ApplicationCommand)
1532
+ return 0;
1533
+ const type = this.data.data?.type;
1534
+ return typeof type === "number" ? type : COMMAND_CHAT_INPUT;
1535
+ }
1536
+ isCommand() {
1537
+ return this.type === InteractionEnum.ApplicationCommand;
1538
+ }
1450
1539
  isChatInputCommand() {
1451
- return this.type === InteractionType.ApplicationCommand;
1540
+ return this.#commandType() === COMMAND_CHAT_INPUT;
1541
+ }
1542
+ isContextMenuCommand() {
1543
+ const type = this.#commandType();
1544
+ return type === COMMAND_USER || type === COMMAND_MESSAGE;
1545
+ }
1546
+ isUserContextMenuCommand() {
1547
+ return this.#commandType() === COMMAND_USER;
1548
+ }
1549
+ isMessageContextMenuCommand() {
1550
+ return this.#commandType() === COMMAND_MESSAGE;
1551
+ }
1552
+ get resourceContext() {
1553
+ return this.#client.resourceContext;
1554
+ }
1555
+ awaitModalSubmit(options) {
1556
+ const collect = this.#client.resourceContext?.collectInteractions;
1557
+ if (!collect)
1558
+ return Promise.reject(new Error("This interaction is not attached to a client."));
1559
+ if (!(options.time > 0))
1560
+ return Promise.reject(new RangeError("awaitModalSubmit needs a positive time."));
1561
+ const userId = this.user?.id;
1562
+ const collector = collect({
1563
+ time: options.time,
1564
+ max: 1,
1565
+ filter: async (interaction) => interaction.isModalSubmit() && interaction.user?.id === userId && (options.customId === undefined || interaction.customId === options.customId) && (options.filter ? await options.filter(interaction) : true)
1566
+ });
1567
+ return collector.next();
1452
1568
  }
1453
1569
  isMessageComponent() {
1454
- return this.type === InteractionType.MessageComponent;
1570
+ return this.type === InteractionEnum.MessageComponent;
1455
1571
  }
1456
1572
  isModalSubmit() {
1457
- return this.type === InteractionType.ModalSubmit;
1573
+ return this.type === InteractionEnum.ModalSubmit;
1458
1574
  }
1459
1575
  isAutocomplete() {
1460
- return this.type === InteractionType.ApplicationCommandAutocomplete;
1576
+ return this.type === InteractionEnum.ApplicationCommandAutocomplete;
1461
1577
  }
1462
1578
  #componentType() {
1463
1579
  return this.isMessageComponent() ? this.data.data?.component_type ?? 0 : 0;
@@ -1509,7 +1625,7 @@ class Interaction {
1509
1625
  return new GuildMember({
1510
1626
  ...raw,
1511
1627
  guild_id: this.guildId
1512
- });
1628
+ }, this.#client.resourceContext);
1513
1629
  }
1514
1630
  get createdTimestamp() {
1515
1631
  return Number((BigInt(this.id) >> 22n) + DISCORD_EPOCH);
@@ -1542,11 +1658,24 @@ class Interaction {
1542
1658
  postResponse(response) {
1543
1659
  return this.#client.postInteractionResponse(this.id, this.token, response);
1544
1660
  }
1545
- async reply(options) {
1546
- return this.acknowledge(InteractionResponse.message(toMessageData(options)), "replied");
1661
+ async acknowledgeWith(response, state, withResponse) {
1662
+ response.withResponse = withResponse;
1663
+ const result = await this.acknowledge(response, state);
1664
+ if (!withResponse)
1665
+ return result;
1666
+ const message = result?.resource?.message;
1667
+ return message ? new Message(message, this.#client.resourceContext) : null;
1547
1668
  }
1548
- async deferReply(ephemeral = false) {
1549
- await this.acknowledge(InteractionResponse.defer(ephemeral), "deferred");
1669
+ async reply(options) {
1670
+ const { withResponse, rest } = splitWithResponse(options);
1671
+ return this.acknowledgeWith(InteractionResponse.message(toMessageData(rest)), "replied", withResponse);
1672
+ }
1673
+ async deferReply(options = false) {
1674
+ const ephemeral = typeof options === "boolean" ? options : options.ephemeral === true;
1675
+ const withResponse = typeof options === "object" && options.withResponse === true;
1676
+ const result = await this.acknowledgeWith(InteractionResponse.defer(ephemeral), "deferred", withResponse);
1677
+ if (withResponse)
1678
+ return result;
1550
1679
  }
1551
1680
  editReply(options) {
1552
1681
  this.assertAcknowledged();
@@ -1560,10 +1689,12 @@ class Interaction {
1560
1689
  return this.#client.followUpInteraction(this.token, toMessageData(options));
1561
1690
  }
1562
1691
  async update(options) {
1563
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
1692
+ const { withResponse, rest } = splitWithResponse(options);
1693
+ return this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.MessageUpdate, toMessageData(rest)), "replied", withResponse);
1564
1694
  }
1565
1695
  async showModal(modal) {
1566
- return this.acknowledge(new InteractionResponse(InteractionResponseType.Modal, modal), "replied");
1696
+ const data = "toJSON" in modal && typeof modal.toJSON === "function" ? modal.toJSON() : modal;
1697
+ return this.acknowledge(new InteractionResponse(InteractionResponseEnum.Modal, data), "replied");
1567
1698
  }
1568
1699
  }
1569
1700
 
@@ -1580,21 +1711,56 @@ class CommandInteraction extends Interaction {
1580
1711
  }
1581
1712
  }
1582
1713
 
1714
+ class ContextMenuCommandInteraction extends CommandInteraction {
1715
+ #resolved() {
1716
+ return this.data.data?.resolved ?? {};
1717
+ }
1718
+ get targetId() {
1719
+ const id = this.data.data?.target_id;
1720
+ return typeof id === "string" ? id : null;
1721
+ }
1722
+ get targetUser() {
1723
+ const id = this.targetId;
1724
+ const raw = id ? this.#resolved().users?.[id] : undefined;
1725
+ return raw ? new User(raw) : null;
1726
+ }
1727
+ get targetMember() {
1728
+ const id = this.targetId;
1729
+ const raw = id ? this.#resolved().members?.[id] : undefined;
1730
+ const user = id ? this.#resolved().users?.[id] : undefined;
1731
+ if (!raw || !user || !this.guildId)
1732
+ return null;
1733
+ return new GuildMember({
1734
+ ...raw,
1735
+ user,
1736
+ guild_id: this.guildId
1737
+ }, this.resourceContext);
1738
+ }
1739
+ get targetMessage() {
1740
+ const id = this.targetId;
1741
+ const raw = id ? this.#resolved().messages?.[id] : undefined;
1742
+ return raw ? new Message(raw, this.resourceContext) : null;
1743
+ }
1744
+ }
1745
+
1583
1746
  class ComponentInteraction extends Interaction {
1584
1747
  get customId() {
1585
1748
  return this.data?.data?.custom_id ?? "";
1586
1749
  }
1750
+ get messageId() {
1751
+ return this.data?.message?.id;
1752
+ }
1587
1753
  get componentType() {
1588
1754
  return this.data?.data?.component_type ?? 0;
1589
1755
  }
1590
1756
  get values() {
1591
1757
  return this.data?.data?.values ?? [];
1592
1758
  }
1593
- async deferUpdate() {
1594
- await this.acknowledge(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate), "deferred");
1595
- }
1596
- async update(options) {
1597
- return this.acknowledge(new InteractionResponse(InteractionResponseType.MessageUpdate, toMessageData(options)), "replied");
1759
+ async deferUpdate(options = {}) {
1760
+ const withResponse = options.withResponse === true;
1761
+ const result = await this.acknowledgeWith(new InteractionResponse(InteractionResponseEnum.DeferredMessageUpdate), "deferred", withResponse);
1762
+ if (withResponse)
1763
+ return result;
1598
1764
  }
1599
1765
  }
1600
1766
 
@@ -1636,7 +1802,7 @@ class AutocompleteInteraction extends Interaction {
1636
1802
  async respond(choices) {
1637
1803
  if (!Array.isArray(choices))
1638
1804
  throw new TypeError("Autocomplete choices must be an array.");
1639
- const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
1805
+ const response = new InteractionResponse(InteractionResponseEnum.Autocomplete, { choices });
1640
1806
  await this.acknowledge(response, "replied");
1641
1807
  }
1642
1808
  }
@@ -1654,18 +1820,21 @@ function findFocused(options) {
1654
1820
  }
1655
1821
  function createInteraction(client, data) {
1656
1822
  switch (data.type) {
1657
- case InteractionType.ApplicationCommand:
1658
- return new CommandInteraction(client, data);
1659
- case InteractionType.ApplicationCommandAutocomplete:
1823
+ case InteractionEnum.ApplicationCommand: {
1824
+ const commandType = data.data?.type;
1825
+ return commandType === COMMAND_USER || commandType === COMMAND_MESSAGE ? new ContextMenuCommandInteraction(client, data) : new CommandInteraction(client, data);
1826
+ }
1827
+ case InteractionEnum.ApplicationCommandAutocomplete:
1660
1828
  return new AutocompleteInteraction(client, data);
1661
- case InteractionType.MessageComponent:
1829
+ case InteractionEnum.MessageComponent:
1662
1830
  return new ComponentInteraction(client, data);
1663
- case InteractionType.ModalSubmit:
1831
+ case InteractionEnum.ModalSubmit:
1664
1832
  return new ModalSubmitInteraction(client, data);
1665
1833
  default:
1666
1834
  return new Interaction(client, data);
1667
1835
  }
1668
1836
  }
1837
+ var InteractionType = InteractionEnum;
1669
1838
  // packages/structures/src/embed.ts
1670
1839
  class Embed {
1671
1840
  #data;
@@ -1834,6 +2003,7 @@ class AuditLog {
1834
2003
  }
1835
2004
 
1836
2005
  // packages/structures/src/index.ts
2006
+ var COMPONENT_COLLECTOR_DEFAULT_TIME = 15 * 60000;
1837
2007
  var NON_SYSTEM_MESSAGE_TYPES = new Set([0, 19, 20, 23]);
1838
2008
 
1839
2009
  class Message extends BaseStructure {
@@ -1854,6 +2024,10 @@ class Message extends BaseStructure {
1854
2024
  reference;
1855
2025
  components;
1856
2026
  referencedMessage;
2027
+ stickers;
2028
+ poll;
2029
+ messageSnapshots;
2030
+ member;
1857
2031
  #context;
1858
2032
  constructor(data, context) {
1859
2033
  super(data.id);
@@ -1874,8 +2048,20 @@ class Message extends BaseStructure {
1874
2048
  this.mentionEveryone = data.mention_everyone ?? false;
1875
2049
  this.type = data.type ?? 0;
1876
2050
  this.reference = data.message_reference;
2051
+ this.stickers = data.sticker_items ?? (data.stickers ?? []).map(({ id, name, format_type }) => ({
2052
+ id,
2053
+ name,
2054
+ format_type
2055
+ }));
2056
+ this.poll = data.poll ?? null;
2057
+ this.messageSnapshots = data.message_snapshots ?? [];
1877
2058
  this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
1878
2059
  this.#context = context;
2060
+ this.member = data.member && data.guild_id ? new GuildMember({
2061
+ ...data.member,
2062
+ user: data.member.user ?? data.author,
2063
+ guild_id: data.guild_id
2064
+ }, context) : null;
1879
2065
  this.channel = new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context);
1880
2066
  }
1881
2067
  get embedsSuppressed() {
@@ -1916,6 +2102,20 @@ class Message extends BaseStructure {
1916
2102
  throw new Error("This message is not attached to a client.");
1917
2103
  return this.#context.crosspostMessage(this.channelId, this.id);
1918
2104
  }
2105
+ createComponentCollector(options = {}) {
2106
+ const collect = this.#context?.collectInteractions;
2107
+ if (!collect)
2108
+ throw new Error("This message is not attached to a client.");
2109
+ const { componentType, filter, ...rest } = options;
2110
+ return collect({
2111
+ ...rest,
2112
+ time: rest.time ?? (rest.idle ? undefined : COMPONENT_COLLECTOR_DEFAULT_TIME),
2113
+ filter: async (interaction) => interaction.isMessageComponent() && interaction.messageId === this.id && (componentType === undefined || interaction.componentType === componentType) && (filter ? await filter(interaction) : true)
2114
+ });
2115
+ }
2116
+ awaitComponent(options = {}) {
2117
+ return this.createComponentCollector({ ...options, max: 1 }).next();
2118
+ }
1919
2119
  react(emoji) {
1920
2120
  if (!this.#context?.addReaction)
1921
2121
  throw new Error("This message is not attached to a client.");
@@ -1993,11 +2193,13 @@ export {
1993
2193
  AutoModerationRule,
1994
2194
  AutocompleteInteraction,
1995
2195
  BaseStructure,
2196
+ CDN_BASE,
1996
2197
  CategoryChannel,
1997
2198
  Channel,
1998
2199
  CommandInteraction,
1999
2200
  CommandOptions,
2000
2201
  ComponentInteraction,
2202
+ ContextMenuCommandInteraction,
2001
2203
  DMChannel,
2002
2204
  Embed,
2003
2205
  Emoji,
@@ -2007,7 +2209,9 @@ export {
2007
2209
  GuildOnboarding2 as GuildOnboarding,
2008
2210
  GuildWelcomeScreen2 as GuildWelcomeScreen,
2009
2211
  Interaction,
2212
+ InteractionEnum,
2010
2213
  InteractionResponse,
2214
+ InteractionResponseEnum,
2011
2215
  InteractionResponseType,
2012
2216
  InteractionType,
2013
2217
  Invite,
@@ -2025,10 +2229,12 @@ export {
2025
2229
  User,
2026
2230
  VoiceChannel,
2027
2231
  Webhook,
2232
+ WebhookEnum,
2028
2233
  WebhookType,
2029
2234
  WelcomeScreenChannel,
2235
+ cdnURL,
2030
2236
  createChannel,
2031
2237
  createInteraction
2032
2238
  };
2033
2239
 
2034
- //# debugId=39460C3E91D6CD3564756E2164756E21
2240
+ //# debugId=1DD80FEE9EB768DF64756E2164756E21