lunibee 0.3.3 → 0.4.0

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 (125) hide show
  1. package/README.md +1 -1
  2. package/dist/builders/commands.d.ts +1 -1
  3. package/dist/builders/components.d.ts +9 -11
  4. package/dist/builders/embed.d.ts +1 -1
  5. package/dist/builders/index.d.ts +1 -1
  6. package/dist/builders/index.js +87 -1298
  7. package/dist/builders/index.js.map +3 -11
  8. package/dist/chunks/index-0wn81eng.js +2492 -0
  9. package/dist/chunks/index-0wn81eng.js.map +17 -0
  10. package/dist/chunks/index-2en489j6.js +40 -0
  11. package/dist/chunks/index-2en489j6.js.map +10 -0
  12. package/dist/chunks/index-3hyps48a.js +203 -0
  13. package/dist/chunks/index-3hyps48a.js.map +11 -0
  14. package/dist/chunks/index-57c5n3ms.js +2274 -0
  15. package/dist/chunks/index-57c5n3ms.js.map +19 -0
  16. package/dist/chunks/index-5yx92e36.js +1170 -0
  17. package/dist/chunks/index-5yx92e36.js.map +14 -0
  18. package/dist/chunks/index-690bp093.js +95 -0
  19. package/dist/chunks/index-690bp093.js.map +10 -0
  20. package/dist/chunks/index-7fp2hvmg.js +2155 -0
  21. package/dist/chunks/index-7fp2hvmg.js.map +24 -0
  22. package/dist/chunks/index-cnmsajvk.js +1119 -0
  23. package/dist/chunks/index-cnmsajvk.js.map +12 -0
  24. package/dist/chunks/index-fdvgk2sw.js +1310 -0
  25. package/dist/chunks/index-fdvgk2sw.js.map +21 -0
  26. package/dist/chunks/index-gyvps8b9.js +214 -0
  27. package/dist/chunks/index-gyvps8b9.js.map +12 -0
  28. package/dist/chunks/index-jzg4bh99.js +1533 -0
  29. package/dist/chunks/index-jzg4bh99.js.map +21 -0
  30. package/dist/chunks/index-mgw2yvrm.js +3547 -0
  31. package/dist/chunks/index-mgw2yvrm.js.map +25 -0
  32. package/dist/chunks/index-yh76b55h.js +3449 -0
  33. package/dist/chunks/index-yh76b55h.js.map +29 -0
  34. package/dist/collection/index.js +9 -1118
  35. package/dist/collection/index.js.map +3 -6
  36. package/dist/core/api.d.ts +3 -3
  37. package/dist/core/channel-create.d.ts +2 -2
  38. package/dist/core/commands.d.ts +3 -3
  39. package/dist/core/events.d.ts +4 -4
  40. package/dist/core/handles.d.ts +4 -4
  41. package/dist/core/index.d.ts +25 -20
  42. package/dist/core/index.js +68 -10130
  43. package/dist/core/index.js.map +3 -65
  44. package/dist/core/permissions.d.ts +1 -1
  45. package/dist/core/redis-cache.d.ts +1 -1
  46. package/dist/formatters/index.js +41 -110
  47. package/dist/formatters/index.js.map +3 -4
  48. package/dist/handlers/index.js +5 -37
  49. package/dist/handlers/index.js.map +3 -4
  50. package/dist/index.d.ts +21 -21
  51. package/dist/index.js +641 -16325
  52. package/dist/index.js.map +3 -92
  53. package/dist/managers/advanced.d.ts +3 -3
  54. package/dist/managers/application.d.ts +2 -2
  55. package/dist/managers/base.d.ts +1 -1
  56. package/dist/managers/emoji.d.ts +2 -2
  57. package/dist/managers/guild-resources.d.ts +6 -6
  58. package/dist/managers/guild.d.ts +3 -3
  59. package/dist/managers/index.d.ts +4 -8
  60. package/dist/managers/index.js +51 -4060
  61. package/dist/managers/index.js.map +3 -29
  62. package/dist/managers/member.d.ts +2 -2
  63. package/dist/managers/message.d.ts +14 -6
  64. package/dist/managers/role.d.ts +2 -2
  65. package/dist/managers/thread.d.ts +3 -3
  66. package/dist/managers/user.d.ts +7 -4
  67. package/dist/rest/index.d.ts +10 -35
  68. package/dist/rest/index.js +57 -2184
  69. package/dist/rest/index.js.map +3 -18
  70. package/dist/rest/limiter.d.ts +9 -1
  71. package/dist/rest/webhook.d.ts +2 -8
  72. package/dist/sharding/bus.d.ts +2 -2
  73. package/dist/sharding/cluster.d.ts +45 -5
  74. package/dist/sharding/context.d.ts +45 -3
  75. package/dist/sharding/gateway-bot.d.ts +2 -1
  76. package/dist/sharding/health.d.ts +1 -1
  77. package/dist/sharding/identify.d.ts +12 -0
  78. package/dist/sharding/index.d.ts +44 -11
  79. package/dist/sharding/index.js +60 -4620
  80. package/dist/sharding/index.js.map +3 -33
  81. package/dist/sharding/supervisor.d.ts +4 -2
  82. package/dist/structures/audit-log.d.ts +1 -1
  83. package/dist/structures/base.d.ts +6 -6
  84. package/dist/structures/channels.d.ts +1 -1
  85. package/dist/structures/embed.d.ts +1 -1
  86. package/dist/structures/index.d.ts +14 -14
  87. package/dist/structures/index.js +109 -2382
  88. package/dist/structures/index.js.map +3 -16
  89. package/dist/structures/interactions.d.ts +13 -9
  90. package/dist/structures/options.d.ts +1 -1
  91. package/dist/structures/permissions.d.ts +2 -2
  92. package/dist/structures/resources.d.ts +10 -10
  93. package/dist/structures/sticker.d.ts +1 -1
  94. package/dist/types/gateway.d.ts +2 -79
  95. package/dist/types/index.d.ts +0 -6
  96. package/dist/types/index.js +41 -272
  97. package/dist/types/index.js.map +3 -6
  98. package/dist/utils/index.js +23 -209
  99. package/dist/utils/index.js.map +3 -5
  100. package/dist/voice/connection.d.ts +200 -0
  101. package/dist/voice/crypto.d.ts +50 -0
  102. package/dist/voice/dave.d.ts +85 -0
  103. package/dist/voice/effects.d.ts +31 -0
  104. package/dist/voice/emitter.d.ts +14 -0
  105. package/dist/voice/gateway.d.ts +59 -0
  106. package/dist/voice/index.d.ts +25 -228
  107. package/dist/voice/index.js +111 -442
  108. package/dist/voice/index.js.map +3 -4
  109. package/dist/voice/libopus.d.ts +88 -0
  110. package/dist/voice/networking.d.ts +80 -0
  111. package/dist/voice/ogg.d.ts +24 -0
  112. package/dist/voice/opus.d.ts +18 -0
  113. package/dist/voice/player.d.ts +79 -0
  114. package/dist/voice/protocol.d.ts +76 -0
  115. package/dist/voice/receiver.d.ts +59 -0
  116. package/dist/voice/resource.d.ts +102 -0
  117. package/dist/voice/udp.d.ts +40 -0
  118. package/dist/ws/close-codes.d.ts +1 -1
  119. package/dist/ws/index.d.ts +25 -4
  120. package/dist/ws/index.js +47 -1336
  121. package/dist/ws/index.js.map +3 -17
  122. package/dist/ws/protocol.d.ts +1 -1
  123. package/dist/ws/send-budget.d.ts +0 -2
  124. package/dist/ws/state.d.ts +0 -10
  125. package/package.json +19 -16
@@ -0,0 +1,2492 @@
1
+ // @bun
2
+ import {
3
+ ChannelKinds2,
4
+ GatewayIntentBits2,
5
+ resolveGatewayIntents2,
6
+ ActivityEnum2
7
+ } from "./index-gyvps8b9.js";
8
+ import {
9
+ User2,
10
+ PermissionSet2,
11
+ computePermissions2,
12
+ GuildMember2,
13
+ Role2,
14
+ createChannel2,
15
+ createInteraction2,
16
+ Message2
17
+ } from "./index-57c5n3ms.js";
18
+ import {
19
+ CreateSlashCommand2,
20
+ CreateStringOption2,
21
+ CreateIntegerOption2,
22
+ CreateNumberOption2,
23
+ CreateBooleanOption2,
24
+ CreateUserOption2,
25
+ CreateRoleOption2,
26
+ CreateMentionableOption2,
27
+ CreateAttachmentOption2,
28
+ CreateChannelOption2
29
+ } from "./index-5yx92e36.js";
30
+ import {
31
+ parsePrefixArgs2
32
+ } from "./index-3hyps48a.js";
33
+ import {
34
+ Routes2,
35
+ REST2
36
+ } from "./index-7fp2hvmg.js";
37
+ import {
38
+ toRequest2,
39
+ UserManager2,
40
+ MonetizationManager2,
41
+ ApplicationEmojiManager2,
42
+ StageInstanceManager2,
43
+ GuildManager2,
44
+ ApplicationCommandManager2,
45
+ ChannelManager2
46
+ } from "./index-jzg4bh99.js";
47
+ import {
48
+ Gateway2
49
+ } from "./index-fdvgk2sw.js";
50
+ import {
51
+ VoiceManager2
52
+ } from "./index-yh76b55h.js";
53
+ import {
54
+ readClusterContext2,
55
+ ClusterWorker2,
56
+ connectInQueue2
57
+ } from "./index-mgw2yvrm.js";
58
+ // packages/core/src/events.ts
59
+ var ClientEvent2;
60
+ ((ClientEvent) => {
61
+ ClientEvent["Ready"] = "ready";
62
+ ClientEvent["Resumed"] = "resumed";
63
+ ClientEvent["InvalidSession"] = "invalidSession";
64
+ ClientEvent["Raw"] = "raw";
65
+ ClientEvent["Error"] = "error";
66
+ ClientEvent["Open"] = "open";
67
+ ClientEvent["Close"] = "close";
68
+ ClientEvent["MessageCreate"] = "messageCreate";
69
+ ClientEvent["MessageUpdate"] = "messageUpdate";
70
+ ClientEvent["MessageDelete"] = "messageDelete";
71
+ ClientEvent["MessageDeleteBulk"] = "messageDeleteBulk";
72
+ ClientEvent["MessageReactionAdd"] = "messageReactionAdd";
73
+ ClientEvent["MessageReactionRemove"] = "messageReactionRemove";
74
+ ClientEvent["MessageReactionRemoveAll"] = "messageReactionRemoveAll";
75
+ ClientEvent["MessageReactionRemoveEmoji"] = "messageReactionRemoveEmoji";
76
+ ClientEvent["MessagePollVoteAdd"] = "messagePollVoteAdd";
77
+ ClientEvent["MessagePollVoteRemove"] = "messagePollVoteRemove";
78
+ ClientEvent["GuildCreate"] = "guildCreate";
79
+ ClientEvent["GuildUpdate"] = "guildUpdate";
80
+ ClientEvent["GuildDelete"] = "guildDelete";
81
+ ClientEvent["GuildAvailable"] = "guildAvailable";
82
+ ClientEvent["GuildUnavailable"] = "guildUnavailable";
83
+ ClientEvent["GuildMemberAdd"] = "guildMemberAdd";
84
+ ClientEvent["GuildMemberUpdate"] = "guildMemberUpdate";
85
+ ClientEvent["GuildMemberRemove"] = "guildMemberRemove";
86
+ ClientEvent["GuildMembersChunk"] = "guildMembersChunk";
87
+ ClientEvent["GuildBanAdd"] = "guildBanAdd";
88
+ ClientEvent["GuildBanRemove"] = "guildBanRemove";
89
+ ClientEvent["GuildRoleCreate"] = "guildRoleCreate";
90
+ ClientEvent["GuildRoleUpdate"] = "guildRoleUpdate";
91
+ ClientEvent["GuildRoleDelete"] = "guildRoleDelete";
92
+ ClientEvent["GuildEmojisUpdate"] = "guildEmojisUpdate";
93
+ ClientEvent["GuildStickersUpdate"] = "guildStickersUpdate";
94
+ ClientEvent["EntitlementCreate"] = "entitlementCreate";
95
+ ClientEvent["EntitlementUpdate"] = "entitlementUpdate";
96
+ ClientEvent["EntitlementDelete"] = "entitlementDelete";
97
+ ClientEvent["SoundboardSoundCreate"] = "soundboardSoundCreate";
98
+ ClientEvent["SoundboardSoundUpdate"] = "soundboardSoundUpdate";
99
+ ClientEvent["SoundboardSoundDelete"] = "soundboardSoundDelete";
100
+ ClientEvent["SoundboardSoundsUpdate"] = "soundboardSoundsUpdate";
101
+ ClientEvent["GuildIntegrationsUpdate"] = "guildIntegrationsUpdate";
102
+ ClientEvent["GuildScheduledEventCreate"] = "guildScheduledEventCreate";
103
+ ClientEvent["GuildScheduledEventUpdate"] = "guildScheduledEventUpdate";
104
+ ClientEvent["GuildScheduledEventDelete"] = "guildScheduledEventDelete";
105
+ ClientEvent["GuildScheduledEventUserAdd"] = "guildScheduledEventUserAdd";
106
+ ClientEvent["GuildScheduledEventUserRemove"] = "guildScheduledEventUserRemove";
107
+ ClientEvent["AutoModerationRuleCreate"] = "autoModerationRuleCreate";
108
+ ClientEvent["AutoModerationRuleUpdate"] = "autoModerationRuleUpdate";
109
+ ClientEvent["AutoModerationRuleDelete"] = "autoModerationRuleDelete";
110
+ ClientEvent["AutoModerationActionExecution"] = "autoModerationActionExecution";
111
+ ClientEvent["ChannelCreate"] = "channelCreate";
112
+ ClientEvent["ChannelUpdate"] = "channelUpdate";
113
+ ClientEvent["ChannelDelete"] = "channelDelete";
114
+ ClientEvent["ChannelPinsUpdate"] = "channelPinsUpdate";
115
+ ClientEvent["ThreadCreate"] = "threadCreate";
116
+ ClientEvent["ThreadUpdate"] = "threadUpdate";
117
+ ClientEvent["ThreadDelete"] = "threadDelete";
118
+ ClientEvent["ThreadListSync"] = "threadListSync";
119
+ ClientEvent["ThreadMembersUpdate"] = "threadMembersUpdate";
120
+ ClientEvent["ThreadMemberUpdate"] = "threadMemberUpdate";
121
+ ClientEvent["StageInstanceCreate"] = "stageInstanceCreate";
122
+ ClientEvent["StageInstanceUpdate"] = "stageInstanceUpdate";
123
+ ClientEvent["StageInstanceDelete"] = "stageInstanceDelete";
124
+ ClientEvent["InviteCreate"] = "inviteCreate";
125
+ ClientEvent["InviteDelete"] = "inviteDelete";
126
+ ClientEvent["WebhooksUpdate"] = "webhooksUpdate";
127
+ ClientEvent["VoiceStateUpdate"] = "voiceStateUpdate";
128
+ ClientEvent["VoiceServerUpdate"] = "voiceServerUpdate";
129
+ ClientEvent["PresenceUpdate"] = "presenceUpdate";
130
+ ClientEvent["TypingStart"] = "typingStart";
131
+ ClientEvent["InteractionCreate"] = "interactionCreate";
132
+ })(ClientEvent2 ||= {});
133
+ // packages/core/src/collector.ts
134
+ import { EventEmitter } from "events";
135
+
136
+ class Collector2 extends EventEmitter {
137
+ collected = new Map;
138
+ options;
139
+ ended = false;
140
+ endReason;
141
+ totalProcessed = 0;
142
+ #timeoutTimer;
143
+ #idleTimer;
144
+ #onAbort = () => this.stop("abort");
145
+ #cleanup = [];
146
+ on(event, listener) {
147
+ return super.on(event, listener);
148
+ }
149
+ once(event, listener) {
150
+ return super.once(event, listener);
151
+ }
152
+ constructor(options = {}) {
153
+ super();
154
+ this.options = options;
155
+ if (options.time && options.time > 0) {
156
+ this.#timeoutTimer = setTimeout(() => {
157
+ this.stop("time");
158
+ }, options.time);
159
+ }
160
+ this.#resetIdle();
161
+ if (options.signal?.aborted)
162
+ this.stop("abort");
163
+ else
164
+ options.signal?.addEventListener("abort", this.#onAbort, {
165
+ once: true
166
+ });
167
+ }
168
+ onDispose(cleanup) {
169
+ if (this.ended)
170
+ cleanup();
171
+ else
172
+ this.#cleanup.push(cleanup);
173
+ return this;
174
+ }
175
+ #resetIdle() {
176
+ if (!this.options.idle || this.options.idle <= 0)
177
+ return;
178
+ if (this.#idleTimer)
179
+ clearTimeout(this.#idleTimer);
180
+ this.#idleTimer = setTimeout(() => this.stop("idle"), this.options.idle);
181
+ }
182
+ async handle(key, item) {
183
+ if (this.ended)
184
+ return false;
185
+ this.totalProcessed++;
186
+ const reachedProcessed = !!this.options.maxProcessed && this.totalProcessed >= this.options.maxProcessed;
187
+ let passed = true;
188
+ if (this.options.filter)
189
+ passed = !!await this.options.filter(item);
190
+ if (this.ended)
191
+ return false;
192
+ if (!passed) {
193
+ if (reachedProcessed)
194
+ this.stop("processedLimit");
195
+ return false;
196
+ }
197
+ this.collected.set(key, item);
198
+ this.#resetIdle();
199
+ this.emit("collect", item);
200
+ if (this.options.max && this.collected.size >= this.options.max) {
201
+ this.stop("limit");
202
+ return true;
203
+ }
204
+ if (reachedProcessed) {
205
+ this.stop("processedLimit");
206
+ return true;
207
+ }
208
+ return true;
209
+ }
210
+ stop(reason = "user") {
211
+ if (this.ended)
212
+ return;
213
+ this.ended = true;
214
+ this.endReason = reason;
215
+ if (this.#timeoutTimer)
216
+ clearTimeout(this.#timeoutTimer);
217
+ if (this.#idleTimer)
218
+ clearTimeout(this.#idleTimer);
219
+ this.options.signal?.removeEventListener("abort", this.#onAbort);
220
+ for (const cleanup of this.#cleanup.splice(0)) {
221
+ try {
222
+ cleanup();
223
+ } catch {}
224
+ }
225
+ this.emit("end", this.collected, reason);
226
+ this.removeAllListeners();
227
+ }
228
+ wait() {
229
+ if (this.ended)
230
+ return Promise.resolve(this.collected);
231
+ return new Promise((resolve) => this.once("end", (collected) => resolve(collected)));
232
+ }
233
+ async* [Symbol.asyncIterator]() {
234
+ const queue = [];
235
+ let wake;
236
+ const onCollect = (item) => {
237
+ queue.push(item);
238
+ wake?.();
239
+ };
240
+ const onEnd = () => wake?.();
241
+ if (!this.ended) {
242
+ this.on("collect", onCollect);
243
+ this.on("end", onEnd);
244
+ }
245
+ try {
246
+ for (;; ) {
247
+ if (queue.length > 0) {
248
+ yield queue.shift();
249
+ continue;
250
+ }
251
+ if (this.ended)
252
+ return;
253
+ await new Promise((resolve) => wake = resolve);
254
+ wake = undefined;
255
+ }
256
+ } finally {
257
+ this.off("collect", onCollect);
258
+ this.off("end", onEnd);
259
+ }
260
+ }
261
+ [Symbol.dispose]() {
262
+ this.stop("disposed");
263
+ }
264
+ next() {
265
+ return new Promise((resolve, reject) => {
266
+ if (this.ended) {
267
+ return reject(new Error(`Collector already ended: ${this.endReason ?? "unknown"}`));
268
+ }
269
+ const onCollect = (item) => {
270
+ this.off("end", onEnd);
271
+ resolve(item);
272
+ };
273
+ const onEnd = (_collected, reason) => {
274
+ this.off("collect", onCollect);
275
+ reject(new Error(`Collector ended before item was collected: ${reason}`));
276
+ };
277
+ this.once("collect", onCollect);
278
+ this.once("end", onEnd);
279
+ });
280
+ }
281
+ }
282
+ // packages/core/src/redis-cache.ts
283
+ var GUILD_LISTS = [
284
+ "members",
285
+ "channels",
286
+ "threads",
287
+ "roles",
288
+ "presences",
289
+ "voice_states",
290
+ "stage_instances",
291
+ "guild_scheduled_events",
292
+ "soundboard_sounds"
293
+ ];
294
+ var CHUNK = 1000;
295
+ var id = (value) => typeof value === "string" && /^\d{1,20}$/.test(value) ? value : undefined;
296
+
297
+ class RedisCache2 {
298
+ #redis;
299
+ #prefix;
300
+ #members;
301
+ #ttl;
302
+ #onError;
303
+ #chains = new Map;
304
+ #attached = new Map;
305
+ #writes = 0;
306
+ #failures = 0;
307
+ #pending = 0;
308
+ constructor(options) {
309
+ this.#redis = options.client;
310
+ this.#prefix = `${options.prefix ?? "lunibee:cache:"}v1:`;
311
+ this.#members = options.members ?? true;
312
+ if (options.ttlSeconds !== undefined && !(Number.isInteger(options.ttlSeconds) && options.ttlSeconds > 0))
313
+ throw new RangeError("ttlSeconds must be a positive integer.");
314
+ this.#ttl = options.ttlSeconds;
315
+ this.#onError = options.onError;
316
+ }
317
+ attach(source) {
318
+ if (this.#attached.has(source))
319
+ return this;
320
+ const event = "gateway" in source ? "raw" : "RAW";
321
+ const listener = (payload) => {
322
+ const { event: name, data } = payload;
323
+ if (typeof name === "string")
324
+ this.handle(name, data);
325
+ };
326
+ source.on(event, listener);
327
+ this.#attached.set(source, { event, listener });
328
+ return this;
329
+ }
330
+ detach(source) {
331
+ for (const [s, { event, listener }] of this.#attached)
332
+ if (!source || s === source) {
333
+ s.off(event, listener);
334
+ this.#attached.delete(s);
335
+ }
336
+ return this;
337
+ }
338
+ async flush() {
339
+ while (this.#chains.size > 0)
340
+ await Promise.all([...this.#chains.values()]);
341
+ }
342
+ diagnostics() {
343
+ return {
344
+ writes: this.#writes,
345
+ failures: this.#failures,
346
+ pending: this.#pending
347
+ };
348
+ }
349
+ handle(event, data) {
350
+ if (!data || typeof data !== "object")
351
+ return;
352
+ const d = data;
353
+ const users = this.#usersOf(event, d);
354
+ if (users.length)
355
+ this.#enqueue("users", event, async () => {
356
+ for (const user of users)
357
+ await this.#setJSON(this.#k("user", user.id), user);
358
+ });
359
+ const write = this.#writer(event, d);
360
+ if (!write)
361
+ return;
362
+ const guild = id(d.guild_id) ?? id(d.id) ?? "-";
363
+ const key = event.startsWith("GUILD_") || d.guild_id ? guild : "-";
364
+ this.#enqueue(key, event, write);
365
+ }
366
+ #usersOf(event, d) {
367
+ const list = event === "USER_UPDATE" ? [d] : !this.#members ? [] : event === "GUILD_CREATE" || event === "GUILD_MEMBERS_CHUNK" ? (d.members ?? []).map((m) => m?.user) : event === "GUILD_MEMBER_ADD" || event === "GUILD_MEMBER_UPDATE" ? [d.user] : [];
368
+ return list.filter((u) => !!u && typeof u === "object" && !!id(u.id));
369
+ }
370
+ #enqueue(key, event, write) {
371
+ this.#pending++;
372
+ const previous = this.#chains.get(key) ?? Promise.resolve();
373
+ const next = previous.then(async () => {
374
+ try {
375
+ await write();
376
+ this.#writes++;
377
+ } catch (error) {
378
+ this.#failures++;
379
+ try {
380
+ this.#onError?.(event, error);
381
+ } catch {}
382
+ } finally {
383
+ this.#pending--;
384
+ }
385
+ });
386
+ this.#chains.set(key, next);
387
+ next.then(() => {
388
+ if (this.#chains.get(key) === next)
389
+ this.#chains.delete(key);
390
+ });
391
+ }
392
+ #k(...parts) {
393
+ return this.#prefix + parts.join(":");
394
+ }
395
+ async#cmd(command, ...args) {
396
+ return this.#redis.send(command, args);
397
+ }
398
+ async#setJSON(key, value) {
399
+ const args = [key, JSON.stringify(value)];
400
+ if (this.#ttl)
401
+ args.push("EX", String(this.#ttl));
402
+ await this.#redis.send("SET", args);
403
+ }
404
+ async#touch(key) {
405
+ if (this.#ttl)
406
+ await this.#cmd("EXPIRE", key, String(this.#ttl));
407
+ }
408
+ async#hset(key, entries) {
409
+ for (let i = 0;i < entries.length; i += CHUNK) {
410
+ const args = [key];
411
+ for (const [field, value] of entries.slice(i, i + CHUNK))
412
+ args.push(field, JSON.stringify(value));
413
+ await this.#redis.send("HSET", args);
414
+ }
415
+ if (entries.length)
416
+ await this.#touch(key);
417
+ }
418
+ async#channel(channel, guildId) {
419
+ const channelId = id(channel.id);
420
+ if (!channelId)
421
+ return;
422
+ const value = guildId ? { ...channel, guild_id: guildId } : channel;
423
+ await this.#setJSON(this.#k("channel", channelId), value);
424
+ if (guildId)
425
+ await this.#hset(this.#k("guild", guildId, "channels"), [
426
+ [channelId, value]
427
+ ]);
428
+ }
429
+ async#member(guildId, member) {
430
+ if (!this.#members)
431
+ return;
432
+ const userId = id(member.user?.id);
433
+ if (!userId)
434
+ return;
435
+ const { user: _user, ...rest } = member;
436
+ await this.#hset(this.#k("guild", guildId, "members"), [
437
+ [userId, { ...rest, user_id: userId }]
438
+ ]);
439
+ }
440
+ async#dropGuild(guildId) {
441
+ const channels = await this.#cmd("HKEYS", this.#k("guild", guildId, "channels"));
442
+ const keys = [
443
+ this.#k("guild", guildId),
444
+ this.#k("guild", guildId, "channels"),
445
+ this.#k("guild", guildId, "roles"),
446
+ this.#k("guild", guildId, "members"),
447
+ ...(channels ?? []).map((c) => this.#k("channel", c))
448
+ ];
449
+ await this.#redis.send("DEL", keys);
450
+ await this.#cmd("SREM", this.#k("guilds"), guildId);
451
+ }
452
+ async#patchGuild(guildId, patch) {
453
+ const current = await this.guild(guildId);
454
+ if (!current)
455
+ return;
456
+ await this.#setJSON(this.#k("guild", guildId), {
457
+ ...current,
458
+ ...patch
459
+ });
460
+ }
461
+ #writer(event, d) {
462
+ const guildId = id(d.guild_id);
463
+ switch (event) {
464
+ case "GUILD_CREATE":
465
+ case "GUILD_UPDATE":
466
+ return async () => {
467
+ const gid = id(d.id);
468
+ if (!gid)
469
+ return;
470
+ const doc = {};
471
+ for (const [k, v] of Object.entries(d))
472
+ if (!GUILD_LISTS.includes(k))
473
+ doc[k] = v;
474
+ if (event === "GUILD_CREATE") {
475
+ await this.#dropGuild(gid);
476
+ await this.#hset(this.#k("guild", gid, "roles"), (d.roles ?? []).filter((r) => id(r.id)).map((r) => [r.id, r]));
477
+ for (const c of [
478
+ ...d.channels ?? [],
479
+ ...d.threads ?? []
480
+ ])
481
+ await this.#channel(c, gid);
482
+ if (this.#members) {
483
+ const members = (d.members ?? []).filter((m) => id(m.user?.id));
484
+ await this.#hset(this.#k("guild", gid, "members"), members.map((m) => {
485
+ const { user, ...rest } = m;
486
+ const uid = user.id;
487
+ return [uid, { ...rest, user_id: uid }];
488
+ }));
489
+ }
490
+ await this.#setJSON(this.#k("guild", gid), doc);
491
+ } else {
492
+ if (Array.isArray(d.roles))
493
+ await this.#hset(this.#k("guild", gid, "roles"), d.roles.filter((r) => id(r.id)).map((r) => [r.id, r]));
494
+ const current = await this.guild(gid);
495
+ await this.#setJSON(this.#k("guild", gid), {
496
+ ...current,
497
+ ...doc
498
+ });
499
+ }
500
+ await this.#cmd("SADD", this.#k("guilds"), gid);
501
+ };
502
+ case "GUILD_DELETE":
503
+ return async () => {
504
+ const gid = id(d.id);
505
+ if (!gid)
506
+ return;
507
+ if (d.unavailable === true)
508
+ await this.#patchGuild(gid, { unavailable: true });
509
+ else
510
+ await this.#dropGuild(gid);
511
+ };
512
+ case "CHANNEL_CREATE":
513
+ case "CHANNEL_UPDATE":
514
+ case "THREAD_CREATE":
515
+ case "THREAD_UPDATE":
516
+ return () => this.#channel(d, guildId);
517
+ case "CHANNEL_DELETE":
518
+ case "THREAD_DELETE":
519
+ return async () => {
520
+ const channelId = id(d.id);
521
+ if (!channelId)
522
+ return;
523
+ await this.#cmd("DEL", this.#k("channel", channelId));
524
+ if (guildId)
525
+ await this.#cmd("HDEL", this.#k("guild", guildId, "channels"), channelId);
526
+ };
527
+ case "GUILD_ROLE_CREATE":
528
+ case "GUILD_ROLE_UPDATE":
529
+ return async () => {
530
+ const role = d.role;
531
+ if (!guildId || !role || !id(role.id))
532
+ return;
533
+ await this.#hset(this.#k("guild", guildId, "roles"), [
534
+ [role.id, role]
535
+ ]);
536
+ };
537
+ case "GUILD_ROLE_DELETE":
538
+ return async () => {
539
+ const roleId = id(d.role_id);
540
+ if (!guildId || !roleId)
541
+ return;
542
+ await this.#cmd("HDEL", this.#k("guild", guildId, "roles"), roleId);
543
+ };
544
+ case "GUILD_MEMBER_ADD":
545
+ case "GUILD_MEMBER_UPDATE":
546
+ return async () => {
547
+ if (!guildId)
548
+ return;
549
+ if (event === "GUILD_MEMBER_UPDATE" && this.#members) {
550
+ const userId = id(d.user?.id);
551
+ const current = userId ? await this.#hget(this.#k("guild", guildId, "members"), userId) : undefined;
552
+ await this.#member(guildId, { ...current, ...d });
553
+ } else
554
+ await this.#member(guildId, d);
555
+ };
556
+ case "GUILD_MEMBER_REMOVE":
557
+ return async () => {
558
+ const userId = id(d.user?.id);
559
+ if (!guildId || !userId || !this.#members)
560
+ return;
561
+ await this.#cmd("HDEL", this.#k("guild", guildId, "members"), userId);
562
+ };
563
+ case "GUILD_MEMBERS_CHUNK":
564
+ return async () => {
565
+ if (!guildId)
566
+ return;
567
+ for (const m of d.members ?? [])
568
+ await this.#member(guildId, m);
569
+ };
570
+ case "GUILD_EMOJIS_UPDATE":
571
+ return async () => {
572
+ if (guildId)
573
+ await this.#patchGuild(guildId, { emojis: d.emojis });
574
+ };
575
+ case "GUILD_STICKERS_UPDATE":
576
+ return async () => {
577
+ if (guildId)
578
+ await this.#patchGuild(guildId, {
579
+ stickers: d.stickers
580
+ });
581
+ };
582
+ default:
583
+ return;
584
+ }
585
+ }
586
+ async#get(key) {
587
+ const raw = await this.#cmd("GET", key);
588
+ return raw ? JSON.parse(raw) : undefined;
589
+ }
590
+ async#hget(key, field) {
591
+ const raw = await this.#cmd("HGET", key, field);
592
+ return raw ? JSON.parse(raw) : undefined;
593
+ }
594
+ async#hvals(key) {
595
+ const raw = await this.#cmd("HVALS", key) ?? [];
596
+ return raw.map((v) => JSON.parse(v));
597
+ }
598
+ guild(guildId) {
599
+ return this.#get(this.#k("guild", guildId));
600
+ }
601
+ async guildIds() {
602
+ return await this.#cmd("SMEMBERS", this.#k("guilds")) ?? [];
603
+ }
604
+ channel(channelId) {
605
+ return this.#get(this.#k("channel", channelId));
606
+ }
607
+ channels(guildId) {
608
+ return this.#hvals(this.#k("guild", guildId, "channels"));
609
+ }
610
+ role(guildId, roleId) {
611
+ return this.#hget(this.#k("guild", guildId, "roles"), roleId);
612
+ }
613
+ roles(guildId) {
614
+ return this.#hvals(this.#k("guild", guildId, "roles"));
615
+ }
616
+ user(userId) {
617
+ return this.#get(this.#k("user", userId));
618
+ }
619
+ async member(guildId, userId) {
620
+ const member = await this.#hget(this.#k("guild", guildId, "members"), userId);
621
+ if (!member)
622
+ return;
623
+ return { ...member, user: await this.user(userId) };
624
+ }
625
+ async members(guildId) {
626
+ const members = await this.#hvals(this.#k("guild", guildId, "members"));
627
+ if (members.length === 0)
628
+ return [];
629
+ const users = await this.#redis.send("MGET", members.map((m) => this.#k("user", String(m.user_id))));
630
+ return members.map((m, i) => ({
631
+ ...m,
632
+ user: users[i] ? JSON.parse(users[i]) : undefined
633
+ }));
634
+ }
635
+ }
636
+ // packages/core/src/api.ts
637
+ var SAFE_WORD = /^[a-z][a-zA-Z0-9]*$/;
638
+ var SAFE_SEGMENT = /^[A-Za-z0-9_@.%-]+$/;
639
+ var PAGING = {
640
+ members: {
641
+ limit: 1000,
642
+ cursor: "after",
643
+ idOf: (member) => member.user.id
644
+ },
645
+ bans: {
646
+ limit: 1000,
647
+ cursor: "after",
648
+ idOf: (ban) => ban.user.id
649
+ },
650
+ messages: { limit: 100, cursor: "before" },
651
+ guilds: { limit: 200, cursor: "after" }
652
+ };
653
+ var DEFAULT_PAGING = { limit: 100, cursor: "after" };
654
+ var DEFAULT_MAX = 1e4;
655
+ function kebab(word) {
656
+ return word.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
657
+ }
658
+ function idSegment(id) {
659
+ if (typeof id !== "string" && typeof id !== "number" && typeof id !== "bigint")
660
+ throw new TypeError("A route id must be a string, number or bigint.");
661
+ const text = String(id);
662
+ if (text === "")
663
+ throw new TypeError("A route id cannot be empty.");
664
+ return encodeURIComponent(text).replace(/%40/g, "@");
665
+ }
666
+ function defaultId(item) {
667
+ const record = item;
668
+ const id = record?.id ?? record?.user?.id;
669
+ if (typeof id !== "string")
670
+ throw new TypeError("Cannot find an id on a page item; pass idOf to pages().");
671
+ return id;
672
+ }
673
+ function node(rest, segments) {
674
+ const path = `/${segments.join("/")}`;
675
+ const send = (method, hasBody) => (first, second) => rest.request(method, path, hasBody ? first : undefined, (hasBody ? second : first) ?? {});
676
+ const last = segments[segments.length - 1] ?? "";
677
+ const pages = async function* (options = {}) {
678
+ const paging = { ...DEFAULT_PAGING, ...PAGING[last] };
679
+ const cursorName = options.cursor ?? paging.cursor;
680
+ const limit = options.limit ?? paging.limit;
681
+ const idOf = options.idOf ?? paging.idOf ?? defaultId;
682
+ let cursor = options.start;
683
+ for (;; ) {
684
+ const batch = await rest.request("GET", path, undefined, {
685
+ signal: options.signal,
686
+ query: {
687
+ ...options.query,
688
+ limit,
689
+ ...cursor === undefined ? {} : { [cursorName]: cursor }
690
+ }
691
+ });
692
+ if (!Array.isArray(batch) || batch.length === 0)
693
+ return;
694
+ yield batch;
695
+ if (batch.length < limit)
696
+ return;
697
+ cursor = idOf(batch[batch.length - 1]);
698
+ }
699
+ };
700
+ const all = async (options = {}) => {
701
+ const max = options.max ?? DEFAULT_MAX;
702
+ const paging = { ...DEFAULT_PAGING, ...PAGING[last] };
703
+ const items = [];
704
+ if (max <= 0)
705
+ return items;
706
+ for await (const page of pages({
707
+ ...options,
708
+ limit: Math.min(options.limit ?? paging.limit, max)
709
+ })) {
710
+ items.push(...page);
711
+ if (items.length >= max)
712
+ break;
713
+ }
714
+ return items.slice(0, max);
715
+ };
716
+ const members = {
717
+ path,
718
+ get: send("GET", false),
719
+ post: send("POST", true),
720
+ put: send("PUT", true),
721
+ patch: send("PATCH", true),
722
+ delete: send("DELETE", false),
723
+ pages,
724
+ all,
725
+ toString: () => path
726
+ };
727
+ return new Proxy(function route() {}, {
728
+ get(_target, property) {
729
+ if (typeof property !== "string")
730
+ return;
731
+ if (property in members)
732
+ return members[property];
733
+ if (property === "then" || !SAFE_WORD.test(property))
734
+ return;
735
+ return node(rest, [...segments, kebab(property)]);
736
+ },
737
+ apply(_target, _this, args) {
738
+ if (args.length !== 1)
739
+ throw new TypeError(`Call a route with exactly one id, e.g. ${path}(id).`);
740
+ return node(rest, [...segments, idSegment(args[0])]);
741
+ }
742
+ });
743
+ }
744
+ function createApi2(rest) {
745
+ const root = node(rest, []);
746
+ return new Proxy(root, {
747
+ get(target, property, receiver) {
748
+ if (property === "to")
749
+ return (...segments) => {
750
+ if (segments.length === 0)
751
+ throw new TypeError("to() needs at least one segment.");
752
+ const cleaned = segments.map((segment) => {
753
+ const text = String(segment);
754
+ if (!SAFE_SEGMENT.test(text))
755
+ throw new TypeError(`Invalid route segment: ${JSON.stringify(text)}.`);
756
+ return text;
757
+ });
758
+ return node(rest, cleaned);
759
+ };
760
+ return Reflect.get(target, property, receiver);
761
+ }
762
+ });
763
+ }
764
+ // packages/core/src/commands.ts
765
+ function settings(def) {
766
+ return def.config;
767
+ }
768
+ function define(kind, config, words) {
769
+ return { kind, config: config ?? {}, words };
770
+ }
771
+ var option2 = {
772
+ string: (config) => define("string", config),
773
+ integer: (config) => define("integer", config),
774
+ number: (config) => define("number", config),
775
+ boolean: (config) => define("boolean", config),
776
+ user: (config) => define("user", config),
777
+ role: (config) => define("role", config),
778
+ channel: (config) => define("channel", config),
779
+ mentionable: (config) => define("mentionable", config),
780
+ attachment: (config) => define("attachment", config),
781
+ choice: (words, config) => define("string", config, words)
782
+ };
783
+ var COMMAND_NAME = /^[-_\p{Ll}\p{Lo}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$/u;
784
+ var channelTypes = (kinds) => [
785
+ ...new Set(kinds.flatMap((kind) => ChannelKinds2[kind]))
786
+ ];
787
+ function named(builder, name, def) {
788
+ const config = settings(def);
789
+ return builder.setName(name).setDescription(config.description ?? name).setRequired(config.required === true);
790
+ }
791
+ function addOptionTo(slash, name, def) {
792
+ switch (def.kind) {
793
+ case "string": {
794
+ const config = def.config;
795
+ const text = named(new CreateStringOption2, name, def);
796
+ if (config.min !== undefined)
797
+ text.setMinLength(config.min);
798
+ if (config.max !== undefined)
799
+ text.setMaxLength(config.max);
800
+ const choices = def.words ?? config.choices;
801
+ if (choices?.length)
802
+ text.addChoices(...choices.map((choice) => typeof choice === "string" ? { name: choice, value: choice } : choice));
803
+ slash.addStringOption(() => text);
804
+ break;
805
+ }
806
+ case "integer":
807
+ case "number": {
808
+ const config = def.config;
809
+ const numeric = named(def.kind === "integer" ? new CreateIntegerOption2 : new CreateNumberOption2, name, def);
810
+ if (config.min !== undefined)
811
+ numeric.setMinValue(config.min);
812
+ if (config.max !== undefined)
813
+ numeric.setMaxValue(config.max);
814
+ if (config.choices?.length)
815
+ numeric.addChoices(...config.choices.map((choice) => typeof choice === "number" ? { name: String(choice), value: choice } : choice));
816
+ if (def.kind === "integer")
817
+ slash.addIntegerOption(() => numeric);
818
+ else
819
+ slash.addNumberOption(() => numeric);
820
+ break;
821
+ }
822
+ case "boolean":
823
+ slash.addBooleanOption(() => named(new CreateBooleanOption2, name, def));
824
+ break;
825
+ case "user":
826
+ slash.addUserOption(() => named(new CreateUserOption2, name, def));
827
+ break;
828
+ case "role":
829
+ slash.addRoleOption(() => named(new CreateRoleOption2, name, def));
830
+ break;
831
+ case "mentionable":
832
+ slash.addMentionableOption(() => named(new CreateMentionableOption2, name, def));
833
+ break;
834
+ case "attachment":
835
+ slash.addAttachmentOption(() => named(new CreateAttachmentOption2, name, def));
836
+ break;
837
+ case "channel": {
838
+ const config = def.config;
839
+ const channel = named(new CreateChannelOption2, name, def);
840
+ if (config.kinds?.length)
841
+ channel.addChannelTypes(...channelTypes(config.kinds));
842
+ slash.addChannelOption(() => channel);
843
+ break;
844
+ }
845
+ }
846
+ }
847
+ var PREFIX_TYPES = {
848
+ string: "string",
849
+ integer: "integer",
850
+ number: "number",
851
+ boolean: "boolean",
852
+ user: "user",
853
+ role: "role",
854
+ channel: "channel",
855
+ mentionable: "mentionable",
856
+ attachment: null
857
+ };
858
+ function prefixSpecs(options) {
859
+ const entries = Object.entries(options);
860
+ const specs = [];
861
+ for (const [index, [name, def]] of entries.entries()) {
862
+ const type = PREFIX_TYPES[def.kind];
863
+ if (type === null)
864
+ continue;
865
+ const config = def.config;
866
+ const choices = (def.words ?? config.choices)?.map((choice) => typeof choice === "object" ? choice.value : choice);
867
+ specs.push({
868
+ name,
869
+ type: type === "string" && index === entries.length - 1 ? "rest" : type,
870
+ required: settings(def).required === true && config.default === undefined,
871
+ min: config.min,
872
+ max: config.max,
873
+ maxLength: def.kind === "string" ? config.max : undefined,
874
+ choices
875
+ });
876
+ }
877
+ return specs;
878
+ }
879
+ function command2(definition) {
880
+ const slash = definition.slash ?? true;
881
+ const prefix = definition.prefix ? {
882
+ aliases: typeof definition.prefix === "object" ? [...definition.prefix.aliases ?? []] : []
883
+ } : false;
884
+ if (!COMMAND_NAME.test(definition.name))
885
+ throw new RangeError(`Invalid command name: ${definition.name}. Use 1-32 lowercase letters, digits, - or _.`);
886
+ if (definition.description.length < 1 || definition.description.length > 100)
887
+ throw new RangeError("A command description must be 1-100 characters.");
888
+ if (!slash && !prefix)
889
+ throw new TypeError(`Command ${definition.name} is neither a slash nor a prefix command.`);
890
+ for (const alias of prefix ? prefix.aliases : [])
891
+ if (!COMMAND_NAME.test(alias))
892
+ throw new RangeError(`Invalid alias for ${definition.name}: ${alias}.`);
893
+ const options = definition.options ?? {};
894
+ let optionalSeen;
895
+ for (const [name, def] of Object.entries(options)) {
896
+ const needed = settings(def).required === true;
897
+ if (needed && optionalSeen !== undefined)
898
+ throw new TypeError(`Option ${name} is required but follows the optional option ${optionalSeen}; put required options first.`);
899
+ if (!needed)
900
+ optionalSeen ??= name;
901
+ }
902
+ const permissions = definition.permissions ?? [];
903
+ const guildOnly = definition.guildOnly ?? permissions.length > 0;
904
+ const toJSON = () => {
905
+ const builder = new CreateSlashCommand2().setName(definition.name).setDescription(definition.description);
906
+ for (const [name, def] of Object.entries(options))
907
+ addOptionTo(builder, name, def);
908
+ if (permissions.length)
909
+ builder.setDefaultMemberPermissions(new PermissionSet2([...permissions]).bitfield);
910
+ if (guildOnly)
911
+ builder.setContexts(0);
912
+ if (definition.nsfw)
913
+ builder.setNSFW(true);
914
+ return builder.toJSON();
915
+ };
916
+ if (slash)
917
+ toJSON();
918
+ return Object.freeze({
919
+ name: definition.name,
920
+ description: definition.description,
921
+ options,
922
+ permissions,
923
+ guildOnly,
924
+ nsfw: definition.nsfw ?? false,
925
+ slash,
926
+ prefix,
927
+ run: definition.run,
928
+ toJSON,
929
+ usage(prefixText) {
930
+ const parts = Object.entries(options).map(([name, def]) => {
931
+ const required = settings(def).required === true && settings(def).default === undefined;
932
+ const label = def.kind === "attachment" ? `${name}\uD83D\uDCCE` : name;
933
+ return required ? `<${label}>` : `[${label}]`;
934
+ });
935
+ return [`${prefixText}${definition.name}`, ...parts].join(" ");
936
+ }
937
+ });
938
+ }
939
+ function applyDefault(def, value) {
940
+ if (value !== null && value !== undefined)
941
+ return value;
942
+ return settings(def).default;
943
+ }
944
+ function readSlashOptions(options, interaction) {
945
+ const values = {};
946
+ for (const [name, def] of Object.entries(options)) {
947
+ const source = interaction.options;
948
+ let value;
949
+ switch (def.kind) {
950
+ case "string":
951
+ value = source.getString(name);
952
+ break;
953
+ case "integer":
954
+ value = source.getInteger(name);
955
+ break;
956
+ case "number":
957
+ value = source.getNumber(name);
958
+ break;
959
+ case "boolean":
960
+ value = source.getBoolean(name);
961
+ break;
962
+ case "user":
963
+ value = idOf(source.getUser(name));
964
+ break;
965
+ case "role":
966
+ value = idOf(source.getRole(name));
967
+ break;
968
+ case "channel":
969
+ value = idOf(source.getChannel(name));
970
+ break;
971
+ case "mentionable": {
972
+ const id = idOf(source.getMentionable(name));
973
+ value = id ? { id, type: source.getMentionableType(name) ?? "user" } : null;
974
+ break;
975
+ }
976
+ case "attachment":
977
+ value = source.getAttachment(name);
978
+ break;
979
+ }
980
+ values[name] = applyDefault(def, value);
981
+ }
982
+ return values;
983
+ }
984
+ function idOf(record) {
985
+ return record === null ? null : String(record.id);
986
+ }
987
+ function words(name) {
988
+ return name.replace(/([a-z])([A-Z])/g, "$1 $2");
989
+ }
990
+
991
+ class CommandRegistry2 {
992
+ #bot;
993
+ #commands = new Map;
994
+ #names = new Map;
995
+ #listening = false;
996
+ constructor(bot) {
997
+ this.#bot = bot;
998
+ }
999
+ add(...commands) {
1000
+ for (const added of commands) {
1001
+ const taken = [
1002
+ added.name,
1003
+ ...added.prefix ? added.prefix.aliases : []
1004
+ ];
1005
+ for (const name of taken) {
1006
+ const owner = this.#names.get(name);
1007
+ if (owner && owner.name !== added.name)
1008
+ throw new TypeError(`The name "${name}" is already used by the ${owner.name} command.`);
1009
+ }
1010
+ const previous = this.#commands.get(added.name);
1011
+ if (previous)
1012
+ for (const name of [
1013
+ previous.name,
1014
+ ...previous.prefix ? previous.prefix.aliases : []
1015
+ ])
1016
+ this.#names.delete(name);
1017
+ this.#commands.set(added.name, added);
1018
+ if (added.slash || added.prefix)
1019
+ for (const name of taken)
1020
+ this.#names.set(name, added);
1021
+ }
1022
+ return this;
1023
+ }
1024
+ get(name) {
1025
+ return this.#names.get(name.toLowerCase());
1026
+ }
1027
+ list() {
1028
+ return [...this.#commands.values()];
1029
+ }
1030
+ async deploy(options = {}) {
1031
+ if (!this.#bot.isReady())
1032
+ throw new Error('Deploy commands after the client is ready: bot.once("ready", () => bot.commands.deploy()).');
1033
+ const payloads = this.list().filter((entry) => entry.slash).map((entry) => entry.toJSON());
1034
+ await (options.guildId === undefined ? this.#bot.application.commands.set(payloads) : this.#bot.application.commands.setGuild(options.guildId, payloads));
1035
+ return payloads.length;
1036
+ }
1037
+ listen(options = {}) {
1038
+ if (this.#listening)
1039
+ throw new TypeError("bot.commands.listen() was already called.");
1040
+ this.#listening = true;
1041
+ const prefixes = options.prefix === undefined ? [] : typeof options.prefix === "string" ? [options.prefix] : [...options.prefix];
1042
+ if (prefixes.some((prefix) => prefix === ""))
1043
+ throw new TypeError("A command prefix cannot be empty.");
1044
+ this.#bot.on("interactionCreate", async (interaction) => {
1045
+ if (!interaction.isChatInputCommand())
1046
+ return;
1047
+ const found = this.#commands.get(interaction.commandName);
1048
+ if (found?.slash)
1049
+ await this.#runSlash(found, interaction);
1050
+ });
1051
+ if (prefixes.length) {
1052
+ this.#warnAboutIntents();
1053
+ this.#bot.on("messageCreate", async (message) => {
1054
+ if (message.author.bot)
1055
+ return;
1056
+ const prefix = prefixes.find((p) => message.content.startsWith(p));
1057
+ if (prefix !== undefined)
1058
+ await this.#runPrefix(message, prefix);
1059
+ });
1060
+ }
1061
+ return this;
1062
+ }
1063
+ #warnAboutIntents() {
1064
+ const intents = resolveGatewayIntents2(this.#bot.options.intents);
1065
+ const missing = [];
1066
+ if ((intents & 1 << 15) === 0)
1067
+ missing.push("MessageContent");
1068
+ if ((intents & (1 << 9 | 1 << 12)) === 0)
1069
+ missing.push("GuildMessages or DirectMessages");
1070
+ if (missing.length === 0)
1071
+ return;
1072
+ process.emitWarning(`Prefix commands need the ${missing.join(" and ")} intent${missing.length > 1 ? "s" : ""}; without ${missing.length > 1 ? "them" : "it"} Discord sends empty message content and no prefix command will match.`, { type: "LunibeeWarning", code: "LUNIBEE_MESSAGE_CONTENT_INTENT" });
1073
+ }
1074
+ async#runSlash(found, interaction) {
1075
+ let answered = false;
1076
+ const reply = async (content) => {
1077
+ const body = typeof content === "string" ? { content } : content;
1078
+ if (answered)
1079
+ await interaction.followUp(body);
1080
+ else if (interaction.deferred)
1081
+ await interaction.editReply(body);
1082
+ else
1083
+ await interaction.reply(body);
1084
+ answered = true;
1085
+ };
1086
+ await found.run({
1087
+ bot: this.#bot,
1088
+ options: readSlashOptions(found.options, interaction),
1089
+ source: "slash",
1090
+ guildId: interaction.guildId,
1091
+ channelId: interaction.channelId,
1092
+ userId: interaction.user?.id ?? "",
1093
+ member: interaction.member,
1094
+ interaction,
1095
+ message: undefined,
1096
+ reply,
1097
+ defer: async (deferOptions) => {
1098
+ await interaction.deferReply({
1099
+ ephemeral: deferOptions?.ephemeral ?? false
1100
+ });
1101
+ }
1102
+ });
1103
+ }
1104
+ async#outOfScope(options, values, message) {
1105
+ const guildId = message.guildId ?? undefined;
1106
+ for (const [key, def] of Object.entries(options)) {
1107
+ const value = values[key];
1108
+ if (value === undefined || value === null)
1109
+ continue;
1110
+ if (def.kind === "channel") {
1111
+ const id = String(value);
1112
+ const channel = await this.#channel(id);
1113
+ const inScope = guildId ? channel?.guildId === guildId : id === message.channelId;
1114
+ if (!channel || !inScope)
1115
+ return {
1116
+ key,
1117
+ error: guildId ? "must be a channel in this server" : "must be this channel"
1118
+ };
1119
+ const kinds = def.config.kinds;
1120
+ if (kinds?.length && !channelTypes(kinds).includes(channel.type))
1121
+ return {
1122
+ key,
1123
+ error: `must be a ${kinds.join(" or ")} channel`
1124
+ };
1125
+ }
1126
+ const roleId = def.kind === "role" ? String(value) : def.kind === "mentionable" && value.type === "role" ? value.id : undefined;
1127
+ if (roleId !== undefined && !(guildId && await this.#hasRole(guildId, roleId)))
1128
+ return { key, error: "must be a role in this server" };
1129
+ }
1130
+ return;
1131
+ }
1132
+ async#channel(id) {
1133
+ const cached = this.#bot.channels.get(id);
1134
+ if (cached && !cached.partial)
1135
+ return cached;
1136
+ try {
1137
+ return await this.#bot.channels.fetch(id);
1138
+ } catch {
1139
+ return;
1140
+ }
1141
+ }
1142
+ async#hasRole(guildId, roleId) {
1143
+ if (roleId === guildId)
1144
+ return true;
1145
+ const roles = this.#bot.guilds.roles(guildId);
1146
+ if (roles.get(roleId))
1147
+ return true;
1148
+ try {
1149
+ return (await roles.fetchAll()).some((role) => role.id === roleId);
1150
+ } catch {
1151
+ return false;
1152
+ }
1153
+ }
1154
+ async#runPrefix(message, prefix) {
1155
+ const text = message.content.slice(prefix.length).trim();
1156
+ const [name = "", ...rest] = text.split(/\s+/);
1157
+ const found = this.get(name);
1158
+ if (!found?.prefix)
1159
+ return;
1160
+ const reply = async (content) => {
1161
+ const { ephemeral: _ephemeral, ...body } = typeof content === "string" ? { content } : content;
1162
+ await message.reply(body);
1163
+ };
1164
+ if (found.guildOnly && !message.guildId) {
1165
+ await reply("This command only works in servers.");
1166
+ return;
1167
+ }
1168
+ if (found.permissions.length) {
1169
+ const lacking = found.permissions.filter((permission) => !message.member?.permissions.has(permission));
1170
+ if (lacking.length) {
1171
+ await reply(`You need ${lacking.map((p) => `**${words(p)}**`).join(", ")}.`);
1172
+ return;
1173
+ }
1174
+ }
1175
+ const parsed = parsePrefixArgs2(rest.join(" "), prefixSpecs(found.options));
1176
+ const attachments = [...message.attachments];
1177
+ const values = {};
1178
+ if (parsed.ok)
1179
+ for (const [key, def] of Object.entries(found.options)) {
1180
+ if (def.kind === "attachment") {
1181
+ const attachment = attachments.shift();
1182
+ if (!attachment && settings(def).required === true) {
1183
+ await reply(`\`${key}\` is required. Usage: \`${found.usage(prefix)}\``);
1184
+ return;
1185
+ }
1186
+ values[key] = applyDefault(def, attachment);
1187
+ } else
1188
+ values[key] = applyDefault(def, parsed.values[key]);
1189
+ }
1190
+ else {
1191
+ await reply(`\`${parsed.arg}\` ${parsed.error}. Usage: \`${found.usage(prefix)}\``);
1192
+ return;
1193
+ }
1194
+ const outOfScope = await this.#outOfScope(found.options, values, message);
1195
+ if (outOfScope) {
1196
+ await reply(`\`${outOfScope.key}\` ${outOfScope.error}. Usage: \`${found.usage(prefix)}\``);
1197
+ return;
1198
+ }
1199
+ await found.run({
1200
+ bot: this.#bot,
1201
+ options: values,
1202
+ source: "prefix",
1203
+ guildId: message.guildId,
1204
+ channelId: message.channelId,
1205
+ userId: message.author.id,
1206
+ member: message.member ?? null,
1207
+ interaction: undefined,
1208
+ message,
1209
+ reply,
1210
+ defer: async () => {}
1211
+ });
1212
+ }
1213
+ }
1214
+ // packages/core/src/channel-create.ts
1215
+ var CREATABLE = [
1216
+ "text",
1217
+ "announcement",
1218
+ "voice",
1219
+ "stage",
1220
+ "category",
1221
+ "forum",
1222
+ "media"
1223
+ ];
1224
+ function emoji(value) {
1225
+ return /^\d+$/.test(value) ? { emoji_id: value, emoji_name: null } : { emoji_id: null, emoji_name: value };
1226
+ }
1227
+ function channelCreatePayload2(options) {
1228
+ if (!CREATABLE.includes(options.kind))
1229
+ throw new TypeError(`Cannot create a ${String(options.kind)} channel here. Use one of: ${CREATABLE.join(", ")}.`);
1230
+ if (options.name.length < 1 || options.name.length > 100)
1231
+ throw new RangeError("A channel name must be 1-100 characters.");
1232
+ const body = {
1233
+ name: options.name,
1234
+ type: ChannelKinds2[options.kind][0],
1235
+ parent_id: options.parent,
1236
+ position: options.position,
1237
+ permission_overwrites: options.permissionOverwrites,
1238
+ reason: options.reason
1239
+ };
1240
+ switch (options.kind) {
1241
+ case "text":
1242
+ case "announcement":
1243
+ case "forum":
1244
+ case "media": {
1245
+ if (options.slowmode !== undefined && (!Number.isInteger(options.slowmode) || options.slowmode < 0 || options.slowmode > 21600))
1246
+ throw new RangeError("slowmode must be 0-21600 seconds.");
1247
+ body.topic = options.topic;
1248
+ body.nsfw = options.nsfw;
1249
+ body.rate_limit_per_user = options.slowmode;
1250
+ body.default_auto_archive_duration = options.autoArchive;
1251
+ if (options.kind === "forum" || options.kind === "media") {
1252
+ body.default_thread_rate_limit_per_user = options.threadSlowmode;
1253
+ body.available_tags = options.tags?.map((tag) => ({
1254
+ name: tag.name,
1255
+ moderated: tag.moderated ?? false,
1256
+ ...tag.emoji ? emoji(tag.emoji) : {}
1257
+ }));
1258
+ if (options.defaultReaction)
1259
+ body.default_reaction_emoji = emoji(options.defaultReaction);
1260
+ if (options.sortOrder)
1261
+ body.default_sort_order = options.sortOrder === "latest-activity" ? 0 : 1;
1262
+ if (options.layout)
1263
+ body.default_forum_layout = options.layout === "list" ? 1 : 2;
1264
+ }
1265
+ break;
1266
+ }
1267
+ case "voice":
1268
+ case "stage":
1269
+ if (options.userLimit !== undefined && (!Number.isInteger(options.userLimit) || options.userLimit < 0 || options.userLimit > 99))
1270
+ throw new RangeError("userLimit must be 0-99.");
1271
+ body.bitrate = options.bitrate;
1272
+ body.user_limit = options.userLimit;
1273
+ body.rtc_region = options.region;
1274
+ body.nsfw = options.nsfw;
1275
+ if (options.videoQuality)
1276
+ body.video_quality_mode = options.videoQuality === "auto" ? 1 : 2;
1277
+ break;
1278
+ case "category":
1279
+ break;
1280
+ }
1281
+ return body;
1282
+ }
1283
+ // packages/core/src/handles.ts
1284
+ var UNIT_MS = {
1285
+ ms: 1,
1286
+ s: 1000,
1287
+ m: 60000,
1288
+ h: 3600000,
1289
+ d: 86400000,
1290
+ w: 604800000
1291
+ };
1292
+ function parseDuration2(value) {
1293
+ if (typeof value === "number") {
1294
+ if (!Number.isFinite(value) || value < 0)
1295
+ throw new RangeError("A duration must be a non-negative, finite number of milliseconds.");
1296
+ return value;
1297
+ }
1298
+ const text = value.replace(/\s+/g, "").toLowerCase();
1299
+ if (!/^(?:\d+(?:\.\d+)?(?:ms|s|m|h|d|w))+$/.test(text))
1300
+ throw new RangeError(`Invalid duration: ${JSON.stringify(value)}. Use a number of milliseconds or text such as "90s", "10m" or "1h30m".`);
1301
+ let total = 0;
1302
+ for (const [, amount, unit] of text.matchAll(/(\d+(?:\.\d+)?)(ms|s|m|h|d|w)/g))
1303
+ total += Number(amount) * UNIT_MS[unit];
1304
+ return Math.round(total);
1305
+ }
1306
+ function payload(input) {
1307
+ return typeof input === "string" ? { content: input } : input;
1308
+ }
1309
+
1310
+ class UserHandle2 {
1311
+ bot;
1312
+ id;
1313
+ constructor(bot, id) {
1314
+ this.bot = bot;
1315
+ this.id = id;
1316
+ }
1317
+ peek() {
1318
+ return this.bot.users.get(this.id);
1319
+ }
1320
+ get() {
1321
+ return this.bot.users.resolve(this.id);
1322
+ }
1323
+ fetch() {
1324
+ return this.bot.users.fetch(this.id);
1325
+ }
1326
+ async dm() {
1327
+ const data = await this.bot.users.createDM(this.id);
1328
+ this.bot.channels.upsert(data);
1329
+ return new ChannelHandle2(this.bot, data.id);
1330
+ }
1331
+ async send(message) {
1332
+ return (await this.dm()).send(message);
1333
+ }
1334
+ }
1335
+
1336
+ class GuildHandle2 {
1337
+ bot;
1338
+ id;
1339
+ constructor(bot, id) {
1340
+ this.bot = bot;
1341
+ this.id = id;
1342
+ }
1343
+ peek() {
1344
+ return this.bot.guilds.get(this.id);
1345
+ }
1346
+ get() {
1347
+ return this.bot.guilds.resolve(this.id);
1348
+ }
1349
+ fetch() {
1350
+ return this.bot.guilds.fetch(this.id);
1351
+ }
1352
+ get members() {
1353
+ return this.bot.guilds.members(this.id).cache;
1354
+ }
1355
+ get roles() {
1356
+ return this.bot.guilds.roles(this.id).cache;
1357
+ }
1358
+ get channels() {
1359
+ return this.bot.channels.cache.filter((channel) => channel.guildId === this.id);
1360
+ }
1361
+ member(userId) {
1362
+ return new MemberHandle2(this.bot, this.id, userId);
1363
+ }
1364
+ role(roleId) {
1365
+ return new RoleHandle2(this.bot, this.id, roleId);
1366
+ }
1367
+ channel(channelId) {
1368
+ return new ChannelHandle2(this.bot, channelId);
1369
+ }
1370
+ async createChannel(options) {
1371
+ const channel = await this.bot.channels.create(this.id, channelCreatePayload2(options));
1372
+ return channel.as(options.kind);
1373
+ }
1374
+ ban(userId, options) {
1375
+ return this.bot.guilds.members(this.id).ban(userId, options);
1376
+ }
1377
+ unban(userId, reason) {
1378
+ return this.bot.guilds.members(this.id).unban(userId, reason);
1379
+ }
1380
+ edit(options) {
1381
+ return this.bot.guilds.edit(this.id, options);
1382
+ }
1383
+ leave() {
1384
+ return this.bot.users.leaveGuild(this.id);
1385
+ }
1386
+ }
1387
+
1388
+ class MemberHandle2 {
1389
+ bot;
1390
+ guildId;
1391
+ userId;
1392
+ constructor(bot, guildId, userId) {
1393
+ this.bot = bot;
1394
+ this.guildId = guildId;
1395
+ this.userId = userId;
1396
+ }
1397
+ get members() {
1398
+ return this.bot.guilds.members(this.guildId);
1399
+ }
1400
+ peek() {
1401
+ return this.members.get(this.userId);
1402
+ }
1403
+ get() {
1404
+ return this.members.resolve(this.userId);
1405
+ }
1406
+ fetch() {
1407
+ return this.members.fetch(this.userId);
1408
+ }
1409
+ guild() {
1410
+ return new GuildHandle2(this.bot, this.guildId);
1411
+ }
1412
+ user() {
1413
+ return new UserHandle2(this.bot, this.userId);
1414
+ }
1415
+ kick(reason) {
1416
+ return this.members.kick(this.userId, reason);
1417
+ }
1418
+ ban(options) {
1419
+ return this.members.ban(this.userId, options);
1420
+ }
1421
+ unban(reason) {
1422
+ return this.members.unban(this.userId, reason);
1423
+ }
1424
+ edit(options) {
1425
+ return this.members.edit(this.userId, options);
1426
+ }
1427
+ addRole(roleId, reason) {
1428
+ return this.members.addRole(this.userId, roleId, reason);
1429
+ }
1430
+ removeRole(roleId, reason) {
1431
+ return this.members.removeRole(this.userId, roleId, reason);
1432
+ }
1433
+ async timeout(duration, reason) {
1434
+ return this.members.timeout(this.userId, duration === null ? null : parseDuration2(duration), reason);
1435
+ }
1436
+ }
1437
+
1438
+ class RoleHandle2 {
1439
+ bot;
1440
+ guildId;
1441
+ roleId;
1442
+ constructor(bot, guildId, roleId) {
1443
+ this.bot = bot;
1444
+ this.guildId = guildId;
1445
+ this.roleId = roleId;
1446
+ }
1447
+ get roles() {
1448
+ return this.bot.guilds.roles(this.guildId);
1449
+ }
1450
+ peek() {
1451
+ return this.roles.get(this.roleId);
1452
+ }
1453
+ get() {
1454
+ return this.roles.resolve(this.roleId);
1455
+ }
1456
+ fetch() {
1457
+ return this.roles.fetch(this.roleId);
1458
+ }
1459
+ edit(options) {
1460
+ return this.roles.edit(this.roleId, options);
1461
+ }
1462
+ delete(reason) {
1463
+ return this.roles.remove(this.roleId, reason);
1464
+ }
1465
+ }
1466
+
1467
+ class ChannelHandle2 {
1468
+ bot;
1469
+ id;
1470
+ constructor(bot, id) {
1471
+ this.bot = bot;
1472
+ this.id = id;
1473
+ }
1474
+ peek() {
1475
+ return this.bot.channels.get(this.id);
1476
+ }
1477
+ get() {
1478
+ return this.bot.channels.resolve(this.id);
1479
+ }
1480
+ fetch() {
1481
+ return this.bot.channels.fetch(this.id);
1482
+ }
1483
+ message(messageId) {
1484
+ return new MessageHandle2(this.bot, this.id, messageId);
1485
+ }
1486
+ async as(...kinds) {
1487
+ return (await this.get()).as(...kinds);
1488
+ }
1489
+ send(message) {
1490
+ return this.bot.channels.send(this.id, payload(message));
1491
+ }
1492
+ messages(query = {}) {
1493
+ return this.bot.channels.fetchMessages(this.id, query);
1494
+ }
1495
+ edit(options) {
1496
+ return this.bot.channels.edit(this.id, options);
1497
+ }
1498
+ delete(reason) {
1499
+ return this.bot.channels.remove(this.id, reason);
1500
+ }
1501
+ bulkDelete(messageIds, reason) {
1502
+ return this.bot.channels.bulkDeleteMessages(this.id, messageIds, reason);
1503
+ }
1504
+ }
1505
+
1506
+ class MessageHandle2 {
1507
+ bot;
1508
+ channelId;
1509
+ messageId;
1510
+ constructor(bot, channelId, messageId) {
1511
+ this.bot = bot;
1512
+ this.channelId = channelId;
1513
+ this.messageId = messageId;
1514
+ }
1515
+ peek() {
1516
+ return this.bot.channels.cachedMessages(this.channelId)?.cache.peek(this.messageId);
1517
+ }
1518
+ async get() {
1519
+ return this.peek() ?? this.fetch();
1520
+ }
1521
+ fetch() {
1522
+ return this.bot.channels.fetchMessage(this.channelId, this.messageId);
1523
+ }
1524
+ channel() {
1525
+ return new ChannelHandle2(this.bot, this.channelId);
1526
+ }
1527
+ edit(message) {
1528
+ return this.bot.channels.editMessage(this.channelId, this.messageId, typeof message === "string" ? { content: message } : message);
1529
+ }
1530
+ delete(reason) {
1531
+ return this.bot.channels.deleteMessage(this.channelId, this.messageId, reason);
1532
+ }
1533
+ reply(message) {
1534
+ return this.bot.channels.send(this.channelId, {
1535
+ ...payload(message),
1536
+ message_reference: {
1537
+ message_id: this.messageId,
1538
+ channel_id: this.channelId
1539
+ }
1540
+ });
1541
+ }
1542
+ react(emoji) {
1543
+ return this.bot.channels.addReaction(this.channelId, this.messageId, emoji);
1544
+ }
1545
+ pin(reason) {
1546
+ return this.bot.channels.pinMessage(this.channelId, this.messageId, reason);
1547
+ }
1548
+ unpin(reason) {
1549
+ return this.bot.channels.unpinMessage(this.channelId, this.messageId, reason);
1550
+ }
1551
+ crosspost() {
1552
+ return this.bot.channels.crosspostMessage(this.channelId, this.messageId);
1553
+ }
1554
+ }
1555
+ // packages/core/src/index.ts
1556
+ class EventEmitter2 {
1557
+ #listeners = {};
1558
+ redactSecrets = (text) => text;
1559
+ on(event, listener) {
1560
+ if (typeof listener !== "function")
1561
+ throw new TypeError("Event listener must be a function.");
1562
+ (this.#listeners[event] ??= new Set).add(listener);
1563
+ return this;
1564
+ }
1565
+ once(event, listener) {
1566
+ const wrapped = (...args) => {
1567
+ this.off(event, wrapped);
1568
+ return listener(...args);
1569
+ };
1570
+ return this.on(event, wrapped);
1571
+ }
1572
+ off(event, listener) {
1573
+ this.#listeners[event]?.delete(listener);
1574
+ return this;
1575
+ }
1576
+ removeListener(event, listener) {
1577
+ return this.off(event, listener);
1578
+ }
1579
+ listenerCount(event) {
1580
+ return this.#listeners[event]?.size ?? 0;
1581
+ }
1582
+ removeAllListeners(event) {
1583
+ if (event === undefined)
1584
+ this.#listeners = {};
1585
+ else
1586
+ delete this.#listeners[event];
1587
+ return this;
1588
+ }
1589
+ emit(event, ...args) {
1590
+ const listeners = this.#listeners[event];
1591
+ if (!listeners?.size)
1592
+ return false;
1593
+ for (const listener of [...listeners]) {
1594
+ try {
1595
+ const result = listener(...args);
1596
+ if (result && typeof result.then === "function")
1597
+ Promise.resolve(result).catch((error) => this.#handleError(event, error));
1598
+ } catch (error) {
1599
+ this.#handleError(event, error);
1600
+ }
1601
+ }
1602
+ return true;
1603
+ }
1604
+ #handleError(event, error) {
1605
+ const normalized = error instanceof Error ? error : new Error(String(error), { cause: error });
1606
+ const errorListeners = this.#listeners["error" /* Error */];
1607
+ const listeners = event === "error" /* Error */ ? [] : [...errorListeners ?? []];
1608
+ if (listeners.length === 0)
1609
+ return warnListenerError(event, normalized, this.redactSecrets);
1610
+ for (const listener of listeners) {
1611
+ try {
1612
+ const result = listener(normalized);
1613
+ if (result && typeof result.then === "function")
1614
+ Promise.resolve(result).catch((failure) => warnListenerError("error" /* Error */, failure, this.redactSecrets));
1615
+ } catch (failure) {
1616
+ warnListenerError("error" /* Error */, failure, this.redactSecrets);
1617
+ }
1618
+ }
1619
+ }
1620
+ }
1621
+ function warnListenerError(event, error, redact = (text) => text) {
1622
+ const failure = error instanceof Error ? error : new Error(String(error));
1623
+ process.emitWarning(redact(`A "${String(event)}" listener threw and no error listener handled it: ${failure.message}`), {
1624
+ type: "LunibeeWarning",
1625
+ code: "LUNIBEE_UNHANDLED_LISTENER_ERROR",
1626
+ detail: failure.stack === undefined ? undefined : redact(failure.stack)
1627
+ });
1628
+ }
1629
+
1630
+ class Client2 extends EventEmitter2 {
1631
+ options;
1632
+ rest;
1633
+ users;
1634
+ guilds;
1635
+ channels;
1636
+ stageInstances;
1637
+ application;
1638
+ #api;
1639
+ get api() {
1640
+ return this.#api ??= createApi2(this.rest);
1641
+ }
1642
+ commands = new CommandRegistry2(this);
1643
+ monetization;
1644
+ applicationEmojis;
1645
+ get ws() {
1646
+ return this.#gateway;
1647
+ }
1648
+ get gateway() {
1649
+ return this.#gateway;
1650
+ }
1651
+ user;
1652
+ voice;
1653
+ readyAt;
1654
+ state = "idle";
1655
+ redactSecrets = (text) => {
1656
+ const token = this.options.token;
1657
+ return token && token.length >= 8 ? text.split(token).join("[token]") : text;
1658
+ };
1659
+ get token() {
1660
+ return this.state === "destroyed" ? null : this.options.token ?? null;
1661
+ }
1662
+ get uptime() {
1663
+ return this.readyAt ? Date.now() - this.readyAt.getTime() : null;
1664
+ }
1665
+ get ping() {
1666
+ return this.#gateway.ping;
1667
+ }
1668
+ isReady() {
1669
+ return this.state === "ready";
1670
+ }
1671
+ setPresence(data) {
1672
+ return this.#gateway.setPresence(data);
1673
+ }
1674
+ setActivity(name, options = {}) {
1675
+ const type = options.type ?? ActivityEnum2.Playing;
1676
+ return this.setPresence({
1677
+ status: options.status ?? "online",
1678
+ activities: name === null ? [] : [
1679
+ {
1680
+ name,
1681
+ type,
1682
+ url: options.url,
1683
+ state: options.state ?? (type === ActivityEnum2.Custom ? name : undefined)
1684
+ }
1685
+ ]
1686
+ });
1687
+ }
1688
+ setVoiceState(data) {
1689
+ return this.#gateway.setVoiceState(data);
1690
+ }
1691
+ sendVoiceState(guildId, channelId, options = {}) {
1692
+ return this.#gateway.sendVoiceState(guildId, channelId, options);
1693
+ }
1694
+ requestGuildMembers(data) {
1695
+ return this.#gateway.requestGuildMembers(data);
1696
+ }
1697
+ #gateway;
1698
+ #cluster;
1699
+ #identifyGate;
1700
+ #collectors = new Set;
1701
+ #cache;
1702
+ #resourceContext;
1703
+ #guildsIntent;
1704
+ constructor(options) {
1705
+ super();
1706
+ this.options = options;
1707
+ const client = this;
1708
+ this.voice = new VoiceManager2({
1709
+ get userId() {
1710
+ return client.user?.id;
1711
+ },
1712
+ canSendVoiceState: (guildId) => client.#gateway.ownsGuild(guildId),
1713
+ sendVoiceState: (guildId, channelId, voiceOptions) => client.#gateway.sendVoiceState(guildId, channelId, voiceOptions)
1714
+ });
1715
+ if (!options.token?.trim())
1716
+ throw new TypeError("Client token is required.");
1717
+ this.rest = new REST2({ token: options.token, ...options.rest });
1718
+ this.#cache = {
1719
+ users: true,
1720
+ members: true,
1721
+ roles: true,
1722
+ emojis: true,
1723
+ presences: false,
1724
+ ...options.cache
1725
+ };
1726
+ this.#guildsIntent = Array.isArray(options.intents) && (resolveGatewayIntents2(options.intents) & GatewayIntentBits2.Guilds) !== 0;
1727
+ this.users = new UserManager2(this.rest, {
1728
+ maxSize: options.cache?.maxUsers
1729
+ });
1730
+ this.guilds = new GuildManager2(this.rest, {
1731
+ maxMembers: options.cache?.maxMembers
1732
+ });
1733
+ this.channels = new ChannelManager2(this.rest, {
1734
+ messageCache: options.messageCache,
1735
+ allowedMentions: options.allowedMentions
1736
+ });
1737
+ this.stageInstances = new StageInstanceManager2(this.rest);
1738
+ const placeholderAppCommands = new ApplicationCommandManager2(this.rest, "0");
1739
+ this.application = { commands: placeholderAppCommands };
1740
+ this.#resourceContext = this.#createResourceContext();
1741
+ this.guilds.attachContext(this.#resourceContext);
1742
+ this.#cluster = readClusterContext2();
1743
+ const shardId = options.gateway?.shardId;
1744
+ const gate = this.#cluster?.coordinatedIdentify && shardId !== undefined ? ClusterWorker2.current()?.identifyGate : undefined;
1745
+ this.#identifyGate = gate;
1746
+ this.#gateway = new Gateway2({
1747
+ token: options.token,
1748
+ intents: options.intents,
1749
+ ...options.compress === undefined ? {} : { compress: options.compress },
1750
+ ...gate ? {
1751
+ identifyGate: {
1752
+ acquire: () => gate.acquire(shardId),
1753
+ release: () => gate.release(shardId)
1754
+ }
1755
+ } : {},
1756
+ ...options.gateway
1757
+ });
1758
+ this.#wireLifecycle();
1759
+ this.#wireMessages();
1760
+ this.#wireGuilds();
1761
+ this.#wireGuildFeatures();
1762
+ this.#wireChannels();
1763
+ this.#wireMisc();
1764
+ }
1765
+ #createResourceContext() {
1766
+ return {
1767
+ sendMessage: (channelId, options) => this.channels.send(channelId, options),
1768
+ editMessage: (channelId, messageId, options) => this.channels.editMessage(channelId, messageId, options),
1769
+ deleteMessage: (channelId, messageId, reason) => this.channels.deleteMessage(channelId, messageId, reason),
1770
+ crosspostMessage: (channelId, messageId) => this.channels.crosspostMessage(channelId, messageId),
1771
+ editChannel: (channelId, options) => this.channels.edit(channelId, options),
1772
+ deleteChannel: (channelId, reason) => this.channels.remove(channelId, reason),
1773
+ addReaction: (channelId, messageId, emoji) => this.channels.addReaction(channelId, messageId, emoji),
1774
+ removeOwnReaction: (channelId, messageId, emoji) => this.channels.removeOwnReaction(channelId, messageId, emoji),
1775
+ removeReaction: (channelId, messageId, emoji, userId) => this.channels.removeReaction(channelId, messageId, emoji, userId),
1776
+ removeAllReactions: (channelId, messageId) => this.channels.removeAllReactions(channelId, messageId),
1777
+ pinMessage: (channelId, messageId, reason) => this.channels.pinMessage(channelId, messageId, reason),
1778
+ unpinMessage: (channelId, messageId, reason) => this.channels.unpinMessage(channelId, messageId, reason),
1779
+ collectInteractions: (options) => this.createCollector("interactionCreate" /* InteractionCreate */, options),
1780
+ cachedChannel: (channelId) => {
1781
+ const channel = this.channels.get(channelId);
1782
+ return channel && !channel.partial ? channel : undefined;
1783
+ },
1784
+ memberPermissions: (guildId, memberId, roleIds, channelId, timedOutUntil) => this.#memberPermissions(guildId, memberId, roleIds, channelId, timedOutUntil),
1785
+ kickMember: (guildId, userId, reason) => this.guilds.members(guildId).kick(userId, reason),
1786
+ banMember: (guildId, userId, options) => this.guilds.members(guildId).ban(userId, options),
1787
+ editMember: (guildId, userId, options, reason) => this.guilds.members(guildId).edit(userId, {
1788
+ ...options,
1789
+ reason: typeof options.reason === "string" ? options.reason : reason
1790
+ }),
1791
+ addMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).addRole(userId, roleId, reason),
1792
+ removeMemberRole: (guildId, userId, roleId, reason) => this.guilds.members(guildId).removeRole(userId, roleId, reason),
1793
+ editPermissionOverwrite: async (channelId, targetId, changes, options) => {
1794
+ const bits = { allow: 0n, deny: 0n, inherit: 0n };
1795
+ for (const [name, value] of Object.entries(changes)) {
1796
+ if (!/^[A-Za-z]+$/.test(name))
1797
+ throw new TypeError(`Unknown permission: ${name}`);
1798
+ let bit;
1799
+ try {
1800
+ bit = new PermissionSet2(name).bitfield;
1801
+ } catch {
1802
+ throw new TypeError(`Unknown permission: ${name}`);
1803
+ }
1804
+ const key = value === true ? "allow" : value === false ? "deny" : "inherit";
1805
+ bits[key] |= bit;
1806
+ }
1807
+ return this.channels.permissionOverwrites(channelId).update(targetId, bits, options);
1808
+ }
1809
+ };
1810
+ }
1811
+ #wireLifecycle() {
1812
+ this.#gateway.on("READY", (data) => {
1813
+ const ready = data;
1814
+ this.user = ready.user;
1815
+ this.users.set(this.user.id, new User2(this.user));
1816
+ this.readyAt = new Date;
1817
+ this.state = "ready";
1818
+ const appId = ready.application?.id ?? this.user.id;
1819
+ this.application.commands = new ApplicationCommandManager2(this.rest, appId);
1820
+ if (this.monetization?.applicationId !== appId)
1821
+ this.monetization = new MonetizationManager2(this.rest, appId);
1822
+ if (this.applicationEmojis?.applicationId !== appId)
1823
+ this.applicationEmojis = new ApplicationEmojiManager2(this.rest, appId);
1824
+ this.emit("ready" /* Ready */, this.user);
1825
+ });
1826
+ this.#gateway.on("RESUMED", () => {
1827
+ this.state = "ready";
1828
+ this.emit("resumed" /* Resumed */);
1829
+ });
1830
+ this.#gateway.on("invalidSession", (isRecoverable) => {
1831
+ this.emit("invalidSession" /* InvalidSession */, isRecoverable);
1832
+ });
1833
+ this.#gateway.on("open", () => this.emit("open" /* Open */));
1834
+ this.#gateway.on("close", (data) => {
1835
+ if (this.state !== "destroyed")
1836
+ this.state = "idle";
1837
+ this.emit("close" /* Close */, data);
1838
+ });
1839
+ }
1840
+ #wireMessages() {
1841
+ this.#gateway.on("MESSAGE_CREATE", (data) => {
1842
+ const payload = data;
1843
+ const message = new Message2(payload, this.#resourceContext);
1844
+ this.#observeMessage(message);
1845
+ if (payload.member && payload.guild_id && this.guilds.has(payload.guild_id))
1846
+ this.#upsertMember(payload.guild_id, {
1847
+ ...payload.member,
1848
+ user: payload.member.user ?? payload.author
1849
+ });
1850
+ const cached = this.options.messageCache ? this.channels.messages(message.channelId).upsert(data) : message;
1851
+ this.emit("messageCreate" /* MessageCreate */, cached);
1852
+ });
1853
+ this.#gateway.on("MESSAGE_UPDATE", (data) => {
1854
+ const partial = data;
1855
+ if (!partial.author) {
1856
+ const cachedMessage = this.channels.cachedMessages(partial.channel_id)?.cache.peek(partial.id);
1857
+ if (!cachedMessage)
1858
+ return;
1859
+ const before = this.listenerCount("messageUpdate" /* MessageUpdate */) ? this.#snapshot(cachedMessage) : null;
1860
+ if (partial.content !== undefined)
1861
+ cachedMessage.content = partial.content;
1862
+ this.emit("messageUpdate" /* MessageUpdate */, cachedMessage, before);
1863
+ return;
1864
+ }
1865
+ const message = new Message2(data, this.#resourceContext);
1866
+ this.#observeMessage(message);
1867
+ const messages = this.channels.cachedMessages(message.channelId);
1868
+ const previous = messages?.cache.peek(message.id);
1869
+ if (previous)
1870
+ messages.set(message.id, message);
1871
+ this.emit("messageUpdate" /* MessageUpdate */, message, previous ?? null);
1872
+ });
1873
+ this.#gateway.on("MESSAGE_DELETE", (data) => {
1874
+ const payload = data;
1875
+ const messages = this.channels.cachedMessages(payload.channel_id);
1876
+ const removed = messages?.cache.peek(payload.id);
1877
+ messages?.delete(payload.id);
1878
+ this.emit("messageDelete" /* MessageDelete */, payload, removed);
1879
+ });
1880
+ this.#gateway.on("MESSAGE_DELETE_BULK", (data) => {
1881
+ const payload = data;
1882
+ const messages = this.channels.cachedMessages(payload.channel_id);
1883
+ const removed = [];
1884
+ if (messages)
1885
+ for (const id of payload.ids) {
1886
+ const message = messages.cache.peek(id);
1887
+ if (message)
1888
+ removed.push(message);
1889
+ messages.delete(id);
1890
+ }
1891
+ this.emit("messageDeleteBulk" /* MessageDeleteBulk */, payload, removed);
1892
+ });
1893
+ this.#gateway.on("MESSAGE_REACTION_ADD", (data) => this.emit("messageReactionAdd" /* MessageReactionAdd */, data));
1894
+ this.#gateway.on("MESSAGE_REACTION_REMOVE", (data) => this.emit("messageReactionRemove" /* MessageReactionRemove */, data));
1895
+ this.#gateway.on("MESSAGE_REACTION_REMOVE_ALL", (data) => this.emit("messageReactionRemoveAll" /* MessageReactionRemoveAll */, data));
1896
+ this.#gateway.on("MESSAGE_REACTION_REMOVE_EMOJI", (data) => this.emit("messageReactionRemoveEmoji" /* MessageReactionRemoveEmoji */, data));
1897
+ this.#gateway.on("MESSAGE_POLL_VOTE_ADD", (data) => this.emit("messagePollVoteAdd" /* MessagePollVoteAdd */, data));
1898
+ this.#gateway.on("MESSAGE_POLL_VOTE_REMOVE", (data) => this.emit("messagePollVoteRemove" /* MessagePollVoteRemove */, data));
1899
+ }
1900
+ #wireGuilds() {
1901
+ this.#gateway.on("GUILD_CREATE", (data) => {
1902
+ const payload = data;
1903
+ if (payload.unavailable) {
1904
+ this.emit("guildUnavailable" /* GuildUnavailable */, payload);
1905
+ return;
1906
+ }
1907
+ const wasCached = this.guilds.has(payload.id);
1908
+ this.guilds.patch(payload);
1909
+ for (const role of payload.roles ?? [])
1910
+ this.#upsertRole(payload.id, role);
1911
+ if (this.#cache.emojis) {
1912
+ const emojis = this.guilds.emojis(payload.id);
1913
+ for (const emoji of payload.emojis ?? [])
1914
+ emojis.upsert(emoji);
1915
+ }
1916
+ for (const member of payload.members ?? [])
1917
+ this.#upsertMember(payload.id, member);
1918
+ for (const state of payload.voice_states ?? [])
1919
+ this.#storeVoiceState(payload.id, state);
1920
+ for (const channelData of [
1921
+ ...payload.channels ?? [],
1922
+ ...payload.threads ?? []
1923
+ ])
1924
+ this.channels.upsert({ ...channelData, guild_id: payload.id });
1925
+ this.emit(wasCached ? "guildAvailable" /* GuildAvailable */ : "guildCreate" /* GuildCreate */, payload);
1926
+ });
1927
+ this.#gateway.on("GUILD_UPDATE", (data) => {
1928
+ const payload = data;
1929
+ const cached = this.listenerCount("guildUpdate" /* GuildUpdate */) ? this.guilds.get(payload.id) : undefined;
1930
+ const previous = cached ? this.#snapshot(cached) : null;
1931
+ this.guilds.patch(payload);
1932
+ this.emit("guildUpdate" /* GuildUpdate */, payload, previous);
1933
+ });
1934
+ this.#gateway.on("GUILD_DELETE", (data) => {
1935
+ const payload = data;
1936
+ if (payload.unavailable) {
1937
+ this.emit("guildUnavailable" /* GuildUnavailable */, payload);
1938
+ return;
1939
+ }
1940
+ this.guilds.delete(payload.id);
1941
+ this.channels.deleteGuildChannels(payload.id);
1942
+ this.voice.handleGuildRemove(payload.id);
1943
+ this.emit("guildDelete" /* GuildDelete */, payload);
1944
+ });
1945
+ this.#gateway.on("GUILD_MEMBER_ADD", (data) => {
1946
+ const member = data;
1947
+ this.#upsertMember(member.guild_id, member);
1948
+ this.emit("guildMemberAdd" /* GuildMemberAdd */, member);
1949
+ });
1950
+ this.#gateway.on("GUILD_MEMBER_UPDATE", (data) => {
1951
+ const member = data;
1952
+ const cached = this.#cache.members && !this.#guildGone(member.guild_id) ? this.guilds.members(member.guild_id).get(member.user.id) : undefined;
1953
+ const previous = cached && this.listenerCount("guildMemberUpdate" /* GuildMemberUpdate */) ? this.#snapshot(cached, new GuildMember2({ user: member.user, guild_id: member.guild_id }, this.#resourceContext)) : null;
1954
+ this.#upsertMember(member.guild_id, member);
1955
+ this.emit("guildMemberUpdate" /* GuildMemberUpdate */, member, previous);
1956
+ });
1957
+ this.#gateway.on("GUILD_MEMBER_REMOVE", (data) => {
1958
+ const member = data;
1959
+ if (!this.#guildGone(member.guild_id))
1960
+ this.guilds.members(member.guild_id).delete(member.user.id);
1961
+ this.emit("guildMemberRemove" /* GuildMemberRemove */, member);
1962
+ });
1963
+ this.#gateway.on("GUILD_MEMBERS_CHUNK", (data) => {
1964
+ const chunk = data;
1965
+ for (const member of chunk.members)
1966
+ this.#upsertMember(chunk.guild_id, member);
1967
+ this.emit("guildMembersChunk" /* GuildMembersChunk */, chunk);
1968
+ });
1969
+ this.#gateway.on("GUILD_BAN_ADD", (data) => {
1970
+ const ban = data;
1971
+ if (!this.#guildGone(ban.guild_id)) {
1972
+ const bans = this.guilds.bans(ban.guild_id);
1973
+ bans.set(ban.user.id, {
1974
+ reason: bans.get(ban.user.id)?.reason ?? null,
1975
+ user: ban.user
1976
+ });
1977
+ this.guilds.members(ban.guild_id).delete(ban.user.id);
1978
+ }
1979
+ this.emit("guildBanAdd" /* GuildBanAdd */, ban);
1980
+ });
1981
+ this.#gateway.on("GUILD_BAN_REMOVE", (data) => {
1982
+ const ban = data;
1983
+ if (!this.#guildGone(ban.guild_id))
1984
+ this.guilds.bans(ban.guild_id).delete(ban.user.id);
1985
+ this.emit("guildBanRemove" /* GuildBanRemove */, ban);
1986
+ });
1987
+ this.#gateway.on("GUILD_ROLE_CREATE", (data) => {
1988
+ const event = data;
1989
+ this.#upsertRole(event.guild_id, event.role);
1990
+ this.emit("guildRoleCreate" /* GuildRoleCreate */, event);
1991
+ });
1992
+ this.#gateway.on("GUILD_ROLE_UPDATE", (data) => {
1993
+ const event = data;
1994
+ const cached = this.#cache.roles ? this.guilds.roles(event.guild_id).get(event.role.id) : undefined;
1995
+ const previous = cached && this.listenerCount("guildRoleUpdate" /* GuildRoleUpdate */) ? this.#snapshot(cached) : null;
1996
+ this.#upsertRole(event.guild_id, event.role);
1997
+ this.emit("guildRoleUpdate" /* GuildRoleUpdate */, event, previous);
1998
+ });
1999
+ this.#gateway.on("GUILD_ROLE_DELETE", (data) => {
2000
+ const event = data;
2001
+ const roles = this.guilds.roles(event.guild_id);
2002
+ const removed = roles.get(event.role_id) ?? null;
2003
+ roles.delete(event.role_id);
2004
+ this.emit("guildRoleDelete" /* GuildRoleDelete */, event, removed);
2005
+ });
2006
+ }
2007
+ #wireGuildFeatures() {
2008
+ this.#gateway.on("GUILD_EMOJIS_UPDATE", (data) => {
2009
+ const event = data;
2010
+ let previous = null;
2011
+ if (this.#cache.emojis) {
2012
+ const emojis = this.guilds.emojis(event.guild_id);
2013
+ if (this.listenerCount("guildEmojisUpdate" /* GuildEmojisUpdate */))
2014
+ previous = [...emojis.cache.values()].map((emoji) => this.#snapshot(emoji));
2015
+ const current = new Set(event.emojis.map((emoji) => emoji.id));
2016
+ for (const id of [...emojis.cache.keys()])
2017
+ if (!current.has(id))
2018
+ emojis.delete(id);
2019
+ for (const emoji of event.emojis)
2020
+ emojis.upsert(emoji);
2021
+ }
2022
+ this.emit("guildEmojisUpdate" /* GuildEmojisUpdate */, event, previous);
2023
+ });
2024
+ this.#gateway.on("GUILD_STICKERS_UPDATE", (data) => {
2025
+ const event = data;
2026
+ const stickers = this.guilds.stickers(event.guild_id);
2027
+ const previous = [...stickers.cache.values()];
2028
+ stickers.sync(event.stickers);
2029
+ this.emit("guildStickersUpdate" /* GuildStickersUpdate */, event, previous);
2030
+ });
2031
+ this.#gateway.on("GUILD_SOUNDBOARD_SOUND_CREATE", (data) => {
2032
+ const sound = data;
2033
+ if (sound.guild_id)
2034
+ this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
2035
+ this.emit("soundboardSoundCreate" /* SoundboardSoundCreate */, sound);
2036
+ });
2037
+ this.#gateway.on("GUILD_SOUNDBOARD_SOUND_UPDATE", (data) => {
2038
+ const sound = data;
2039
+ if (sound.guild_id)
2040
+ this.guilds.soundboard(sound.guild_id).set(sound.sound_id, sound);
2041
+ this.emit("soundboardSoundUpdate" /* SoundboardSoundUpdate */, sound);
2042
+ });
2043
+ this.#gateway.on("GUILD_SOUNDBOARD_SOUND_DELETE", (data) => {
2044
+ const event = data;
2045
+ this.guilds.soundboard(event.guild_id).delete(event.sound_id);
2046
+ this.emit("soundboardSoundDelete" /* SoundboardSoundDelete */, event);
2047
+ });
2048
+ this.#gateway.on("GUILD_SOUNDBOARD_SOUNDS_UPDATE", (data) => {
2049
+ const event = data;
2050
+ const sounds = this.guilds.soundboard(event.guild_id);
2051
+ sounds.clear();
2052
+ for (const sound of event.soundboard_sounds)
2053
+ sounds.set(sound.sound_id, sound);
2054
+ this.emit("soundboardSoundsUpdate" /* SoundboardSoundsUpdate */, event);
2055
+ });
2056
+ this.#gateway.on("ENTITLEMENT_CREATE", (data) => {
2057
+ const entitlement = data;
2058
+ this.monetization?.set(entitlement.id, entitlement);
2059
+ this.emit("entitlementCreate" /* EntitlementCreate */, entitlement);
2060
+ });
2061
+ this.#gateway.on("ENTITLEMENT_UPDATE", (data) => {
2062
+ const entitlement = data;
2063
+ this.monetization?.set(entitlement.id, entitlement);
2064
+ this.emit("entitlementUpdate" /* EntitlementUpdate */, entitlement);
2065
+ });
2066
+ this.#gateway.on("ENTITLEMENT_DELETE", (data) => {
2067
+ const entitlement = data;
2068
+ this.monetization?.delete(entitlement.id);
2069
+ this.emit("entitlementDelete" /* EntitlementDelete */, entitlement);
2070
+ });
2071
+ this.#gateway.on("GUILD_INTEGRATIONS_UPDATE", (data) => this.emit("guildIntegrationsUpdate" /* GuildIntegrationsUpdate */, data));
2072
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_CREATE", (data) => {
2073
+ const event = data;
2074
+ this.guilds.scheduledEvents(event.guild_id).set(event.id, event);
2075
+ this.emit("guildScheduledEventCreate" /* GuildScheduledEventCreate */, event);
2076
+ });
2077
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_UPDATE", (data) => {
2078
+ const event = data;
2079
+ const events = this.guilds.scheduledEvents(event.guild_id);
2080
+ const previous = events.get(event.id) ?? null;
2081
+ events.set(event.id, event);
2082
+ this.emit("guildScheduledEventUpdate" /* GuildScheduledEventUpdate */, event, previous);
2083
+ });
2084
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_DELETE", (data) => {
2085
+ const event = data;
2086
+ this.guilds.scheduledEvents(event.guild_id).delete(event.id);
2087
+ this.emit("guildScheduledEventDelete" /* GuildScheduledEventDelete */, event);
2088
+ });
2089
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_ADD", (data) => this.emit("guildScheduledEventUserAdd" /* GuildScheduledEventUserAdd */, data));
2090
+ this.#gateway.on("GUILD_SCHEDULED_EVENT_USER_REMOVE", (data) => this.emit("guildScheduledEventUserRemove" /* GuildScheduledEventUserRemove */, data));
2091
+ this.#gateway.on("AUTO_MODERATION_RULE_CREATE", (data) => {
2092
+ const rule = data;
2093
+ this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);
2094
+ this.emit("autoModerationRuleCreate" /* AutoModerationRuleCreate */, rule);
2095
+ });
2096
+ this.#gateway.on("AUTO_MODERATION_RULE_UPDATE", (data) => {
2097
+ const rule = data;
2098
+ const rules = this.guilds.autoModerationRules(rule.guild_id);
2099
+ const previous = rules.get(rule.id) ?? null;
2100
+ rules.set(rule.id, rule);
2101
+ this.emit("autoModerationRuleUpdate" /* AutoModerationRuleUpdate */, rule, previous);
2102
+ });
2103
+ this.#gateway.on("AUTO_MODERATION_RULE_DELETE", (data) => {
2104
+ const rule = data;
2105
+ this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);
2106
+ this.emit("autoModerationRuleDelete" /* AutoModerationRuleDelete */, rule);
2107
+ });
2108
+ this.#gateway.on("AUTO_MODERATION_ACTION_EXECUTION", (data) => this.emit("autoModerationActionExecution" /* AutoModerationActionExecution */, data));
2109
+ }
2110
+ #wireChannels() {
2111
+ this.#gateway.on("CHANNEL_CREATE", (data) => {
2112
+ const channel = this.channels.upsert(data);
2113
+ this.emit("channelCreate" /* ChannelCreate */, channel);
2114
+ });
2115
+ this.#gateway.on("CHANNEL_UPDATE", (data) => {
2116
+ const previous = this.listenerCount("channelUpdate" /* ChannelUpdate */) ? this.#previousChannel(data) : null;
2117
+ const channel = this.channels.upsert(data);
2118
+ this.emit("channelUpdate" /* ChannelUpdate */, channel, previous);
2119
+ });
2120
+ this.#gateway.on("CHANNEL_DELETE", (data) => {
2121
+ const payload = data;
2122
+ const removed = this.channels.get(payload.id) ?? null;
2123
+ this.channels.delete(payload.id);
2124
+ this.emit("channelDelete" /* ChannelDelete */, payload, removed);
2125
+ });
2126
+ this.#gateway.on("CHANNEL_PINS_UPDATE", (data) => this.emit("channelPinsUpdate" /* ChannelPinsUpdate */, data));
2127
+ this.#gateway.on("THREAD_CREATE", (data) => {
2128
+ const channel = this.channels.upsert(data);
2129
+ this.emit("threadCreate" /* ThreadCreate */, channel);
2130
+ });
2131
+ this.#gateway.on("THREAD_UPDATE", (data) => {
2132
+ const previous = this.listenerCount("threadUpdate" /* ThreadUpdate */) ? this.#previousChannel(data) : null;
2133
+ const channel = this.channels.upsert(data);
2134
+ this.emit("threadUpdate" /* ThreadUpdate */, channel, previous);
2135
+ });
2136
+ this.#gateway.on("THREAD_DELETE", (data) => {
2137
+ const payload = data;
2138
+ const removed = this.channels.get(payload.id) ?? null;
2139
+ this.channels.delete(payload.id);
2140
+ this.emit("threadDelete" /* ThreadDelete */, payload, removed);
2141
+ });
2142
+ this.#gateway.on("THREAD_LIST_SYNC", (data) => {
2143
+ const sync = data;
2144
+ for (const thread of sync.threads)
2145
+ this.channels.upsert({ ...thread, guild_id: sync.guild_id });
2146
+ this.emit("threadListSync" /* ThreadListSync */, sync);
2147
+ });
2148
+ this.#gateway.on("THREAD_MEMBERS_UPDATE", (data) => this.emit("threadMembersUpdate" /* ThreadMembersUpdate */, data));
2149
+ this.#gateway.on("THREAD_MEMBER_UPDATE", (data) => this.emit("threadMemberUpdate" /* ThreadMemberUpdate */, data));
2150
+ this.#gateway.on("STAGE_INSTANCE_CREATE", (data) => {
2151
+ const stage = data;
2152
+ this.stageInstances.set(stage.channel_id, stage);
2153
+ this.emit("stageInstanceCreate" /* StageInstanceCreate */, stage);
2154
+ });
2155
+ this.#gateway.on("STAGE_INSTANCE_UPDATE", (data) => {
2156
+ const stage = data;
2157
+ const previous = this.stageInstances.get(stage.channel_id) ?? null;
2158
+ this.stageInstances.set(stage.channel_id, stage);
2159
+ this.emit("stageInstanceUpdate" /* StageInstanceUpdate */, stage, previous);
2160
+ });
2161
+ this.#gateway.on("STAGE_INSTANCE_DELETE", (data) => {
2162
+ const stage = data;
2163
+ this.stageInstances.delete(stage.channel_id);
2164
+ this.emit("stageInstanceDelete" /* StageInstanceDelete */, stage);
2165
+ });
2166
+ this.#gateway.on("INVITE_CREATE", (data) => {
2167
+ const invite = data;
2168
+ if (invite.guild_id)
2169
+ this.guilds.invites(invite.guild_id).set(invite.code, invite);
2170
+ this.emit("inviteCreate" /* InviteCreate */, invite);
2171
+ });
2172
+ this.#gateway.on("INVITE_DELETE", (data) => {
2173
+ const invite = data;
2174
+ if (invite.guild_id)
2175
+ this.guilds.invites(invite.guild_id).delete(invite.code);
2176
+ this.emit("inviteDelete" /* InviteDelete */, invite);
2177
+ });
2178
+ this.#gateway.on("WEBHOOKS_UPDATE", (data) => this.emit("webhooksUpdate" /* WebhooksUpdate */, data));
2179
+ }
2180
+ #wireMisc() {
2181
+ this.#gateway.on("VOICE_STATE_UPDATE", (data) => {
2182
+ const state = data;
2183
+ const previous = state.guild_id ? this.guilds.voiceStates(state.guild_id).get(state.user_id) ?? null : null;
2184
+ if (state.guild_id)
2185
+ this.#storeVoiceState(state.guild_id, state);
2186
+ this.voice.handleVoiceState({
2187
+ ...state,
2188
+ channel_id: state.channel_id ?? null
2189
+ });
2190
+ this.emit("voiceStateUpdate" /* VoiceStateUpdate */, state, previous);
2191
+ });
2192
+ this.#gateway.on("VOICE_SERVER_UPDATE", (data) => {
2193
+ const server = data;
2194
+ this.voice.handleVoiceServer({
2195
+ ...server,
2196
+ endpoint: server.endpoint ?? null
2197
+ });
2198
+ this.emit("voiceServerUpdate" /* VoiceServerUpdate */, server);
2199
+ });
2200
+ this.#gateway.on("PRESENCE_UPDATE", (data) => {
2201
+ const presence = data;
2202
+ let previous = null;
2203
+ if (this.#cache.presences && presence.guild_id) {
2204
+ const presences = this.guilds.presences(presence.guild_id);
2205
+ previous = presences.get(presence.user.id) ?? null;
2206
+ presences.set(presence.user.id, presence);
2207
+ }
2208
+ this.emit("presenceUpdate" /* PresenceUpdate */, presence, previous);
2209
+ });
2210
+ this.#gateway.on("TYPING_START", (data) => this.emit("typingStart" /* TypingStart */, data));
2211
+ this.#gateway.on("INTERACTION_CREATE", (data) => this.emit("interactionCreate" /* InteractionCreate */, createInteraction2(this, data)));
2212
+ this.#gateway.on("RAW", (data) => this.emit("raw" /* Raw */, data));
2213
+ this.#gateway.on("error", (error) => this.emit("error" /* Error */, error));
2214
+ }
2215
+ #observeMessage(message) {
2216
+ if (!this.channels.has(message.channelId))
2217
+ this.channels.set(message.channelId, message.channel);
2218
+ if (this.#cache.users)
2219
+ this.#merge(this.users, message.author.id, message.author);
2220
+ }
2221
+ #upsertMember(guildId, data) {
2222
+ const member = new GuildMember2({ ...data, guild_id: guildId }, this.#resourceContext);
2223
+ if (this.#cache.users)
2224
+ this.#merge(this.users, member.user.id, member.user);
2225
+ if (!this.#cache.members || this.#guildGone(guildId))
2226
+ return member;
2227
+ const members = this.guilds.members(guildId);
2228
+ const known = members.get(member.user.id);
2229
+ const timedOutUntil = known?.timedOutUntil;
2230
+ const merged = this.#merge(members, member.user.id, member);
2231
+ if (known && timedOutUntil !== undefined && data.communication_disabled_until === undefined)
2232
+ merged.timedOutUntil = timedOutUntil;
2233
+ return merged;
2234
+ }
2235
+ #guildGone(guildId) {
2236
+ return this.#guildsIntent && !this.guilds.has(guildId);
2237
+ }
2238
+ #storeVoiceState(guildId, state) {
2239
+ const states = this.guilds.voiceStates(guildId);
2240
+ if (state.channel_id)
2241
+ states.set(state.user_id, state);
2242
+ else
2243
+ states.delete(state.user_id);
2244
+ }
2245
+ #upsertRole(guildId, data) {
2246
+ if (!this.#cache.roles)
2247
+ return new Role2(data);
2248
+ return this.#merge(this.guilds.roles(guildId), data.id, new Role2(data));
2249
+ }
2250
+ #snapshot(cached, blank = Object.create(Object.getPrototypeOf(cached))) {
2251
+ const from = cached;
2252
+ const into = blank;
2253
+ for (const key of Object.keys(from))
2254
+ into[key] = from[key];
2255
+ return blank;
2256
+ }
2257
+ #previousChannel(data) {
2258
+ const cached = this.channels.get(data.id);
2259
+ if (!cached)
2260
+ return null;
2261
+ return this.#snapshot(cached, createChannel2({ id: cached.id, type: cached.type, guild_id: cached.guildId }, this.#resourceContext));
2262
+ }
2263
+ #merge(manager, id, next) {
2264
+ const existing = manager.get(id);
2265
+ if (!existing) {
2266
+ manager.set(id, next);
2267
+ return next;
2268
+ }
2269
+ const from = next;
2270
+ const into = existing;
2271
+ for (const key of Object.keys(from)) {
2272
+ const value = from[key];
2273
+ if (value !== undefined)
2274
+ into[key] = value;
2275
+ }
2276
+ manager.set(id, existing);
2277
+ return existing;
2278
+ }
2279
+ createCollector(event, options = {}) {
2280
+ const collector = new Collector2(options);
2281
+ let order = 0;
2282
+ const listener = (...args) => {
2283
+ const item = args[0];
2284
+ const id = item?.id;
2285
+ const key = options.key?.(item) ?? (typeof id === "string" ? id : String(order++));
2286
+ collector.handle(key, item).catch((error) => this.emit("error" /* Error */, error instanceof Error ? error : new Error(String(error))));
2287
+ };
2288
+ this.on(event, listener);
2289
+ this.#collectors.add(collector);
2290
+ collector.onDispose(() => {
2291
+ this.off(event, listener);
2292
+ this.#collectors.delete(collector);
2293
+ });
2294
+ return collector;
2295
+ }
2296
+ guild(id) {
2297
+ return new GuildHandle2(this, id);
2298
+ }
2299
+ channel(id) {
2300
+ return new ChannelHandle2(this, id);
2301
+ }
2302
+ person(id) {
2303
+ return new UserHandle2(this, id);
2304
+ }
2305
+ member(guildId, userId) {
2306
+ return new MemberHandle2(this, guildId, userId);
2307
+ }
2308
+ role(guildId, roleId) {
2309
+ return new RoleHandle2(this, guildId, roleId);
2310
+ }
2311
+ message(channelId, messageId) {
2312
+ return new MessageHandle2(this, channelId, messageId);
2313
+ }
2314
+ get resourceContext() {
2315
+ return this.#resourceContext;
2316
+ }
2317
+ #memberPermissions(guildId, memberId, roleIds, channelId, timedOutUntil) {
2318
+ const guild = this.guilds.get(guildId);
2319
+ if (!guild)
2320
+ return null;
2321
+ let channel = channelId ? this.channels.get(channelId) : undefined;
2322
+ if (channelId) {
2323
+ if (channel?.isThread())
2324
+ channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
2325
+ if (!channel || channel.partial || channel.guildId !== guildId)
2326
+ return null;
2327
+ }
2328
+ return computePermissions2({
2329
+ guildId,
2330
+ ownerId: guild.ownerId,
2331
+ memberId,
2332
+ memberRoleIds: [...roleIds],
2333
+ roles: this.guilds.roles(guildId).values(),
2334
+ overwrites: channel?.permissionOverwrites,
2335
+ timedOutUntil
2336
+ });
2337
+ }
2338
+ permissionsFor(memberId, guildOrChannelId) {
2339
+ let channel = this.channels.get(guildOrChannelId);
2340
+ if (channel?.partial)
2341
+ return null;
2342
+ if (channel?.isThread()) {
2343
+ channel = channel.parentId ? this.channels.get(channel.parentId) : undefined;
2344
+ if (!channel || channel.partial)
2345
+ return null;
2346
+ }
2347
+ const guildId = channel?.guildId ?? guildOrChannelId;
2348
+ const guild = this.guilds.get(guildId);
2349
+ const member = this.guilds.members(guildId).get(memberId);
2350
+ if (!guild || !member)
2351
+ return null;
2352
+ return computePermissions2({
2353
+ guildId,
2354
+ ownerId: guild.ownerId,
2355
+ memberId,
2356
+ memberRoleIds: member.roleIds,
2357
+ roles: this.guilds.roles(guildId).values(),
2358
+ overwrites: channel?.permissionOverwrites,
2359
+ timedOutUntil: member.timedOutUntil
2360
+ });
2361
+ }
2362
+ fetchDefaultSoundboardSounds() {
2363
+ return this.rest.get(Routes2.soundboardDefaultSounds());
2364
+ }
2365
+ async login(token) {
2366
+ if (this.state === "destroyed")
2367
+ throw new Error("Cannot login a destroyed client.");
2368
+ if (token?.trim()) {
2369
+ this.rest.setToken(token);
2370
+ this.options.token = token;
2371
+ }
2372
+ const usedToken = this.options.token;
2373
+ if (!usedToken?.trim())
2374
+ throw new TypeError("A bot token is required to log in.");
2375
+ const shardId = this.#assertClusterShard();
2376
+ this.state = "connecting";
2377
+ if (this.#identifyGate && shardId !== undefined)
2378
+ await connectInQueue2(this.#gateway, shardId, this.#identifyGate, {
2379
+ waitForReady: this.#cluster?.startup === "sequential",
2380
+ readyTimeout: this.#cluster?.readyTimeout
2381
+ });
2382
+ else
2383
+ await this.#gateway.connect();
2384
+ return usedToken;
2385
+ }
2386
+ #assertClusterShard() {
2387
+ const cluster = this.#cluster;
2388
+ if (!cluster)
2389
+ return;
2390
+ const { shardId, shardCount } = this.options.gateway ?? {};
2391
+ const fix = `new Client({ \u2026, gateway: { shardId, shardCount: ${cluster.shardCount} } }) with shardId one of ${cluster.shardIds.join(", ")}, or a ShardManager to run them all`;
2392
+ if (shardId === undefined)
2393
+ throw new Error(`This process is cluster ${cluster.clusterId}'s worker: use ${fix}.`);
2394
+ if (!cluster.shardIds.includes(shardId))
2395
+ throw new Error(`Shard ${shardId} belongs to another cluster; cluster ${cluster.clusterId} runs ${cluster.shardIds.join(", ")}. Use ${fix}.`);
2396
+ if (shardCount !== cluster.shardCount)
2397
+ throw new Error(`gateway.shardCount must be the deployment's ${cluster.shardCount} shards (got ${String(shardCount)}).`);
2398
+ return shardId;
2399
+ }
2400
+ destroy() {
2401
+ this.state = "destroyed";
2402
+ this.voice.destroy();
2403
+ this.#gateway.close();
2404
+ for (const collector of [...this.#collectors])
2405
+ collector.stop("destroyed");
2406
+ this.users.clear();
2407
+ this.guilds.clear();
2408
+ this.channels.clear();
2409
+ }
2410
+ postInteractionResponse(id, token, response) {
2411
+ const json = response.toJSON();
2412
+ const callback = response.withResponse ? `${Routes2.interactionCallback(id, token)}?with_response=true` : Routes2.interactionCallback(id, token);
2413
+ const carriesMessage = json.type === 4 || json.type === 7;
2414
+ const upload = json.data ? toRequest2(json.data, carriesMessage ? this.options.allowedMentions : undefined) : undefined;
2415
+ return this.rest.post(callback, upload === undefined ? json : { ...json, data: upload.body }, { files: upload?.files });
2416
+ }
2417
+ editInteractionReply(token, data, applicationId) {
2418
+ const appId = applicationId ?? this.user?.id;
2419
+ if (!appId)
2420
+ return Promise.reject(new Error("Client is unauthenticated."));
2421
+ const { body, files } = toRequest2(data, this.options.allowedMentions);
2422
+ return this.rest.patch(Routes2.interactionOriginalResponse(appId, token), body, { files });
2423
+ }
2424
+ deleteInteractionReply(token, applicationId) {
2425
+ const appId = applicationId ?? this.user?.id;
2426
+ if (!appId)
2427
+ return Promise.reject(new Error("Client is unauthenticated."));
2428
+ return this.rest.delete(Routes2.interactionOriginalResponse(appId, token));
2429
+ }
2430
+ async followUpInteraction(token, data, applicationId) {
2431
+ const appId = applicationId ?? this.user?.id;
2432
+ if (!appId)
2433
+ return Promise.reject(new Error("Client is unauthenticated."));
2434
+ const { body, files } = toRequest2(data, this.options.allowedMentions);
2435
+ return this.rest.post(Routes2.webhook(appId, token), body, { files });
2436
+ }
2437
+ interactionWebhookMessage(method, applicationId, token, messageId, data) {
2438
+ const path = messageId === "@original" ? Routes2.interactionOriginalResponse(applicationId, token) : Routes2.webhookMessage(applicationId, token, messageId);
2439
+ if (method === "GET")
2440
+ return this.rest.get(path);
2441
+ if (method === "PATCH") {
2442
+ const request = data ? toRequest2(data, this.options.allowedMentions) : undefined;
2443
+ return this.rest.patch(path, request?.body, {
2444
+ files: request?.files
2445
+ });
2446
+ }
2447
+ return this.rest.delete(path);
2448
+ }
2449
+ async fetchWebhook(id, token) {
2450
+ return this.rest.get(Routes2.webhook(id, token));
2451
+ }
2452
+ async fetchGuildPreview(guildId) {
2453
+ return this.rest.get(Routes2.guildPreview(guildId));
2454
+ }
2455
+ fetchVoiceRegions() {
2456
+ return this.rest.get("/voice/regions");
2457
+ }
2458
+ fetchInvite(code, options) {
2459
+ const query = new URLSearchParams;
2460
+ if (options?.withCounts)
2461
+ query.set("with_counts", "true");
2462
+ if (options?.guildScheduledEventId)
2463
+ query.set("guild_scheduled_event_id", options.guildScheduledEventId);
2464
+ const qs = query.toString();
2465
+ return this.rest.get(`/invites/${encodeURIComponent(code)}${qs ? `?${qs}` : ""}`);
2466
+ }
2467
+ async fetchSticker(id) {
2468
+ return this.rest.get(Routes2.sticker(id));
2469
+ }
2470
+ fetchPremiumStickerPacks() {
2471
+ return this.rest.get(Routes2.stickerPacks());
2472
+ }
2473
+ fetchGuildTemplate(code) {
2474
+ return this.rest.get(`/guilds/templates/${encodeURIComponent(code)}`);
2475
+ }
2476
+ generateInvite(options) {
2477
+ if (!this.user)
2478
+ throw new Error("Client must be ready to generate invite.");
2479
+ const params = new URLSearchParams({
2480
+ client_id: this.user.id,
2481
+ scope: (options?.scopes ?? ["bot"]).join(" ")
2482
+ });
2483
+ if (options?.permissions) {
2484
+ params.set("permissions", String(options.permissions));
2485
+ }
2486
+ return `https://discord.com/api/oauth2/authorize?${params.toString()}`;
2487
+ }
2488
+ }
2489
+
2490
+ export { ClientEvent2, Collector2, RedisCache2, createApi2, option2, command2, CommandRegistry2, channelCreatePayload2, parseDuration2, UserHandle2, GuildHandle2, MemberHandle2, RoleHandle2, ChannelHandle2, MessageHandle2, Client2 };
2491
+
2492
+ //# debugId=BA934EB30EED6CAE64756E2164756E21