lunibee 0.1.5 → 0.1.7

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 (60) hide show
  1. package/README.md +13 -24
  2. package/dist/builders/commands.d.ts +37 -0
  3. package/dist/builders/components.d.ts +127 -12
  4. package/dist/builders/embed.d.ts +3 -1
  5. package/dist/builders/index.d.ts +2 -2
  6. package/dist/builders/index.js +319 -16
  7. package/dist/builders/index.js.map +8 -7
  8. package/dist/collection/index.d.ts +36 -0
  9. package/dist/collection/index.js +110 -6
  10. package/dist/collection/index.js.map +4 -4
  11. package/dist/core/events.d.ts +69 -3
  12. package/dist/core/index.d.ts +158 -90
  13. package/dist/core/index.js +1543 -1169
  14. package/dist/core/index.js.map +24 -23
  15. package/dist/core/permissions.d.ts +112 -53
  16. package/dist/formatters/index.d.ts +43 -3
  17. package/dist/formatters/index.js +64 -1
  18. package/dist/formatters/index.js.map +3 -3
  19. package/dist/handlers/index.js.map +2 -2
  20. package/dist/index.d.ts +5 -4
  21. package/dist/index.js +3882 -1588
  22. package/dist/index.js.map +43 -35
  23. package/dist/managers/emoji.d.ts +38 -0
  24. package/dist/managers/guild.d.ts +141 -0
  25. package/dist/managers/index.d.ts +86 -75
  26. package/dist/managers/index.js +1084 -67
  27. package/dist/managers/index.js.map +21 -16
  28. package/dist/managers/message.d.ts +7 -12
  29. package/dist/managers/user.d.ts +20 -0
  30. package/dist/rest/index.d.ts +173 -1
  31. package/dist/rest/index.js +343 -47
  32. package/dist/rest/index.js.map +8 -6
  33. package/dist/rest/redis.d.ts +37 -0
  34. package/dist/rest/routes.d.ts +26 -1
  35. package/dist/rest/store.d.ts +38 -0
  36. package/dist/rest/webhook.d.ts +2 -2
  37. package/dist/sharding/cluster.d.ts +61 -0
  38. package/dist/sharding/index.d.ts +8 -0
  39. package/dist/sharding/index.js +289 -18
  40. package/dist/sharding/index.js.map +8 -7
  41. package/dist/structures/audit-log.d.ts +26 -0
  42. package/dist/structures/base.d.ts +131 -48
  43. package/dist/structures/embed.d.ts +65 -0
  44. package/dist/structures/index.d.ts +74 -26
  45. package/dist/structures/index.js +1528 -59
  46. package/dist/structures/index.js.map +14 -8
  47. package/dist/structures/interactions.d.ts +72 -17
  48. package/dist/structures/resources.d.ts +199 -7
  49. package/dist/types/index.d.ts +605 -84
  50. package/dist/types/index.js +71 -1
  51. package/dist/types/index.js.map +3 -3
  52. package/dist/utils/index.js.map +2 -2
  53. package/dist/voice/index.d.ts +88 -0
  54. package/dist/voice/index.js +204 -5
  55. package/dist/voice/index.js.map +3 -3
  56. package/dist/ws/index.d.ts +40 -1
  57. package/dist/ws/index.js +105 -18
  58. package/dist/ws/index.js.map +4 -4
  59. package/package.json +16 -16
  60. package/dist/structures/permissions.d.ts +0 -73
@@ -107,58 +107,57 @@ var Permissions = {
107
107
  SendPolls: 1n << 49n,
108
108
  UseExternalApps: 1n << 50n
109
109
  };
110
- var PermissionFlagsBits;
111
- ((PermissionFlagsBits2) => {
112
- PermissionFlagsBits2["CreateInstantInvite"] = "1";
113
- PermissionFlagsBits2["KickMembers"] = "2";
114
- PermissionFlagsBits2["BanMembers"] = "4";
115
- PermissionFlagsBits2["Administrator"] = "8";
116
- PermissionFlagsBits2["ManageChannels"] = "16";
117
- PermissionFlagsBits2["ManageGuild"] = "32";
118
- PermissionFlagsBits2["AddReactions"] = "64";
119
- PermissionFlagsBits2["ViewAuditLog"] = "128";
120
- PermissionFlagsBits2["PrioritySpeaker"] = "256";
121
- PermissionFlagsBits2["Stream"] = "512";
122
- PermissionFlagsBits2["ViewChannel"] = "1024";
123
- PermissionFlagsBits2["SendMessages"] = "2048";
124
- PermissionFlagsBits2["SendTTSMessages"] = "4096";
125
- PermissionFlagsBits2["ManageMessages"] = "8192";
126
- PermissionFlagsBits2["EmbedLinks"] = "16384";
127
- PermissionFlagsBits2["AttachFiles"] = "32768";
128
- PermissionFlagsBits2["ReadMessageHistory"] = "65536";
129
- PermissionFlagsBits2["MentionEveryone"] = "131072";
130
- PermissionFlagsBits2["UseExternalEmojis"] = "262144";
131
- PermissionFlagsBits2["ViewGuildInsights"] = "524288";
132
- PermissionFlagsBits2["Connect"] = "1048576";
133
- PermissionFlagsBits2["Speak"] = "2097152";
134
- PermissionFlagsBits2["MuteMembers"] = "4194304";
135
- PermissionFlagsBits2["DeafenMembers"] = "8388608";
136
- PermissionFlagsBits2["MoveMembers"] = "16777216";
137
- PermissionFlagsBits2["UseVAD"] = "33554432";
138
- PermissionFlagsBits2["ChangeNickname"] = "67108864";
139
- PermissionFlagsBits2["ManageNicknames"] = "134217728";
140
- PermissionFlagsBits2["ManageRoles"] = "268435456";
141
- PermissionFlagsBits2["ManageWebhooks"] = "536870912";
142
- PermissionFlagsBits2["ManageGuildExpressions"] = "1073741824";
143
- PermissionFlagsBits2["UseApplicationCommands"] = "2147483648";
144
- PermissionFlagsBits2["RequestToSpeak"] = "4294967296";
145
- PermissionFlagsBits2["ManageEvents"] = "8589934592";
146
- PermissionFlagsBits2["ManageThreads"] = "17179869184";
147
- PermissionFlagsBits2["CreatePublicThreads"] = "34359738368";
148
- PermissionFlagsBits2["CreatePrivateThreads"] = "68719476736";
149
- PermissionFlagsBits2["UseExternalStickers"] = "137438953472";
150
- PermissionFlagsBits2["SendMessagesInThreads"] = "274877906944";
151
- PermissionFlagsBits2["UseEmbeddedActivities"] = "549755813888";
152
- PermissionFlagsBits2["ModerateMembers"] = "1099511627776";
153
- PermissionFlagsBits2["ViewCreatorMonetizationAnalytics"] = "2199023255552";
154
- PermissionFlagsBits2["UseSoundboard"] = "4398046511104";
155
- PermissionFlagsBits2["CreateGuildExpressions"] = "8796093022208";
156
- PermissionFlagsBits2["CreateEvents"] = "17592186044416";
157
- PermissionFlagsBits2["UseExternalSounds"] = "35184372088832";
158
- PermissionFlagsBits2["SendVoiceMessages"] = "70368744177664";
159
- PermissionFlagsBits2["SendPolls"] = "562949953421312";
160
- PermissionFlagsBits2["UseExternalApps"] = "1125899906842624";
161
- })(PermissionFlagsBits ||= {});
110
+ var PermissionFlagsBits = {
111
+ CreateInstantInvite: 1n << 0n,
112
+ KickMembers: 1n << 1n,
113
+ BanMembers: 1n << 2n,
114
+ Administrator: 1n << 3n,
115
+ ManageChannels: 1n << 4n,
116
+ ManageGuild: 1n << 5n,
117
+ AddReactions: 1n << 6n,
118
+ ViewAuditLog: 1n << 7n,
119
+ PrioritySpeaker: 1n << 8n,
120
+ Stream: 1n << 9n,
121
+ ViewChannel: 1n << 10n,
122
+ SendMessages: 1n << 11n,
123
+ SendTTSMessages: 1n << 12n,
124
+ ManageMessages: 1n << 13n,
125
+ EmbedLinks: 1n << 14n,
126
+ AttachFiles: 1n << 15n,
127
+ ReadMessageHistory: 1n << 16n,
128
+ MentionEveryone: 1n << 17n,
129
+ UseExternalEmojis: 1n << 18n,
130
+ ViewGuildInsights: 1n << 19n,
131
+ Connect: 1n << 20n,
132
+ Speak: 1n << 21n,
133
+ MuteMembers: 1n << 22n,
134
+ DeafenMembers: 1n << 23n,
135
+ MoveMembers: 1n << 24n,
136
+ UseVAD: 1n << 25n,
137
+ ChangeNickname: 1n << 26n,
138
+ ManageNicknames: 1n << 27n,
139
+ ManageRoles: 1n << 28n,
140
+ ManageWebhooks: 1n << 29n,
141
+ ManageGuildExpressions: 1n << 30n,
142
+ UseApplicationCommands: 1n << 31n,
143
+ RequestToSpeak: 1n << 32n,
144
+ ManageEvents: 1n << 33n,
145
+ ManageThreads: 1n << 34n,
146
+ CreatePublicThreads: 1n << 35n,
147
+ CreatePrivateThreads: 1n << 36n,
148
+ UseExternalStickers: 1n << 37n,
149
+ SendMessagesInThreads: 1n << 38n,
150
+ UseEmbeddedActivities: 1n << 39n,
151
+ ModerateMembers: 1n << 40n,
152
+ ViewCreatorMonetizationAnalytics: 1n << 41n,
153
+ UseSoundboard: 1n << 42n,
154
+ CreateGuildExpressions: 1n << 43n,
155
+ CreateEvents: 1n << 44n,
156
+ UseExternalSounds: 1n << 45n,
157
+ SendVoiceMessages: 1n << 46n,
158
+ SendPolls: 1n << 49n,
159
+ UseExternalApps: 1n << 50n
160
+ };
162
161
 
163
162
  class PermissionSet {
164
163
  bitfield;
@@ -403,7 +402,7 @@ class PermissionSet {
403
402
  if (permission in Permissions)
404
403
  return Permissions[permission];
405
404
  if (permission in PermissionFlagsBits)
406
- return BigInt(PermissionFlagsBits[permission]);
405
+ return PermissionFlagsBits[permission];
407
406
  const lower = permission.charAt(0).toLowerCase() + permission.slice(1);
408
407
  if (lower in Permission)
409
408
  return Permission[lower];
@@ -420,6 +419,228 @@ class PermissionsBitField extends PermissionSet {
420
419
  super(value);
421
420
  }
422
421
  }
422
+ // packages/core/src/events.ts
423
+ var ClientEvent;
424
+ ((ClientEvent2) => {
425
+ ClientEvent2["Ready"] = "ready";
426
+ ClientEvent2["Resumed"] = "resumed";
427
+ ClientEvent2["InvalidSession"] = "invalidSession";
428
+ ClientEvent2["Raw"] = "raw";
429
+ ClientEvent2["Error"] = "error";
430
+ ClientEvent2["Open"] = "open";
431
+ ClientEvent2["Close"] = "close";
432
+ ClientEvent2["MessageCreate"] = "messageCreate";
433
+ ClientEvent2["MessageUpdate"] = "messageUpdate";
434
+ ClientEvent2["MessageDelete"] = "messageDelete";
435
+ ClientEvent2["MessageDeleteBulk"] = "messageDeleteBulk";
436
+ ClientEvent2["MessageReactionAdd"] = "messageReactionAdd";
437
+ ClientEvent2["MessageReactionRemove"] = "messageReactionRemove";
438
+ ClientEvent2["MessageReactionRemoveAll"] = "messageReactionRemoveAll";
439
+ ClientEvent2["MessageReactionRemoveEmoji"] = "messageReactionRemoveEmoji";
440
+ ClientEvent2["MessagePollVoteAdd"] = "messagePollVoteAdd";
441
+ ClientEvent2["MessagePollVoteRemove"] = "messagePollVoteRemove";
442
+ ClientEvent2["GuildCreate"] = "guildCreate";
443
+ ClientEvent2["GuildUpdate"] = "guildUpdate";
444
+ ClientEvent2["GuildDelete"] = "guildDelete";
445
+ ClientEvent2["GuildAvailable"] = "guildAvailable";
446
+ ClientEvent2["GuildUnavailable"] = "guildUnavailable";
447
+ ClientEvent2["GuildMemberAdd"] = "guildMemberAdd";
448
+ ClientEvent2["GuildMemberUpdate"] = "guildMemberUpdate";
449
+ ClientEvent2["GuildMemberRemove"] = "guildMemberRemove";
450
+ ClientEvent2["GuildMembersChunk"] = "guildMembersChunk";
451
+ ClientEvent2["GuildBanAdd"] = "guildBanAdd";
452
+ ClientEvent2["GuildBanRemove"] = "guildBanRemove";
453
+ ClientEvent2["GuildRoleCreate"] = "guildRoleCreate";
454
+ ClientEvent2["GuildRoleUpdate"] = "guildRoleUpdate";
455
+ ClientEvent2["GuildRoleDelete"] = "guildRoleDelete";
456
+ ClientEvent2["GuildEmojisUpdate"] = "guildEmojisUpdate";
457
+ ClientEvent2["GuildStickersUpdate"] = "guildStickersUpdate";
458
+ ClientEvent2["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
459
+ ClientEvent2["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
460
+ ClientEvent2["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
461
+ ClientEvent2["GuildScheduledEventDelete"] = "guildScheduledEventDelete";
462
+ ClientEvent2["GuildScheduledEventUserAdd"] = "guildScheduledEventUserAdd";
463
+ ClientEvent2["GuildScheduledEventUserRemove"] = "guildScheduledEventUserRemove";
464
+ ClientEvent2["AutoModerationRuleCreate"] = "autoModerationRuleCreate";
465
+ ClientEvent2["AutoModerationRuleUpdate"] = "autoModerationRuleUpdate";
466
+ ClientEvent2["AutoModerationRuleDelete"] = "autoModerationRuleDelete";
467
+ ClientEvent2["AutoModerationActionExecution"] = "autoModerationActionExecution";
468
+ ClientEvent2["ChannelCreate"] = "channelCreate";
469
+ ClientEvent2["ChannelUpdate"] = "channelUpdate";
470
+ ClientEvent2["ChannelDelete"] = "channelDelete";
471
+ ClientEvent2["ChannelPinsUpdate"] = "channelPinsUpdate";
472
+ ClientEvent2["ThreadCreate"] = "threadCreate";
473
+ ClientEvent2["ThreadUpdate"] = "threadUpdate";
474
+ ClientEvent2["ThreadDelete"] = "threadDelete";
475
+ ClientEvent2["ThreadListSync"] = "threadListSync";
476
+ ClientEvent2["ThreadMembersUpdate"] = "threadMembersUpdate";
477
+ ClientEvent2["ThreadMemberUpdate"] = "threadMemberUpdate";
478
+ ClientEvent2["StageInstanceCreate"] = "stageInstanceCreate";
479
+ ClientEvent2["StageInstanceUpdate"] = "stageInstanceUpdate";
480
+ ClientEvent2["StageInstanceDelete"] = "stageInstanceDelete";
481
+ ClientEvent2["InviteCreate"] = "inviteCreate";
482
+ ClientEvent2["InviteDelete"] = "inviteDelete";
483
+ ClientEvent2["WebhooksUpdate"] = "webhooksUpdate";
484
+ ClientEvent2["VoiceStateUpdate"] = "voiceStateUpdate";
485
+ ClientEvent2["VoiceServerUpdate"] = "voiceServerUpdate";
486
+ ClientEvent2["PresenceUpdate"] = "presenceUpdate";
487
+ ClientEvent2["TypingStart"] = "typingStart";
488
+ ClientEvent2["InteractionCreate"] = "interactionCreate";
489
+ })(ClientEvent ||= {});
490
+ // packages/core/src/collector.ts
491
+ import { EventEmitter } from "events";
492
+
493
+ class Collector extends EventEmitter {
494
+ collected = new Map;
495
+ options;
496
+ ended = false;
497
+ endReason;
498
+ totalProcessed = 0;
499
+ #timeoutTimer;
500
+ constructor(options = {}) {
501
+ super();
502
+ this.options = options;
503
+ if (options.time && options.time > 0) {
504
+ this.#timeoutTimer = setTimeout(() => {
505
+ this.stop("time");
506
+ }, options.time);
507
+ }
508
+ }
509
+ async handle(key, item) {
510
+ if (this.ended)
511
+ return false;
512
+ this.totalProcessed++;
513
+ const reachedProcessed = !!this.options.maxProcessed && this.totalProcessed >= this.options.maxProcessed;
514
+ let passed = true;
515
+ if (this.options.filter)
516
+ passed = !!await this.options.filter(item);
517
+ if (this.ended)
518
+ return false;
519
+ if (!passed) {
520
+ if (reachedProcessed)
521
+ this.stop("processedLimit");
522
+ return false;
523
+ }
524
+ this.collected.set(key, item);
525
+ this.emit("collect", item);
526
+ if (this.options.max && this.collected.size >= this.options.max) {
527
+ this.stop("limit");
528
+ return true;
529
+ }
530
+ if (reachedProcessed) {
531
+ this.stop("processedLimit");
532
+ return true;
533
+ }
534
+ return true;
535
+ }
536
+ stop(reason = "user") {
537
+ if (this.ended)
538
+ return;
539
+ this.ended = true;
540
+ this.endReason = reason;
541
+ if (this.#timeoutTimer)
542
+ clearTimeout(this.#timeoutTimer);
543
+ this.emit("end", this.collected, reason);
544
+ this.removeAllListeners();
545
+ }
546
+ next() {
547
+ return new Promise((resolve, reject) => {
548
+ if (this.ended) {
549
+ return reject(new Error(`Collector already ended: ${this.endReason ?? "unknown"}`));
550
+ }
551
+ this.once("collect", (item) => {
552
+ resolve(item);
553
+ });
554
+ this.once("end", (_collected, reason) => {
555
+ reject(new Error(`Collector ended before item was collected: ${reason}`));
556
+ });
557
+ });
558
+ }
559
+ }
560
+ // packages/types/src/index.ts
561
+ var GatewayIntentBits = {
562
+ Guilds: 1 << 0,
563
+ GuildMembers: 1 << 1,
564
+ GuildModeration: 1 << 2,
565
+ GuildExpressions: 1 << 3,
566
+ GuildIntegrations: 1 << 4,
567
+ GuildWebhooks: 1 << 5,
568
+ GuildInvites: 1 << 6,
569
+ GuildVoiceStates: 1 << 7,
570
+ GuildPresences: 1 << 8,
571
+ GuildMessages: 1 << 9,
572
+ GuildMessageReactions: 1 << 10,
573
+ GuildMessageTyping: 1 << 11,
574
+ DirectMessages: 1 << 12,
575
+ DirectMessageReactions: 1 << 13,
576
+ DirectMessageTyping: 1 << 14,
577
+ MessageContent: 1 << 15,
578
+ GuildScheduledEvents: 1 << 16,
579
+ AutoModerationConfiguration: 1 << 20,
580
+ AutoModerationExecution: 1 << 21,
581
+ GuildMessagePolls: 1 << 24,
582
+ DirectMessagePolls: 1 << 25
583
+ };
584
+ var IntentBits = {
585
+ guild: 1 << 0,
586
+ guilds: 1 << 0,
587
+ guildMembers: 1 << 1,
588
+ guildModeration: 1 << 2,
589
+ guildBans: 1 << 2,
590
+ guildExpressions: 1 << 3,
591
+ guildEmojis: 1 << 3,
592
+ guildEmojisAndStickers: 1 << 3,
593
+ guildIntegrations: 1 << 4,
594
+ guildWebhooks: 1 << 5,
595
+ guildInvites: 1 << 6,
596
+ guildVoiceStates: 1 << 7,
597
+ guildPresences: 1 << 8,
598
+ guildMessages: 1 << 9,
599
+ guildMessage: 1 << 9,
600
+ guildMessageReactions: 1 << 10,
601
+ guildMessageTyping: 1 << 11,
602
+ directMessages: 1 << 12,
603
+ directMessageReactions: 1 << 13,
604
+ directMessageTyping: 1 << 14,
605
+ messageContent: 1 << 15,
606
+ guildScheduledEvents: 1 << 16,
607
+ autoModerationConfiguration: 1 << 20,
608
+ autoModerationExecution: 1 << 21,
609
+ guildMessagePolls: 1 << 24,
610
+ directMessagePolls: 1 << 25
611
+ };
612
+ var Intents = IntentBits;
613
+ function resolveGatewayIntents(intents) {
614
+ if (typeof intents === "number")
615
+ return intents;
616
+ if (Array.isArray(intents)) {
617
+ return intents.reduce((acc, intent) => {
618
+ return acc | resolveGatewayIntents(intent);
619
+ }, 0);
620
+ }
621
+ if (typeof intents === "string") {
622
+ if (intents in GatewayIntentBits)
623
+ return GatewayIntentBits[intents];
624
+ if (intents in IntentBits)
625
+ return IntentBits[intents];
626
+ const lower = intents.charAt(0).toLowerCase() + intents.slice(1);
627
+ if (lower in IntentBits)
628
+ return IntentBits[lower];
629
+ const num = Number(intents);
630
+ if (!Number.isNaN(num))
631
+ return num;
632
+ }
633
+ return 0;
634
+ }
635
+ var InteractionResponseType = {
636
+ Pong: 1,
637
+ ChannelMessage: 4,
638
+ DeferredChannelMessage: 5,
639
+ DeferredMessageUpdate: 6,
640
+ MessageUpdate: 7,
641
+ Autocomplete: 8,
642
+ Modal: 9
643
+ };
423
644
  // packages/collection/src/index.ts
424
645
  class Collection extends Map {
425
646
  first() {
@@ -544,6 +765,97 @@ class Collection extends Map {
544
765
  entry = [item[0], item[1]];
545
766
  return entry;
546
767
  }
768
+ union(other) {
769
+ const result = this.clone();
770
+ for (const [key, value] of other)
771
+ result.set(key, value);
772
+ return result;
773
+ }
774
+ intersection(other) {
775
+ const result = new Collection;
776
+ for (const [key, value] of this) {
777
+ if (other.has(key))
778
+ result.set(key, value);
779
+ }
780
+ return result;
781
+ }
782
+ difference(other) {
783
+ const result = new Collection;
784
+ for (const [key, value] of this) {
785
+ if (!other.has(key))
786
+ result.set(key, value);
787
+ }
788
+ return result;
789
+ }
790
+ partition(predicate) {
791
+ const pass = new Collection;
792
+ const fail = new Collection;
793
+ for (const [key, value] of this) {
794
+ if (predicate(value, key, this))
795
+ pass.set(key, value);
796
+ else
797
+ fail.set(key, value);
798
+ }
799
+ return [pass, fail];
800
+ }
801
+ tap(fn) {
802
+ fn(this);
803
+ return this;
804
+ }
805
+ flatMap(transform) {
806
+ const result = [];
807
+ for (const [key, value] of this) {
808
+ for (const item of transform(value, key, this))
809
+ result.push(item);
810
+ }
811
+ return result;
812
+ }
813
+ reduce(fn, initialValue) {
814
+ let acc = initialValue;
815
+ for (const [key, value] of this)
816
+ acc = fn(acc, value, key, this);
817
+ return acc;
818
+ }
819
+ sorted(comparator) {
820
+ const decorated = [...this.entries()].map((entry, index) => ({
821
+ entry,
822
+ index
823
+ }));
824
+ if (comparator)
825
+ decorated.sort((x, y) => {
826
+ const comparison = comparator(x.entry[1], y.entry[1], x.entry[0], y.entry[0]);
827
+ return comparison !== 0 ? comparison : x.index - y.index;
828
+ });
829
+ const result = new Collection;
830
+ for (const { entry } of decorated)
831
+ result.set(entry[0], entry[1]);
832
+ return result;
833
+ }
834
+ random() {
835
+ const arr = [...this.values()];
836
+ if (!arr.length)
837
+ return;
838
+ return arr[Math.floor(Math.random() * arr.length)];
839
+ }
840
+ randomKey() {
841
+ const arr = [...this.keys()];
842
+ if (!arr.length)
843
+ return;
844
+ return arr[Math.floor(Math.random() * arr.length)];
845
+ }
846
+ at(index) {
847
+ const arr = [...this.values()];
848
+ const i = index < 0 ? arr.length + index : index;
849
+ return arr[i];
850
+ }
851
+ keyAt(index) {
852
+ const arr = [...this.keys()];
853
+ const i = index < 0 ? arr.length + index : index;
854
+ return arr[i];
855
+ }
856
+ toJSON() {
857
+ return [...this.entries()];
858
+ }
547
859
  }
548
860
 
549
861
  // packages/managers/src/base.ts
@@ -612,11 +924,66 @@ class ResourceManager extends Manager {
612
924
  return this.upsert(resource);
613
925
  }
614
926
  }
927
+ // packages/rest/package.json
928
+ var package_default = {
929
+ name: "@lunibee/rest",
930
+ version: "0.1.7",
931
+ type: "module",
932
+ module: "./src/index.ts",
933
+ types: "./src/index.ts",
934
+ exports: {
935
+ ".": "./src/index.ts"
936
+ }
937
+ };
938
+
939
+ // packages/rest/src/store.ts
940
+ class MemoryRateLimitStore {
941
+ #buckets = new Map;
942
+ #routeBuckets = new Map;
943
+ #globalResetAt = 0;
944
+ static #PRUNE_INTERVAL = 60000;
945
+ #lastPruneAt = 0;
946
+ getBucketHash(route) {
947
+ return this.#routeBuckets.get(route);
948
+ }
949
+ setBucketHash(route, hash) {
950
+ this.#routeBuckets.set(route, hash);
951
+ }
952
+ getBucket(key) {
953
+ return this.#buckets.get(key);
954
+ }
955
+ updateBucket(key, state) {
956
+ this.#buckets.set(key, state);
957
+ const now = Date.now();
958
+ if (now - this.#lastPruneAt >= MemoryRateLimitStore.#PRUNE_INTERVAL) {
959
+ this.#lastPruneAt = now;
960
+ this.prune();
961
+ }
962
+ }
963
+ prune(maxAge = 0) {
964
+ const cutoff = Date.now() - Math.max(0, maxAge);
965
+ for (const [key, state] of this.#buckets) {
966
+ if (state.resetAt <= cutoff)
967
+ this.#buckets.delete(key);
968
+ }
969
+ }
970
+ getGlobalReset() {
971
+ return this.#globalResetAt;
972
+ }
973
+ setGlobalReset(resetAt) {
974
+ this.#globalResetAt = resetAt;
975
+ }
976
+ }
977
+
615
978
  // packages/rest/src/routes.ts
616
979
  var Routes = {
617
980
  user: () => "/users/@me",
618
981
  userById: (userId) => `/users/${snowflake(userId, "User ID")}`,
619
982
  guild: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}`,
983
+ guildPreview: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/preview`,
984
+ guildActiveThreads: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/threads/active`,
985
+ guildWebhooks: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/webhooks`,
986
+ guildInvites: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/invites`,
620
987
  guildChannels: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/channels`,
621
988
  guildMember: (guildId, userId) => `/guilds/${snowflake(guildId, "Guild ID")}/members/${snowflake(userId, "User ID")}`,
622
989
  guildRoles: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/roles`,
@@ -644,7 +1011,6 @@ var Routes = {
644
1011
  guildApplicationCommand: (applicationId, guildId, commandId) => `/applications/${snowflake(applicationId, "Application ID")}/guilds/${snowflake(guildId, "Guild ID")}/commands/${snowflake(commandId, "Command ID")}`,
645
1012
  interactionCallback: (interactionId, token) => `/interactions/${snowflake(interactionId, "Interaction ID")}/${encodeURIComponent(token)}/callback`,
646
1013
  interactionOriginalResponse: (applicationId, token) => `/webhooks/${snowflake(applicationId, "Application ID")}/${encodeURIComponent(token)}/messages/@original`,
647
- guildActiveThreads: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/threads/active`,
648
1014
  channelPublicArchivedThreads: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/threads/archived/public`,
649
1015
  channelPrivateArchivedThreads: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/threads/archived/private`,
650
1016
  threadMembers: (threadId) => `/channels/${snowflake(threadId, "Thread ID")}/thread-members`,
@@ -654,7 +1020,18 @@ var Routes = {
654
1020
  guildAutoModerationRule: (guildId, ruleId) => `/guilds/${snowflake(guildId, "Guild ID")}/auto-moderation/rules/${snowflake(ruleId, "Rule ID")}`,
655
1021
  voiceRegions: () => "/voice/regions",
656
1022
  gateway: () => "/gateway",
657
- gatewayBot: () => "/gateway/bot"
1023
+ gatewayBot: () => "/gateway/bot",
1024
+ guildAuditLog: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/audit-logs`,
1025
+ guildMembers: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/members`,
1026
+ guildWelcomeScreen: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/welcome-screen`,
1027
+ guildOnboarding: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/onboarding`,
1028
+ guildPrune: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/prune`,
1029
+ stageInstances: () => "/stage-instances",
1030
+ stageInstanceByChannel: (channelId) => `/stage-instances/${snowflake(channelId, "Channel ID")}`,
1031
+ invite: (code) => `/invites/${encodeURIComponent(code)}`,
1032
+ guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
1033
+ guildEmoji: (guildId, emojiId) => emojiId ? `/guilds/${snowflake(guildId, "Guild ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/emojis`,
1034
+ applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`
658
1035
  };
659
1036
  function snowflake(value, field) {
660
1037
  if (!/^\d{1,20}$/.test(value))
@@ -679,7 +1056,53 @@ class RESTError extends Error {
679
1056
  this.path = options.path;
680
1057
  }
681
1058
  }
682
- function createRetryPolicy(maxRetries = 2) {
1059
+ var LIBRARY_VERSION = package_default.version;
1060
+ var LIBRARY_URL = "https://github.com/Ekretos/lunibee";
1061
+ var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${package_default.version})`;
1062
+ var REQUEST_DATA_KEYS = new Set([
1063
+ "body",
1064
+ "files",
1065
+ "query",
1066
+ "headers",
1067
+ "reason",
1068
+ "auth",
1069
+ "signal"
1070
+ ]);
1071
+ function isRequestData(value) {
1072
+ if (value === null || typeof value !== "object")
1073
+ return false;
1074
+ if (Array.isArray(value))
1075
+ return false;
1076
+ if (typeof FormData !== "undefined" && value instanceof FormData)
1077
+ return false;
1078
+ if (value instanceof Blob || value instanceof Uint8Array || value instanceof ArrayBuffer)
1079
+ return false;
1080
+ const keys = Object.keys(value);
1081
+ if (keys.length === 0)
1082
+ return false;
1083
+ return keys.every((key) => REQUEST_DATA_KEYS.has(key));
1084
+ }
1085
+ function serializeQuery(query) {
1086
+ if (query === undefined)
1087
+ return "";
1088
+ if (typeof query === "string")
1089
+ return query.length === 0 || query.startsWith("?") ? query : `?${query}`;
1090
+ const params = query instanceof URLSearchParams ? query : new URLSearchParams(Object.entries(query).flatMap(([key, value]) => value === undefined || value === null ? [] : [[key, String(value)]]));
1091
+ const serialized = params.toString();
1092
+ return serialized.length === 0 ? "" : `?${serialized}`;
1093
+ }
1094
+ function majorParameter(path) {
1095
+ const match = /^\/(channels|guilds|webhooks)\/(\d+)(?:\/([^/?]+))?/.exec(path);
1096
+ if (!match)
1097
+ return "@none";
1098
+ if (match[1] === "webhooks" && match[3] !== undefined)
1099
+ return `${match[2]}:${match[3]}`;
1100
+ return match[2];
1101
+ }
1102
+ function scopeBucket(hashOrRoute, major) {
1103
+ return `${hashOrRoute}|${major}`;
1104
+ }
1105
+ function createRetryPolicy(maxRetries = 2) {
683
1106
  if (!Number.isFinite(maxRetries) || maxRetries < 0)
684
1107
  throw new TypeError("maxRetries must be a non-negative finite number.");
685
1108
  return {
@@ -701,14 +1124,21 @@ class REST {
701
1124
  #timeout;
702
1125
  #retryPolicy;
703
1126
  #token;
704
- #globalResetAt = 0;
705
- #buckets = new Map;
706
- #routeBuckets = new Map;
1127
+ #store;
1128
+ #localQueues = new Map;
1129
+ #hooks = {};
707
1130
  constructor(options = {}) {
708
1131
  this.#token = options.token;
709
1132
  this.#timeout = Math.max(1, options.timeout ?? 15000);
710
1133
  this.#retryPolicy = options.retryPolicy ?? createRetryPolicy(options.retries ?? 2);
711
1134
  this.#baseURL = (options.baseURL ?? "https://discord.com/api/v10").replace(/\/$/, "");
1135
+ this.#store = options.store ?? new MemoryRateLimitStore;
1136
+ if (options.hooks)
1137
+ this.#hooks = options.hooks;
1138
+ }
1139
+ setHooks(hooks) {
1140
+ this.#hooks = hooks;
1141
+ return this;
712
1142
  }
713
1143
  setToken(token) {
714
1144
  if (!token.trim())
@@ -721,52 +1151,91 @@ class REST {
721
1151
  throw new TypeError("REST method is required.");
722
1152
  if (!path.startsWith("/"))
723
1153
  throw new TypeError("REST paths must start with '/'.");
1154
+ const files = options.files;
1155
+ if (files && files.length > 0 && !(body instanceof FormData))
1156
+ body = this.#fileForm(body, files);
1157
+ const query = serializeQuery(options.query);
1158
+ const finalPath = query ? `${path}${query}` : path;
724
1159
  const route = `${normalizedMethod}:${this.#normalizeRoute(path)}`;
725
- let bucketKey = this.#routeBuckets.get(route) ?? route;
726
- let bucket = this.#buckets.get(bucketKey) ?? {
727
- remaining: 1,
728
- resetAt: 0,
729
- queue: Promise.resolve()
730
- };
731
- this.#buckets.set(bucketKey, bucket);
732
- const previous = bucket.queue;
1160
+ const major = majorParameter(path);
1161
+ let bucketKey = scopeBucket(await this.#store.getBucketHash(route) ?? route, major);
1162
+ const queueKey = bucketKey;
1163
+ const previous = this.#localQueues.get(queueKey) ?? Promise.resolve();
733
1164
  let release;
734
- bucket.queue = new Promise((resolve) => {
1165
+ const gate = new Promise((resolve) => {
735
1166
  release = resolve;
736
1167
  });
1168
+ this.#localQueues.set(queueKey, gate);
737
1169
  await this.#abortable(previous, options.signal, path);
738
1170
  try {
739
1171
  for (let attempt = 0;attempt <= this.#retryPolicy.maxRetries; attempt++) {
740
- await this.#wait(bucket, options.signal, path);
1172
+ await this.#wait(bucketKey, options.signal, path);
741
1173
  await this.#waitGlobal(options.signal, path);
742
1174
  const controller = new AbortController;
743
1175
  const onAbort = () => controller.abort(options.signal?.reason);
744
1176
  if (options.signal?.aborted)
745
1177
  throw this.#abortError(path, options.signal.reason);
746
- options.signal?.addEventListener("abort", onAbort, { once: true });
1178
+ options.signal?.addEventListener("abort", onAbort, {
1179
+ once: true
1180
+ });
747
1181
  const timer = setTimeout(() => controller.abort(new DOMException("REST request timeout", "TimeoutError")), this.#timeout);
1182
+ const isFormData = typeof FormData !== "undefined" && body instanceof FormData;
1183
+ const headers = { ...options.headers };
1184
+ if (options.auth !== false && this.#token)
1185
+ headers["Authorization"] = `Bot ${this.#token}`;
1186
+ headers["User-Agent"] = USER_AGENT;
1187
+ if (options.reason !== undefined)
1188
+ headers["X-Audit-Log-Reason"] = encodeURIComponent(options.reason);
1189
+ if (!isFormData)
1190
+ headers["Content-Type"] = "application/json";
1191
+ const fetchBody = isFormData ? body : body === undefined ? undefined : JSON.stringify(body);
748
1192
  try {
749
- const response = await fetch(`${this.#baseURL}${path}`, {
1193
+ this.#emit(this.#hooks.onRequest, {
1194
+ method: normalizedMethod,
1195
+ path,
1196
+ attempt
1197
+ });
1198
+ const requestStart = Date.now();
1199
+ const response = await fetch(`${this.#baseURL}${finalPath}`, {
750
1200
  method: normalizedMethod,
751
- headers: {
752
- ...this.#token ? { Authorization: `Bot ${this.#token}` } : {},
753
- "Content-Type": "application/json",
754
- "User-Agent": "Lunibee/0.1.0"
755
- },
756
- body: body === undefined ? undefined : JSON.stringify(body),
1201
+ headers,
1202
+ body: fetchBody,
757
1203
  signal: controller.signal
758
1204
  });
759
- bucket = this.#update(response, bucket, route, bucketKey);
760
- bucketKey = this.#routeBuckets.get(route) ?? bucketKey;
1205
+ this.#emit(this.#hooks.onResponse, {
1206
+ method: normalizedMethod,
1207
+ path,
1208
+ status: response.status,
1209
+ durationMs: Date.now() - requestStart
1210
+ });
1211
+ bucketKey = await this.#update(response, bucketKey, route, major);
761
1212
  const payload = await this.#readPayload(response);
762
1213
  if (response.ok)
763
1214
  return response.status === 204 ? undefined : payload;
764
1215
  const data = this.#errorData(payload);
765
1216
  const retryAfter = response.status === 429 ? this.#retryAfter(response, data) : undefined;
766
- if (data.global && retryAfter !== undefined)
767
- this.#globalResetAt = Date.now() + retryAfter * 1000;
1217
+ if (data.global && retryAfter !== undefined) {
1218
+ const currentGlobal = await this.#store.getGlobalReset();
1219
+ await this.#store.setGlobalReset(Math.max(currentGlobal, Date.now() + retryAfter * 1000));
1220
+ }
1221
+ if (response.status === 429)
1222
+ this.#emit(this.#hooks.onRateLimit, {
1223
+ method: normalizedMethod,
1224
+ path,
1225
+ retryAfterMs: (retryAfter ?? 1) * 1000,
1226
+ global: data.global ?? false,
1227
+ bucket: await this.#store.getBucketHash(route)
1228
+ });
768
1229
  if (attempt < this.#retryPolicy.maxRetries && this.#retryPolicy.shouldRetry(normalizedMethod, response.status)) {
769
- await this.#sleep(this.#retryPolicy.getDelay(attempt, retryAfter), options.signal, path);
1230
+ const delay = this.#retryPolicy.getDelay(attempt, retryAfter);
1231
+ this.#emit(this.#hooks.onRetry, {
1232
+ method: normalizedMethod,
1233
+ path,
1234
+ attempt,
1235
+ status: response.status,
1236
+ delayMs: delay
1237
+ });
1238
+ await this.#sleep(delay, options.signal, path);
770
1239
  continue;
771
1240
  }
772
1241
  throw new RESTError(data.message ?? response.statusText ?? `Discord REST request failed with status ${response.status}`, response.status, data.code, payload, { method: normalizedMethod, path });
@@ -789,30 +1258,64 @@ class REST {
789
1258
  throw new RESTError("Discord REST request exhausted its retry attempts", 0, undefined, undefined, { method: normalizedMethod, path });
790
1259
  } finally {
791
1260
  release();
1261
+ if (this.#localQueues.get(queueKey) === gate)
1262
+ this.#localQueues.delete(queueKey);
792
1263
  }
793
1264
  }
1265
+ #dispatch(method, path, bodyOrOptions, options) {
1266
+ if (options === undefined && isRequestData(bodyOrOptions))
1267
+ return this.request(method, path, bodyOrOptions.body, bodyOrOptions);
1268
+ return this.request(method, path, bodyOrOptions, options);
1269
+ }
794
1270
  get(path, options) {
795
- return this.request("GET", path, undefined, options);
1271
+ return this.request("GET", path, options?.body, options);
796
1272
  }
797
1273
  post(path, body, options) {
798
- return this.request("POST", path, body, options);
1274
+ return this.#dispatch("POST", path, body, options);
799
1275
  }
800
1276
  patch(path, body, options) {
801
- return this.request("PATCH", path, body, options);
1277
+ return this.#dispatch("PATCH", path, body, options);
802
1278
  }
803
1279
  put(path, body, options) {
804
- return this.request("PUT", path, body, options);
1280
+ return this.#dispatch("PUT", path, body, options);
805
1281
  }
806
1282
  delete(path, options) {
807
- return this.request("DELETE", path, undefined, options);
1283
+ return this.request("DELETE", path, options?.body, options);
1284
+ }
1285
+ #fileForm(payload, files) {
1286
+ const form = new FormData;
1287
+ form.append("payload_json", JSON.stringify(payload));
1288
+ for (let i = 0;i < files.length; i++) {
1289
+ const file = files[i];
1290
+ const blob = file.data instanceof Blob ? file.data : new Blob([file.data], {
1291
+ type: file.contentType ?? "application/octet-stream"
1292
+ });
1293
+ form.append(`files[${i}]`, blob, file.name);
1294
+ }
1295
+ return form;
1296
+ }
1297
+ postWithFiles(path, payload, files, options) {
1298
+ return this.request("POST", path, this.#fileForm(payload, files), options);
1299
+ }
1300
+ patchWithFiles(path, payload, files, options) {
1301
+ return this.request("PATCH", path, this.#fileForm(payload, files), options);
1302
+ }
1303
+ #emit(hook, ctx) {
1304
+ if (!hook)
1305
+ return;
1306
+ Promise.resolve().then(() => hook(ctx)).catch(() => {});
808
1307
  }
809
- async#wait(bucket, signal, path) {
1308
+ async#wait(bucketKey, signal, path) {
1309
+ const bucket = await this.#store.getBucket(bucketKey);
1310
+ if (!bucket)
1311
+ return;
810
1312
  const delay = bucket.resetAt - Date.now();
811
1313
  if (bucket.remaining <= 0 && delay > 0)
812
1314
  await this.#sleep(delay, signal, path);
813
1315
  }
814
1316
  async#waitGlobal(signal, path) {
815
- const delay = this.#globalResetAt - Date.now();
1317
+ const globalResetAt = await this.#store.getGlobalReset();
1318
+ const delay = globalResetAt - Date.now();
816
1319
  if (delay > 0)
817
1320
  await this.#sleep(delay, signal, path);
818
1321
  }
@@ -876,16 +1379,17 @@ class REST {
876
1379
  const routePath = queryIndex === -1 ? path : path.slice(0, queryIndex);
877
1380
  return routePath.replace(/\/\d+(?=\/|$)/g, "/:id");
878
1381
  }
879
- #update(response, bucket, route, bucketKey) {
1382
+ async#update(response, bucketKey, route, major) {
1383
+ let currentKey = bucketKey;
880
1384
  const serverBucket = response.headers.get("X-RateLimit-Bucket");
881
1385
  if (serverBucket) {
882
- this.#routeBuckets.set(route, serverBucket);
883
- if (serverBucket !== bucketKey) {
884
- const shared = this.#buckets.get(serverBucket) ?? bucket;
885
- this.#buckets.set(serverBucket, shared);
886
- bucket = shared;
887
- }
1386
+ await this.#store.setBucketHash(route, serverBucket);
1387
+ currentKey = scopeBucket(serverBucket, major);
888
1388
  }
1389
+ let bucket = await this.#store.getBucket(currentKey) ?? {
1390
+ remaining: 1,
1391
+ resetAt: 0
1392
+ };
889
1393
  const remaining = Number(response.headers.get("X-RateLimit-Remaining"));
890
1394
  const resetAfter = Number(response.headers.get("X-RateLimit-Reset-After"));
891
1395
  const reset = Number(response.headers.get("X-RateLimit-Reset"));
@@ -900,12 +1404,15 @@ class REST {
900
1404
  if (Number.isFinite(retryAfter))
901
1405
  bucket.resetAt = Math.max(bucket.resetAt, Date.now() + retryAfter * 1000);
902
1406
  }
1407
+ await this.#store.updateBucket(currentKey, bucket);
903
1408
  if (response.headers.get("X-RateLimit-Global") === "true") {
904
1409
  const retryAfter = Number(response.headers.get("Retry-After"));
905
- if (Number.isFinite(retryAfter))
906
- this.#globalResetAt = Math.max(this.#globalResetAt, Date.now() + retryAfter * 1000);
1410
+ if (Number.isFinite(retryAfter)) {
1411
+ const currentGlobal = await this.#store.getGlobalReset();
1412
+ await this.#store.setGlobalReset(Math.max(currentGlobal, Date.now() + retryAfter * 1000));
1413
+ }
907
1414
  }
908
- return bucket;
1415
+ return currentKey;
909
1416
  }
910
1417
  }
911
1418
 
@@ -920,6 +1427,16 @@ class BaseStructure {
920
1427
  toString() {
921
1428
  return this.id;
922
1429
  }
1430
+ get createdAt() {
1431
+ return new Date(Number((BigInt(this.id) >> 22n) + 1420070400000n));
1432
+ }
1433
+ }
1434
+ var CDN_BASE = "https://cdn.discordapp.com";
1435
+ function cdnURL(path, hash, options = {}) {
1436
+ const isAnimated = hash.startsWith("a_") && !options.forceStatic;
1437
+ const ext = options.extension ?? (isAnimated ? "gif" : "png");
1438
+ const size = options.size ? `?size=${options.size}` : "";
1439
+ return `${CDN_BASE}${path}/${hash}.${ext}${size}`;
923
1440
  }
924
1441
 
925
1442
  class User extends BaseStructure {
@@ -929,6 +1446,7 @@ class User extends BaseStructure {
929
1446
  bot;
930
1447
  system;
931
1448
  flags;
1449
+ discriminator;
932
1450
  constructor(data) {
933
1451
  super(data.id);
934
1452
  if (!data.username)
@@ -939,6 +1457,7 @@ class User extends BaseStructure {
939
1457
  this.bot = data.bot ?? false;
940
1458
  this.system = data.system ?? false;
941
1459
  this.flags = data.public_flags ?? 0;
1460
+ this.discriminator = data.discriminator && data.discriminator !== "0" ? data.discriminator : null;
942
1461
  }
943
1462
  get displayName() {
944
1463
  return this.globalName ?? this.username;
@@ -946,21 +1465,29 @@ class User extends BaseStructure {
946
1465
  avatarURL(options = {}) {
947
1466
  if (!this.avatar)
948
1467
  return null;
949
- const extension = options.extension ?? (this.avatar.startsWith("a_") ? "gif" : "png");
950
- return `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.${extension}${options.size ? `?size=${options.size}` : ""}`;
1468
+ return cdnURL(`/avatars/${this.id}`, this.avatar, options);
951
1469
  }
952
1470
  defaultAvatarURL() {
953
- return `https://cdn.discordapp.com/embed/avatars/${Number(BigInt(this.id) % 5n)}.png`;
1471
+ const index = this.discriminator ? Number(this.discriminator) % 5 : Number((BigInt(this.id) >> 22n) % 6n);
1472
+ return `${CDN_BASE}/embed/avatars/${index}.png`;
954
1473
  }
955
1474
  displayAvatarURL(options = {}) {
956
1475
  return this.avatarURL(options) ?? this.defaultAvatarURL();
957
1476
  }
1477
+ toString() {
1478
+ return `<@${this.id}>`;
1479
+ }
958
1480
  }
959
1481
 
960
1482
  class Channel extends BaseStructure {
961
1483
  type;
962
1484
  name;
963
1485
  guildId;
1486
+ topic;
1487
+ parentId;
1488
+ nsfw;
1489
+ rateLimitPerUser;
1490
+ position;
964
1491
  #context;
965
1492
  constructor(data, context) {
966
1493
  super(data.id);
@@ -969,6 +1496,11 @@ class Channel extends BaseStructure {
969
1496
  this.type = data.type;
970
1497
  this.name = data.name;
971
1498
  this.guildId = data.guild_id;
1499
+ this.topic = data.topic;
1500
+ this.parentId = data.parent_id;
1501
+ this.nsfw = data.nsfw;
1502
+ this.rateLimitPerUser = data.rate_limit_per_user;
1503
+ this.position = data.position;
972
1504
  this.#context = context;
973
1505
  }
974
1506
  sendMessage(options) {
@@ -976,73 +1508,187 @@ class Channel extends BaseStructure {
976
1508
  throw new Error("This channel is not attached to a client.");
977
1509
  return this.#context.sendMessage(this.id, options);
978
1510
  }
1511
+ send(options) {
1512
+ return this.sendMessage(options);
1513
+ }
1514
+ edit(options) {
1515
+ if (!this.#context?.editChannel)
1516
+ throw new Error("This channel is not attached to a client.");
1517
+ return this.#context.editChannel(this.id, options);
1518
+ }
1519
+ editName(name) {
1520
+ if (!name.trim())
1521
+ throw new TypeError("Channel name cannot be empty.");
1522
+ return this.edit({ name });
1523
+ }
1524
+ editTopic(topic) {
1525
+ return this.edit({ topic });
1526
+ }
1527
+ editParent(parentId) {
1528
+ return this.edit({ parent_id: parentId });
1529
+ }
1530
+ delete() {
1531
+ if (!this.#context?.deleteChannel)
1532
+ throw new Error("This channel is not attached to a client.");
1533
+ return this.#context.deleteChannel(this.id);
1534
+ }
1535
+ update(options) {
1536
+ return this.edit(options);
1537
+ }
1538
+ toString() {
1539
+ return `<#${this.id}>`;
1540
+ }
979
1541
  }
980
1542
 
981
1543
  class Guild extends BaseStructure {
982
1544
  name;
1545
+ icon;
1546
+ splash;
1547
+ banner;
1548
+ description;
983
1549
  preferredLocale;
984
1550
  ownerId;
1551
+ features;
1552
+ verificationLevel;
1553
+ premiumTier;
1554
+ premiumSubscriptionCount;
1555
+ memberCount;
1556
+ approximateMemberCount;
1557
+ approximatePresenceCount;
1558
+ vanityUrlCode;
1559
+ nsfwLevel;
1560
+ discoverySplash;
1561
+ rulesChannelId;
1562
+ systemChannelId;
1563
+ systemChannelFlags;
1564
+ maxMembers;
1565
+ mfaLevel;
1566
+ explicitContentFilter;
1567
+ defaultMessageNotifications;
985
1568
  constructor(data) {
986
1569
  super(data.id);
987
1570
  if (!data.name)
988
1571
  throw new TypeError("A Discord guild requires a name.");
989
1572
  this.name = data.name;
990
- this.preferredLocale = data.preferred_locale;
1573
+ this.icon = data.icon ?? null;
1574
+ this.splash = data.splash ?? null;
1575
+ this.banner = data.banner ?? null;
1576
+ this.description = data.description ?? null;
1577
+ this.preferredLocale = data.preferred_locale ?? "en-US";
991
1578
  this.ownerId = data.owner_id;
1579
+ this.features = data.features ?? [];
1580
+ this.verificationLevel = data.verification_level ?? 0;
1581
+ this.premiumTier = data.premium_tier ?? 0;
1582
+ this.premiumSubscriptionCount = data.premium_subscription_count ?? 0;
1583
+ this.memberCount = data.member_count ?? data.approximate_member_count;
1584
+ this.approximateMemberCount = data.approximate_member_count;
1585
+ this.approximatePresenceCount = data.approximate_presence_count;
1586
+ this.vanityUrlCode = data.vanity_url_code ?? null;
1587
+ this.nsfwLevel = data.nsfw_level ?? 0;
1588
+ this.discoverySplash = data.discovery_splash ?? null;
1589
+ const d = data;
1590
+ this.rulesChannelId = d.rules_channel_id ?? null;
1591
+ this.systemChannelId = d.system_channel_id ?? null;
1592
+ this.systemChannelFlags = d.system_channel_flags ?? 0;
1593
+ this.maxMembers = d.max_members ?? 0;
1594
+ this.mfaLevel = d.mfa_level ?? 0;
1595
+ this.explicitContentFilter = d.explicit_content_filter ?? 0;
1596
+ this.defaultMessageNotifications = d.default_message_notifications ?? 0;
1597
+ }
1598
+ iconURL(options = {}) {
1599
+ if (!this.icon)
1600
+ return null;
1601
+ return cdnURL(`/icons/${this.id}`, this.icon, options);
1602
+ }
1603
+ splashURL(options = {}) {
1604
+ if (!this.splash)
1605
+ return null;
1606
+ return cdnURL(`/splashes/${this.id}`, this.splash, options);
1607
+ }
1608
+ bannerURL(options = {}) {
1609
+ if (!this.banner)
1610
+ return null;
1611
+ return cdnURL(`/banners/${this.id}`, this.banner, options);
1612
+ }
1613
+ discoverySplashURL(options = {}) {
1614
+ if (!this.discoverySplash)
1615
+ return null;
1616
+ return cdnURL(`/discovery-splashes/${this.id}`, this.discoverySplash, options);
1617
+ }
1618
+ widgetImageURL(style = "shield") {
1619
+ return `https://discord.com/api/guilds/${this.id}/widget.png?style=${style}`;
1620
+ }
1621
+ hasFeature(feature) {
1622
+ return this.features.includes(feature);
1623
+ }
1624
+ get isCommunity() {
1625
+ return this.hasFeature("COMMUNITY");
1626
+ }
1627
+ get isPartnered() {
1628
+ return this.hasFeature("PARTNERED");
1629
+ }
1630
+ get isVerified() {
1631
+ return this.hasFeature("VERIFIED");
1632
+ }
1633
+ get isBoosted() {
1634
+ return this.premiumSubscriptionCount > 0;
1635
+ }
1636
+ get boostLevel() {
1637
+ return this.premiumTier;
1638
+ }
1639
+ get hasVanityUrl() {
1640
+ return this.vanityUrlCode !== null;
1641
+ }
1642
+ get vanityURL() {
1643
+ return this.vanityUrlCode ? `https://discord.gg/${this.vanityUrlCode}` : null;
1644
+ }
1645
+ toString() {
1646
+ return this.name;
1647
+ }
1648
+ }
1649
+ // packages/structures/src/resources.ts
1650
+ class AutoModerationRule extends BaseStructure {
1651
+ guildId;
1652
+ name;
1653
+ creatorId;
1654
+ eventType;
1655
+ triggerType;
1656
+ triggerMetadata;
1657
+ actions;
1658
+ enabled;
1659
+ exemptRoles;
1660
+ exemptChannels;
1661
+ constructor(data) {
1662
+ super(data.id);
1663
+ if (!/^\d{1,20}$/.test(data.guild_id))
1664
+ throw new TypeError("AutoModerationRule guild_id must be a valid snowflake.");
1665
+ this.guildId = data.guild_id;
1666
+ this.name = data.name;
1667
+ this.creatorId = data.creator_id;
1668
+ this.eventType = data.event_type;
1669
+ this.triggerType = data.trigger_type;
1670
+ this.triggerMetadata = data.trigger_metadata;
1671
+ this.actions = data.actions;
1672
+ this.enabled = data.enabled;
1673
+ this.exemptRoles = data.exempt_roles;
1674
+ this.exemptChannels = data.exempt_channels;
1675
+ }
1676
+ toJSON() {
1677
+ return {
1678
+ id: this.id,
1679
+ guildId: this.guildId,
1680
+ name: this.name,
1681
+ creatorId: this.creatorId,
1682
+ eventType: this.eventType,
1683
+ triggerType: this.triggerType,
1684
+ triggerMetadata: this.triggerMetadata,
1685
+ actions: this.actions,
1686
+ enabled: this.enabled,
1687
+ exemptRoles: this.exemptRoles,
1688
+ exemptChannels: this.exemptChannels
1689
+ };
992
1690
  }
993
1691
  }
994
- // packages/structures/src/permissions.ts
995
- var Permissions2 = {
996
- CreateInstantInvite: 1n << 0n,
997
- KickMembers: 1n << 1n,
998
- BanMembers: 1n << 2n,
999
- Administrator: 1n << 3n,
1000
- ManageChannels: 1n << 4n,
1001
- ManageGuild: 1n << 5n,
1002
- AddReactions: 1n << 6n,
1003
- ViewAuditLog: 1n << 7n,
1004
- PrioritySpeaker: 1n << 8n,
1005
- Stream: 1n << 9n,
1006
- ViewChannel: 1n << 10n,
1007
- SendMessages: 1n << 11n,
1008
- SendTTSMessages: 1n << 12n,
1009
- ManageMessages: 1n << 13n,
1010
- EmbedLinks: 1n << 14n,
1011
- AttachFiles: 1n << 15n,
1012
- ReadMessageHistory: 1n << 16n,
1013
- MentionEveryone: 1n << 17n,
1014
- UseExternalEmojis: 1n << 18n,
1015
- ViewGuildInsights: 1n << 19n,
1016
- Connect: 1n << 20n,
1017
- Speak: 1n << 21n,
1018
- MuteMembers: 1n << 22n,
1019
- DeafenMembers: 1n << 23n,
1020
- MoveMembers: 1n << 24n,
1021
- UseVAD: 1n << 25n,
1022
- ChangeNickname: 1n << 26n,
1023
- ManageNicknames: 1n << 27n,
1024
- ManageRoles: 1n << 28n,
1025
- ManageWebhooks: 1n << 29n,
1026
- ManageGuildExpressions: 1n << 30n,
1027
- UseApplicationCommands: 1n << 31n,
1028
- RequestToSpeak: 1n << 32n,
1029
- ManageEvents: 1n << 33n,
1030
- ManageThreads: 1n << 34n,
1031
- CreatePublicThreads: 1n << 35n,
1032
- CreatePrivateThreads: 1n << 36n,
1033
- UseExternalStickers: 1n << 37n,
1034
- SendMessagesInThreads: 1n << 38n,
1035
- UseEmbeddedActivities: 1n << 39n,
1036
- ModerateMembers: 1n << 40n,
1037
- ViewCreatorMonetizationAnalytics: 1n << 41n,
1038
- UseSoundboard: 1n << 42n,
1039
- CreateGuildExpressions: 1n << 43n,
1040
- CreateEvents: 1n << 44n,
1041
- UseExternalSounds: 1n << 45n,
1042
- SendVoiceMessages: 1n << 46n,
1043
- SendPolls: 1n << 49n,
1044
- UseExternalApps: 1n << 50n
1045
- };
1046
1692
  // packages/structures/src/interactions.ts
1047
1693
  var InteractionType = {
1048
1694
  Ping: 1,
@@ -1051,16 +1697,167 @@ var InteractionType = {
1051
1697
  ApplicationCommandAutocomplete: 4,
1052
1698
  ModalSubmit: 5
1053
1699
  };
1054
- var InteractionResponseType = {
1055
- Pong: 1,
1056
- ChannelMessage: 4,
1057
- DeferredChannelMessage: 5,
1058
- DeferredMessageUpdate: 6,
1059
- MessageUpdate: 7,
1060
- Autocomplete: 8,
1061
- Modal: 9
1700
+ var OptionType = {
1701
+ SubCommand: 1,
1702
+ SubCommandGroup: 2,
1703
+ String: 3,
1704
+ Integer: 4,
1705
+ Boolean: 5,
1706
+ User: 6,
1707
+ Channel: 7,
1708
+ Role: 8,
1709
+ Mentionable: 9,
1710
+ Number: 10,
1711
+ Attachment: 11
1062
1712
  };
1063
1713
 
1714
+ class CommandOptions {
1715
+ #options;
1716
+ #resolved;
1717
+ constructor(options, resolved = {}) {
1718
+ let currentOptions = options;
1719
+ let group = null;
1720
+ let sub = null;
1721
+ while (currentOptions.length === 1) {
1722
+ const opt = currentOptions[0];
1723
+ if (opt.type === OptionType.SubCommandGroup) {
1724
+ group = opt.name;
1725
+ currentOptions = opt.options ?? [];
1726
+ } else if (opt.type === OptionType.SubCommand) {
1727
+ sub = opt.name;
1728
+ currentOptions = opt.options ?? [];
1729
+ } else {
1730
+ break;
1731
+ }
1732
+ }
1733
+ this.#options = currentOptions;
1734
+ this.#resolved = resolved;
1735
+ this.#subcommandGroup = group;
1736
+ this.#subcommand = sub;
1737
+ }
1738
+ #subcommandGroup;
1739
+ #subcommand;
1740
+ #get(name) {
1741
+ return this.#options.find((o) => o.name.toLowerCase() === name.toLowerCase());
1742
+ }
1743
+ getSubcommand(required = false) {
1744
+ if (!this.#subcommand && required) {
1745
+ throw new TypeError("No subcommand was provided.");
1746
+ }
1747
+ return this.#subcommand;
1748
+ }
1749
+ getSubcommandGroup(required = false) {
1750
+ if (!this.#subcommandGroup && required) {
1751
+ throw new TypeError("No subcommand group was provided.");
1752
+ }
1753
+ return this.#subcommandGroup;
1754
+ }
1755
+ getString(name, required = false) {
1756
+ const opt = this.#get(name);
1757
+ if (!opt || opt.type !== OptionType.String) {
1758
+ if (required)
1759
+ throw new TypeError(`Required option "${name}" (string) is missing.`);
1760
+ return null;
1761
+ }
1762
+ return typeof opt.value === "string" ? opt.value : null;
1763
+ }
1764
+ getInteger(name, required = false) {
1765
+ const opt = this.#get(name);
1766
+ if (!opt || opt.type !== OptionType.Integer) {
1767
+ if (required)
1768
+ throw new TypeError(`Required option "${name}" (integer) is missing.`);
1769
+ return null;
1770
+ }
1771
+ return typeof opt.value === "number" ? Math.trunc(opt.value) : null;
1772
+ }
1773
+ getNumber(name, required = false) {
1774
+ const opt = this.#get(name);
1775
+ if (!opt || opt.type !== OptionType.Number) {
1776
+ if (required)
1777
+ throw new TypeError(`Required option "${name}" (number) is missing.`);
1778
+ return null;
1779
+ }
1780
+ return typeof opt.value === "number" ? opt.value : null;
1781
+ }
1782
+ getBoolean(name, required = false) {
1783
+ const opt = this.#get(name);
1784
+ if (!opt || opt.type !== OptionType.Boolean) {
1785
+ if (required)
1786
+ throw new TypeError(`Required option "${name}" (boolean) is missing.`);
1787
+ return null;
1788
+ }
1789
+ return typeof opt.value === "boolean" ? opt.value : null;
1790
+ }
1791
+ getUser(name, required = false) {
1792
+ const opt = this.#get(name);
1793
+ if (!opt || opt.type !== OptionType.User) {
1794
+ if (required)
1795
+ throw new TypeError(`Required option "${name}" (user) is missing.`);
1796
+ return null;
1797
+ }
1798
+ const userId = String(opt.value);
1799
+ const resolved = this.#resolved?.users?.[userId] ?? null;
1800
+ if (!resolved && required)
1801
+ throw new TypeError(`Resolved user for option "${name}" is missing.`);
1802
+ return resolved;
1803
+ }
1804
+ getChannel(name, required = false) {
1805
+ const opt = this.#get(name);
1806
+ if (!opt || opt.type !== OptionType.Channel) {
1807
+ if (required)
1808
+ throw new TypeError(`Required option "${name}" (channel) is missing.`);
1809
+ return null;
1810
+ }
1811
+ const channelId = String(opt.value);
1812
+ const resolved = this.#resolved?.channels?.[channelId] ?? null;
1813
+ if (!resolved && required)
1814
+ throw new TypeError(`Resolved channel for option "${name}" is missing.`);
1815
+ return resolved;
1816
+ }
1817
+ getRole(name, required = false) {
1818
+ const opt = this.#get(name);
1819
+ if (!opt || opt.type !== OptionType.Role) {
1820
+ if (required)
1821
+ throw new TypeError(`Required option "${name}" (role) is missing.`);
1822
+ return null;
1823
+ }
1824
+ const roleId = String(opt.value);
1825
+ const resolved = this.#resolved?.roles?.[roleId] ?? null;
1826
+ if (!resolved && required)
1827
+ throw new TypeError(`Resolved role for option "${name}" is missing.`);
1828
+ return resolved;
1829
+ }
1830
+ getMentionable(name, required = false) {
1831
+ const opt = this.#get(name);
1832
+ if (!opt || opt.type !== OptionType.Mentionable) {
1833
+ if (required)
1834
+ throw new TypeError(`Required option "${name}" (mentionable) is missing.`);
1835
+ return null;
1836
+ }
1837
+ const id = String(opt.value);
1838
+ const resolved = this.#resolved?.users?.[id] ?? this.#resolved?.roles?.[id] ?? null;
1839
+ if (!resolved && required)
1840
+ throw new TypeError(`Resolved mentionable for option "${name}" is missing.`);
1841
+ return resolved;
1842
+ }
1843
+ getAttachment(name, required = false) {
1844
+ const opt = this.#get(name);
1845
+ if (!opt || opt.type !== OptionType.Attachment) {
1846
+ if (required)
1847
+ throw new TypeError(`Required option "${name}" (attachment) is missing.`);
1848
+ return null;
1849
+ }
1850
+ const attachmentId = String(opt.value);
1851
+ const resolved = this.#resolved?.attachments?.[attachmentId] ?? null;
1852
+ if (!resolved && required)
1853
+ throw new TypeError(`Resolved attachment for option "${name}" is missing.`);
1854
+ return resolved;
1855
+ }
1856
+ get raw() {
1857
+ return this.#options;
1858
+ }
1859
+ }
1860
+
1064
1861
  class InteractionResponse {
1065
1862
  type;
1066
1863
  data;
@@ -1174,9 +1971,16 @@ class Interaction {
1174
1971
  }
1175
1972
 
1176
1973
  class CommandInteraction extends Interaction {
1974
+ options;
1177
1975
  get commandName() {
1178
1976
  return typeof this.data.data?.name === "string" ? this.data.data.name : "";
1179
1977
  }
1978
+ constructor(client, data) {
1979
+ super(client, data);
1980
+ const rawOptions = data.data?.options ?? [];
1981
+ const resolved = data.data?.resolved ?? {};
1982
+ this.options = new CommandOptions(rawOptions, resolved);
1983
+ }
1180
1984
  }
1181
1985
 
1182
1986
  class ComponentInteraction extends Interaction {
@@ -1202,20 +2006,75 @@ class ComponentInteraction extends Interaction {
1202
2006
  return result;
1203
2007
  }
1204
2008
  }
2009
+
2010
+ class ModalSubmitInteraction extends Interaction {
2011
+ get customId() {
2012
+ return this.data?.data?.custom_id ?? "";
2013
+ }
2014
+ getInputValue(customId) {
2015
+ const rows = this.data?.data?.components ?? [];
2016
+ for (const row of rows) {
2017
+ for (const comp of row.components ?? []) {
2018
+ if (comp.custom_id === customId)
2019
+ return comp.value;
2020
+ }
2021
+ }
2022
+ return;
2023
+ }
2024
+ getRequiredInputValue(customId) {
2025
+ const value = this.getInputValue(customId);
2026
+ if (value === undefined)
2027
+ throw new TypeError(`Modal input "${customId}" was not found in the submission.`);
2028
+ return value;
2029
+ }
2030
+ }
2031
+
2032
+ class AutocompleteInteraction extends Interaction {
2033
+ get commandName() {
2034
+ return this.data?.data?.name ?? "";
2035
+ }
2036
+ get focusedOption() {
2037
+ const options = this.data?.data?.options ?? [];
2038
+ return findFocused(options);
2039
+ }
2040
+ async respond(choices) {
2041
+ if (!Array.isArray(choices))
2042
+ throw new TypeError("Autocomplete choices must be an array.");
2043
+ const response = new InteractionResponse(InteractionResponseType.Autocomplete, { choices });
2044
+ await this.postResponse(response);
2045
+ this.replied = true;
2046
+ }
2047
+ }
2048
+ function findFocused(options) {
2049
+ for (const opt of options) {
2050
+ if (opt.focused)
2051
+ return { name: opt.name, value: opt.value, type: opt.type };
2052
+ if (Array.isArray(opt.options)) {
2053
+ const found = findFocused(opt.options);
2054
+ if (found)
2055
+ return found;
2056
+ }
2057
+ }
2058
+ return;
2059
+ }
1205
2060
  function createInteraction(client, data) {
1206
2061
  switch (data.type) {
1207
2062
  case InteractionType.ApplicationCommand:
1208
- case InteractionType.ApplicationCommandAutocomplete:
1209
2063
  return new CommandInteraction(client, data);
2064
+ case InteractionType.ApplicationCommandAutocomplete:
2065
+ return new AutocompleteInteraction(client, data);
1210
2066
  case InteractionType.MessageComponent:
1211
- case InteractionType.ModalSubmit:
1212
2067
  return new ComponentInteraction(client, data);
2068
+ case InteractionType.ModalSubmit:
2069
+ return new ModalSubmitInteraction(client, data);
1213
2070
  default:
1214
2071
  return new Interaction(client, data);
1215
2072
  }
1216
2073
  }
1217
2074
 
1218
2075
  // packages/structures/src/index.ts
2076
+ var NON_SYSTEM_MESSAGE_TYPES = new Set([0, 19, 20, 23]);
2077
+
1219
2078
  class Message extends BaseStructure {
1220
2079
  content;
1221
2080
  author;
@@ -1223,7 +2082,7 @@ class Message extends BaseStructure {
1223
2082
  channel;
1224
2083
  guildId;
1225
2084
  flags;
1226
- createdAt;
2085
+ timestamp;
1227
2086
  attachments;
1228
2087
  embeds;
1229
2088
  mentions;
@@ -1232,6 +2091,7 @@ class Message extends BaseStructure {
1232
2091
  mentionEveryone;
1233
2092
  type;
1234
2093
  reference;
2094
+ components;
1235
2095
  referencedMessage;
1236
2096
  #context;
1237
2097
  constructor(data, context) {
@@ -1243,9 +2103,10 @@ class Message extends BaseStructure {
1243
2103
  this.channelId = data.channel_id;
1244
2104
  this.guildId = data.guild_id;
1245
2105
  this.flags = data.flags ?? 0;
1246
- this.createdAt = new Date(data.timestamp ?? Number((BigInt(this.id) >> 22n) + 1420070400000n));
2106
+ this.timestamp = new Date(data.timestamp ?? Number((BigInt(this.id) >> 22n) + 1420070400000n));
1247
2107
  this.attachments = data.attachments ?? [];
1248
2108
  this.embeds = data.embeds ?? [];
2109
+ this.components = data.components ?? [];
1249
2110
  this.mentions = (data.mentions ?? []).map((user) => new User(user));
1250
2111
  this.mentionRoles = data.mention_roles ?? [];
1251
2112
  this.pinned = data.pinned ?? false;
@@ -1259,21 +2120,25 @@ class Message extends BaseStructure {
1259
2120
  get embedsSuppressed() {
1260
2121
  return (this.flags & 4) !== 0;
1261
2122
  }
2123
+ get createdTimestamp() {
2124
+ return this.timestamp.getTime();
2125
+ }
2126
+ get createdAt() {
2127
+ return this.timestamp;
2128
+ }
1262
2129
  edit(options) {
1263
2130
  if (!this.#context)
1264
2131
  throw new Error("This message is not attached to a client.");
1265
2132
  return this.#context.editMessage(this.channelId, this.id, options);
1266
2133
  }
2134
+ update(options) {
2135
+ return this.edit(options);
2136
+ }
1267
2137
  delete() {
1268
2138
  if (!this.#context)
1269
2139
  throw new Error("This message is not attached to a client.");
1270
2140
  return this.#context.deleteMessage(this.channelId, this.id);
1271
2141
  }
1272
- crosspost() {
1273
- if (!this.#context)
1274
- throw new Error("This message is not attached to a client.");
1275
- return this.#context.crosspostMessage(this.channelId, this.id);
1276
- }
1277
2142
  reply(options) {
1278
2143
  if (!this.#context)
1279
2144
  throw new Error("This message is not attached to a client.");
@@ -1285,6 +2150,81 @@ class Message extends BaseStructure {
1285
2150
  };
1286
2151
  return this.#context.sendMessage(this.channelId, payload);
1287
2152
  }
2153
+ crosspost() {
2154
+ if (!this.#context)
2155
+ throw new Error("This message is not attached to a client.");
2156
+ return this.#context.crosspostMessage(this.channelId, this.id);
2157
+ }
2158
+ react(emoji) {
2159
+ if (!this.#context?.addReaction)
2160
+ throw new Error("This message is not attached to a client.");
2161
+ return this.#context.addReaction(this.channelId, this.id, emoji);
2162
+ }
2163
+ removeReaction(emoji, userId) {
2164
+ if (!this.#context)
2165
+ throw new Error("This message is not attached to a client.");
2166
+ return userId ? this.#context.removeReaction?.(this.channelId, this.id, emoji, userId) ?? Promise.reject(new Error("Reaction operations are unavailable.")) : this.#context.removeOwnReaction?.(this.channelId, this.id, emoji) ?? Promise.reject(new Error("Reaction operations are unavailable."));
2167
+ }
2168
+ removeAllReactions() {
2169
+ if (!this.#context?.removeAllReactions)
2170
+ throw new Error("This message is not attached to a client.");
2171
+ return this.#context.removeAllReactions(this.channelId, this.id);
2172
+ }
2173
+ pin() {
2174
+ if (!this.#context?.pinMessage)
2175
+ throw new Error("This message is not attached to a client.");
2176
+ return this.#context.pinMessage(this.channelId, this.id);
2177
+ }
2178
+ unpin() {
2179
+ if (!this.#context?.unpinMessage)
2180
+ throw new Error("This message is not attached to a client.");
2181
+ return this.#context.unpinMessage(this.channelId, this.id);
2182
+ }
2183
+ get isEphemeral() {
2184
+ return (this.flags & 64) !== 0;
2185
+ }
2186
+ get isPinned() {
2187
+ return this.pinned;
2188
+ }
2189
+ get isSystemMessage() {
2190
+ return !NON_SYSTEM_MESSAGE_TYPES.has(this.type);
2191
+ }
2192
+ get isCrosspost() {
2193
+ return (this.flags & 2) !== 0;
2194
+ }
2195
+ get hasAttachments() {
2196
+ return this.attachments.length > 0;
2197
+ }
2198
+ get hasEmbeds() {
2199
+ return this.embeds.length > 0;
2200
+ }
2201
+ get hasComponents() {
2202
+ return this.components.length > 0;
2203
+ }
2204
+ suppressEmbeds() {
2205
+ return this.edit({ flags: this.flags | 4 });
2206
+ }
2207
+ toJSON() {
2208
+ return {
2209
+ id: this.id,
2210
+ content: this.content,
2211
+ channelId: this.channelId,
2212
+ guildId: this.guildId,
2213
+ flags: this.flags,
2214
+ pinned: this.pinned,
2215
+ mentionEveryone: this.mentionEveryone,
2216
+ type: this.type,
2217
+ timestamp: this.timestamp.toISOString(),
2218
+ author: { id: this.author.id, username: this.author.username },
2219
+ attachments: [...this.attachments],
2220
+ embeds: [...this.embeds],
2221
+ components: [...this.components],
2222
+ mentions: this.mentions.map((u) => u.id),
2223
+ mentionRoles: [...this.mentionRoles],
2224
+ reference: this.reference,
2225
+ referencedMessage: this.referencedMessage ? this.referencedMessage.id : this.referencedMessage
2226
+ };
2227
+ }
1288
2228
  }
1289
2229
 
1290
2230
  // packages/managers/src/message.ts
@@ -1309,10 +2249,7 @@ class MessageManager {
1309
2249
  }
1310
2250
  async fetch(messageId) {
1311
2251
  const data = await this.#rest.get(Routes.message(this.#channelId, messageId));
1312
- const message = Array.isArray(data) ? data[0] : data;
1313
- if (!message)
1314
- throw new Error("Discord returned no message payload.");
1315
- return this.upsert(message);
2252
+ return this.upsert(data);
1316
2253
  }
1317
2254
  fetchMany(messageIds) {
1318
2255
  return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
@@ -1353,8 +2290,110 @@ class ThreadManager {
1353
2290
  return new Channel(data, this.#context);
1354
2291
  }
1355
2292
  }
1356
- // packages/managers/src/application.ts
1357
- class ApplicationCommandManager {
2293
+
2294
+ // packages/managers/src/user.ts
2295
+ class UserManager extends ResourceManager {
2296
+ #rest;
2297
+ constructor(rest) {
2298
+ super(async (id) => new User(await rest.get(Routes.userById(id))), (user) => user.id);
2299
+ this.#rest = rest;
2300
+ }
2301
+ async fetchMe() {
2302
+ const data = await this.#rest.get("/users/@me");
2303
+ return this.upsert(new User(data));
2304
+ }
2305
+ async editMe(options) {
2306
+ const data = await this.#rest.patch("/users/@me", options);
2307
+ return this.upsert(new User(data));
2308
+ }
2309
+ async leaveGuild(guildId) {
2310
+ await this.#rest.delete(`/users/@me/guilds/${guildId}`);
2311
+ }
2312
+ async createDM(userId) {
2313
+ return this.#rest.post("/users/@me/channels", {
2314
+ recipient_id: userId
2315
+ });
2316
+ }
2317
+ }
2318
+ // packages/managers/src/guild.ts
2319
+ function withQuery(path, params) {
2320
+ const suffix = params.toString();
2321
+ return suffix ? `${path}?${suffix}` : path;
2322
+ }
2323
+
2324
+ class GuildManager extends ResourceManager {
2325
+ #rest;
2326
+ constructor(rest) {
2327
+ super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
2328
+ this.#rest = rest;
2329
+ }
2330
+ async create(options) {
2331
+ const data = await this.#rest.post("/guilds", options);
2332
+ return this.upsert(new Guild(data));
2333
+ }
2334
+ async edit(id, options) {
2335
+ const data = await this.#rest.patch(Routes.guild(id), options);
2336
+ return this.upsert(new Guild(data));
2337
+ }
2338
+ async deleteGuild(id) {
2339
+ await this.#rest.delete(Routes.guild(id));
2340
+ }
2341
+ async fetchPreview(id) {
2342
+ return this.#rest.get(Routes.guildPreview(id));
2343
+ }
2344
+ async fetchActiveThreads(id) {
2345
+ return this.#rest.get(Routes.guildActiveThreads(id));
2346
+ }
2347
+ async fetchWebhooks(id) {
2348
+ return this.#rest.get(Routes.guildWebhooks(id));
2349
+ }
2350
+ async fetchInvites(id) {
2351
+ return this.#rest.get(Routes.guildInvites(id));
2352
+ }
2353
+ async fetchAuditLog(guildId, options = {}) {
2354
+ const params = new URLSearchParams;
2355
+ if (options.userId)
2356
+ params.set("user_id", options.userId);
2357
+ if (options.actionType !== undefined)
2358
+ params.set("action_type", String(options.actionType));
2359
+ if (options.before)
2360
+ params.set("before", options.before);
2361
+ if (options.after)
2362
+ params.set("after", options.after);
2363
+ if (options.limit !== undefined)
2364
+ params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
2365
+ return this.#rest.get(withQuery(Routes.guildAuditLog(guildId), params));
2366
+ }
2367
+ async fetchMembers(guildId, options = {}) {
2368
+ const params = new URLSearchParams;
2369
+ if (options.limit !== undefined)
2370
+ params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
2371
+ if (options.after)
2372
+ params.set("after", options.after);
2373
+ return this.#rest.get(withQuery(Routes.guildMembers(guildId), params));
2374
+ }
2375
+ async fetchAutoModerationRules(guildId) {
2376
+ const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
2377
+ return rules.map((r) => new AutoModerationRule(r));
2378
+ }
2379
+ async fetchAutoModerationRule(guildId, ruleId) {
2380
+ const rule = await this.#rest.get(Routes.guildAutoModerationRule(guildId, ruleId));
2381
+ return new AutoModerationRule(rule);
2382
+ }
2383
+ async createAutoModerationRule(guildId, options) {
2384
+ const rule = await this.#rest.post(Routes.guildAutoModerationRules(guildId), options);
2385
+ return new AutoModerationRule(rule);
2386
+ }
2387
+ async editAutoModerationRule(guildId, ruleId, options) {
2388
+ const rule = await this.#rest.patch(Routes.guildAutoModerationRule(guildId, ruleId), options);
2389
+ return new AutoModerationRule(rule);
2390
+ }
2391
+ async deleteAutoModerationRule(guildId, ruleId) {
2392
+ await this.#rest.delete(Routes.guildAutoModerationRule(guildId, ruleId));
2393
+ }
2394
+ }
2395
+ // packages/managers/src/application.ts
2396
+ class ApplicationCommandManager {
1358
2397
  #rest;
1359
2398
  #applicationId;
1360
2399
  constructor(rest, applicationId) {
@@ -1394,23 +2433,6 @@ class ApplicationCommandManager {
1394
2433
  }
1395
2434
 
1396
2435
  // packages/managers/src/index.ts
1397
- class UserManager extends ResourceManager {
1398
- constructor(rest) {
1399
- super(async (id) => new User(await rest.get(Routes.userById(id))), (user) => user.id);
1400
- }
1401
- }
1402
-
1403
- class GuildManager extends ResourceManager {
1404
- constructor(rest) {
1405
- super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
1406
- }
1407
- }
1408
- var MessageCreateOptions = undefined;
1409
- var MessageEditOptions = undefined;
1410
- var MessageFetchOptions = undefined;
1411
- var MessageThreadOptions = undefined;
1412
- var ReactionFetchOptions = undefined;
1413
-
1414
2436
  class ChannelManager extends Manager {
1415
2437
  #rest;
1416
2438
  #context;
@@ -1422,7 +2444,15 @@ class ChannelManager extends Manager {
1422
2444
  sendMessage: (channelId, options) => this.send(channelId, options),
1423
2445
  editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
1424
2446
  deleteMessage: (channelId, messageId) => this.deleteMessage(channelId, messageId),
1425
- crosspostMessage: (channelId, messageId) => this.crosspostMessage(channelId, messageId)
2447
+ crosspostMessage: (channelId, messageId) => this.crosspostMessage(channelId, messageId),
2448
+ editChannel: (channelId, options) => this.edit(channelId, options),
2449
+ deleteChannel: (channelId) => this.deleteChannel(channelId),
2450
+ addReaction: (channelId, messageId, emoji) => this.addReaction(channelId, messageId, emoji),
2451
+ removeOwnReaction: (channelId, messageId, emoji) => this.removeOwnReaction(channelId, messageId, emoji),
2452
+ removeReaction: (channelId, messageId, emoji, userId) => this.removeReaction(channelId, messageId, emoji, userId),
2453
+ removeAllReactions: (channelId, messageId) => this.removeAllReactions(channelId, messageId),
2454
+ pinMessage: (channelId, messageId) => this.pinMessage(channelId, messageId),
2455
+ unpinMessage: (channelId, messageId) => this.unpinMessage(channelId, messageId)
1426
2456
  };
1427
2457
  }
1428
2458
  messages(channelId) {
@@ -1437,8 +2467,7 @@ class ChannelManager extends Manager {
1437
2467
  return new ThreadManager(this.#rest, this.#context, channelId);
1438
2468
  }
1439
2469
  async fetch(channelId) {
1440
- const data = await this.#rest.get(Routes.channel(channelId));
1441
- return this.upsert(data);
2470
+ return this.upsert(await this.#rest.get(Routes.channel(channelId)));
1442
2471
  }
1443
2472
  async resolve(channelId) {
1444
2473
  return this.get(channelId) ?? this.fetch(channelId);
@@ -1456,6 +2485,20 @@ class ChannelManager extends Manager {
1456
2485
  update(channel) {
1457
2486
  return this.set(channel.id, channel);
1458
2487
  }
2488
+ async create(guildId, options) {
2489
+ return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
2490
+ }
2491
+ async edit(channelId, options) {
2492
+ return this.upsert(await this.#rest.patch(Routes.channel(channelId), options));
2493
+ }
2494
+ async deleteChannel(channelId) {
2495
+ await this.#rest.delete(Routes.channel(channelId));
2496
+ this.delete(channelId);
2497
+ }
2498
+ delete(channelId) {
2499
+ this.#messageManagers.delete(channelId);
2500
+ return super.delete(channelId);
2501
+ }
1459
2502
  send(channelId, options) {
1460
2503
  return this.messages(channelId).send(options);
1461
2504
  }
@@ -1485,8 +2528,7 @@ class ChannelManager extends Manager {
1485
2528
  return this.messages(data.channel_id).upsert(data);
1486
2529
  }
1487
2530
  async editMessage(channelId, messageId, options) {
1488
- const data = await this.#rest.patch(Routes.message(channelId, messageId), options);
1489
- return this.messages(channelId).upsert(data);
2531
+ return this.messages(channelId).upsert(await this.#rest.patch(Routes.message(channelId, messageId), options));
1490
2532
  }
1491
2533
  async deleteMessage(channelId, messageId) {
1492
2534
  await this.#rest.delete(Routes.message(channelId, messageId));
@@ -1496,11 +2538,12 @@ class ChannelManager extends Manager {
1496
2538
  return this.messages(channelId).delete(messageId);
1497
2539
  }
1498
2540
  async crosspostMessage(channelId, messageId) {
1499
- const data = await this.#rest.post(Routes.crosspostMessage(channelId, messageId));
1500
- return this.messages(channelId).upsert(data);
2541
+ return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
1501
2542
  }
1502
2543
  async bulkDeleteMessages(channelId, messageIds) {
1503
2544
  const ids = [...messageIds];
2545
+ if (ids.length < 2 || ids.length > 100)
2546
+ throw new RangeError("bulkDelete requires between 2 and 100 message IDs.");
1504
2547
  await this.#rest.post(Routes.channelBulkDelete(channelId), {
1505
2548
  messages: ids
1506
2549
  });
@@ -1508,7 +2551,7 @@ class ChannelManager extends Manager {
1508
2551
  this.messages(channelId).delete(id);
1509
2552
  }
1510
2553
  async addReaction(channelId, messageId, emoji) {
1511
- await this.#rest.put(Routes.messageReactions(channelId, messageId, emoji));
2554
+ await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
1512
2555
  }
1513
2556
  async fetchReactions(channelId, messageId, emoji, options = {}) {
1514
2557
  const params = new URLSearchParams;
@@ -1521,7 +2564,7 @@ class ChannelManager extends Manager {
1521
2564
  return data.map((user) => new User(user));
1522
2565
  }
1523
2566
  async removeOwnReaction(channelId, messageId, emoji) {
1524
- await this.#rest.delete(Routes.messageReactions(channelId, messageId, emoji) + "/@me");
2567
+ await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
1525
2568
  }
1526
2569
  async removeReaction(channelId, messageId, emoji, userId) {
1527
2570
  await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/${userId}`);
@@ -1542,9 +2585,21 @@ class ChannelManager extends Manager {
1542
2585
  createThreadFromMessage(channelId, messageId, options) {
1543
2586
  return this.threads(channelId).createFromMessage(messageId, options);
1544
2587
  }
1545
- delete(channelId) {
1546
- this.#messageManagers.delete(channelId);
1547
- return super.delete(channelId);
2588
+ async fetchPage(channelId, options = {}) {
2589
+ const limit = Math.min(100, Math.max(1, options.limit ?? 50));
2590
+ const messages = await this.fetchMessages(channelId, {
2591
+ ...options,
2592
+ limit
2593
+ });
2594
+ return {
2595
+ messages,
2596
+ before: messages[0]?.id,
2597
+ after: messages[messages.length - 1]?.id,
2598
+ hasMore: messages.length === limit
2599
+ };
2600
+ }
2601
+ async bulkDelete(channelId, messageIds) {
2602
+ return this.bulkDeleteMessages(channelId, messageIds);
1548
2603
  }
1549
2604
  clear() {
1550
2605
  this.#messageManagers.clear();
@@ -1555,126 +2610,6 @@ function isMessageQuery(value) {
1555
2610
  return typeof value === "object" && value !== null && !(Symbol.iterator in value);
1556
2611
  }
1557
2612
 
1558
- // packages/types/src/index.ts
1559
- var GatewayIntentBits = {
1560
- Guilds: 1 << 0,
1561
- GuildMembers: 1 << 1,
1562
- GuildModeration: 1 << 2,
1563
- GuildExpressions: 1 << 3,
1564
- GuildIntegrations: 1 << 4,
1565
- GuildWebhooks: 1 << 5,
1566
- GuildInvites: 1 << 6,
1567
- GuildVoiceStates: 1 << 7,
1568
- GuildPresences: 1 << 8,
1569
- GuildMessages: 1 << 9,
1570
- GuildMessageReactions: 1 << 10,
1571
- GuildMessageTyping: 1 << 11,
1572
- DirectMessages: 1 << 12,
1573
- DirectMessageReactions: 1 << 13,
1574
- DirectMessageTyping: 1 << 14,
1575
- MessageContent: 1 << 15,
1576
- GuildScheduledEvents: 1 << 16,
1577
- AutoModerationConfiguration: 1 << 20,
1578
- AutoModerationExecution: 1 << 21,
1579
- GuildMessagePolls: 1 << 24,
1580
- DirectMessagePolls: 1 << 25
1581
- };
1582
- var IntentBits = {
1583
- guild: 1 << 0,
1584
- guilds: 1 << 0,
1585
- guildMembers: 1 << 1,
1586
- guildModeration: 1 << 2,
1587
- guildBans: 1 << 2,
1588
- guildExpressions: 1 << 3,
1589
- guildEmojis: 1 << 3,
1590
- guildEmojisAndStickers: 1 << 3,
1591
- guildIntegrations: 1 << 4,
1592
- guildWebhooks: 1 << 5,
1593
- guildInvites: 1 << 6,
1594
- guildVoiceStates: 1 << 7,
1595
- guildPresences: 1 << 8,
1596
- guildMessages: 1 << 9,
1597
- guildMessage: 1 << 9,
1598
- guildMessageReactions: 1 << 10,
1599
- guildMessageTyping: 1 << 11,
1600
- directMessages: 1 << 12,
1601
- directMessageReactions: 1 << 13,
1602
- directMessageTyping: 1 << 14,
1603
- messageContent: 1 << 15,
1604
- guildScheduledEvents: 1 << 16,
1605
- autoModerationConfiguration: 1 << 20,
1606
- autoModerationExecution: 1 << 21,
1607
- guildMessagePolls: 1 << 24,
1608
- directMessagePolls: 1 << 25
1609
- };
1610
- var Intents = IntentBits;
1611
- function resolveGatewayIntents(intents) {
1612
- if (typeof intents === "number")
1613
- return intents;
1614
- if (Array.isArray(intents)) {
1615
- return intents.reduce((acc, intent) => {
1616
- return acc | resolveGatewayIntents(intent);
1617
- }, 0);
1618
- }
1619
- if (typeof intents === "string") {
1620
- if (intents in GatewayIntentBits)
1621
- return GatewayIntentBits[intents];
1622
- if (intents in IntentBits)
1623
- return IntentBits[intents];
1624
- const lower = intents.charAt(0).toLowerCase() + intents.slice(1);
1625
- if (lower in IntentBits)
1626
- return IntentBits[lower];
1627
- const num = Number(intents);
1628
- if (!Number.isNaN(num))
1629
- return num;
1630
- }
1631
- return 0;
1632
- }
1633
- var MessageFlags = {
1634
- Crossposted: 1,
1635
- IsCrosspost: 2,
1636
- SuppressEmbeds: 4,
1637
- SourceMessageDeleted: 8,
1638
- Urgent: 16,
1639
- HasThread: 32,
1640
- Ephemeral: 64,
1641
- Loading: 128,
1642
- IsComponentsV2: 32768
1643
- };
1644
- var ChannelType = {
1645
- GuildText: 0,
1646
- DM: 1,
1647
- GuildVoice: 2,
1648
- GroupDM: 3,
1649
- GuildCategory: 4,
1650
- GuildAnnouncement: 5,
1651
- AnnouncementThread: 10,
1652
- PublicThread: 11,
1653
- PrivateThread: 12,
1654
- GuildStageVoice: 13,
1655
- GuildDirectory: 14,
1656
- GuildForum: 15,
1657
- GuildMedia: 16
1658
- };
1659
- var ApplicationCommandOptionType = {
1660
- SubCommand: 1,
1661
- SubCommandGroup: 2,
1662
- String: 3,
1663
- Integer: 4,
1664
- Boolean: 5,
1665
- User: 6,
1666
- Channel: 7,
1667
- Role: 8,
1668
- Mentionable: 9,
1669
- Number: 10,
1670
- Attachment: 11
1671
- };
1672
- var ApplicationCommandType = {
1673
- ChatInput: 1,
1674
- User: 2,
1675
- Message: 3
1676
- };
1677
-
1678
2613
  // packages/ws/src/index.ts
1679
2614
  var GatewayOpcodes = {
1680
2615
  Dispatch: 0,
@@ -1689,6 +2624,22 @@ var GatewayOpcodes = {
1689
2624
  Hello: 10,
1690
2625
  HeartbeatAck: 11
1691
2626
  };
2627
+ var GatewayCloseCodes = {
2628
+ UnknownError: 4000,
2629
+ UnknownOpcode: 4001,
2630
+ DecodeError: 4002,
2631
+ NotAuthenticated: 4003,
2632
+ AuthenticationFailed: 4004,
2633
+ AlreadyAuthenticated: 4005,
2634
+ InvalidSeq: 4007,
2635
+ RateLimited: 4008,
2636
+ SessionTimedOut: 4009,
2637
+ InvalidShard: 4010,
2638
+ ShardingRequired: 4011,
2639
+ InvalidAPIVersion: 4012,
2640
+ InvalidIntents: 4013,
2641
+ DisallowedIntents: 4014
2642
+ };
1692
2643
  class GatewayError extends Error {
1693
2644
  code;
1694
2645
  constructor(message, code, options) {
@@ -1722,6 +2673,8 @@ class Gateway {
1722
2673
  #rejectConnect;
1723
2674
  #listeners = new Map;
1724
2675
  #sendTimestamps = [];
2676
+ ping = -1;
2677
+ #decompressor;
1725
2678
  constructor(options) {
1726
2679
  if (!options.token?.trim())
1727
2680
  throw new TypeError("A Gateway token is required.");
@@ -1742,7 +2695,12 @@ class Gateway {
1742
2695
  browser: "Discord Android",
1743
2696
  device: "Discord Android"
1744
2697
  },
1745
- presence: { status: "online", activities: [], afk: false, since: null },
2698
+ presence: {
2699
+ status: "online",
2700
+ activities: [],
2701
+ afk: false,
2702
+ since: null
2703
+ },
1746
2704
  ...options
1747
2705
  };
1748
2706
  if (this.#options.shardId < 0 || this.#options.shardId >= this.#options.shardCount)
@@ -1757,10 +2715,13 @@ class Gateway {
1757
2715
  return this.#connectPromise;
1758
2716
  this.#closed = false;
1759
2717
  this.#setState("CONNECT" /* Connect */);
2718
+ const connectURL = this.#options.compress ? url.includes("compress=") ? url : `${url}&compress=zlib-stream` : url;
2719
+ if (this.#options.compress)
2720
+ this.#initDecompressor();
1760
2721
  this.#connectPromise = new Promise((resolve, reject) => {
1761
2722
  this.#resolveConnect = resolve;
1762
2723
  this.#rejectConnect = reject;
1763
- this.#open(url);
2724
+ this.#open(connectURL);
1764
2725
  });
1765
2726
  return this.#connectPromise;
1766
2727
  }
@@ -1796,12 +2757,15 @@ class Gateway {
1796
2757
  send(payload) {
1797
2758
  if (!payload || !Number.isInteger(payload.op))
1798
2759
  throw new TypeError("Gateway payload must contain an integer opcode.");
2760
+ return this.#dispatch(payload, false);
2761
+ }
2762
+ #dispatch(payload, privileged) {
1799
2763
  if (this.#ws?.readyState !== WebSocket.OPEN)
1800
2764
  return false;
1801
2765
  const now = Date.now();
1802
2766
  while (this.#sendTimestamps.length && now - this.#sendTimestamps[0] >= 60000)
1803
2767
  this.#sendTimestamps.shift();
1804
- if (this.#sendTimestamps.length >= 115) {
2768
+ if (!privileged && this.#sendTimestamps.length >= 115) {
1805
2769
  this.#emitError(new GatewayError("Gateway send rate budget exhausted."));
1806
2770
  return false;
1807
2771
  }
@@ -1872,7 +2836,11 @@ class Gateway {
1872
2836
  ws.addEventListener("message", (event) => {
1873
2837
  this.#lastMessageAt = Date.now();
1874
2838
  this.#zombieReported = false;
1875
- this.#message(ws, String(event.data));
2839
+ if (this.#options.compress && event.data instanceof ArrayBuffer) {
2840
+ this.#decompress(new Uint8Array(event.data)).then((text) => this.#message(ws, text)).catch((err) => this.#emitError(err));
2841
+ } else {
2842
+ this.#message(ws, String(event.data));
2843
+ }
1876
2844
  });
1877
2845
  ws.addEventListener("close", (event) => this.#close(ws, event.code));
1878
2846
  ws.addEventListener("error", () => this.#emitError(new GatewayError("Gateway WebSocket error")));
@@ -1880,7 +2848,7 @@ class Gateway {
1880
2848
  #startZombieDetection() {
1881
2849
  if (this.#zombieTimer)
1882
2850
  clearInterval(this.#zombieTimer);
1883
- const interval = Math.max(1, Math.min(250, this.#options.heartbeatAckTimeout, this.#options.zombieTimeout / 2));
2851
+ const interval = Math.max(1, Math.min(1000, this.#options.heartbeatAckTimeout, this.#options.zombieTimeout / 2));
1884
2852
  this.#zombieTimer = setInterval(() => {
1885
2853
  if (this.#closed || this.#ws?.readyState !== WebSocket.OPEN || this.#lastMessageAt === 0)
1886
2854
  return;
@@ -1931,18 +2899,24 @@ class Gateway {
1931
2899
  break;
1932
2900
  case GatewayOpcodes.HeartbeatAck:
1933
2901
  this.#heartbeatACK = true;
2902
+ this.ping = Date.now() - this.#heartbeatSentAt;
1934
2903
  this.#clearHeartbeatAckTimer();
1935
2904
  this.#emit("heartbeatAck", payload.d);
1936
2905
  break;
1937
2906
  case GatewayOpcodes.Reconnect:
1938
2907
  ws.close(1001, "Server requested reconnect");
1939
2908
  break;
1940
- case GatewayOpcodes.InvalidSession:
1941
- this.#sessionId = undefined;
1942
- this.#sequence = null;
1943
- this.#emit("invalidSession", payload.d);
1944
- ws.close(1000, "Invalid session");
2909
+ case GatewayOpcodes.InvalidSession: {
2910
+ const resumable = payload.d === true;
2911
+ if (!resumable) {
2912
+ this.#sessionId = undefined;
2913
+ this.#sequence = null;
2914
+ this.#resumeURL = undefined;
2915
+ }
2916
+ this.#emit("invalidSession", resumable);
2917
+ ws.close(resumable ? GatewayCloseCodes.UnknownError : 1000, resumable ? "Invalid session (resumable)" : "Invalid session");
1945
2918
  break;
2919
+ }
1946
2920
  }
1947
2921
  }
1948
2922
  #handleDispatch(event, data) {
@@ -1957,7 +2931,14 @@ class Gateway {
1957
2931
  this.#attempt = 0;
1958
2932
  this.#setState("READY" /* Ready */);
1959
2933
  this.#emit("ready", data);
2934
+ } else if (event === "RESUMED") {
2935
+ this.#attempt = 0;
2936
+ this.#setState("READY" /* Ready */);
2937
+ this.#emit("resumed", data);
1960
2938
  }
2939
+ this.#emit("RAW", { event: event ?? "UNKNOWN", data });
2940
+ if (this.#closed)
2941
+ return;
1961
2942
  this.#emit(event ?? "dispatch", data);
1962
2943
  }
1963
2944
  #handleHello(data) {
@@ -2031,12 +3012,12 @@ class Gateway {
2031
3012
  #sendHeartbeat() {
2032
3013
  this.#heartbeatACK = false;
2033
3014
  this.#heartbeatSentAt = Date.now();
2034
- if (!this.send({
3015
+ if (!this.#dispatch({
2035
3016
  op: GatewayOpcodes.Heartbeat,
2036
3017
  d: this.#sequence,
2037
3018
  s: null,
2038
3019
  t: null
2039
- })) {
3020
+ }, true)) {
2040
3021
  this.#emitError(new GatewayError("Unable to send Gateway heartbeat because the WebSocket is not open."));
2041
3022
  return;
2042
3023
  }
@@ -2069,14 +3050,23 @@ class Gateway {
2069
3050
  if (action === "identify") {
2070
3051
  this.#sequence = null;
2071
3052
  this.#sessionId = undefined;
3053
+ this.#resumeURL = undefined;
2072
3054
  }
2073
3055
  this.#setState("RECONNECT" /* Reconnect */);
2074
3056
  this.#scheduleReconnect();
2075
3057
  }
2076
3058
  #closeAction(code) {
2077
- if ([4004, 4010, 4011, 4012, 4013, 4014].includes(code))
3059
+ const fatal = [
3060
+ GatewayCloseCodes.AuthenticationFailed,
3061
+ GatewayCloseCodes.InvalidShard,
3062
+ GatewayCloseCodes.ShardingRequired,
3063
+ GatewayCloseCodes.InvalidAPIVersion,
3064
+ GatewayCloseCodes.InvalidIntents,
3065
+ GatewayCloseCodes.DisallowedIntents
3066
+ ];
3067
+ if (fatal.includes(code))
2078
3068
  return "stop";
2079
- if ([4007, 4009].includes(code))
3069
+ if (code === GatewayCloseCodes.InvalidSeq || code === GatewayCloseCodes.SessionTimedOut)
2080
3070
  return "identify";
2081
3071
  return this.#sessionId && this.#sequence !== null ? "resume" : "identify";
2082
3072
  }
@@ -2089,7 +3079,7 @@ class Gateway {
2089
3079
  return;
2090
3080
  }
2091
3081
  const delay = Math.min(this.#options.reconnectMaxDelay, this.#options.reconnectBaseDelay * 2 ** this.#attempt++);
2092
- const jitter = Math.random() * Math.min(250, Math.max(1, delay * 0.25));
3082
+ const jitter = Math.random() * Math.max(1, delay * 0.25);
2093
3083
  this.#reconnectTimer = setTimeout(() => {
2094
3084
  this.#reconnectTimer = undefined;
2095
3085
  this.#open(this.#resumeURL ?? "wss://gateway.discord.gg/?v=10&encoding=json");
@@ -2159,690 +3149,36 @@ class Gateway {
2159
3149
  this.state = next;
2160
3150
  this.#emit("stateChange", { previous, next });
2161
3151
  }
2162
- }
2163
- // packages/builders/src/embed.ts
2164
- class EmbedBuilder {
2165
- #data = {};
2166
- setTitle(value) {
2167
- this.#data.title = validate(value, 256, "Embed title");
2168
- return this;
2169
- }
2170
- setDescription(value) {
2171
- this.#data.description = validate(value, 4096, "Embed description");
2172
- return this;
2173
- }
2174
- setURL(value) {
2175
- this.#data.url = url(value, "Embed URL");
2176
- return this;
2177
- }
2178
- setColor(value) {
2179
- if (!Number.isInteger(value) || value < 0 || value > 16777215)
2180
- throw new RangeError("Embed color must be an integer between 0 and 16777215.");
2181
- this.#data.color = value;
2182
- return this;
2183
- }
2184
- setTimestamp(value = new Date) {
2185
- const date = value instanceof Date ? value : new Date(value);
2186
- if (Number.isNaN(date.getTime()))
2187
- throw new RangeError("Embed timestamp must be a valid date.");
2188
- this.#data.timestamp = date.toISOString();
2189
- return this;
2190
- }
2191
- setFooter(value) {
2192
- this.#data.footer = {
2193
- text: validate(value.text, 2048, "Footer text"),
2194
- ...value.icon_url ? { icon_url: url(value.icon_url, "Footer icon URL") } : {}
2195
- };
2196
- return this;
2197
- }
2198
- setAuthor(value) {
2199
- this.#data.author = {
2200
- name: validate(value.name, 256, "Author name"),
2201
- ...value.url ? { url: url(value.url, "Author URL") } : {},
2202
- ...value.icon_url ? { icon_url: url(value.icon_url, "Author icon URL") } : {}
3152
+ #initDecompressor() {
3153
+ const ds = new DecompressionStream("deflate-raw");
3154
+ this.#decompressor = {
3155
+ writer: ds.writable.getWriter(),
3156
+ reader: ds.readable.getReader()
2203
3157
  };
2204
- return this;
2205
- }
2206
- setThumbnail(value) {
2207
- const valueURL = typeof value === "string" ? value : value.url;
2208
- this.#data.thumbnail = { url: url(valueURL, "Thumbnail URL") };
2209
- return this;
2210
- }
2211
- setImage(value) {
2212
- const valueURL = typeof value === "string" ? value : value.url;
2213
- this.#data.image = { url: url(valueURL, "Image URL") };
2214
- return this;
2215
- }
2216
- addFields(...fields) {
2217
- if (!fields.length)
2218
- throw new TypeError("At least one embed field is required.");
2219
- const current = this.#data.fields ?? [];
2220
- if (current.length + fields.length > 25)
2221
- throw new RangeError("An embed cannot contain more than 25 fields.");
2222
- for (const field of fields) {
2223
- validate(field.name, 256, "Embed field name");
2224
- validate(field.value, 1024, "Embed field value");
2225
- }
2226
- this.#data.fields = [...current, ...fields.map((field) => ({ ...field }))];
2227
- return this;
2228
- }
2229
- setFields(fields) {
2230
- this.#data.fields = [];
2231
- return this.addFields(...fields);
2232
- }
2233
- spliceFields(index, deleteCount, ...fields) {
2234
- const current = [...this.#data.fields ?? []];
2235
- if (!Number.isInteger(index) || !Number.isInteger(deleteCount) || index < 0 || deleteCount < 0)
2236
- throw new RangeError("Field index and delete count must be non-negative integers.");
2237
- current.splice(index, deleteCount, ...fields);
2238
- if (current.length > 25)
2239
- throw new RangeError("An embed cannot contain more than 25 fields.");
2240
- this.#data.fields = current;
2241
- return this;
2242
- }
2243
- clearFields() {
2244
- delete this.#data.fields;
2245
- return this;
2246
- }
2247
- clearTitle() {
2248
- delete this.#data.title;
2249
- return this;
2250
- }
2251
- clearDescription() {
2252
- delete this.#data.description;
2253
- return this;
2254
- }
2255
- get data() {
2256
- return this.toJSON();
2257
- }
2258
- toJSON() {
2259
- return structuredClone(this.#data);
2260
- }
2261
- }
2262
- function validate(value, max, field) {
2263
- if (typeof value !== "string" || value.length === 0 || value.length > max)
2264
- throw new RangeError(`${field} must contain 1-${max} characters.`);
2265
- return value;
2266
- }
2267
- function url(value, field) {
2268
- try {
2269
- return new URL(value).toString();
2270
- } catch (error) {
2271
- throw new TypeError(`${field} must be a valid URL.`, { cause: error });
2272
- }
2273
- }
2274
- // packages/builders/src/components.ts
2275
- var ComponentType = {
2276
- ActionRow: 1,
2277
- Button: 2,
2278
- StringSelect: 3,
2279
- TextInput: 4,
2280
- UserSelect: 5,
2281
- RoleSelect: 6,
2282
- MentionableSelect: 7,
2283
- ChannelSelect: 8
2284
- };
2285
- var ButtonStyle = {
2286
- Primary: 1,
2287
- Secondary: 2,
2288
- Success: 3,
2289
- Danger: 4,
2290
- Link: 5
2291
- };
2292
- class ActionRowBuilder {
2293
- #components = [];
2294
- addComponents(...components) {
2295
- if (!components.length)
2296
- throw new TypeError("At least one component is required.");
2297
- if (this.#components.length + components.length > 5)
2298
- throw new RangeError("An action row cannot contain more than 5 components.");
2299
- this.#components.push(...components);
2300
- return this;
2301
- }
2302
- clearComponents() {
2303
- this.#components.length = 0;
2304
- return this;
2305
- }
2306
- toJSON() {
2307
- return {
2308
- type: ComponentType.ActionRow,
2309
- components: this.#components.map((component) => component.toJSON())
2310
- };
2311
- }
2312
- }
2313
-
2314
- class StringSelectBuilder {
2315
- #data = {
2316
- type: ComponentType.StringSelect
2317
- };
2318
- setCustomId(value) {
2319
- validateText(value, 100, "Component custom ID");
2320
- this.#data.custom_id = value;
2321
- return this;
2322
- }
2323
- setPlaceholder(value) {
2324
- validateText(value, 150, "Component placeholder");
2325
- this.#data.placeholder = value;
2326
- return this;
2327
- }
2328
- setMinValues(value) {
2329
- validateCount(value, "min_values", 0);
2330
- this.#data.min_values = value;
2331
- return this;
2332
- }
2333
- setMaxValues(value) {
2334
- validateCount(value, "max_values", 1);
2335
- this.#data.max_values = value;
2336
- return this;
2337
- }
2338
- setRequired(value = true) {
2339
- this.#data.required = value;
2340
- return this;
2341
- }
2342
- setDisabled(value = true) {
2343
- this.#data.disabled = value;
2344
- return this;
2345
- }
2346
- addOptions(...options) {
2347
- if (!options.length)
2348
- throw new TypeError("At least one select option is required.");
2349
- const current = this.#data.options ?? [];
2350
- if (current.length + options.length > 25)
2351
- throw new RangeError("A string select cannot contain more than 25 options.");
2352
- for (const option of options) {
2353
- validateText(option.label, 100, "Select option label");
2354
- validateText(option.value, 100, "Select option value");
2355
- if (option.description)
2356
- validateText(option.description, 100, "Select option description");
2357
- }
2358
- this.#data.options = [
2359
- ...current,
2360
- ...options.map((option) => ({ ...option }))
2361
- ];
2362
- return this;
2363
- }
2364
- toJSON() {
2365
- return structuredClone(this.#data);
2366
- }
2367
- }
2368
-
2369
- class ButtonBuilder {
2370
- #data = {
2371
- type: ComponentType.Button,
2372
- style: ButtonStyle.Secondary
2373
- };
2374
- setStyle(style) {
2375
- this.#data.style = style;
2376
- if (style === ButtonStyle.Link)
2377
- delete this.#data.custom_id;
2378
- return this;
2379
- }
2380
- setCustomId(value) {
2381
- validateText(value, 100, "Button custom ID");
2382
- if (this.#data.style === ButtonStyle.Link)
2383
- throw new TypeError("Link buttons cannot use custom IDs.");
2384
- this.#data.custom_id = value;
2385
- return this;
2386
- }
2387
- setLabel(value) {
2388
- validateText(value, 80, "Button label");
2389
- this.#data.label = value;
2390
- return this;
2391
- }
2392
- setURL(value) {
2393
- validateText(value, 512, "Button URL");
2394
- let url2;
2395
- try {
2396
- url2 = new URL(value);
2397
- } catch (error) {
2398
- throw new TypeError("Button URL must be a valid URL.", { cause: error });
2399
- }
2400
- this.#data.style = ButtonStyle.Link;
2401
- delete this.#data.custom_id;
2402
- this.#data.url = url2.toString();
2403
- return this;
2404
- }
2405
- setEmoji(emoji) {
2406
- this.#data.emoji = typeof emoji === "string" ? { name: emoji } : { ...emoji };
2407
- return this;
2408
- }
2409
- setDisabled(value = true) {
2410
- this.#data.disabled = value;
2411
- return this;
2412
- }
2413
- toJSON() {
2414
- return structuredClone(this.#data);
2415
- }
2416
- }
2417
- function validateText(value, max, field) {
2418
- if (typeof value !== "string")
2419
- throw new TypeError(`${field} must be a string.`);
2420
- if (!value.trim())
2421
- throw new RangeError(`${field} must be a non-empty string.`);
2422
- if (value.length > max)
2423
- throw new RangeError(`${field} cannot exceed ${max} characters.`);
2424
- }
2425
- function validateCount(value, field, min, max = 25) {
2426
- if (!Number.isInteger(value) || value < min || value > max)
2427
- throw new RangeError(`${field} must be an integer between ${min} and ${max}.`);
2428
- }
2429
- // packages/builders/src/commands.ts
2430
- var ApplicationCommandOptionType2 = {
2431
- Subcommand: 1,
2432
- SubcommandGroup: 2,
2433
- String: 3,
2434
- Integer: 4,
2435
- Boolean: 5,
2436
- User: 6,
2437
- Channel: 7,
2438
- Role: 8,
2439
- Mentionable: 9,
2440
- Number: 10,
2441
- Attachment: 11
2442
- };
2443
-
2444
- class SlashCommandBuilder {
2445
- #data = { type: 1 };
2446
- setName(name) {
2447
- validateName(name, "Command name");
2448
- this.#data.name = name;
2449
- return this;
2450
- }
2451
- setDescription(description) {
2452
- validateText2(description, "Command description", 100);
2453
- this.#data.description = description;
2454
- return this;
2455
- }
2456
- setDMPermission(enabled) {
2457
- this.#data.dm_permission = enabled;
2458
- return this;
2459
- }
2460
- setNSFW(nsfw = true) {
2461
- this.#data.nsfw = nsfw;
2462
- return this;
2463
- }
2464
- setNsfw(nsfw = true) {
2465
- return this.setNSFW(nsfw);
2466
- }
2467
- setDefaultMemberPermissions(permissions) {
2468
- this.#data.default_member_permissions = permissions === null ? null : BigInt(permissions).toString();
2469
- return this;
2470
- }
2471
- setIntegrationTypes(...types) {
2472
- this.#data.integration_types = [...types];
2473
- return this;
2474
- }
2475
- addStringOption(configure) {
2476
- return this.addOption(configure(new StringOptionBuilder));
2477
- }
2478
- addIntegerOption(configure) {
2479
- return this.addOption(configure(new IntegerOptionBuilder));
2480
- }
2481
- addNumberOption(configure) {
2482
- return this.addOption(configure(new NumberOptionBuilder));
2483
- }
2484
- addBooleanOption(configure) {
2485
- return this.addOption(configure(new BooleanOptionBuilder));
2486
3158
  }
2487
- addUserOption(configure) {
2488
- return this.addOption(configure(new UserOptionBuilder));
2489
- }
2490
- addChannelOption(configure) {
2491
- return this.addOption(configure(new ChannelOptionBuilder));
2492
- }
2493
- addRoleOption(configure) {
2494
- return this.addOption(configure(new RoleOptionBuilder));
2495
- }
2496
- addMentionableOption(configure) {
2497
- return this.addOption(configure(new MentionableOptionBuilder));
2498
- }
2499
- addAttachmentOption(configure) {
2500
- return this.addOption(configure(new AttachmentOptionBuilder));
2501
- }
2502
- addSubcommand(configure) {
2503
- return this.addOption(configure(new SubcommandBuilder));
2504
- }
2505
- addSubcommandGroup(configure) {
2506
- return this.addOption(configure(new SubcommandGroupBuilder));
2507
- }
2508
- toJSON() {
2509
- return structuredClone(this.#data);
2510
- }
2511
- addOption(option) {
2512
- const options = this.#data.options ?? [];
2513
- if (options.length >= 25)
2514
- throw new RangeError("An application command cannot contain more than 25 options.");
2515
- const payload = option.toJSON();
2516
- if (options.some((existing) => existing.name === payload.name))
2517
- throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);
2518
- if (payload.required === true && options.some((existing) => existing.required !== true))
2519
- throw new RangeError("Required application command options must be placed before optional options.");
2520
- options.push(payload);
2521
- this.#data.options = options;
2522
- return this;
2523
- }
2524
- }
2525
-
2526
- class CommandOptionBuilder {
2527
- data;
2528
- constructor(type) {
2529
- this.data = { type };
2530
- }
2531
- setName(name) {
2532
- validateName(name, "Option name");
2533
- this.data.name = name;
2534
- return this;
2535
- }
2536
- setDescription(description) {
2537
- validateText2(description, "Option description", 100);
2538
- this.data.description = description;
2539
- return this;
2540
- }
2541
- setRequired(required = true) {
2542
- this.data.required = required;
2543
- return this;
2544
- }
2545
- setAutocomplete(enabled = true) {
2546
- this.data.autocomplete = enabled;
2547
- return this;
2548
- }
2549
- toJSON() {
2550
- return structuredClone(this.data);
2551
- }
2552
- }
2553
-
2554
- class StringOptionBuilder extends CommandOptionBuilder {
2555
- constructor() {
2556
- super(ApplicationCommandOptionType2.String);
2557
- }
2558
- addChoices(...choices) {
2559
- const current = this.data.choices ?? [];
2560
- if (!choices.length)
2561
- throw new TypeError("At least one choice is required.");
2562
- if (this.data.autocomplete === true)
2563
- throw new RangeError("Autocomplete options cannot define choices.");
2564
- if (current.length + choices.length > 25)
2565
- throw new RangeError("An option cannot contain more than 25 choices.");
2566
- for (const choice of choices) {
2567
- validateText2(choice.name, "Choice name", 100);
2568
- validateText2(choice.value, "Choice value", 100);
2569
- }
2570
- this.data.choices = [
2571
- ...current,
2572
- ...choices.map((choice) => ({ ...choice }))
2573
- ];
2574
- return this;
2575
- }
2576
- setMinLength(value) {
2577
- validateIntegerRange(value, 0, 6000, "min_length");
2578
- this.data.min_length = value;
2579
- return this;
2580
- }
2581
- setMaxLength(value) {
2582
- validateIntegerRange(value, 1, 6000, "max_length");
2583
- if (this.data.min_length !== undefined && this.data.min_length > value)
2584
- throw new RangeError("min_length cannot exceed max_length.");
2585
- this.data.max_length = value;
2586
- return this;
2587
- }
2588
- }
2589
-
2590
- class IntegerOptionBuilder extends CommandOptionBuilder {
2591
- constructor() {
2592
- super(ApplicationCommandOptionType2.Integer);
2593
- }
2594
- setMinValue(value) {
2595
- validateNumberRange(value, -9007199254740991, 9007199254740991, "min_value", true);
2596
- this.data.min_value = value;
2597
- return this;
2598
- }
2599
- setMaxValue(value) {
2600
- validateNumberRange(value, -9007199254740991, 9007199254740991, "max_value", true);
2601
- if (this.data.min_value !== undefined && this.data.min_value > value)
2602
- throw new RangeError("min_value cannot exceed max_value.");
2603
- this.data.max_value = value;
2604
- return this;
2605
- }
2606
- setAutocomplete(enabled = true) {
2607
- if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)
2608
- throw new RangeError("Autocomplete options cannot define choices.");
2609
- this.data.autocomplete = enabled;
2610
- return this;
2611
- }
2612
- addChoices(...choices) {
2613
- const current = this.data.choices ?? [];
2614
- if (!choices.length)
2615
- throw new TypeError("At least one choice is required.");
2616
- if (this.data.autocomplete === true)
2617
- throw new RangeError("Autocomplete options cannot define choices.");
2618
- if (current.length + choices.length > 25)
2619
- throw new RangeError("An option cannot contain more than 25 choices.");
2620
- this.data.choices = [...current, ...choices];
2621
- return this;
2622
- }
2623
- }
2624
-
2625
- class NumberOptionBuilder extends CommandOptionBuilder {
2626
- constructor() {
2627
- super(ApplicationCommandOptionType2.Number);
2628
- }
2629
- setMinValue(value) {
2630
- validateNumberRange(value, -9007199254740991, 9007199254740991, "min_value", false);
2631
- this.data.min_value = value;
2632
- return this;
2633
- }
2634
- setMaxValue(value) {
2635
- validateNumberRange(value, -9007199254740991, 9007199254740991, "max_value", false);
2636
- if (this.data.min_value !== undefined && this.data.min_value > value)
2637
- throw new RangeError("min_value cannot exceed max_value.");
2638
- this.data.max_value = value;
2639
- return this;
2640
- }
2641
- setAutocomplete(enabled = true) {
2642
- if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)
2643
- throw new RangeError("Autocomplete options cannot define choices.");
2644
- this.data.autocomplete = enabled;
2645
- return this;
2646
- }
2647
- addChoices(...choices) {
2648
- const current = this.data.choices ?? [];
2649
- if (!choices.length)
2650
- throw new TypeError("At least one choice is required.");
2651
- if (this.data.autocomplete === true)
2652
- throw new RangeError("Autocomplete options cannot define choices.");
2653
- if (current.length + choices.length > 25)
2654
- throw new RangeError("An option cannot contain more than 25 choices.");
2655
- this.data.choices = [...current, ...choices];
2656
- return this;
2657
- }
2658
- }
2659
-
2660
- class BooleanOptionBuilder extends CommandOptionBuilder {
2661
- constructor() {
2662
- super(ApplicationCommandOptionType2.Boolean);
2663
- }
2664
- }
2665
-
2666
- class UserOptionBuilder extends CommandOptionBuilder {
2667
- constructor() {
2668
- super(ApplicationCommandOptionType2.User);
2669
- }
2670
- }
2671
-
2672
- class RoleOptionBuilder extends CommandOptionBuilder {
2673
- constructor() {
2674
- super(ApplicationCommandOptionType2.Role);
2675
- }
2676
- }
2677
-
2678
- class MentionableOptionBuilder extends CommandOptionBuilder {
2679
- constructor() {
2680
- super(ApplicationCommandOptionType2.Mentionable);
2681
- }
2682
- }
2683
-
2684
- class AttachmentOptionBuilder extends CommandOptionBuilder {
2685
- constructor() {
2686
- super(ApplicationCommandOptionType2.Attachment);
2687
- }
2688
- }
2689
-
2690
- class ChannelOptionBuilder extends CommandOptionBuilder {
2691
- constructor() {
2692
- super(ApplicationCommandOptionType2.Channel);
2693
- }
2694
- addChannelTypes(...types) {
2695
- if (types.some((type) => !Number.isInteger(type) || type < 0))
2696
- throw new RangeError("Channel types must be non-negative integers.");
2697
- this.data.channel_types = [...new Set(types)];
2698
- return this;
2699
- }
2700
- }
2701
-
2702
- class SubcommandBuilder extends CommandOptionBuilder {
2703
- constructor() {
2704
- super(ApplicationCommandOptionType2.Subcommand);
2705
- }
2706
- addStringOption(configure) {
2707
- return this.addChildOption(configure(new StringOptionBuilder));
2708
- }
2709
- addIntegerOption(configure) {
2710
- return this.addChildOption(configure(new IntegerOptionBuilder));
2711
- }
2712
- addNumberOption(configure) {
2713
- return this.addChildOption(configure(new NumberOptionBuilder));
2714
- }
2715
- addBooleanOption(configure) {
2716
- return this.addChildOption(configure(new BooleanOptionBuilder));
2717
- }
2718
- addUserOption(configure) {
2719
- return this.addChildOption(configure(new UserOptionBuilder));
2720
- }
2721
- addChannelOption(configure) {
2722
- return this.addChildOption(configure(new ChannelOptionBuilder));
2723
- }
2724
- addRoleOption(configure) {
2725
- return this.addChildOption(configure(new RoleOptionBuilder));
2726
- }
2727
- addMentionableOption(configure) {
2728
- return this.addChildOption(configure(new MentionableOptionBuilder));
2729
- }
2730
- addAttachmentOption(configure) {
2731
- return this.addChildOption(configure(new AttachmentOptionBuilder));
2732
- }
2733
- addChildOption(option) {
2734
- const options = this.data.options ?? [];
2735
- if (options.length >= 25)
2736
- throw new RangeError("A subcommand cannot contain more than 25 options.");
2737
- const payload = option.toJSON();
2738
- if (options.some((existing) => existing.name === payload.name))
2739
- throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);
2740
- if (payload.required === true && options.some((existing) => existing.required !== true))
2741
- throw new RangeError("Required subcommand options must be placed before optional options.");
2742
- if (options.some((existing) => existing.type === ApplicationCommandOptionType2.Subcommand))
2743
- throw new RangeError("Subcommands cannot contain nested subcommands.");
2744
- options.push(payload);
2745
- this.data.options = options;
2746
- return this;
2747
- }
2748
- }
2749
-
2750
- class SubcommandGroupBuilder extends CommandOptionBuilder {
2751
- constructor() {
2752
- super(ApplicationCommandOptionType2.SubcommandGroup);
2753
- }
2754
- addSubcommand(configure) {
2755
- const options = this.data.options ?? [];
2756
- if (options.length >= 25)
2757
- throw new RangeError("A subcommand group cannot contain more than 25 subcommands.");
2758
- const payload = configure(new SubcommandBuilder).toJSON();
2759
- if (options.some((existing) => existing.name === payload.name))
2760
- throw new RangeError(`Duplicate subcommand name: ${String(payload.name)}.`);
2761
- if (payload.type !== ApplicationCommandOptionType2.Subcommand)
2762
- throw new TypeError("Subcommand group children must be subcommands.");
2763
- options.push(payload);
2764
- this.data.options = options;
2765
- return this;
2766
- }
2767
- }
2768
- function validateName(value, field) {
2769
- if (!/^[\p{L}\p{N}_-]{1,32}$/u.test(value) || value !== value.toLowerCase())
2770
- throw new RangeError(`${field} must contain 1-32 lowercase letters, numbers, underscores, or hyphens.`);
2771
- }
2772
- function validateText2(value, field, max) {
2773
- if (typeof value !== "string" || !value.trim() || value.length > max)
2774
- throw new RangeError(`${field} must contain 1-${max} characters.`);
2775
- }
2776
- function validateIntegerRange(value, minimum, maximum, field) {
2777
- if (!Number.isInteger(value) || value < minimum || value > maximum)
2778
- throw new RangeError(`${field} must be an integer between ${minimum} and ${maximum}.`);
2779
- }
2780
- function validateNumberRange(value, minimum, maximum, field, integerOnly = true) {
2781
- if (!Number.isFinite(value) || integerOnly && !Number.isInteger(value) || value < minimum || value > maximum)
2782
- throw new RangeError(`${field} must be ${integerOnly ? "an integer" : "a number"} between ${minimum} and ${maximum}.`);
2783
- }
2784
- // packages/core/src/collector.ts
2785
- import { EventEmitter } from "events";
2786
-
2787
- class Collector extends EventEmitter {
2788
- collected = new Map;
2789
- options;
2790
- ended = false;
2791
- endReason;
2792
- totalProcessed = 0;
2793
- #timeoutTimer;
2794
- constructor(options = {}) {
2795
- super();
2796
- this.options = options;
2797
- if (options.time && options.time > 0) {
2798
- this.#timeoutTimer = setTimeout(() => {
2799
- this.stop("time");
2800
- }, options.time);
2801
- }
2802
- }
2803
- async handle(key, item) {
2804
- if (this.ended)
2805
- return false;
2806
- this.totalProcessed++;
2807
- if (this.options.filter) {
2808
- const passed = await this.options.filter(item);
2809
- if (!passed)
2810
- return false;
2811
- }
2812
- this.collected.set(key, item);
2813
- this.emit("collect", item);
2814
- if (this.options.max && this.collected.size >= this.options.max) {
2815
- this.stop("limit");
2816
- return true;
3159
+ async#decompress(chunk) {
3160
+ if (!this.#decompressor)
3161
+ this.#initDecompressor();
3162
+ const { writer, reader } = this.#decompressor;
3163
+ await writer.write(chunk);
3164
+ const parts = [];
3165
+ while (true) {
3166
+ const { done, value } = await Promise.race([
3167
+ reader.read(),
3168
+ new Promise((resolve) => setTimeout(() => resolve({ done: true, value: undefined }), 50))
3169
+ ]);
3170
+ if (done || !value)
3171
+ break;
3172
+ parts.push(value);
2817
3173
  }
2818
- if (this.options.maxProcessed && this.totalProcessed >= this.options.maxProcessed) {
2819
- this.stop("processedLimit");
2820
- return true;
3174
+ const total = parts.reduce((n, p) => n + p.length, 0);
3175
+ const merged = new Uint8Array(total);
3176
+ let offset = 0;
3177
+ for (const p of parts) {
3178
+ merged.set(p, offset);
3179
+ offset += p.length;
2821
3180
  }
2822
- return true;
2823
- }
2824
- stop(reason = "user") {
2825
- if (this.ended)
2826
- return;
2827
- this.ended = true;
2828
- this.endReason = reason;
2829
- if (this.#timeoutTimer)
2830
- clearTimeout(this.#timeoutTimer);
2831
- this.emit("end", this.collected, reason);
2832
- this.removeAllListeners();
2833
- }
2834
- next() {
2835
- return new Promise((resolve, reject) => {
2836
- if (this.ended) {
2837
- return reject(new Error(`Collector already ended: ${this.endReason ?? "unknown"}`));
2838
- }
2839
- this.once("collect", (item) => {
2840
- resolve(item);
2841
- });
2842
- this.once("end", (_collected, reason) => {
2843
- reject(new Error(`Collector ended before item was collected: ${reason}`));
2844
- });
2845
- });
3181
+ return new TextDecoder().decode(merged);
2846
3182
  }
2847
3183
  }
2848
3184
 
@@ -2869,6 +3205,9 @@ class EventEmitter2 {
2869
3205
  this.#listeners.get(event)?.delete(listener);
2870
3206
  return this;
2871
3207
  }
3208
+ removeListener(event, listener) {
3209
+ return this.off(event, listener);
3210
+ }
2872
3211
  removeAllListeners(event) {
2873
3212
  if (event === undefined)
2874
3213
  this.#listeners.clear();
@@ -2892,11 +3231,11 @@ class EventEmitter2 {
2892
3231
  return true;
2893
3232
  }
2894
3233
  #handleError(event, error) {
2895
- if (event === "error")
3234
+ if (event === "error" /* Error */)
2896
3235
  return;
2897
3236
  const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
2898
3237
  for (const listener of [
2899
- ...this.#listeners.get("error") ?? []
3238
+ ...this.#listeners.get("error" /* Error */) ?? []
2900
3239
  ]) {
2901
3240
  try {
2902
3241
  listener(normalized);
@@ -2921,9 +3260,27 @@ class Client extends EventEmitter2 {
2921
3260
  user;
2922
3261
  readyAt;
2923
3262
  state = "idle";
3263
+ get token() {
3264
+ return this.state === "destroyed" ? null : this.options.token ?? null;
3265
+ }
2924
3266
  get uptime() {
2925
3267
  return this.readyAt ? Date.now() - this.readyAt.getTime() : null;
2926
3268
  }
3269
+ get ping() {
3270
+ return this.#gateway.ping;
3271
+ }
3272
+ isReady() {
3273
+ return this.state === "ready";
3274
+ }
3275
+ setPresence(data) {
3276
+ return this.#gateway.setPresence(data);
3277
+ }
3278
+ setVoiceState(data) {
3279
+ return this.#gateway.setVoiceState(data);
3280
+ }
3281
+ requestGuildMembers(data) {
3282
+ return this.#gateway.requestGuildMembers(data);
3283
+ }
2927
3284
  #gateway;
2928
3285
  #resourceContext;
2929
3286
  constructor(options) {
@@ -2941,7 +3298,15 @@ class Client extends EventEmitter2 {
2941
3298
  sendMessage: (channelId, options2) => this.channels.send(channelId, options2),
2942
3299
  editMessage: (channelId, messageId, options2) => this.channels.editMessage(channelId, messageId, options2),
2943
3300
  deleteMessage: (channelId, messageId) => this.channels.deleteMessage(channelId, messageId),
2944
- crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId)
3301
+ crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId),
3302
+ editChannel: (channelId, options2) => this.channels.edit(channelId, options2),
3303
+ deleteChannel: (channelId) => this.channels.deleteChannel(channelId),
3304
+ addReaction: (channelId, messageId, emoji) => this.channels.addReaction(channelId, messageId, emoji),
3305
+ removeOwnReaction: (channelId, messageId, emoji) => this.channels.removeOwnReaction(channelId, messageId, emoji),
3306
+ removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
3307
+ removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
3308
+ pinMessage: (channelId, messageId) => this.channels.pinMessage(channelId, messageId),
3309
+ unpinMessage: (channelId, messageId) => this.channels.unpinMessage(channelId, messageId)
2945
3310
  };
2946
3311
  this.#gateway = new Gateway({
2947
3312
  token: options.token,
@@ -2956,233 +3321,242 @@ class Client extends EventEmitter2 {
2956
3321
  this.state = "ready";
2957
3322
  const appId = ready.application?.id ?? this.user.id;
2958
3323
  this.application.commands = new ApplicationCommandManager(this.rest, appId);
2959
- this.emit("ready", this.user);
3324
+ this.emit("ready" /* Ready */, this.user);
3325
+ });
3326
+ this.#gateway.on("RESUMED", () => {
3327
+ this.state = "ready";
3328
+ this.emit("resumed" /* Resumed */);
2960
3329
  });
2961
- this.#gateway.on("open", () => this.emit("open"));
3330
+ this.#gateway.on("invalidSession", (isRecoverable) => {
3331
+ this.emit("invalidSession" /* InvalidSession */, isRecoverable);
3332
+ });
3333
+ this.#gateway.on("open", () => this.emit("open" /* Open */));
2962
3334
  this.#gateway.on("close", (data) => {
2963
3335
  if (this.state !== "destroyed")
2964
3336
  this.state = "idle";
2965
- this.emit("close", data);
3337
+ this.emit("close" /* Close */, data);
2966
3338
  });
2967
3339
  this.#gateway.on("MESSAGE_CREATE", (data) => {
2968
3340
  const message = new Message(data, this.#resourceContext);
2969
3341
  this.channels.set(message.channelId, message.channel);
2970
3342
  this.users.set(message.author.id, message.author);
2971
- this.emit("messageCreate", message);
3343
+ this.emit("messageCreate" /* MessageCreate */, message);
2972
3344
  });
2973
3345
  this.#gateway.on("MESSAGE_UPDATE", (data) => {
2974
3346
  const message = new Message(data, this.#resourceContext);
2975
3347
  this.channels.set(message.channelId, message.channel);
2976
3348
  this.users.set(message.author.id, message.author);
2977
- this.emit("messageUpdate", message);
3349
+ this.emit("messageUpdate" /* MessageUpdate */, message);
2978
3350
  });
2979
- this.#gateway.on("MESSAGE_DELETE", (data) => this.emit("messageDelete", data));
2980
- this.#gateway.on("MESSAGE_DELETE_BULK", (data) => this.emit("messageDeleteBulk", data));
3351
+ this.#gateway.on("MESSAGE_DELETE", (data) => this.emit("messageDelete" /* MessageDelete */, data));
3352
+ this.#gateway.on("MESSAGE_DELETE_BULK", (data) => this.emit("messageDeleteBulk" /* MessageDeleteBulk */, data));
3353
+ this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
3354
+ this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
3355
+ this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
3356
+ this.#gateway.on("MESSAGE_REACTION_REMOVE_EMOJI", (data) => this.emit("messageReactionRemoveEmoji" /* MessageReactionRemoveEmoji */, data));
3357
+ this.#gateway.on("MESSAGE_POLL_VOTE_ADD", (data) => this.emit("messagePollVoteAdd" /* MessagePollVoteAdd */, data));
3358
+ this.#gateway.on("MESSAGE_POLL_VOTE_REMOVE", (data) => this.emit("messagePollVoteRemove" /* MessagePollVoteRemove */, data));
2981
3359
  this.#gateway.on("GUILD_CREATE", (data) => {
2982
- const guild = new Guild(data);
2983
- this.guilds.set(guild.id, guild);
2984
3360
  const payload = data;
3361
+ if (payload.unavailable) {
3362
+ this.emit("guildUnavailable" /* GuildUnavailable */, payload);
3363
+ return;
3364
+ }
3365
+ const wasCached = this.guilds.has(payload.id);
3366
+ const guild = new Guild(payload);
3367
+ this.guilds.set(guild.id, guild);
2985
3368
  for (const member of payload.members ?? [])
2986
3369
  this.users.set(member.user.id, new User(member.user));
2987
3370
  for (const channelData of [
2988
3371
  ...payload.channels ?? [],
2989
3372
  ...payload.threads ?? []
2990
- ]) {
2991
- const channel = new Channel(channelData, this.#resourceContext);
2992
- this.channels.set(channel.id, channel);
2993
- }
2994
- this.emit("guildCreate", data);
3373
+ ])
3374
+ this.channels.set(channelData.id, new Channel(channelData, this.#resourceContext));
3375
+ this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
2995
3376
  });
2996
3377
  this.#gateway.on("GUILD_UPDATE", (data) => {
2997
3378
  const guild = new Guild(data);
2998
3379
  this.guilds.update(guild);
2999
- this.emit("guildUpdate", data);
3380
+ this.emit("guildUpdate" /* GuildUpdate */, data);
3000
3381
  });
3001
3382
  this.#gateway.on("GUILD_DELETE", (data) => {
3002
3383
  const payload = data;
3003
- if (!payload.unavailable)
3004
- this.guilds.delete(payload.id);
3005
- this.emit("guildDelete", payload);
3384
+ if (payload.unavailable) {
3385
+ this.emit("guildUnavailable" /* GuildUnavailable */, payload);
3386
+ return;
3387
+ }
3388
+ this.guilds.delete(payload.id);
3389
+ this.emit("guildDelete" /* GuildDelete */, payload);
3006
3390
  });
3391
+ this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
3392
+ const member = data;
3393
+ this.users.set(member.user.id, new User(member.user));
3394
+ this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
3395
+ });
3396
+ this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
3397
+ const member = data;
3398
+ this.users.set(member.user.id, new User(member.user));
3399
+ this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member);
3400
+ });
3401
+ this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => this.emit("guildMemberRemove" /* GuildMemberRemove */, data));
3402
+ this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => this.emit("guildMembersChunk" /* GuildMembersChunk */, data));
3403
+ this.#gateway.on("GUILD_BAN_ADD", (data) => this.emit("guildBanAdd" /* GuildBanAdd */, data));
3404
+ this.#gateway.on("GUILD_BAN_REMOVE", (data) => this.emit("guildBanRemove" /* GuildBanRemove */, data));
3405
+ this.#gateway.on("GUILD_ROLE_CREATE", (data) => this.emit("guildRoleCreate" /* GuildRoleCreate */, data));
3406
+ this.#gateway.on("GUILD_ROLE_UPDATE", (data) => this.emit("guildRoleUpdate" /* GuildRoleUpdate */, data));
3407
+ this.#gateway.on("GUILD_ROLE_DELETE", (data) => this.emit("guildRoleDelete" /* GuildRoleDelete */, data));
3408
+ this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, data));
3409
+ this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => this.emit("guildStickersUpdate" /* GuildStickersUpdate */, data));
3410
+ this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
3411
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, data));
3412
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, data));
3413
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, data));
3414
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
3415
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_REMOVE", (data) => this.emit("guildScheduledEventUserRemove" /* GuildScheduledEventUserRemove */, data));
3416
+ this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, data));
3417
+ this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, data));
3418
+ this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, data));
3419
+ this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
3007
3420
  this.#gateway.on("CHANNEL_CREATE", (data) => {
3008
3421
  const channel = new Channel(data, this.#resourceContext);
3009
3422
  this.channels.update(channel);
3010
- this.emit("channelCreate", channel);
3423
+ this.emit("channelCreate" /* ChannelCreate */, channel);
3011
3424
  });
3012
3425
  this.#gateway.on("CHANNEL_UPDATE", (data) => {
3013
3426
  const channel = new Channel(data, this.#resourceContext);
3014
3427
  this.channels.update(channel);
3015
- this.emit("channelUpdate", channel);
3428
+ this.emit("channelUpdate" /* ChannelUpdate */, channel);
3016
3429
  });
3017
3430
  this.#gateway.on("CHANNEL_DELETE", (data) => {
3018
3431
  const payload = data;
3019
3432
  this.channels.delete(payload.id);
3020
- this.emit("channelDelete", payload);
3433
+ this.emit("channelDelete" /* ChannelDelete */, payload);
3021
3434
  });
3435
+ this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
3022
3436
  this.#gateway.on("THREAD_CREATE", (data) => {
3023
3437
  const channel = new Channel(data, this.#resourceContext);
3024
3438
  this.channels.update(channel);
3025
- this.emit("threadCreate", channel);
3439
+ this.emit("threadCreate" /* ThreadCreate */, channel);
3026
3440
  });
3027
3441
  this.#gateway.on("THREAD_UPDATE", (data) => {
3028
3442
  const channel = new Channel(data, this.#resourceContext);
3029
3443
  this.channels.update(channel);
3030
- this.emit("threadUpdate", channel);
3444
+ this.emit("threadUpdate" /* ThreadUpdate */, channel);
3031
3445
  });
3032
3446
  this.#gateway.on("THREAD_DELETE", (data) => {
3033
3447
  const payload = data;
3034
3448
  this.channels.delete(payload.id);
3035
- this.emit("threadDelete", payload);
3449
+ this.emit("threadDelete" /* ThreadDelete */, payload);
3036
3450
  });
3037
- this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
3038
- const member = data;
3039
- this.users.set(member.user.id, new User(member.user));
3040
- this.emit("guildMemberAdd", member);
3041
- });
3042
- this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
3043
- const member = data;
3044
- this.users.set(member.user.id, new User(member.user));
3045
- this.emit("guildMemberUpdate", member);
3046
- });
3047
- this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => this.emit("guildMemberRemove", data));
3048
- this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd", data));
3049
- this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove", data));
3050
- this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll", data));
3051
- this.#gateway.on("INTERACTION_CREATE", (data) => this.emit("interactionCreate", createInteraction(this, data)));
3052
- this.#gateway.on("GUILD_ROLE_CREATE", (data) => this.emit("guildRoleCreate", data));
3053
- this.#gateway.on("GUILD_ROLE_UPDATE", (data) => this.emit("guildRoleUpdate", data));
3054
- this.#gateway.on("GUILD_ROLE_DELETE", (data) => this.emit("guildRoleDelete", data));
3055
- this.#gateway.on("GUILD_BAN_ADD", (data) => this.emit("guildBanAdd", data));
3056
- this.#gateway.on("GUILD_BAN_REMOVE", (data) => this.emit("guildBanRemove", data));
3057
- this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => this.emit("guildEmojisUpdate", data));
3058
- for (const event of [
3059
- "READY",
3060
- "MESSAGE_CREATE",
3061
- "MESSAGE_UPDATE",
3062
- "MESSAGE_DELETE",
3063
- "MESSAGE_DELETE_BULK",
3064
- "GUILD_CREATE",
3065
- "GUILD_UPDATE",
3066
- "GUILD_DELETE",
3067
- "CHANNEL_CREATE",
3068
- "CHANNEL_UPDATE",
3069
- "CHANNEL_DELETE",
3070
- "THREAD_CREATE",
3071
- "THREAD_UPDATE",
3072
- "THREAD_DELETE",
3073
- "GUILD_MEMBER_ADD",
3074
- "GUILD_MEMBER_UPDATE",
3075
- "GUILD_MEMBER_REMOVE",
3076
- "MESSAGE_REACTION_ADD",
3077
- "MESSAGE_REACTION_REMOVE",
3078
- "MESSAGE_REACTION_REMOVE_ALL",
3079
- "INTERACTION_CREATE",
3080
- "GUILD_ROLE_CREATE",
3081
- "GUILD_ROLE_UPDATE",
3082
- "GUILD_ROLE_DELETE",
3083
- "GUILD_BAN_ADD",
3084
- "GUILD_BAN_REMOVE",
3085
- "GUILD_EMOJIS_UPDATE"
3086
- ])
3087
- this.#gateway.on(event, (data) => this.emit("raw", { event, data }));
3088
- this.#gateway.on("error", (data) => this.emit("error", data));
3089
- }
3090
- isReady() {
3091
- return this.state === "ready" && this.user !== undefined && this.readyAt !== undefined;
3092
- }
3093
- async login() {
3451
+ this.#gateway.on("THREAD_LIST_SYNC", (data) => this.emit("threadListSync" /* ThreadListSync */, data));
3452
+ this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
3453
+ this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
3454
+ this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => this.emit("stageInstanceCreate" /* StageInstanceCreate */, data));
3455
+ this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, data));
3456
+ this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => this.emit("stageInstanceDelete" /* StageInstanceDelete */, data));
3457
+ this.#gateway.on("INVITE_CREATE", (data) => this.emit("inviteCreate" /* InviteCreate */, data));
3458
+ this.#gateway.on("INVITE_DELETE", (data) => this.emit("inviteDelete" /* InviteDelete */, data));
3459
+ this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
3460
+ this.#gateway.on("VOICE_STATE_UPDATE", (data) => this.emit("voiceStateUpdate" /* VoiceStateUpdate */, data));
3461
+ this.#gateway.on("VOICE_SERVER_UPDATE", (data) => this.emit("voiceServerUpdate" /* VoiceServerUpdate */, data));
3462
+ this.#gateway.on("PRESENCE_UPDATE", (data) => this.emit("presenceUpdate" /* PresenceUpdate */, data));
3463
+ this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
3464
+ this.#gateway.on("INTERACTION_CREATE", (data) => this.emit("interactionCreate" /* InteractionCreate */, createInteraction(this, data)));
3465
+ this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
3466
+ this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
3467
+ }
3468
+ async login(token) {
3094
3469
  if (this.state === "destroyed")
3095
3470
  throw new Error("Cannot login a destroyed client.");
3096
- if (this.state === "connecting" || this.state === "ready")
3097
- return;
3098
- this.state = "connecting";
3099
- try {
3100
- this.user = await this.rest.get(Routes.user());
3101
- this.users.set(this.user.id, new User(this.user));
3102
- await this.#gateway.connect();
3103
- } catch (error) {
3104
- this.state = "idle";
3105
- throw error;
3471
+ if (token?.trim()) {
3472
+ this.rest.setToken(token);
3473
+ this.options.token = token;
3106
3474
  }
3475
+ const usedToken = this.options.token;
3476
+ if (!usedToken?.trim())
3477
+ throw new TypeError("A bot token is required to log in.");
3478
+ this.state = "connecting";
3479
+ await this.#gateway.connect();
3480
+ return usedToken;
3107
3481
  }
3108
3482
  destroy() {
3109
- if (this.state === "destroyed")
3110
- return;
3111
- this.#gateway.close();
3112
- this.users.clear();
3113
- this.guilds.clear();
3114
- this.channels.clear();
3115
3483
  this.state = "destroyed";
3116
- this.readyAt = undefined;
3117
- this.user = undefined;
3484
+ this.#gateway.close();
3118
3485
  }
3119
3486
  postInteractionResponse(id, token, response) {
3120
3487
  return this.rest.post(Routes.interactionCallback(id, token), response.toJSON());
3121
3488
  }
3122
3489
  editInteractionReply(token, data) {
3123
- if (!this.user?.id)
3124
- throw new Error("Client user is unavailable; login is required.");
3490
+ if (!this.user)
3491
+ return Promise.reject(new Error("Client is unauthenticated."));
3125
3492
  return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), data);
3126
3493
  }
3127
- async deleteInteractionReply(token) {
3128
- if (!this.user?.id)
3129
- throw new Error("Client user is unavailable; login is required.");
3130
- await this.rest.delete(Routes.interactionOriginalResponse(this.user.id, token));
3131
- }
3132
- setPresence(presence) {
3133
- return this.#gateway.setPresence(presence);
3494
+ deleteInteractionReply(token) {
3495
+ if (!this.user)
3496
+ return Promise.reject(new Error("Client is unauthenticated."));
3497
+ return this.rest.delete(Routes.interactionOriginalResponse(this.user.id, token));
3134
3498
  }
3135
3499
  followUpInteraction(token, data) {
3136
- if (!this.user?.id)
3137
- throw new Error("Client user is unavailable; login is required.");
3138
- return this.rest.post(Routes.webhook(this.user.id, token), data);
3500
+ if (!this.user)
3501
+ return Promise.reject(new Error("Client is unauthenticated."));
3502
+ return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);
3503
+ }
3504
+ fetchWebhook(id, token) {
3505
+ return this.rest.get(token ? `/webhooks/${id}/${token}` : `/webhooks/${id}`);
3506
+ }
3507
+ fetchGuildPreview(guildId) {
3508
+ return this.rest.get(`/guilds/${guildId}/preview`);
3509
+ }
3510
+ fetchVoiceRegions() {
3511
+ return this.rest.get("/voice/regions");
3512
+ }
3513
+ fetchInvite(code, options) {
3514
+ const query = new URLSearchParams;
3515
+ if (options?.withCounts)
3516
+ query.set("with_counts", "true");
3517
+ if (options?.withExpiration)
3518
+ query.set("with_expiration", "true");
3519
+ if (options?.guildScheduledEventId)
3520
+ query.set("guild_scheduled_event_id", options.guildScheduledEventId);
3521
+ const qs = query.toString();
3522
+ return this.rest.get(`/invites/${code}${qs ? `?${qs}` : ""}`);
3523
+ }
3524
+ fetchSticker(id) {
3525
+ return this.rest.get(`/stickers/${id}`);
3526
+ }
3527
+ fetchPremiumStickerPacks() {
3528
+ return this.rest.get(`/sticker-packs`);
3529
+ }
3530
+ fetchGuildTemplate(code) {
3531
+ return this.rest.get(`/guilds/templates/${code}`);
3532
+ }
3533
+ generateInvite(options) {
3534
+ if (!this.user)
3535
+ throw new Error("Client must be ready to generate invite.");
3536
+ const params = new URLSearchParams({
3537
+ client_id: this.user.id,
3538
+ scopes: (options?.scopes ?? ["bot"]).join(" ")
3539
+ });
3540
+ if (options?.permissions) {
3541
+ params.set("permissions", String(options.permissions));
3542
+ }
3543
+ return `https://discord.com/api/oauth2/authorize?${params.toString()}`;
3139
3544
  }
3140
3545
  }
3141
3546
  export {
3142
- ActionRowBuilder,
3143
- ApplicationCommandManager,
3144
- ApplicationCommandOptionType,
3145
- ApplicationCommandType,
3146
- ButtonBuilder,
3147
- Channel,
3148
- ChannelManager,
3149
- ChannelType,
3150
3547
  Client,
3151
- Collection,
3548
+ ClientEvent,
3152
3549
  Collector,
3153
- EmbedBuilder,
3154
- Gateway,
3155
- GatewayError,
3156
3550
  GatewayIntentBits,
3157
- GatewayOpcodes,
3158
- Guild,
3159
- GuildManager,
3160
3551
  IntentBits,
3161
3552
  Intents,
3162
- Manager,
3163
- Message,
3164
- MessageCreateOptions,
3165
- MessageEditOptions,
3166
- MessageFetchOptions,
3167
- MessageFlags,
3168
- MessageThreadOptions,
3169
3553
  Permission,
3170
3554
  PermissionFlagsBits,
3171
3555
  PermissionOverwriteType,
3172
3556
  PermissionSet,
3173
3557
  Permissions,
3174
3558
  PermissionsBitField,
3175
- REST,
3176
- RESTError,
3177
- ReactionFetchOptions,
3178
- ResourceManager,
3179
- Routes,
3180
- SlashCommandBuilder,
3181
- StringOptionBuilder,
3182
- StringSelectBuilder,
3183
- User,
3184
- UserManager,
3185
3559
  resolveGatewayIntents
3186
3560
  };
3187
3561
 
3188
- //# debugId=8E6F3C716D06EF5664756E2164756E21
3562
+ //# debugId=5F8825194034E27864756E2164756E21