lunibee 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +229 -0
  2. package/dist/builders/attachment.d.ts +20 -0
  3. package/dist/builders/commands.d.ts +118 -0
  4. package/dist/builders/components.d.ts +151 -0
  5. package/dist/builders/embed.d.ts +59 -0
  6. package/dist/builders/index.d.ts +5 -0
  7. package/dist/builders/index.js +828 -0
  8. package/dist/builders/index.js.map +13 -0
  9. package/dist/collection/cache.d.ts +37 -0
  10. package/dist/collection/index.d.ts +47 -0
  11. package/dist/collection/index.js +214 -0
  12. package/dist/collection/index.js.map +11 -0
  13. package/dist/core/client-state.d.ts +10 -0
  14. package/dist/core/collector.d.ts +27 -0
  15. package/dist/core/events.d.ts +5 -0
  16. package/dist/core/index.d.ts +111 -0
  17. package/dist/core/index.js +3188 -0
  18. package/dist/core/index.js.map +29 -0
  19. package/dist/core/permissions.d.ts +293 -0
  20. package/dist/formatters/index.d.ts +10 -0
  21. package/dist/formatters/index.js +43 -0
  22. package/dist/formatters/index.js.map +10 -0
  23. package/dist/handlers/index.d.ts +16 -0
  24. package/dist/handlers/index.js +37 -0
  25. package/dist/handlers/index.js.map +10 -0
  26. package/{src/index.ts → dist/index.d.ts} +2 -29
  27. package/dist/index.js +4182 -0
  28. package/dist/index.js.map +41 -0
  29. package/dist/managers/application.d.ts +28 -0
  30. package/dist/managers/base.d.ts +28 -0
  31. package/dist/managers/index.d.ts +96 -0
  32. package/dist/managers/index.js +947 -0
  33. package/dist/managers/index.js.map +22 -0
  34. package/dist/managers/member.d.ts +35 -0
  35. package/dist/managers/message.d.ts +25 -0
  36. package/dist/managers/role.d.ts +34 -0
  37. package/dist/managers/thread.d.ts +14 -0
  38. package/dist/rest/index.d.ts +49 -0
  39. package/dist/rest/index.js +344 -0
  40. package/dist/rest/index.js.map +12 -0
  41. package/dist/rest/routes.d.ts +44 -0
  42. package/dist/rest/types.d.ts +26 -0
  43. package/dist/rest/webhook.d.ts +40 -0
  44. package/dist/sharding/bus.d.ts +22 -0
  45. package/dist/sharding/index.d.ts +34 -0
  46. package/dist/sharding/index.js +732 -0
  47. package/dist/sharding/index.js.map +13 -0
  48. package/dist/structures/base.d.ts +75 -0
  49. package/dist/structures/index.d.ts +39 -0
  50. package/dist/structures/index.js +571 -0
  51. package/dist/structures/index.js.map +14 -0
  52. package/dist/structures/interactions.d.ts +136 -0
  53. package/dist/structures/permissions.d.ts +73 -0
  54. package/dist/structures/resources.d.ts +64 -0
  55. package/dist/types/index.d.ts +535 -0
  56. package/dist/types/index.js +132 -0
  57. package/dist/types/index.js.map +10 -0
  58. package/dist/utils/index.d.ts +6 -0
  59. package/dist/utils/index.js +18 -0
  60. package/dist/utils/index.js.map +10 -0
  61. package/dist/voice/index.d.ts +97 -0
  62. package/dist/voice/index.js +161 -0
  63. package/dist/voice/index.js.map +10 -0
  64. package/dist/ws/index.d.ts +76 -0
  65. package/dist/ws/index.js +582 -0
  66. package/dist/ws/index.js.map +11 -0
  67. package/package.json +113 -28
@@ -0,0 +1,3188 @@
1
+ // @bun
2
+ // packages/core/src/permissions.ts
3
+ var PermissionOverwriteType;
4
+ ((PermissionOverwriteType2) => {
5
+ PermissionOverwriteType2[PermissionOverwriteType2["Role"] = 0] = "Role";
6
+ PermissionOverwriteType2[PermissionOverwriteType2["Member"] = 1] = "Member";
7
+ })(PermissionOverwriteType ||= {});
8
+ var Permission = {
9
+ createInstantInvite: 1n << 0n,
10
+ kickMembers: 1n << 1n,
11
+ banMembers: 1n << 2n,
12
+ administrator: 1n << 3n,
13
+ manageChannels: 1n << 4n,
14
+ manageGuild: 1n << 5n,
15
+ addReactions: 1n << 6n,
16
+ viewAuditLog: 1n << 7n,
17
+ prioritySpeaker: 1n << 8n,
18
+ stream: 1n << 9n,
19
+ viewChannel: 1n << 10n,
20
+ sendMessages: 1n << 11n,
21
+ sendTTSMessages: 1n << 12n,
22
+ manageMessages: 1n << 13n,
23
+ embedLinks: 1n << 14n,
24
+ attachFiles: 1n << 15n,
25
+ readMessageHistory: 1n << 16n,
26
+ mentionEveryone: 1n << 17n,
27
+ useExternalEmojis: 1n << 18n,
28
+ viewGuildInsights: 1n << 19n,
29
+ connect: 1n << 20n,
30
+ speak: 1n << 21n,
31
+ muteMembers: 1n << 22n,
32
+ deafenMembers: 1n << 23n,
33
+ moveMembers: 1n << 24n,
34
+ useVAD: 1n << 25n,
35
+ changeNickname: 1n << 26n,
36
+ manageNicknames: 1n << 27n,
37
+ manageRoles: 1n << 28n,
38
+ manageWebhooks: 1n << 29n,
39
+ manageGuildExpressions: 1n << 30n,
40
+ useApplicationCommands: 1n << 31n,
41
+ requestToSpeak: 1n << 32n,
42
+ manageEvents: 1n << 33n,
43
+ manageThreads: 1n << 34n,
44
+ createPublicThreads: 1n << 35n,
45
+ createPrivateThreads: 1n << 36n,
46
+ useExternalStickers: 1n << 37n,
47
+ sendMessagesInThreads: 1n << 38n,
48
+ useEmbeddedActivities: 1n << 39n,
49
+ moderateMembers: 1n << 40n,
50
+ viewCreatorMonetizationAnalytics: 1n << 41n,
51
+ useSoundboard: 1n << 42n,
52
+ createGuildExpressions: 1n << 43n,
53
+ createEvents: 1n << 44n,
54
+ useExternalSounds: 1n << 45n,
55
+ sendVoiceMessages: 1n << 46n,
56
+ sendPolls: 1n << 49n,
57
+ useExternalApps: 1n << 50n
58
+ };
59
+ var Permissions = {
60
+ CreateInstantInvite: 1n << 0n,
61
+ KickMembers: 1n << 1n,
62
+ BanMembers: 1n << 2n,
63
+ Administrator: 1n << 3n,
64
+ ManageChannels: 1n << 4n,
65
+ ManageGuild: 1n << 5n,
66
+ AddReactions: 1n << 6n,
67
+ ViewAuditLog: 1n << 7n,
68
+ PrioritySpeaker: 1n << 8n,
69
+ Stream: 1n << 9n,
70
+ ViewChannel: 1n << 10n,
71
+ SendMessages: 1n << 11n,
72
+ SendTTSMessages: 1n << 12n,
73
+ ManageMessages: 1n << 13n,
74
+ EmbedLinks: 1n << 14n,
75
+ AttachFiles: 1n << 15n,
76
+ ReadMessageHistory: 1n << 16n,
77
+ MentionEveryone: 1n << 17n,
78
+ UseExternalEmojis: 1n << 18n,
79
+ ViewGuildInsights: 1n << 19n,
80
+ Connect: 1n << 20n,
81
+ Speak: 1n << 21n,
82
+ MuteMembers: 1n << 22n,
83
+ DeafenMembers: 1n << 23n,
84
+ MoveMembers: 1n << 24n,
85
+ UseVAD: 1n << 25n,
86
+ ChangeNickname: 1n << 26n,
87
+ ManageNicknames: 1n << 27n,
88
+ ManageRoles: 1n << 28n,
89
+ ManageWebhooks: 1n << 29n,
90
+ ManageGuildExpressions: 1n << 30n,
91
+ UseApplicationCommands: 1n << 31n,
92
+ RequestToSpeak: 1n << 32n,
93
+ ManageEvents: 1n << 33n,
94
+ ManageThreads: 1n << 34n,
95
+ CreatePublicThreads: 1n << 35n,
96
+ CreatePrivateThreads: 1n << 36n,
97
+ UseExternalStickers: 1n << 37n,
98
+ SendMessagesInThreads: 1n << 38n,
99
+ UseEmbeddedActivities: 1n << 39n,
100
+ ModerateMembers: 1n << 40n,
101
+ ViewCreatorMonetizationAnalytics: 1n << 41n,
102
+ UseSoundboard: 1n << 42n,
103
+ CreateGuildExpressions: 1n << 43n,
104
+ CreateEvents: 1n << 44n,
105
+ UseExternalSounds: 1n << 45n,
106
+ SendVoiceMessages: 1n << 46n,
107
+ SendPolls: 1n << 49n,
108
+ UseExternalApps: 1n << 50n
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 ||= {});
162
+
163
+ class PermissionSet {
164
+ bitfield;
165
+ constructor(value = 0n) {
166
+ try {
167
+ if (Array.isArray(value)) {
168
+ let bit = 0n;
169
+ for (const item of value) {
170
+ bit |= this.#resolve(item);
171
+ }
172
+ this.bitfield = bit;
173
+ } else if (value instanceof PermissionSet) {
174
+ this.bitfield = value.bitfield;
175
+ } else {
176
+ const bitfield = this.#resolve(value);
177
+ if (bitfield < 0n)
178
+ throw new RangeError("Permission bitfield cannot be negative.");
179
+ this.bitfield = bitfield;
180
+ }
181
+ } catch (error) {
182
+ if (error instanceof RangeError)
183
+ throw error;
184
+ throw new TypeError("Permission bitfield must be a valid non-negative integer.", { cause: error });
185
+ }
186
+ }
187
+ get createInstantInvite() {
188
+ return (this.bitfield & Permission.createInstantInvite) === Permission.createInstantInvite;
189
+ }
190
+ get kickMembers() {
191
+ return (this.bitfield & Permission.kickMembers) === Permission.kickMembers;
192
+ }
193
+ get banMembers() {
194
+ return (this.bitfield & Permission.banMembers) === Permission.banMembers;
195
+ }
196
+ get administrator() {
197
+ return (this.bitfield & Permission.administrator) === Permission.administrator;
198
+ }
199
+ get manageChannels() {
200
+ return (this.bitfield & Permission.manageChannels) === Permission.manageChannels;
201
+ }
202
+ get manageGuild() {
203
+ return (this.bitfield & Permission.manageGuild) === Permission.manageGuild;
204
+ }
205
+ get addReactions() {
206
+ return (this.bitfield & Permission.addReactions) === Permission.addReactions;
207
+ }
208
+ get viewAuditLog() {
209
+ return (this.bitfield & Permission.viewAuditLog) === Permission.viewAuditLog;
210
+ }
211
+ get prioritySpeaker() {
212
+ return (this.bitfield & Permission.prioritySpeaker) === Permission.prioritySpeaker;
213
+ }
214
+ get stream() {
215
+ return (this.bitfield & Permission.stream) === Permission.stream;
216
+ }
217
+ get viewChannel() {
218
+ return (this.bitfield & Permission.viewChannel) === Permission.viewChannel;
219
+ }
220
+ get sendMessages() {
221
+ return (this.bitfield & Permission.sendMessages) === Permission.sendMessages;
222
+ }
223
+ get sendTTSMessages() {
224
+ return (this.bitfield & Permission.sendTTSMessages) === Permission.sendTTSMessages;
225
+ }
226
+ get manageMessages() {
227
+ return (this.bitfield & Permission.manageMessages) === Permission.manageMessages;
228
+ }
229
+ get embedLinks() {
230
+ return (this.bitfield & Permission.embedLinks) === Permission.embedLinks;
231
+ }
232
+ get attachFiles() {
233
+ return (this.bitfield & Permission.attachFiles) === Permission.attachFiles;
234
+ }
235
+ get readMessageHistory() {
236
+ return (this.bitfield & Permission.readMessageHistory) === Permission.readMessageHistory;
237
+ }
238
+ get mentionEveryone() {
239
+ return (this.bitfield & Permission.mentionEveryone) === Permission.mentionEveryone;
240
+ }
241
+ get useExternalEmojis() {
242
+ return (this.bitfield & Permission.useExternalEmojis) === Permission.useExternalEmojis;
243
+ }
244
+ get viewGuildInsights() {
245
+ return (this.bitfield & Permission.viewGuildInsights) === Permission.viewGuildInsights;
246
+ }
247
+ get connect() {
248
+ return (this.bitfield & Permission.connect) === Permission.connect;
249
+ }
250
+ get speak() {
251
+ return (this.bitfield & Permission.speak) === Permission.speak;
252
+ }
253
+ get muteMembers() {
254
+ return (this.bitfield & Permission.muteMembers) === Permission.muteMembers;
255
+ }
256
+ get deafenMembers() {
257
+ return (this.bitfield & Permission.deafenMembers) === Permission.deafenMembers;
258
+ }
259
+ get moveMembers() {
260
+ return (this.bitfield & Permission.moveMembers) === Permission.moveMembers;
261
+ }
262
+ get useVAD() {
263
+ return (this.bitfield & Permission.useVAD) === Permission.useVAD;
264
+ }
265
+ get changeNickname() {
266
+ return (this.bitfield & Permission.changeNickname) === Permission.changeNickname;
267
+ }
268
+ get manageNicknames() {
269
+ return (this.bitfield & Permission.manageNicknames) === Permission.manageNicknames;
270
+ }
271
+ get manageRoles() {
272
+ return (this.bitfield & Permission.manageRoles) === Permission.manageRoles;
273
+ }
274
+ get manageWebhooks() {
275
+ return (this.bitfield & Permission.manageWebhooks) === Permission.manageWebhooks;
276
+ }
277
+ get manageGuildExpressions() {
278
+ return (this.bitfield & Permission.manageGuildExpressions) === Permission.manageGuildExpressions;
279
+ }
280
+ get useApplicationCommands() {
281
+ return (this.bitfield & Permission.useApplicationCommands) === Permission.useApplicationCommands;
282
+ }
283
+ get requestToSpeak() {
284
+ return (this.bitfield & Permission.requestToSpeak) === Permission.requestToSpeak;
285
+ }
286
+ get manageEvents() {
287
+ return (this.bitfield & Permission.manageEvents) === Permission.manageEvents;
288
+ }
289
+ get manageThreads() {
290
+ return (this.bitfield & Permission.manageThreads) === Permission.manageThreads;
291
+ }
292
+ get createPublicThreads() {
293
+ return (this.bitfield & Permission.createPublicThreads) === Permission.createPublicThreads;
294
+ }
295
+ get createPrivateThreads() {
296
+ return (this.bitfield & Permission.createPrivateThreads) === Permission.createPrivateThreads;
297
+ }
298
+ get useExternalStickers() {
299
+ return (this.bitfield & Permission.useExternalStickers) === Permission.useExternalStickers;
300
+ }
301
+ get sendMessagesInThreads() {
302
+ return (this.bitfield & Permission.sendMessagesInThreads) === Permission.sendMessagesInThreads;
303
+ }
304
+ get useEmbeddedActivities() {
305
+ return (this.bitfield & Permission.useEmbeddedActivities) === Permission.useEmbeddedActivities;
306
+ }
307
+ get moderateMembers() {
308
+ return (this.bitfield & Permission.moderateMembers) === Permission.moderateMembers;
309
+ }
310
+ get viewCreatorMonetizationAnalytics() {
311
+ return (this.bitfield & Permission.viewCreatorMonetizationAnalytics) === Permission.viewCreatorMonetizationAnalytics;
312
+ }
313
+ get useSoundboard() {
314
+ return (this.bitfield & Permission.useSoundboard) === Permission.useSoundboard;
315
+ }
316
+ get createGuildExpressions() {
317
+ return (this.bitfield & Permission.createGuildExpressions) === Permission.createGuildExpressions;
318
+ }
319
+ get createEvents() {
320
+ return (this.bitfield & Permission.createEvents) === Permission.createEvents;
321
+ }
322
+ get useExternalSounds() {
323
+ return (this.bitfield & Permission.useExternalSounds) === Permission.useExternalSounds;
324
+ }
325
+ get sendVoiceMessages() {
326
+ return (this.bitfield & Permission.sendVoiceMessages) === Permission.sendVoiceMessages;
327
+ }
328
+ get sendPolls() {
329
+ return (this.bitfield & Permission.sendPolls) === Permission.sendPolls;
330
+ }
331
+ get useExternalApps() {
332
+ return (this.bitfield & Permission.useExternalApps) === Permission.useExternalApps;
333
+ }
334
+ has(...permissions) {
335
+ if (permissions.length === 1) {
336
+ const p = permissions[0];
337
+ const bit = typeof p === "bigint" ? p : this.#resolve(p);
338
+ return (this.bitfield & bit) === bit;
339
+ }
340
+ for (let i = 0;i < permissions.length; i++) {
341
+ const p = permissions[i];
342
+ const bit = typeof p === "bigint" ? p : this.#resolve(p);
343
+ if ((this.bitfield & bit) !== bit)
344
+ return false;
345
+ }
346
+ return true;
347
+ }
348
+ any(...permissions) {
349
+ if (permissions.length === 1) {
350
+ const p = permissions[0];
351
+ const bit = typeof p === "bigint" ? p : this.#resolve(p);
352
+ return (this.bitfield & bit) !== 0n;
353
+ }
354
+ for (let i = 0;i < permissions.length; i++) {
355
+ const p = permissions[i];
356
+ const bit = typeof p === "bigint" ? p : this.#resolve(p);
357
+ if ((this.bitfield & bit) !== 0n)
358
+ return true;
359
+ }
360
+ return false;
361
+ }
362
+ add(...permissions) {
363
+ let bitfield = this.bitfield;
364
+ for (let i = 0;i < permissions.length; i++) {
365
+ const p = permissions[i];
366
+ bitfield |= typeof p === "bigint" ? p : this.#resolve(p);
367
+ }
368
+ return new PermissionSet(bitfield);
369
+ }
370
+ remove(...permissions) {
371
+ let bitfield = this.bitfield;
372
+ for (let i = 0;i < permissions.length; i++) {
373
+ const p = permissions[i];
374
+ bitfield &= ~(typeof p === "bigint" ? p : this.#resolve(p));
375
+ }
376
+ return new PermissionSet(bitfield);
377
+ }
378
+ equals(other) {
379
+ return this.bitfield === (other instanceof PermissionSet ? other.bitfield : new PermissionSet(other).bitfield);
380
+ }
381
+ toString() {
382
+ return this.bitfield.toString();
383
+ }
384
+ toArray() {
385
+ return Object.keys(Permission).filter((permission) => this.has(permission));
386
+ }
387
+ #resolve(permission) {
388
+ if (typeof permission === "bigint")
389
+ return permission;
390
+ if (typeof permission === "number")
391
+ return BigInt(permission);
392
+ if (permission instanceof PermissionSet)
393
+ return permission.bitfield;
394
+ if (Array.isArray(permission)) {
395
+ let bit = 0n;
396
+ for (let i = 0;i < permission.length; i++)
397
+ bit |= this.#resolve(permission[i]);
398
+ return bit;
399
+ }
400
+ if (typeof permission === "string") {
401
+ if (permission in Permission)
402
+ return Permission[permission];
403
+ if (permission in Permissions)
404
+ return Permissions[permission];
405
+ if (permission in PermissionFlagsBits)
406
+ return BigInt(PermissionFlagsBits[permission]);
407
+ const lower = permission.charAt(0).toLowerCase() + permission.slice(1);
408
+ if (lower in Permission)
409
+ return Permission[lower];
410
+ return BigInt(permission);
411
+ }
412
+ return 0n;
413
+ }
414
+ }
415
+
416
+ class PermissionsBitField extends PermissionSet {
417
+ static Flags = PermissionFlagsBits;
418
+ static All = Permission;
419
+ constructor(value = 0n) {
420
+ super(value);
421
+ }
422
+ }
423
+ // packages/collection/src/index.ts
424
+ class Collection extends Map {
425
+ first() {
426
+ for (const value of this.values())
427
+ return value;
428
+ return;
429
+ }
430
+ firstKey() {
431
+ for (const key of this.keys())
432
+ return key;
433
+ return;
434
+ }
435
+ last() {
436
+ let value;
437
+ for (const item of this.values())
438
+ value = item;
439
+ return value;
440
+ }
441
+ lastKey() {
442
+ let key;
443
+ for (const item of this.keys())
444
+ key = item;
445
+ return key;
446
+ }
447
+ find(predicate) {
448
+ for (const [key, value] of this) {
449
+ if (predicate(value, key, this))
450
+ return value;
451
+ }
452
+ return;
453
+ }
454
+ filter(predicate) {
455
+ const result = new Collection;
456
+ for (const [key, value] of this) {
457
+ if (predicate(value, key, this))
458
+ result.set(key, value);
459
+ }
460
+ return result;
461
+ }
462
+ map(transform) {
463
+ const result = [];
464
+ for (const [key, value] of this) {
465
+ result.push(transform(value, key, this));
466
+ }
467
+ return result;
468
+ }
469
+ some(predicate) {
470
+ for (const [key, value] of this) {
471
+ if (predicate(value, key, this))
472
+ return true;
473
+ }
474
+ return false;
475
+ }
476
+ every(predicate) {
477
+ for (const [key, value] of this) {
478
+ if (!predicate(value, key, this))
479
+ return false;
480
+ }
481
+ return true;
482
+ }
483
+ each(callback) {
484
+ for (const [key, value] of this) {
485
+ callback(value, key, this);
486
+ }
487
+ return this;
488
+ }
489
+ array() {
490
+ return [...this.values()];
491
+ }
492
+ keyArray() {
493
+ return [...this.keys()];
494
+ }
495
+ entriesArray() {
496
+ return [...this.entries()];
497
+ }
498
+ clone() {
499
+ const copy = new Collection;
500
+ for (const [key, value] of this)
501
+ copy.set(key, value);
502
+ return copy;
503
+ }
504
+ hasAll(...keys) {
505
+ for (let i = 0;i < keys.length; i++) {
506
+ if (!this.has(keys[i]))
507
+ return false;
508
+ }
509
+ return true;
510
+ }
511
+ hasAny(...keys) {
512
+ for (let i = 0;i < keys.length; i++) {
513
+ if (this.has(keys[i]))
514
+ return true;
515
+ }
516
+ return false;
517
+ }
518
+ findKey(predicate) {
519
+ for (const [key, value] of this) {
520
+ if (predicate(value, key, this))
521
+ return key;
522
+ }
523
+ return;
524
+ }
525
+ someEntry(predicate) {
526
+ return this.some(predicate);
527
+ }
528
+ sweep(predicate) {
529
+ let removed = 0;
530
+ for (const [key, value] of this) {
531
+ if (predicate(value, key, this) && this.delete(key))
532
+ removed++;
533
+ }
534
+ return removed;
535
+ }
536
+ firstEntry() {
537
+ for (const [key, value] of this)
538
+ return [key, value];
539
+ return;
540
+ }
541
+ lastEntry() {
542
+ let entry;
543
+ for (const item of this)
544
+ entry = [item[0], item[1]];
545
+ return entry;
546
+ }
547
+ }
548
+
549
+ // packages/managers/src/base.ts
550
+ class Manager {
551
+ cache = new Collection;
552
+ get(id) {
553
+ return this.cache.get(id);
554
+ }
555
+ has(id) {
556
+ return this.cache.has(id);
557
+ }
558
+ set(id, value) {
559
+ this.cache.set(id, value);
560
+ return this;
561
+ }
562
+ delete(id) {
563
+ return this.cache.delete(id);
564
+ }
565
+ clear() {
566
+ this.cache.clear();
567
+ }
568
+ get size() {
569
+ return this.cache.size;
570
+ }
571
+ first() {
572
+ return this.cache.first();
573
+ }
574
+ values() {
575
+ return this.cache.array();
576
+ }
577
+ find(predicate) {
578
+ return this.cache.find(predicate);
579
+ }
580
+ [Symbol.iterator]() {
581
+ return this.cache[Symbol.iterator]();
582
+ }
583
+ }
584
+
585
+ class ResourceManager extends Manager {
586
+ #fetcher;
587
+ #key;
588
+ constructor(fetcher, key) {
589
+ super();
590
+ if (typeof fetcher !== "function" || typeof key !== "function")
591
+ throw new TypeError("ResourceManager requires fetcher and key functions.");
592
+ this.#fetcher = fetcher;
593
+ this.#key = key;
594
+ }
595
+ async resolve(id) {
596
+ return this.get(id) ?? this.fetch(id);
597
+ }
598
+ async fetch(id) {
599
+ const resource = await this.#fetcher(id);
600
+ this.set(id, resource);
601
+ return resource;
602
+ }
603
+ async fetchMany(ids) {
604
+ return Promise.all([...ids].map((id) => this.resolve(id)));
605
+ }
606
+ upsert(resource) {
607
+ const key = this.#key(resource);
608
+ this.set(key, resource);
609
+ return resource;
610
+ }
611
+ update(resource) {
612
+ return this.upsert(resource);
613
+ }
614
+ }
615
+ // packages/rest/src/routes.ts
616
+ var Routes = {
617
+ user: () => "/users/@me",
618
+ userById: (userId) => `/users/${snowflake(userId, "User ID")}`,
619
+ guild: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}`,
620
+ guildChannels: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/channels`,
621
+ guildMember: (guildId, userId) => `/guilds/${snowflake(guildId, "Guild ID")}/members/${snowflake(userId, "User ID")}`,
622
+ guildRoles: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/roles`,
623
+ guildRole: (guildId, roleId) => `/guilds/${snowflake(guildId, "Guild ID")}/roles/${snowflake(roleId, "Role ID")}`,
624
+ guildMemberRole: (guildId, userId, roleId) => `/guilds/${snowflake(guildId, "Guild ID")}/members/${snowflake(userId, "User ID")}/roles/${snowflake(roleId, "Role ID")}`,
625
+ guildBans: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/bans`,
626
+ guildBan: (guildId, userId) => `/guilds/${snowflake(guildId, "Guild ID")}/bans/${snowflake(userId, "User ID")}`,
627
+ channel: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}`,
628
+ channelMessages: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/messages`,
629
+ message: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/${snowflake(messageId, "Message ID")}`,
630
+ crosspostMessage: (channelId, messageId) => `${Routes.message(channelId, messageId)}/crosspost`,
631
+ messageReactions: (channelId, messageId, emoji) => `${Routes.message(channelId, messageId)}/reactions/${encodeURIComponent(emoji)}`,
632
+ messageReactionsAll: (channelId, messageId) => `${Routes.message(channelId, messageId)}/reactions`,
633
+ channelPins: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/pins`,
634
+ channelPin: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/pins/${snowflake(messageId, "Message ID")}`,
635
+ messageThread: (channelId, messageId) => `${Routes.message(channelId, messageId)}/threads`,
636
+ channelBulkDelete: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/messages/bulk-delete`,
637
+ channelWebhooks: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/webhooks`,
638
+ channelInvites: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/invites`,
639
+ webhook: (webhookId, token) => `/webhooks/${snowflake(webhookId, "Webhook ID")}${token ? `/${encodeURIComponent(token)}` : ""}`,
640
+ webhookMessage: (webhookId, token, messageId) => `/webhooks/${snowflake(webhookId, "Webhook ID")}/${encodeURIComponent(token)}/messages/${snowflake(messageId, "Message ID")}`,
641
+ applicationCommands: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/commands`,
642
+ applicationCommand: (applicationId, commandId) => `/applications/${snowflake(applicationId, "Application ID")}/commands/${snowflake(commandId, "Command ID")}`,
643
+ guildApplicationCommands: (applicationId, guildId) => `/applications/${snowflake(applicationId, "Application ID")}/guilds/${snowflake(guildId, "Guild ID")}/commands`,
644
+ guildApplicationCommand: (applicationId, guildId, commandId) => `/applications/${snowflake(applicationId, "Application ID")}/guilds/${snowflake(guildId, "Guild ID")}/commands/${snowflake(commandId, "Command ID")}`,
645
+ interactionCallback: (interactionId, token) => `/interactions/${snowflake(interactionId, "Interaction ID")}/${encodeURIComponent(token)}/callback`,
646
+ interactionOriginalResponse: (applicationId, token) => `/webhooks/${snowflake(applicationId, "Application ID")}/${encodeURIComponent(token)}/messages/@original`,
647
+ guildActiveThreads: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/threads/active`,
648
+ channelPublicArchivedThreads: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/threads/archived/public`,
649
+ channelPrivateArchivedThreads: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/threads/archived/private`,
650
+ threadMembers: (threadId) => `/channels/${snowflake(threadId, "Thread ID")}/thread-members`,
651
+ guildScheduledEvents: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/scheduled-events`,
652
+ guildScheduledEvent: (guildId, eventId) => `/guilds/${snowflake(guildId, "Guild ID")}/scheduled-events/${snowflake(eventId, "Event ID")}`,
653
+ guildAutoModerationRules: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/auto-moderation/rules`,
654
+ guildAutoModerationRule: (guildId, ruleId) => `/guilds/${snowflake(guildId, "Guild ID")}/auto-moderation/rules/${snowflake(ruleId, "Rule ID")}`,
655
+ voiceRegions: () => "/voice/regions",
656
+ gateway: () => "/gateway",
657
+ gatewayBot: () => "/gateway/bot"
658
+ };
659
+ function snowflake(value, field) {
660
+ if (!/^\d{1,20}$/.test(value))
661
+ throw new TypeError(`${field} must be a valid Discord snowflake.`);
662
+ return value;
663
+ }
664
+
665
+ // packages/rest/src/index.ts
666
+ class RESTError extends Error {
667
+ status;
668
+ code;
669
+ errors;
670
+ method;
671
+ path;
672
+ constructor(message, status, code, errors, options = {}) {
673
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
674
+ this.name = "RESTError";
675
+ this.status = status;
676
+ this.code = code;
677
+ this.errors = errors;
678
+ this.method = options.method;
679
+ this.path = options.path;
680
+ }
681
+ }
682
+ function createRetryPolicy(maxRetries = 2) {
683
+ if (!Number.isFinite(maxRetries) || maxRetries < 0)
684
+ throw new TypeError("maxRetries must be a non-negative finite number.");
685
+ return {
686
+ maxRetries: Math.floor(maxRetries),
687
+ shouldRetry(method, status) {
688
+ const normalized = method.toUpperCase();
689
+ return status === 429 || status >= 500 && status <= 599 && ["GET", "HEAD", "PUT", "DELETE"].includes(normalized);
690
+ },
691
+ getDelay(attempt, retryAfter) {
692
+ if (retryAfter !== undefined)
693
+ return Math.max(0, retryAfter * 1000);
694
+ return Math.min(1e4, 500 * 2 ** attempt) + Math.random() * 250;
695
+ }
696
+ };
697
+ }
698
+
699
+ class REST {
700
+ #baseURL;
701
+ #timeout;
702
+ #retryPolicy;
703
+ #token;
704
+ #globalResetAt = 0;
705
+ #buckets = new Map;
706
+ #routeBuckets = new Map;
707
+ constructor(options = {}) {
708
+ this.#token = options.token;
709
+ this.#timeout = Math.max(1, options.timeout ?? 15000);
710
+ this.#retryPolicy = options.retryPolicy ?? createRetryPolicy(options.retries ?? 2);
711
+ this.#baseURL = (options.baseURL ?? "https://discord.com/api/v10").replace(/\/$/, "");
712
+ }
713
+ setToken(token) {
714
+ if (!token.trim())
715
+ throw new TypeError("A Discord bot token is required.");
716
+ this.#token = token;
717
+ }
718
+ async request(method, path, body, options = {}) {
719
+ const normalizedMethod = method.toUpperCase();
720
+ if (!normalizedMethod)
721
+ throw new TypeError("REST method is required.");
722
+ if (!path.startsWith("/"))
723
+ throw new TypeError("REST paths must start with '/'.");
724
+ 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;
733
+ let release;
734
+ bucket.queue = new Promise((resolve) => {
735
+ release = resolve;
736
+ });
737
+ await this.#abortable(previous, options.signal, path);
738
+ try {
739
+ for (let attempt = 0;attempt <= this.#retryPolicy.maxRetries; attempt++) {
740
+ await this.#wait(bucket, options.signal, path);
741
+ await this.#waitGlobal(options.signal, path);
742
+ const controller = new AbortController;
743
+ const onAbort = () => controller.abort(options.signal?.reason);
744
+ if (options.signal?.aborted)
745
+ throw this.#abortError(path, options.signal.reason);
746
+ options.signal?.addEventListener("abort", onAbort, { once: true });
747
+ const timer = setTimeout(() => controller.abort(new DOMException("REST request timeout", "TimeoutError")), this.#timeout);
748
+ try {
749
+ const response = await fetch(`${this.#baseURL}${path}`, {
750
+ 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),
757
+ signal: controller.signal
758
+ });
759
+ bucket = this.#update(response, bucket, route, bucketKey);
760
+ bucketKey = this.#routeBuckets.get(route) ?? bucketKey;
761
+ const payload = await this.#readPayload(response);
762
+ if (response.ok)
763
+ return response.status === 204 ? undefined : payload;
764
+ const data = this.#errorData(payload);
765
+ const retryAfter = response.status === 429 ? this.#retryAfter(response, data) : undefined;
766
+ if (data.global && retryAfter !== undefined)
767
+ this.#globalResetAt = Date.now() + retryAfter * 1000;
768
+ if (attempt < this.#retryPolicy.maxRetries && this.#retryPolicy.shouldRetry(normalizedMethod, response.status)) {
769
+ await this.#sleep(this.#retryPolicy.getDelay(attempt, retryAfter), options.signal, path);
770
+ continue;
771
+ }
772
+ throw new RESTError(data.message ?? response.statusText ?? `Discord REST request failed with status ${response.status}`, response.status, data.code, payload, { method: normalizedMethod, path });
773
+ } catch (error) {
774
+ if (error instanceof RESTError)
775
+ throw error;
776
+ if (options.signal?.aborted)
777
+ throw this.#abortError(path, options.signal.reason);
778
+ const isTimeout = error instanceof DOMException && (error.name === "TimeoutError" || error.name === "AbortError");
779
+ if (!isTimeout && attempt < this.#retryPolicy.maxRetries && this.#retryPolicy.shouldRetry(normalizedMethod, 0)) {
780
+ await this.#sleep(this.#retryPolicy.getDelay(attempt), options.signal, path);
781
+ continue;
782
+ }
783
+ throw new RESTError(isTimeout ? `Discord REST request timed out after ${this.#timeout}ms` : "Discord REST request failed", 0, undefined, undefined, { method: normalizedMethod, path, cause: error });
784
+ } finally {
785
+ clearTimeout(timer);
786
+ options.signal?.removeEventListener("abort", onAbort);
787
+ }
788
+ }
789
+ throw new RESTError("Discord REST request exhausted its retry attempts", 0, undefined, undefined, { method: normalizedMethod, path });
790
+ } finally {
791
+ release();
792
+ }
793
+ }
794
+ get(path, options) {
795
+ return this.request("GET", path, undefined, options);
796
+ }
797
+ post(path, body, options) {
798
+ return this.request("POST", path, body, options);
799
+ }
800
+ patch(path, body, options) {
801
+ return this.request("PATCH", path, body, options);
802
+ }
803
+ put(path, body, options) {
804
+ return this.request("PUT", path, body, options);
805
+ }
806
+ delete(path, options) {
807
+ return this.request("DELETE", path, undefined, options);
808
+ }
809
+ async#wait(bucket, signal, path) {
810
+ const delay = bucket.resetAt - Date.now();
811
+ if (bucket.remaining <= 0 && delay > 0)
812
+ await this.#sleep(delay, signal, path);
813
+ }
814
+ async#waitGlobal(signal, path) {
815
+ const delay = this.#globalResetAt - Date.now();
816
+ if (delay > 0)
817
+ await this.#sleep(delay, signal, path);
818
+ }
819
+ async#sleep(delay, signal, path) {
820
+ if (delay <= 0)
821
+ return;
822
+ await new Promise((resolve, reject) => {
823
+ const timer = setTimeout(resolve, delay);
824
+ const abort = () => {
825
+ clearTimeout(timer);
826
+ reject(this.#abortError(path, signal?.reason));
827
+ };
828
+ if (signal?.aborted)
829
+ return abort();
830
+ signal?.addEventListener("abort", abort, { once: true });
831
+ });
832
+ }
833
+ async#abortable(promise, signal, path) {
834
+ if (!signal)
835
+ return promise;
836
+ if (signal.aborted)
837
+ throw this.#abortError(path, signal.reason);
838
+ return Promise.race([
839
+ promise,
840
+ new Promise((_, reject) => signal.addEventListener("abort", () => reject(this.#abortError(path, signal.reason)), { once: true }))
841
+ ]);
842
+ }
843
+ #abortError(path, reason) {
844
+ return new RESTError(reason instanceof Error ? reason.message : "Discord REST request was aborted", 0, undefined, undefined, { path, cause: reason });
845
+ }
846
+ async#readPayload(response) {
847
+ if (response.status === 204)
848
+ return;
849
+ const contentType = response.headers.get("content-type") ?? "";
850
+ if (contentType.includes("application/json"))
851
+ return response.json().catch(() => {
852
+ return;
853
+ });
854
+ return response.text().catch(() => {
855
+ return;
856
+ });
857
+ }
858
+ #errorData(payload) {
859
+ if (!payload || typeof payload !== "object")
860
+ return {};
861
+ const data = payload;
862
+ return {
863
+ message: typeof data.message === "string" ? data.message : undefined,
864
+ code: typeof data.code === "number" ? data.code : undefined,
865
+ retry_after: typeof data.retry_after === "number" ? data.retry_after : undefined,
866
+ global: data.global === true
867
+ };
868
+ }
869
+ #retryAfter(response, data) {
870
+ const header = Number(response.headers.get("Retry-After"));
871
+ const retryAfter = data.retry_after ?? (Number.isFinite(header) ? header : 1);
872
+ return Math.max(0, retryAfter);
873
+ }
874
+ #normalizeRoute(path) {
875
+ const queryIndex = path.indexOf("?");
876
+ const routePath = queryIndex === -1 ? path : path.slice(0, queryIndex);
877
+ return routePath.replace(/\/\d+(?=\/|$)/g, "/:id");
878
+ }
879
+ #update(response, bucket, route, bucketKey) {
880
+ const serverBucket = response.headers.get("X-RateLimit-Bucket");
881
+ 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
+ }
888
+ }
889
+ const remaining = Number(response.headers.get("X-RateLimit-Remaining"));
890
+ const resetAfter = Number(response.headers.get("X-RateLimit-Reset-After"));
891
+ const reset = Number(response.headers.get("X-RateLimit-Reset"));
892
+ if (Number.isFinite(remaining))
893
+ bucket.remaining = Math.max(0, remaining);
894
+ if (Number.isFinite(resetAfter))
895
+ bucket.resetAt = Date.now() + Math.max(0, resetAfter) * 1000;
896
+ else if (Number.isFinite(reset))
897
+ bucket.resetAt = reset * 1000;
898
+ if (response.status === 429) {
899
+ const retryAfter = Number(response.headers.get("Retry-After"));
900
+ if (Number.isFinite(retryAfter))
901
+ bucket.resetAt = Math.max(bucket.resetAt, Date.now() + retryAfter * 1000);
902
+ }
903
+ if (response.headers.get("X-RateLimit-Global") === "true") {
904
+ const retryAfter = Number(response.headers.get("Retry-After"));
905
+ if (Number.isFinite(retryAfter))
906
+ this.#globalResetAt = Math.max(this.#globalResetAt, Date.now() + retryAfter * 1000);
907
+ }
908
+ return bucket;
909
+ }
910
+ }
911
+
912
+ // packages/structures/src/base.ts
913
+ class BaseStructure {
914
+ id;
915
+ constructor(id) {
916
+ if (!/^\d{1,20}$/.test(id))
917
+ throw new TypeError("A Discord structure requires a valid snowflake ID.");
918
+ this.id = id;
919
+ }
920
+ toString() {
921
+ return this.id;
922
+ }
923
+ }
924
+
925
+ class User extends BaseStructure {
926
+ username;
927
+ globalName;
928
+ avatar;
929
+ bot;
930
+ system;
931
+ flags;
932
+ constructor(data) {
933
+ super(data.id);
934
+ if (!data.username)
935
+ throw new TypeError("A Discord user requires a username.");
936
+ this.username = data.username;
937
+ this.globalName = data.global_name ?? null;
938
+ this.avatar = data.avatar ?? null;
939
+ this.bot = data.bot ?? false;
940
+ this.system = data.system ?? false;
941
+ this.flags = data.public_flags ?? 0;
942
+ }
943
+ get displayName() {
944
+ return this.globalName ?? this.username;
945
+ }
946
+ avatarURL(options = {}) {
947
+ if (!this.avatar)
948
+ 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}` : ""}`;
951
+ }
952
+ defaultAvatarURL() {
953
+ return `https://cdn.discordapp.com/embed/avatars/${Number(BigInt(this.id) % 5n)}.png`;
954
+ }
955
+ displayAvatarURL(options = {}) {
956
+ return this.avatarURL(options) ?? this.defaultAvatarURL();
957
+ }
958
+ }
959
+
960
+ class Channel extends BaseStructure {
961
+ type;
962
+ name;
963
+ guildId;
964
+ #context;
965
+ constructor(data, context) {
966
+ super(data.id);
967
+ if (!Number.isInteger(data.type) || data.type < 0)
968
+ throw new RangeError("A Discord channel requires a valid channel type.");
969
+ this.type = data.type;
970
+ this.name = data.name;
971
+ this.guildId = data.guild_id;
972
+ this.#context = context;
973
+ }
974
+ sendMessage(options) {
975
+ if (!this.#context)
976
+ throw new Error("This channel is not attached to a client.");
977
+ return this.#context.sendMessage(this.id, options);
978
+ }
979
+ }
980
+
981
+ class Guild extends BaseStructure {
982
+ name;
983
+ preferredLocale;
984
+ ownerId;
985
+ constructor(data) {
986
+ super(data.id);
987
+ if (!data.name)
988
+ throw new TypeError("A Discord guild requires a name.");
989
+ this.name = data.name;
990
+ this.preferredLocale = data.preferred_locale;
991
+ this.ownerId = data.owner_id;
992
+ }
993
+ }
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
+ // packages/structures/src/interactions.ts
1047
+ var InteractionType = {
1048
+ Ping: 1,
1049
+ ApplicationCommand: 2,
1050
+ MessageComponent: 3,
1051
+ ApplicationCommandAutocomplete: 4,
1052
+ ModalSubmit: 5
1053
+ };
1054
+ var InteractionResponseType = {
1055
+ Pong: 1,
1056
+ ChannelMessage: 4,
1057
+ DeferredChannelMessage: 5,
1058
+ DeferredMessageUpdate: 6,
1059
+ MessageUpdate: 7,
1060
+ Autocomplete: 8,
1061
+ Modal: 9
1062
+ };
1063
+
1064
+ class InteractionResponse {
1065
+ type;
1066
+ data;
1067
+ constructor(type, data) {
1068
+ if (!Number.isFinite(type))
1069
+ throw new TypeError("Interaction response type must be finite.");
1070
+ this.type = type;
1071
+ this.data = data;
1072
+ }
1073
+ toJSON() {
1074
+ return this.data === undefined ? { type: this.type } : { type: this.type, data: this.data };
1075
+ }
1076
+ static message(options) {
1077
+ const data = { ...options };
1078
+ if (options.ephemeral) {
1079
+ data.flags = (typeof options.flags === "number" ? options.flags : 0) | 64;
1080
+ }
1081
+ return new InteractionResponse(InteractionResponseType.ChannelMessage, data);
1082
+ }
1083
+ static defer(ephemeral = false) {
1084
+ return new InteractionResponse(InteractionResponseType.DeferredChannelMessage, ephemeral ? { flags: 64 } : undefined);
1085
+ }
1086
+ static pong() {
1087
+ return new InteractionResponse(InteractionResponseType.Pong);
1088
+ }
1089
+ }
1090
+
1091
+ class Interaction {
1092
+ id;
1093
+ applicationId;
1094
+ token;
1095
+ guildId;
1096
+ channelId;
1097
+ type;
1098
+ data;
1099
+ replied = false;
1100
+ deferred = false;
1101
+ #client;
1102
+ constructor(client, data) {
1103
+ if (!data.id || !data.token)
1104
+ throw new TypeError("Interaction ID and token are required.");
1105
+ this.#client = client;
1106
+ this.id = data.id;
1107
+ this.applicationId = data.application_id;
1108
+ this.token = data.token;
1109
+ this.guildId = data.guild_id;
1110
+ this.channelId = data.channel_id;
1111
+ this.type = data.type;
1112
+ this.data = data;
1113
+ }
1114
+ isChatInputCommand() {
1115
+ return this.type === InteractionType.ApplicationCommand;
1116
+ }
1117
+ isMessageComponent() {
1118
+ return this.type === InteractionType.MessageComponent;
1119
+ }
1120
+ isModalSubmit() {
1121
+ return this.type === InteractionType.ModalSubmit;
1122
+ }
1123
+ isAutocomplete() {
1124
+ return this.type === InteractionType.ApplicationCommandAutocomplete;
1125
+ }
1126
+ assertUnacknowledged() {
1127
+ if (this.replied || this.deferred)
1128
+ throw new Error("Interaction has already been acknowledged.");
1129
+ }
1130
+ assertAcknowledged() {
1131
+ if (!this.replied && !this.deferred)
1132
+ throw new Error("Interaction has not been acknowledged.");
1133
+ }
1134
+ postResponse(response) {
1135
+ return this.#client.postInteractionResponse(this.id, this.token, response);
1136
+ }
1137
+ async reply(options) {
1138
+ this.assertUnacknowledged();
1139
+ const payload = typeof options === "string" ? { content: options } : options;
1140
+ const result = await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.message(payload));
1141
+ this.replied = true;
1142
+ return result;
1143
+ }
1144
+ async deferReply(ephemeral = false) {
1145
+ this.assertUnacknowledged();
1146
+ await this.#client.postInteractionResponse(this.id, this.token, InteractionResponse.defer(ephemeral));
1147
+ this.deferred = true;
1148
+ }
1149
+ editReply(options) {
1150
+ this.assertAcknowledged();
1151
+ return this.#client.editInteractionReply(this.token, options);
1152
+ }
1153
+ deleteReply() {
1154
+ this.assertAcknowledged();
1155
+ return this.#client.deleteInteractionReply(this.token);
1156
+ }
1157
+ followUp(options) {
1158
+ const payload = typeof options === "string" ? { content: options } : options;
1159
+ return this.#client.followUpInteraction(this.token, payload);
1160
+ }
1161
+ async update(options) {
1162
+ this.assertUnacknowledged();
1163
+ const payload = typeof options === "string" ? { content: options } : options;
1164
+ const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
1165
+ this.replied = true;
1166
+ return result;
1167
+ }
1168
+ async showModal(modal) {
1169
+ this.assertUnacknowledged();
1170
+ const result = await this.#client.postInteractionResponse(this.id, this.token, new InteractionResponse(InteractionResponseType.Modal, modal));
1171
+ this.replied = true;
1172
+ return result;
1173
+ }
1174
+ }
1175
+
1176
+ class CommandInteraction extends Interaction {
1177
+ get commandName() {
1178
+ return typeof this.data.data?.name === "string" ? this.data.data.name : "";
1179
+ }
1180
+ }
1181
+
1182
+ class ComponentInteraction extends Interaction {
1183
+ get customId() {
1184
+ return this.data?.data?.custom_id ?? "";
1185
+ }
1186
+ get componentType() {
1187
+ return this.data?.data?.component_type ?? 0;
1188
+ }
1189
+ get values() {
1190
+ return this.data?.data?.values ?? [];
1191
+ }
1192
+ async deferUpdate() {
1193
+ this.assertUnacknowledged();
1194
+ await this.postResponse(new InteractionResponse(InteractionResponseType.DeferredMessageUpdate));
1195
+ this.deferred = true;
1196
+ }
1197
+ async update(options) {
1198
+ this.assertUnacknowledged();
1199
+ const payload = typeof options === "string" ? { content: options } : options;
1200
+ const result = await this.postResponse(new InteractionResponse(InteractionResponseType.MessageUpdate, payload));
1201
+ this.replied = true;
1202
+ return result;
1203
+ }
1204
+ }
1205
+ function createInteraction(client, data) {
1206
+ switch (data.type) {
1207
+ case InteractionType.ApplicationCommand:
1208
+ case InteractionType.ApplicationCommandAutocomplete:
1209
+ return new CommandInteraction(client, data);
1210
+ case InteractionType.MessageComponent:
1211
+ case InteractionType.ModalSubmit:
1212
+ return new ComponentInteraction(client, data);
1213
+ default:
1214
+ return new Interaction(client, data);
1215
+ }
1216
+ }
1217
+
1218
+ // packages/structures/src/index.ts
1219
+ class Message extends BaseStructure {
1220
+ content;
1221
+ author;
1222
+ channelId;
1223
+ channel;
1224
+ guildId;
1225
+ flags;
1226
+ createdAt;
1227
+ attachments;
1228
+ embeds;
1229
+ mentions;
1230
+ mentionRoles;
1231
+ pinned;
1232
+ mentionEveryone;
1233
+ type;
1234
+ reference;
1235
+ referencedMessage;
1236
+ #context;
1237
+ constructor(data, context) {
1238
+ super(data.id);
1239
+ if (!/^\d{1,20}$/.test(data.channel_id))
1240
+ throw new TypeError("Message channel_id must be a valid snowflake.");
1241
+ this.content = data.content ?? "";
1242
+ this.author = new User(data.author);
1243
+ this.channelId = data.channel_id;
1244
+ this.guildId = data.guild_id;
1245
+ this.flags = data.flags ?? 0;
1246
+ this.createdAt = new Date(data.timestamp ?? Number((BigInt(this.id) >> 22n) + 1420070400000n));
1247
+ this.attachments = data.attachments ?? [];
1248
+ this.embeds = data.embeds ?? [];
1249
+ this.mentions = (data.mentions ?? []).map((user) => new User(user));
1250
+ this.mentionRoles = data.mention_roles ?? [];
1251
+ this.pinned = data.pinned ?? false;
1252
+ this.mentionEveryone = data.mention_everyone ?? false;
1253
+ this.type = data.type ?? 0;
1254
+ this.reference = data.message_reference;
1255
+ this.referencedMessage = data.referenced_message ? new Message(data.referenced_message, context) : data.referenced_message === null ? null : undefined;
1256
+ this.#context = context;
1257
+ this.channel = new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context);
1258
+ }
1259
+ get embedsSuppressed() {
1260
+ return (this.flags & 4) !== 0;
1261
+ }
1262
+ edit(options) {
1263
+ if (!this.#context)
1264
+ throw new Error("This message is not attached to a client.");
1265
+ return this.#context.editMessage(this.channelId, this.id, options);
1266
+ }
1267
+ delete() {
1268
+ if (!this.#context)
1269
+ throw new Error("This message is not attached to a client.");
1270
+ return this.#context.deleteMessage(this.channelId, this.id);
1271
+ }
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
+ reply(options) {
1278
+ if (!this.#context)
1279
+ throw new Error("This message is not attached to a client.");
1280
+ const payload = typeof options === "string" ? { content: options } : { ...options };
1281
+ payload.message_reference = {
1282
+ message_id: this.id,
1283
+ channel_id: this.channelId,
1284
+ guild_id: this.guildId
1285
+ };
1286
+ return this.#context.sendMessage(this.channelId, payload);
1287
+ }
1288
+ }
1289
+
1290
+ // packages/managers/src/message.ts
1291
+ class MessageManager {
1292
+ cache = new Collection;
1293
+ #rest;
1294
+ #context;
1295
+ #channelId;
1296
+ constructor(rest, context, channelId) {
1297
+ if (!channelId)
1298
+ throw new TypeError("Channel ID is required.");
1299
+ this.#rest = rest;
1300
+ this.#context = context;
1301
+ this.#channelId = channelId;
1302
+ }
1303
+ async resolve(messageId) {
1304
+ return this.cache.get(messageId) ?? this.fetch(messageId);
1305
+ }
1306
+ async send(options) {
1307
+ const data = await this.#rest.post(Routes.channelMessages(this.#channelId), options);
1308
+ return this.upsert(data);
1309
+ }
1310
+ async fetch(messageId) {
1311
+ 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);
1316
+ }
1317
+ fetchMany(messageIds) {
1318
+ return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
1319
+ }
1320
+ upsert(data) {
1321
+ const existing = this.cache.get(data.id);
1322
+ const message = new Message(data, this.#context);
1323
+ if (existing) {
1324
+ Object.assign(existing, message);
1325
+ return existing;
1326
+ }
1327
+ this.cache.set(message.id, message);
1328
+ return message;
1329
+ }
1330
+ delete(messageId) {
1331
+ return this.cache.delete(messageId);
1332
+ }
1333
+ }
1334
+
1335
+ // packages/managers/src/thread.ts
1336
+ class ThreadManager {
1337
+ #rest;
1338
+ #context;
1339
+ #channelId;
1340
+ constructor(rest, context, channelId) {
1341
+ if (!channelId)
1342
+ throw new TypeError("Channel ID is required.");
1343
+ this.#rest = rest;
1344
+ this.#context = context;
1345
+ this.#channelId = channelId;
1346
+ }
1347
+ async createFromMessage(messageId, options) {
1348
+ const data = await this.#rest.post(Routes.messageThread(this.#channelId, messageId), {
1349
+ name: options.name,
1350
+ auto_archive_duration: options.autoArchiveDuration,
1351
+ rate_limit_per_user: options.rateLimitPerUser
1352
+ });
1353
+ return new Channel(data, this.#context);
1354
+ }
1355
+ }
1356
+ // packages/managers/src/application.ts
1357
+ class ApplicationCommandManager {
1358
+ #rest;
1359
+ #applicationId;
1360
+ constructor(rest, applicationId) {
1361
+ this.#rest = rest;
1362
+ this.#applicationId = applicationId;
1363
+ }
1364
+ fetch() {
1365
+ return this.#rest.get(Routes.applicationCommands(this.#applicationId));
1366
+ }
1367
+ create(data) {
1368
+ return this.#rest.post(Routes.applicationCommands(this.#applicationId), data);
1369
+ }
1370
+ set(commands) {
1371
+ return this.#rest.put(Routes.applicationCommands(this.#applicationId), commands);
1372
+ }
1373
+ edit(commandId, data) {
1374
+ return this.#rest.patch(Routes.applicationCommand(this.#applicationId, commandId), data);
1375
+ }
1376
+ async delete(commandId) {
1377
+ await this.#rest.delete(Routes.applicationCommand(this.#applicationId, commandId));
1378
+ }
1379
+ fetchGuild(guildId) {
1380
+ return this.#rest.get(Routes.guildApplicationCommands(this.#applicationId, guildId));
1381
+ }
1382
+ createGuild(guildId, data) {
1383
+ return this.#rest.post(Routes.guildApplicationCommands(this.#applicationId, guildId), data);
1384
+ }
1385
+ setGuild(guildId, commands) {
1386
+ return this.#rest.put(Routes.guildApplicationCommands(this.#applicationId, guildId), commands);
1387
+ }
1388
+ editGuild(guildId, commandId, data) {
1389
+ return this.#rest.patch(Routes.guildApplicationCommand(this.#applicationId, guildId, commandId), data);
1390
+ }
1391
+ async deleteGuild(guildId, commandId) {
1392
+ await this.#rest.delete(Routes.guildApplicationCommand(this.#applicationId, guildId, commandId));
1393
+ }
1394
+ }
1395
+
1396
+ // 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
+ class ChannelManager extends Manager {
1415
+ #rest;
1416
+ #context;
1417
+ #messageManagers = new Map;
1418
+ constructor(rest) {
1419
+ super();
1420
+ this.#rest = rest;
1421
+ this.#context = {
1422
+ sendMessage: (channelId, options) => this.send(channelId, options),
1423
+ editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
1424
+ deleteMessage: (channelId, messageId) => this.deleteMessage(channelId, messageId),
1425
+ crosspostMessage: (channelId, messageId) => this.crosspostMessage(channelId, messageId)
1426
+ };
1427
+ }
1428
+ messages(channelId) {
1429
+ let manager = this.#messageManagers.get(channelId);
1430
+ if (!manager) {
1431
+ manager = new MessageManager(this.#rest, this.#context, channelId);
1432
+ this.#messageManagers.set(channelId, manager);
1433
+ }
1434
+ return manager;
1435
+ }
1436
+ threads(channelId) {
1437
+ return new ThreadManager(this.#rest, this.#context, channelId);
1438
+ }
1439
+ async fetch(channelId) {
1440
+ const data = await this.#rest.get(Routes.channel(channelId));
1441
+ return this.upsert(data);
1442
+ }
1443
+ async resolve(channelId) {
1444
+ return this.get(channelId) ?? this.fetch(channelId);
1445
+ }
1446
+ upsert(data) {
1447
+ const existing = this.get(data.id);
1448
+ const channel = new Channel(data, this.#context);
1449
+ if (existing) {
1450
+ Object.assign(existing, channel);
1451
+ return existing;
1452
+ }
1453
+ this.set(channel.id, channel);
1454
+ return channel;
1455
+ }
1456
+ update(channel) {
1457
+ return this.set(channel.id, channel);
1458
+ }
1459
+ send(channelId, options) {
1460
+ return this.messages(channelId).send(options);
1461
+ }
1462
+ sendMessage(channelId, options) {
1463
+ return this.send(channelId, options);
1464
+ }
1465
+ async fetchMessage(channelId, messageId, options = {}) {
1466
+ return this.messages(channelId).fetch(messageId);
1467
+ }
1468
+ fetchMessages(channelId, query) {
1469
+ if (isMessageQuery(query)) {
1470
+ const params = new URLSearchParams;
1471
+ if (query.before)
1472
+ params.set("before", query.before);
1473
+ if (query.after)
1474
+ params.set("after", query.after);
1475
+ if (query.around)
1476
+ params.set("around", query.around);
1477
+ if (query.limit !== undefined)
1478
+ params.set("limit", String(query.limit));
1479
+ const suffix = params.toString();
1480
+ return this.#rest.get(`${Routes.channelMessages(channelId)}${suffix ? `?${suffix}` : ""}`).then((data) => data.map((item) => this.messages(channelId).upsert(item)));
1481
+ }
1482
+ return this.messages(channelId).fetchMany(query);
1483
+ }
1484
+ upsertMessage(data) {
1485
+ return this.messages(data.channel_id).upsert(data);
1486
+ }
1487
+ async editMessage(channelId, messageId, options) {
1488
+ const data = await this.#rest.patch(Routes.message(channelId, messageId), options);
1489
+ return this.messages(channelId).upsert(data);
1490
+ }
1491
+ async deleteMessage(channelId, messageId) {
1492
+ await this.#rest.delete(Routes.message(channelId, messageId));
1493
+ this.messages(channelId).delete(messageId);
1494
+ }
1495
+ deleteCachedMessage(channelId, messageId) {
1496
+ return this.messages(channelId).delete(messageId);
1497
+ }
1498
+ async crosspostMessage(channelId, messageId) {
1499
+ const data = await this.#rest.post(Routes.crosspostMessage(channelId, messageId));
1500
+ return this.messages(channelId).upsert(data);
1501
+ }
1502
+ async bulkDeleteMessages(channelId, messageIds) {
1503
+ const ids = [...messageIds];
1504
+ await this.#rest.post(Routes.channelBulkDelete(channelId), {
1505
+ messages: ids
1506
+ });
1507
+ for (const id of ids)
1508
+ this.messages(channelId).delete(id);
1509
+ }
1510
+ async addReaction(channelId, messageId, emoji) {
1511
+ await this.#rest.put(Routes.messageReactions(channelId, messageId, emoji));
1512
+ }
1513
+ async fetchReactions(channelId, messageId, emoji, options = {}) {
1514
+ const params = new URLSearchParams;
1515
+ if (options.limit !== undefined)
1516
+ params.set("limit", String(options.limit));
1517
+ if (options.after)
1518
+ params.set("after", options.after);
1519
+ const suffix = params.toString();
1520
+ const data = await this.#rest.get(`${Routes.messageReactions(channelId, messageId, emoji)}${suffix ? `?${suffix}` : ""}`);
1521
+ return data.map((user) => new User(user));
1522
+ }
1523
+ async removeOwnReaction(channelId, messageId, emoji) {
1524
+ await this.#rest.delete(Routes.messageReactions(channelId, messageId, emoji) + "/@me");
1525
+ }
1526
+ async removeReaction(channelId, messageId, emoji, userId) {
1527
+ await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/${userId}`);
1528
+ }
1529
+ async removeAllReactions(channelId, messageId) {
1530
+ await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));
1531
+ }
1532
+ async fetchPinnedMessages(channelId) {
1533
+ const data = await this.#rest.get(Routes.channelPins(channelId));
1534
+ return data.map((item) => this.messages(channelId).upsert(item));
1535
+ }
1536
+ async pinMessage(channelId, messageId) {
1537
+ await this.#rest.put(Routes.channelPin(channelId, messageId));
1538
+ }
1539
+ async unpinMessage(channelId, messageId) {
1540
+ await this.#rest.delete(Routes.channelPin(channelId, messageId));
1541
+ }
1542
+ createThreadFromMessage(channelId, messageId, options) {
1543
+ return this.threads(channelId).createFromMessage(messageId, options);
1544
+ }
1545
+ delete(channelId) {
1546
+ this.#messageManagers.delete(channelId);
1547
+ return super.delete(channelId);
1548
+ }
1549
+ clear() {
1550
+ this.#messageManagers.clear();
1551
+ super.clear();
1552
+ }
1553
+ }
1554
+ function isMessageQuery(value) {
1555
+ return typeof value === "object" && value !== null && !(Symbol.iterator in value);
1556
+ }
1557
+
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
+ // packages/ws/src/index.ts
1679
+ var GatewayOpcodes = {
1680
+ Dispatch: 0,
1681
+ Heartbeat: 1,
1682
+ Identify: 2,
1683
+ PresenceUpdate: 3,
1684
+ VoiceStateUpdate: 4,
1685
+ Resume: 6,
1686
+ Reconnect: 7,
1687
+ RequestGuildMembers: 8,
1688
+ InvalidSession: 9,
1689
+ Hello: 10,
1690
+ HeartbeatAck: 11
1691
+ };
1692
+ class GatewayError extends Error {
1693
+ code;
1694
+ constructor(message, code, options) {
1695
+ super(message, options);
1696
+ this.name = "GatewayError";
1697
+ this.code = code;
1698
+ }
1699
+ }
1700
+
1701
+ class Gateway {
1702
+ state = "CONNECT" /* Connect */;
1703
+ #options;
1704
+ #ws;
1705
+ #sequence = null;
1706
+ #sessionId;
1707
+ #resumeURL;
1708
+ #heartbeatTimer;
1709
+ #initialHeartbeat;
1710
+ #heartbeatAckTimer;
1711
+ #heartbeatACK = true;
1712
+ #heartbeatInterval = 0;
1713
+ #heartbeatSentAt = 0;
1714
+ #lastMessageAt = 0;
1715
+ #zombieTimer;
1716
+ #zombieReported = false;
1717
+ #closed = false;
1718
+ #attempt = 0;
1719
+ #reconnectTimer;
1720
+ #connectPromise;
1721
+ #resolveConnect;
1722
+ #rejectConnect;
1723
+ #listeners = new Map;
1724
+ #sendTimestamps = [];
1725
+ constructor(options) {
1726
+ if (!options.token?.trim())
1727
+ throw new TypeError("A Gateway token is required.");
1728
+ const resolvedIntents = resolveGatewayIntents(options.intents);
1729
+ if (!Number.isInteger(resolvedIntents) || resolvedIntents < 0)
1730
+ throw new TypeError("Gateway intents must be a non-negative integer.");
1731
+ this.#options = {
1732
+ shardId: 0,
1733
+ shardCount: 1,
1734
+ reconnect: true,
1735
+ maxReconnectAttempts: Infinity,
1736
+ reconnectBaseDelay: 1000,
1737
+ reconnectMaxDelay: 30000,
1738
+ heartbeatAckTimeout: 1e4,
1739
+ zombieTimeout: 30000,
1740
+ properties: {
1741
+ os: "Android",
1742
+ browser: "Discord Android",
1743
+ device: "Discord Android"
1744
+ },
1745
+ presence: { status: "online", activities: [], afk: false, since: null },
1746
+ ...options
1747
+ };
1748
+ if (this.#options.shardId < 0 || this.#options.shardId >= this.#options.shardCount)
1749
+ throw new RangeError("Gateway shardId must be within the configured shard count.");
1750
+ if (this.#options.zombieTimeout <= this.#options.heartbeatAckTimeout)
1751
+ throw new RangeError("Gateway zombieTimeout must be greater than heartbeatAckTimeout");
1752
+ }
1753
+ connect(url = "wss://gateway.discord.gg/?v=10&encoding=json") {
1754
+ if (this.state === "CLOSED" /* Closed */)
1755
+ throw new GatewayError("Gateway has been permanently closed.");
1756
+ if (this.#connectPromise)
1757
+ return this.#connectPromise;
1758
+ this.#closed = false;
1759
+ this.#setState("CONNECT" /* Connect */);
1760
+ this.#connectPromise = new Promise((resolve, reject) => {
1761
+ this.#resolveConnect = resolve;
1762
+ this.#rejectConnect = reject;
1763
+ this.#open(url);
1764
+ });
1765
+ return this.#connectPromise;
1766
+ }
1767
+ close() {
1768
+ this.#closed = true;
1769
+ this.#clearTimers();
1770
+ this.#settleConnect(new GatewayError("Gateway connection closed before socket open."));
1771
+ const ws = this.#ws;
1772
+ this.#ws = undefined;
1773
+ try {
1774
+ ws?.close(1000, "Client closed connection");
1775
+ } catch (error) {
1776
+ this.#emitError(error);
1777
+ }
1778
+ this.#setState("CLOSED" /* Closed */);
1779
+ }
1780
+ emit(event, data) {
1781
+ this.#emit(event, data);
1782
+ }
1783
+ on(event, listener) {
1784
+ if (!event || typeof listener !== "function")
1785
+ throw new TypeError("Gateway event and listener are required.");
1786
+ let listeners = this.#listeners.get(event);
1787
+ if (!listeners)
1788
+ this.#listeners.set(event, listeners = new Set);
1789
+ listeners.add(listener);
1790
+ return this;
1791
+ }
1792
+ off(event, listener) {
1793
+ this.#listeners.get(event)?.delete(listener);
1794
+ return this;
1795
+ }
1796
+ send(payload) {
1797
+ if (!payload || !Number.isInteger(payload.op))
1798
+ throw new TypeError("Gateway payload must contain an integer opcode.");
1799
+ if (this.#ws?.readyState !== WebSocket.OPEN)
1800
+ return false;
1801
+ const now = Date.now();
1802
+ while (this.#sendTimestamps.length && now - this.#sendTimestamps[0] >= 60000)
1803
+ this.#sendTimestamps.shift();
1804
+ if (this.#sendTimestamps.length >= 115) {
1805
+ this.#emitError(new GatewayError("Gateway send rate budget exhausted."));
1806
+ return false;
1807
+ }
1808
+ try {
1809
+ this.#ws.send(JSON.stringify(payload));
1810
+ this.#sendTimestamps.push(now);
1811
+ return true;
1812
+ } catch (error) {
1813
+ this.#emitError(error);
1814
+ return false;
1815
+ }
1816
+ }
1817
+ setPresence(data) {
1818
+ this.#options.presence = { ...this.#options.presence, ...data };
1819
+ const payload = {
1820
+ since: this.#options.presence.since ?? null,
1821
+ activities: this.#options.presence.activities ?? [],
1822
+ status: this.#options.presence.status ?? "online",
1823
+ afk: Boolean(this.#options.presence.afk)
1824
+ };
1825
+ return this.send({
1826
+ op: GatewayOpcodes.PresenceUpdate,
1827
+ d: payload,
1828
+ s: null,
1829
+ t: null
1830
+ });
1831
+ }
1832
+ setVoiceState(data) {
1833
+ return this.send({
1834
+ op: GatewayOpcodes.VoiceStateUpdate,
1835
+ d: data,
1836
+ s: null,
1837
+ t: null
1838
+ });
1839
+ }
1840
+ requestGuildMembers(data) {
1841
+ return this.send({
1842
+ op: GatewayOpcodes.RequestGuildMembers,
1843
+ d: data,
1844
+ s: null,
1845
+ t: null
1846
+ });
1847
+ }
1848
+ #open(url) {
1849
+ if (this.#closed)
1850
+ return;
1851
+ let ws;
1852
+ try {
1853
+ ws = new WebSocket(url);
1854
+ } catch (error) {
1855
+ const failure = this.#normalizeError(error);
1856
+ this.#emitError(failure);
1857
+ if (this.#options.reconnect) {
1858
+ this.#setState("RECONNECT" /* Reconnect */);
1859
+ this.#scheduleReconnect();
1860
+ } else
1861
+ this.#settleConnect(failure);
1862
+ return;
1863
+ }
1864
+ this.#ws = ws;
1865
+ ws.addEventListener("open", () => {
1866
+ this.#lastMessageAt = Date.now();
1867
+ this.#zombieReported = false;
1868
+ this.#startZombieDetection();
1869
+ this.#emit("open", undefined);
1870
+ this.#settleConnect();
1871
+ });
1872
+ ws.addEventListener("message", (event) => {
1873
+ this.#lastMessageAt = Date.now();
1874
+ this.#zombieReported = false;
1875
+ this.#message(ws, String(event.data));
1876
+ });
1877
+ ws.addEventListener("close", (event) => this.#close(ws, event.code));
1878
+ ws.addEventListener("error", () => this.#emitError(new GatewayError("Gateway WebSocket error")));
1879
+ }
1880
+ #startZombieDetection() {
1881
+ if (this.#zombieTimer)
1882
+ clearInterval(this.#zombieTimer);
1883
+ const interval = Math.max(1, Math.min(250, this.#options.heartbeatAckTimeout, this.#options.zombieTimeout / 2));
1884
+ this.#zombieTimer = setInterval(() => {
1885
+ if (this.#closed || this.#ws?.readyState !== WebSocket.OPEN || this.#lastMessageAt === 0)
1886
+ return;
1887
+ const silentFor = Date.now() - this.#lastMessageAt;
1888
+ const deadline = Math.max(this.#options.zombieTimeout, this.#heartbeatInterval + this.#options.heartbeatAckTimeout);
1889
+ if (silentFor < deadline || this.#zombieReported)
1890
+ return;
1891
+ this.#zombieReported = true;
1892
+ const error = new GatewayError(`Gateway connection appears stale after ${silentFor}ms without traffic.`);
1893
+ this.#emit("zombie", { silentFor, timeout: deadline });
1894
+ this.#emitError(error);
1895
+ try {
1896
+ this.#ws.close(1001, "Zombie Gateway connection");
1897
+ } catch (closeError) {
1898
+ this.#emitError(closeError);
1899
+ }
1900
+ }, interval);
1901
+ }
1902
+ #message(ws, raw) {
1903
+ let payload;
1904
+ try {
1905
+ payload = JSON.parse(raw);
1906
+ } catch (error) {
1907
+ this.#emitError(new GatewayError("Gateway returned invalid JSON", undefined, {
1908
+ cause: error
1909
+ }));
1910
+ ws.close(1002, "Invalid JSON");
1911
+ return;
1912
+ }
1913
+ if (!payload || typeof payload.op !== "number") {
1914
+ this.#emitError(new GatewayError("Gateway returned an invalid payload"));
1915
+ ws.close(1002, "Invalid payload");
1916
+ return;
1917
+ }
1918
+ if (typeof payload.s === "number")
1919
+ this.#sequence = payload.s;
1920
+ switch (payload.op) {
1921
+ case GatewayOpcodes.Dispatch:
1922
+ this.#setState("DISPATCH" /* Dispatch */);
1923
+ this.#handleDispatch(payload.t, payload.d);
1924
+ break;
1925
+ case GatewayOpcodes.Hello:
1926
+ this.#handleHello(payload.d);
1927
+ break;
1928
+ case GatewayOpcodes.Heartbeat:
1929
+ this.#setState("HEARTBEAT" /* Heartbeat */);
1930
+ this.#sendHeartbeat();
1931
+ break;
1932
+ case GatewayOpcodes.HeartbeatAck:
1933
+ this.#heartbeatACK = true;
1934
+ this.#clearHeartbeatAckTimer();
1935
+ this.#emit("heartbeatAck", payload.d);
1936
+ break;
1937
+ case GatewayOpcodes.Reconnect:
1938
+ ws.close(1001, "Server requested reconnect");
1939
+ 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");
1945
+ break;
1946
+ }
1947
+ }
1948
+ #handleDispatch(event, data) {
1949
+ if (event === "READY") {
1950
+ const ready = data;
1951
+ if (typeof ready?.session_id !== "string" || typeof ready?.resume_gateway_url !== "string") {
1952
+ this.#emitError(new GatewayError("Gateway READY payload is missing session information"));
1953
+ return;
1954
+ }
1955
+ this.#sessionId = ready.session_id;
1956
+ this.#resumeURL = ready.resume_gateway_url;
1957
+ this.#attempt = 0;
1958
+ this.#setState("READY" /* Ready */);
1959
+ this.#emit("ready", data);
1960
+ }
1961
+ this.#emit(event ?? "dispatch", data);
1962
+ }
1963
+ #handleHello(data) {
1964
+ const interval = data?.heartbeat_interval;
1965
+ if (typeof interval !== "number" || !Number.isFinite(interval) || interval <= 0) {
1966
+ this.#emitError(new GatewayError("Gateway HELLO payload contains an invalid heartbeat interval"));
1967
+ this.#ws?.close(1002, "Invalid heartbeat interval");
1968
+ return;
1969
+ }
1970
+ this.#heartbeatInterval = interval;
1971
+ this.#setState(this.#sessionId && this.#sequence !== null && this.#resumeURL ? "RESUME" /* Resume */ : "HELLO" /* Hello */);
1972
+ this.#startHeartbeat(interval);
1973
+ this.#identifyOrResume();
1974
+ }
1975
+ #identifyOrResume() {
1976
+ if (this.#sessionId && this.#sequence !== null && this.#resumeURL) {
1977
+ this.#setState("RESUME" /* Resume */);
1978
+ this.send({
1979
+ op: GatewayOpcodes.Resume,
1980
+ d: {
1981
+ token: this.#options.token,
1982
+ session_id: this.#sessionId,
1983
+ seq: this.#sequence
1984
+ },
1985
+ s: null,
1986
+ t: null
1987
+ });
1988
+ return;
1989
+ }
1990
+ this.#setState("IDENTIFY" /* Identify */);
1991
+ const props = this.#options.properties ?? {
1992
+ os: "Android",
1993
+ browser: "Discord Android",
1994
+ device: "Discord Android"
1995
+ };
1996
+ const os = props.os ?? "Android";
1997
+ const browser = props.browser ?? "Discord Android";
1998
+ const device = props.device ?? "Discord Android";
1999
+ this.send({
2000
+ op: GatewayOpcodes.Identify,
2001
+ d: {
2002
+ token: this.#options.token,
2003
+ intents: this.#options.intents,
2004
+ properties: {
2005
+ os,
2006
+ browser,
2007
+ device,
2008
+ $os: os,
2009
+ $browser: browser,
2010
+ $device: device,
2011
+ ...props
2012
+ },
2013
+ presence: {
2014
+ since: this.#options.presence?.since ?? null,
2015
+ activities: this.#options.presence?.activities ?? [],
2016
+ status: this.#options.presence?.status ?? "online",
2017
+ afk: Boolean(this.#options.presence?.afk)
2018
+ },
2019
+ shard: [this.#options.shardId, this.#options.shardCount]
2020
+ },
2021
+ s: null,
2022
+ t: null
2023
+ });
2024
+ }
2025
+ #startHeartbeat(interval) {
2026
+ this.#clearHeartbeatTimers();
2027
+ this.#heartbeatACK = true;
2028
+ this.#initialHeartbeat = setTimeout(() => this.#sendHeartbeat(), Math.random() * interval);
2029
+ this.#heartbeatTimer = setInterval(() => this.#sendHeartbeat(), interval);
2030
+ }
2031
+ #sendHeartbeat() {
2032
+ this.#heartbeatACK = false;
2033
+ this.#heartbeatSentAt = Date.now();
2034
+ if (!this.send({
2035
+ op: GatewayOpcodes.Heartbeat,
2036
+ d: this.#sequence,
2037
+ s: null,
2038
+ t: null
2039
+ })) {
2040
+ this.#emitError(new GatewayError("Unable to send Gateway heartbeat because the WebSocket is not open."));
2041
+ return;
2042
+ }
2043
+ this.#clearHeartbeatAckTimer();
2044
+ this.#heartbeatAckTimer = setTimeout(() => {
2045
+ if (!this.#heartbeatACK) {
2046
+ const elapsed = Date.now() - this.#heartbeatSentAt;
2047
+ this.#emitError(new GatewayError(`Gateway heartbeat acknowledgement timed out after ${elapsed}ms.`));
2048
+ try {
2049
+ this.#ws?.close(1001, "Heartbeat timeout");
2050
+ } catch (error) {
2051
+ this.#emitError(error);
2052
+ }
2053
+ }
2054
+ }, this.#options.heartbeatAckTimeout);
2055
+ }
2056
+ #close(ws, code) {
2057
+ if (this.#ws !== ws)
2058
+ return;
2059
+ this.#ws = undefined;
2060
+ this.#clearTimers();
2061
+ const action = this.#closeAction(code);
2062
+ this.#emit("close", { code, action });
2063
+ if (this.#closed || !this.#options.reconnect || action === "stop") {
2064
+ this.#setState(this.#closed ? "CLOSED" /* Closed */ : "CONNECT" /* Connect */);
2065
+ if (this.#connectPromise)
2066
+ this.#settleConnect(new GatewayError(`Gateway closed before READY (code ${code}).`, code));
2067
+ return;
2068
+ }
2069
+ if (action === "identify") {
2070
+ this.#sequence = null;
2071
+ this.#sessionId = undefined;
2072
+ }
2073
+ this.#setState("RECONNECT" /* Reconnect */);
2074
+ this.#scheduleReconnect();
2075
+ }
2076
+ #closeAction(code) {
2077
+ if ([4004, 4010, 4011, 4012, 4013, 4014].includes(code))
2078
+ return "stop";
2079
+ if ([4007, 4009].includes(code))
2080
+ return "identify";
2081
+ return this.#sessionId && this.#sequence !== null ? "resume" : "identify";
2082
+ }
2083
+ #scheduleReconnect() {
2084
+ if (this.#closed || !this.#options.reconnect || this.#reconnectTimer)
2085
+ return;
2086
+ if (this.#attempt >= this.#options.maxReconnectAttempts) {
2087
+ this.#settleConnect(new GatewayError("Gateway reconnect attempts exhausted."));
2088
+ this.#setState("CONNECT" /* Connect */);
2089
+ return;
2090
+ }
2091
+ 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));
2093
+ this.#reconnectTimer = setTimeout(() => {
2094
+ this.#reconnectTimer = undefined;
2095
+ this.#open(this.#resumeURL ?? "wss://gateway.discord.gg/?v=10&encoding=json");
2096
+ }, delay + jitter);
2097
+ }
2098
+ #settleConnect(error) {
2099
+ const resolve = this.#resolveConnect;
2100
+ const reject = this.#rejectConnect;
2101
+ this.#resolveConnect = undefined;
2102
+ this.#rejectConnect = undefined;
2103
+ this.#connectPromise = undefined;
2104
+ if (error)
2105
+ reject?.(error);
2106
+ else
2107
+ resolve?.();
2108
+ }
2109
+ #clearHeartbeatAckTimer() {
2110
+ if (this.#heartbeatAckTimer)
2111
+ clearTimeout(this.#heartbeatAckTimer);
2112
+ this.#heartbeatAckTimer = undefined;
2113
+ }
2114
+ #clearHeartbeatTimers() {
2115
+ if (this.#heartbeatTimer)
2116
+ clearInterval(this.#heartbeatTimer);
2117
+ if (this.#initialHeartbeat)
2118
+ clearTimeout(this.#initialHeartbeat);
2119
+ this.#clearHeartbeatAckTimer();
2120
+ this.#heartbeatTimer = undefined;
2121
+ this.#initialHeartbeat = undefined;
2122
+ }
2123
+ #clearTimers() {
2124
+ if (this.#reconnectTimer)
2125
+ clearTimeout(this.#reconnectTimer);
2126
+ if (this.#zombieTimer)
2127
+ clearInterval(this.#zombieTimer);
2128
+ this.#reconnectTimer = undefined;
2129
+ this.#zombieTimer = undefined;
2130
+ this.#clearHeartbeatTimers();
2131
+ }
2132
+ #normalizeError(error) {
2133
+ return error instanceof GatewayError ? error : new GatewayError("Gateway connection failed.", undefined, {
2134
+ cause: error
2135
+ });
2136
+ }
2137
+ #emitError(error) {
2138
+ this.#emit("error", error instanceof Error ? error : new GatewayError(String(error)));
2139
+ }
2140
+ #emit(event, data) {
2141
+ for (const listener of this.#listeners.get(event) ?? []) {
2142
+ try {
2143
+ const result = listener(data);
2144
+ if (result && typeof result.then === "function")
2145
+ Promise.resolve(result).catch((error) => {
2146
+ if (event !== "error")
2147
+ this.#emitError(error);
2148
+ });
2149
+ } catch (error) {
2150
+ if (event !== "error")
2151
+ this.#emitError(error);
2152
+ }
2153
+ }
2154
+ }
2155
+ #setState(next) {
2156
+ if (this.state === next)
2157
+ return;
2158
+ const previous = this.state;
2159
+ this.state = next;
2160
+ this.#emit("stateChange", { previous, next });
2161
+ }
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") } : {}
2203
+ };
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
+ }
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;
2817
+ }
2818
+ if (this.options.maxProcessed && this.totalProcessed >= this.options.maxProcessed) {
2819
+ this.stop("processedLimit");
2820
+ return true;
2821
+ }
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
+ });
2846
+ }
2847
+ }
2848
+
2849
+ // packages/core/src/index.ts
2850
+ class EventEmitter2 {
2851
+ #listeners = new Map;
2852
+ on(event, listener) {
2853
+ if (typeof listener !== "function")
2854
+ throw new TypeError("Event listener must be a function.");
2855
+ let listeners = this.#listeners.get(event);
2856
+ if (!listeners)
2857
+ this.#listeners.set(event, listeners = new Set);
2858
+ listeners.add(listener);
2859
+ return this;
2860
+ }
2861
+ once(event, listener) {
2862
+ const wrapped = (...args) => {
2863
+ this.off(event, wrapped);
2864
+ return listener(...args);
2865
+ };
2866
+ return this.on(event, wrapped);
2867
+ }
2868
+ off(event, listener) {
2869
+ this.#listeners.get(event)?.delete(listener);
2870
+ return this;
2871
+ }
2872
+ removeAllListeners(event) {
2873
+ if (event === undefined)
2874
+ this.#listeners.clear();
2875
+ else
2876
+ this.#listeners.delete(event);
2877
+ return this;
2878
+ }
2879
+ emit(event, ...args) {
2880
+ const listeners = this.#listeners.get(event);
2881
+ if (!listeners?.size)
2882
+ return false;
2883
+ for (const listener of [...listeners]) {
2884
+ try {
2885
+ const result = listener(...args);
2886
+ if (result && typeof result.then === "function")
2887
+ Promise.resolve(result).catch((error) => this.#handleError(event, error));
2888
+ } catch (error) {
2889
+ this.#handleError(event, error);
2890
+ }
2891
+ }
2892
+ return true;
2893
+ }
2894
+ #handleError(event, error) {
2895
+ if (event === "error")
2896
+ return;
2897
+ const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
2898
+ for (const listener of [
2899
+ ...this.#listeners.get("error") ?? []
2900
+ ]) {
2901
+ try {
2902
+ listener(normalized);
2903
+ } catch {}
2904
+ }
2905
+ }
2906
+ }
2907
+
2908
+ class Client extends EventEmitter2 {
2909
+ options;
2910
+ rest;
2911
+ users;
2912
+ guilds;
2913
+ channels;
2914
+ application;
2915
+ get ws() {
2916
+ return this.#gateway;
2917
+ }
2918
+ get gateway() {
2919
+ return this.#gateway;
2920
+ }
2921
+ user;
2922
+ readyAt;
2923
+ state = "idle";
2924
+ get uptime() {
2925
+ return this.readyAt ? Date.now() - this.readyAt.getTime() : null;
2926
+ }
2927
+ #gateway;
2928
+ #resourceContext;
2929
+ constructor(options) {
2930
+ super();
2931
+ this.options = options;
2932
+ if (!options.token?.trim())
2933
+ throw new TypeError("Client token is required.");
2934
+ this.rest = new REST({ token: options.token, ...options.rest });
2935
+ this.users = new UserManager(this.rest);
2936
+ this.guilds = new GuildManager(this.rest);
2937
+ this.channels = new ChannelManager(this.rest);
2938
+ const placeholderAppCommands = new ApplicationCommandManager(this.rest, "0");
2939
+ this.application = { commands: placeholderAppCommands };
2940
+ this.#resourceContext = {
2941
+ sendMessage: (channelId, options2) => this.channels.send(channelId, options2),
2942
+ editMessage: (channelId, messageId, options2) => this.channels.editMessage(channelId, messageId, options2),
2943
+ deleteMessage: (channelId, messageId) => this.channels.deleteMessage(channelId, messageId),
2944
+ crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId)
2945
+ };
2946
+ this.#gateway = new Gateway({
2947
+ token: options.token,
2948
+ intents: options.intents,
2949
+ ...options.gateway
2950
+ });
2951
+ this.#gateway.on("READY", (data) => {
2952
+ const ready = data;
2953
+ this.user = ready.user;
2954
+ this.users.set(this.user.id, new User(this.user));
2955
+ this.readyAt = new Date;
2956
+ this.state = "ready";
2957
+ const appId = ready.application?.id ?? this.user.id;
2958
+ this.application.commands = new ApplicationCommandManager(this.rest, appId);
2959
+ this.emit("ready", this.user);
2960
+ });
2961
+ this.#gateway.on("open", () => this.emit("open"));
2962
+ this.#gateway.on("close", (data) => {
2963
+ if (this.state !== "destroyed")
2964
+ this.state = "idle";
2965
+ this.emit("close", data);
2966
+ });
2967
+ this.#gateway.on("MESSAGE_CREATE", (data) => {
2968
+ const message = new Message(data, this.#resourceContext);
2969
+ this.channels.set(message.channelId, message.channel);
2970
+ this.users.set(message.author.id, message.author);
2971
+ this.emit("messageCreate", message);
2972
+ });
2973
+ this.#gateway.on("MESSAGE_UPDATE", (data) => {
2974
+ const message = new Message(data, this.#resourceContext);
2975
+ this.channels.set(message.channelId, message.channel);
2976
+ this.users.set(message.author.id, message.author);
2977
+ this.emit("messageUpdate", message);
2978
+ });
2979
+ this.#gateway.on("MESSAGE_DELETE", (data) => this.emit("messageDelete", data));
2980
+ this.#gateway.on("MESSAGE_DELETE_BULK", (data) => this.emit("messageDeleteBulk", data));
2981
+ this.#gateway.on("GUILD_CREATE", (data) => {
2982
+ const guild = new Guild(data);
2983
+ this.guilds.set(guild.id, guild);
2984
+ const payload = data;
2985
+ for (const member of payload.members ?? [])
2986
+ this.users.set(member.user.id, new User(member.user));
2987
+ for (const channelData of [
2988
+ ...payload.channels ?? [],
2989
+ ...payload.threads ?? []
2990
+ ]) {
2991
+ const channel = new Channel(channelData, this.#resourceContext);
2992
+ this.channels.set(channel.id, channel);
2993
+ }
2994
+ this.emit("guildCreate", data);
2995
+ });
2996
+ this.#gateway.on("GUILD_UPDATE", (data) => {
2997
+ const guild = new Guild(data);
2998
+ this.guilds.update(guild);
2999
+ this.emit("guildUpdate", data);
3000
+ });
3001
+ this.#gateway.on("GUILD_DELETE", (data) => {
3002
+ const payload = data;
3003
+ if (!payload.unavailable)
3004
+ this.guilds.delete(payload.id);
3005
+ this.emit("guildDelete", payload);
3006
+ });
3007
+ this.#gateway.on("CHANNEL_CREATE", (data) => {
3008
+ const channel = new Channel(data, this.#resourceContext);
3009
+ this.channels.update(channel);
3010
+ this.emit("channelCreate", channel);
3011
+ });
3012
+ this.#gateway.on("CHANNEL_UPDATE", (data) => {
3013
+ const channel = new Channel(data, this.#resourceContext);
3014
+ this.channels.update(channel);
3015
+ this.emit("channelUpdate", channel);
3016
+ });
3017
+ this.#gateway.on("CHANNEL_DELETE", (data) => {
3018
+ const payload = data;
3019
+ this.channels.delete(payload.id);
3020
+ this.emit("channelDelete", payload);
3021
+ });
3022
+ this.#gateway.on("THREAD_CREATE", (data) => {
3023
+ const channel = new Channel(data, this.#resourceContext);
3024
+ this.channels.update(channel);
3025
+ this.emit("threadCreate", channel);
3026
+ });
3027
+ this.#gateway.on("THREAD_UPDATE", (data) => {
3028
+ const channel = new Channel(data, this.#resourceContext);
3029
+ this.channels.update(channel);
3030
+ this.emit("threadUpdate", channel);
3031
+ });
3032
+ this.#gateway.on("THREAD_DELETE", (data) => {
3033
+ const payload = data;
3034
+ this.channels.delete(payload.id);
3035
+ this.emit("threadDelete", payload);
3036
+ });
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() {
3094
+ if (this.state === "destroyed")
3095
+ 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;
3106
+ }
3107
+ }
3108
+ 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
+ this.state = "destroyed";
3116
+ this.readyAt = undefined;
3117
+ this.user = undefined;
3118
+ }
3119
+ postInteractionResponse(id, token, response) {
3120
+ return this.rest.post(Routes.interactionCallback(id, token), response.toJSON());
3121
+ }
3122
+ editInteractionReply(token, data) {
3123
+ if (!this.user?.id)
3124
+ throw new Error("Client user is unavailable; login is required.");
3125
+ return this.rest.patch(Routes.interactionOriginalResponse(this.user.id, token), data);
3126
+ }
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);
3134
+ }
3135
+ 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);
3139
+ }
3140
+ }
3141
+ export {
3142
+ ActionRowBuilder,
3143
+ ApplicationCommandManager,
3144
+ ApplicationCommandOptionType,
3145
+ ApplicationCommandType,
3146
+ ButtonBuilder,
3147
+ Channel,
3148
+ ChannelManager,
3149
+ ChannelType,
3150
+ Client,
3151
+ Collection,
3152
+ Collector,
3153
+ EmbedBuilder,
3154
+ Gateway,
3155
+ GatewayError,
3156
+ GatewayIntentBits,
3157
+ GatewayOpcodes,
3158
+ Guild,
3159
+ GuildManager,
3160
+ IntentBits,
3161
+ Intents,
3162
+ Manager,
3163
+ Message,
3164
+ MessageCreateOptions,
3165
+ MessageEditOptions,
3166
+ MessageFetchOptions,
3167
+ MessageFlags,
3168
+ MessageThreadOptions,
3169
+ Permission,
3170
+ PermissionFlagsBits,
3171
+ PermissionOverwriteType,
3172
+ PermissionSet,
3173
+ Permissions,
3174
+ PermissionsBitField,
3175
+ REST,
3176
+ RESTError,
3177
+ ReactionFetchOptions,
3178
+ ResourceManager,
3179
+ Routes,
3180
+ SlashCommandBuilder,
3181
+ StringOptionBuilder,
3182
+ StringSelectBuilder,
3183
+ User,
3184
+ UserManager,
3185
+ resolveGatewayIntents
3186
+ };
3187
+
3188
+ //# debugId=8E6F3C716D06EF5664756E2164756E21