lunibee 0.1.8 → 0.2.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 (44) hide show
  1. package/README.md +2 -0
  2. package/dist/builders/components.d.ts +5 -0
  3. package/dist/builders/index.js +72 -12
  4. package/dist/builders/index.js.map +5 -5
  5. package/dist/collection/index.d.ts +68 -1
  6. package/dist/collection/index.js +334 -1
  7. package/dist/collection/index.js.map +3 -3
  8. package/dist/core/collector.d.ts +13 -0
  9. package/dist/core/events.d.ts +29 -3
  10. package/dist/core/index.d.ts +22 -8
  11. package/dist/core/index.js +1526 -124
  12. package/dist/core/index.js.map +26 -22
  13. package/dist/core/permissions.d.ts +48 -0
  14. package/dist/index.js +1578 -268
  15. package/dist/index.js.map +30 -29
  16. package/dist/managers/advanced.d.ts +116 -0
  17. package/dist/managers/base.d.ts +13 -2
  18. package/dist/managers/emoji.d.ts +1 -1
  19. package/dist/managers/guild.d.ts +28 -2
  20. package/dist/managers/index.d.ts +37 -5
  21. package/dist/managers/index.js +870 -152
  22. package/dist/managers/index.js.map +18 -16
  23. package/dist/managers/message.d.ts +10 -1
  24. package/dist/rest/errors.d.ts +33 -0
  25. package/dist/rest/index.d.ts +1 -1
  26. package/dist/rest/index.js +52 -6
  27. package/dist/rest/index.js.map +5 -5
  28. package/dist/rest/routes.d.ts +20 -0
  29. package/dist/sharding/index.d.ts +29 -0
  30. package/dist/sharding/index.js +99 -15
  31. package/dist/sharding/index.js.map +8 -8
  32. package/dist/structures/base.d.ts +2 -0
  33. package/dist/structures/index.js +96 -42
  34. package/dist/structures/index.js.map +10 -9
  35. package/dist/structures/interactions.d.ts +26 -0
  36. package/dist/types/gateway.d.ts +16 -0
  37. package/dist/types/index.d.ts +55 -1
  38. package/dist/types/index.js.map +2 -2
  39. package/dist/voice/index.d.ts +3 -0
  40. package/dist/voice/index.js +15 -1
  41. package/dist/voice/index.js.map +3 -3
  42. package/dist/ws/index.js +13 -5
  43. package/dist/ws/index.js.map +6 -6
  44. package/package.json +14 -14
@@ -1,6 +1,339 @@
1
1
  // @bun
2
2
  // packages/collection/src/index.ts
3
+ class RecencyList {
4
+ #nodes = new Map;
5
+ #oldest;
6
+ #newest;
7
+ get size() {
8
+ return this.#nodes.size;
9
+ }
10
+ oldest() {
11
+ return this.#oldest?.key;
12
+ }
13
+ touch(key) {
14
+ const node = this.#nodes.get(key);
15
+ if (node)
16
+ return this.#moveNewest(node);
17
+ const created = { key, older: this.#newest };
18
+ if (this.#newest)
19
+ this.#newest.newer = created;
20
+ else
21
+ this.#oldest = created;
22
+ this.#newest = created;
23
+ this.#nodes.set(key, created);
24
+ }
25
+ promote(key) {
26
+ const node = this.#nodes.get(key);
27
+ if (node)
28
+ this.#moveNewest(node);
29
+ }
30
+ delete(key) {
31
+ const node = this.#nodes.get(key);
32
+ if (!node)
33
+ return false;
34
+ this.#unlink(node);
35
+ this.#nodes.delete(key);
36
+ return true;
37
+ }
38
+ clear() {
39
+ this.#nodes.clear();
40
+ this.#oldest = this.#newest = undefined;
41
+ }
42
+ #unlink(node) {
43
+ if (node.older)
44
+ node.older.newer = node.newer;
45
+ else
46
+ this.#oldest = node.newer;
47
+ if (node.newer)
48
+ node.newer.older = node.older;
49
+ else
50
+ this.#newest = node.older;
51
+ node.older = node.newer = undefined;
52
+ }
53
+ #moveNewest(node) {
54
+ if (node === this.#newest)
55
+ return;
56
+ this.#unlink(node);
57
+ node.older = this.#newest;
58
+ if (this.#newest)
59
+ this.#newest.newer = node;
60
+ else
61
+ this.#oldest = node;
62
+ this.#newest = node;
63
+ }
64
+ }
65
+ function assertTTL(ttl) {
66
+ if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
67
+ throw new RangeError("TTL must be a positive number, or omitted.");
68
+ }
69
+
3
70
  class Collection extends Map {
71
+ #ttl;
72
+ #maxSize;
73
+ #onEvict;
74
+ #expiry = new Map;
75
+ #lru = new RecencyList;
76
+ #stats = {
77
+ hits: 0,
78
+ misses: 0,
79
+ expired: 0,
80
+ evicted: 0
81
+ };
82
+ #heap = [];
83
+ #timer;
84
+ #armedFor = Infinity;
85
+ constructor(entries, options = {}) {
86
+ super();
87
+ assertTTL(options.ttl);
88
+ if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
89
+ throw new RangeError("maxSize must be a positive integer.");
90
+ this.#ttl = options.ttl;
91
+ this.#maxSize = options.maxSize;
92
+ this.#onEvict = options.onEvict;
93
+ if (entries)
94
+ for (const [key, value] of entries)
95
+ this.set(key, value);
96
+ }
97
+ set(key, value, ttl) {
98
+ assertTTL(ttl);
99
+ const window = ttl ?? this.#ttl;
100
+ if (this.#maxSize !== undefined) {
101
+ this.#lru.touch(key);
102
+ }
103
+ super.set(key, value);
104
+ if (window !== undefined)
105
+ this.#schedule(key, window);
106
+ else if (this.#expiry.size > 0)
107
+ this.#expiry.delete(key);
108
+ this.#enforceCap();
109
+ return this;
110
+ }
111
+ setWithoutTTL(key, value) {
112
+ if (this.#expiry.size > 0)
113
+ this.#expiry.delete(key);
114
+ if (this.#lru.size > 0)
115
+ this.#lru.delete(key);
116
+ super.set(key, value);
117
+ return this;
118
+ }
119
+ get(key) {
120
+ if (this.#expireIfDue(key)) {
121
+ this.#stats.misses++;
122
+ return;
123
+ }
124
+ const value = super.get(key);
125
+ if (value === undefined && !super.has(key)) {
126
+ this.#stats.misses++;
127
+ return;
128
+ }
129
+ this.#stats.hits++;
130
+ const expiry = this.#expiry.get(key);
131
+ if (expiry)
132
+ expiry.deadline = Date.now() + expiry.window;
133
+ this.#lru.promote(key);
134
+ return value;
135
+ }
136
+ peek(key) {
137
+ if (!this.#expireIfDue(key) && super.has(key)) {
138
+ this.#stats.hits++;
139
+ return super.get(key);
140
+ }
141
+ this.#stats.misses++;
142
+ return;
143
+ }
144
+ get stats() {
145
+ return { ...this.#stats };
146
+ }
147
+ has(key) {
148
+ return !this.#expireIfDue(key) && super.has(key);
149
+ }
150
+ delete(key) {
151
+ if (this.#expireIfDue(key))
152
+ return false;
153
+ this.#expiry.delete(key);
154
+ this.#lru.delete(key);
155
+ return super.delete(key);
156
+ }
157
+ clear() {
158
+ super.clear();
159
+ this.#expiry.clear();
160
+ this.#lru.clear();
161
+ this.#heap.length = 0;
162
+ if (this.#timer)
163
+ clearTimeout(this.#timer);
164
+ this.#timer = undefined;
165
+ this.#armedFor = Infinity;
166
+ }
167
+ get size() {
168
+ this.purge();
169
+ return super.size;
170
+ }
171
+ entries() {
172
+ this.purge();
173
+ return super.entries();
174
+ }
175
+ keys() {
176
+ this.purge();
177
+ return super.keys();
178
+ }
179
+ values() {
180
+ this.purge();
181
+ return super.values();
182
+ }
183
+ [Symbol.iterator]() {
184
+ return this.entries();
185
+ }
186
+ forEach(callback, thisArg) {
187
+ this.purge();
188
+ super.forEach(callback, thisArg);
189
+ }
190
+ ttlRemaining(key) {
191
+ if (this.#expireIfDue(key))
192
+ return;
193
+ const expiry = this.#expiry.get(key);
194
+ return expiry && Math.max(0, expiry.deadline - Date.now());
195
+ }
196
+ purge() {
197
+ if (this.#expiry.size === 0)
198
+ return 0;
199
+ const now = Date.now();
200
+ let removed = 0;
201
+ const dropped = [];
202
+ while (this.#nextDeadline() <= now) {
203
+ const due = this.#heapPop();
204
+ dropped.push([due.key, super.get(due.key)]);
205
+ this.#remove(due.key);
206
+ removed++;
207
+ }
208
+ this.#stats.expired += removed;
209
+ this.#rearm();
210
+ for (const [key, value] of dropped)
211
+ this.#notify(key, value, "expired");
212
+ return removed;
213
+ }
214
+ #expireIfDue(key) {
215
+ const expiry = this.#expiry.get(key);
216
+ if (!expiry || expiry.deadline > Date.now())
217
+ return false;
218
+ const value = super.get(key);
219
+ this.#remove(key);
220
+ this.#stats.expired++;
221
+ this.#notify(key, value, "expired");
222
+ return true;
223
+ }
224
+ #remove(key) {
225
+ this.#expiry.delete(key);
226
+ this.#lru.delete(key);
227
+ super.delete(key);
228
+ }
229
+ #notify(key, value, reason) {
230
+ if (!this.#onEvict)
231
+ return;
232
+ try {
233
+ this.#onEvict(key, value, reason);
234
+ } catch {}
235
+ }
236
+ #enforceCap() {
237
+ if (this.#maxSize === undefined)
238
+ return;
239
+ while (this.#lru.size > this.#maxSize) {
240
+ const oldest = this.#lru.oldest();
241
+ const value = super.get(oldest);
242
+ this.#remove(oldest);
243
+ this.#stats.evicted++;
244
+ this.#notify(oldest, value, "evicted");
245
+ }
246
+ }
247
+ #schedule(key, window) {
248
+ const deadline = Date.now() + window;
249
+ const expiry = this.#expiry.get(key);
250
+ if (expiry) {
251
+ expiry.deadline = deadline;
252
+ expiry.window = window;
253
+ if (deadline >= expiry.filed)
254
+ return;
255
+ expiry.filed = deadline;
256
+ } else
257
+ this.#expiry.set(key, { deadline, window, filed: deadline });
258
+ this.#heapPush({ key, deadline });
259
+ if (this.#heap.length > 2 * this.#expiry.size + 8)
260
+ this.#compact();
261
+ this.#rearm();
262
+ }
263
+ #nextDeadline() {
264
+ for (;; ) {
265
+ const top = this.#heap[0];
266
+ if (top === undefined)
267
+ return Infinity;
268
+ const expiry = this.#expiry.get(top.key);
269
+ if (!expiry || expiry.filed !== top.deadline) {
270
+ this.#heapPop();
271
+ continue;
272
+ }
273
+ if (expiry.deadline === top.deadline)
274
+ return top.deadline;
275
+ this.#heapPop();
276
+ expiry.filed = expiry.deadline;
277
+ this.#heapPush({ key: top.key, deadline: expiry.deadline });
278
+ }
279
+ }
280
+ #compact() {
281
+ const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
282
+ this.#heap.length = 0;
283
+ for (const record of live)
284
+ this.#heapPush(record);
285
+ }
286
+ #rearm() {
287
+ const deadline = this.#nextDeadline();
288
+ if (this.#timer !== undefined && deadline >= this.#armedFor)
289
+ return;
290
+ if (this.#timer)
291
+ clearTimeout(this.#timer);
292
+ this.#timer = undefined;
293
+ this.#armedFor = deadline;
294
+ if (deadline === Infinity)
295
+ return;
296
+ this.#timer = setTimeout(() => {
297
+ this.#timer = undefined;
298
+ this.#armedFor = Infinity;
299
+ this.purge();
300
+ }, Math.max(0, deadline - Date.now()));
301
+ this.#timer.unref?.();
302
+ }
303
+ #heapPush(record) {
304
+ const heap = this.#heap;
305
+ heap.push(record);
306
+ let i = heap.length - 1;
307
+ while (i > 0) {
308
+ const parent = i - 1 >> 1;
309
+ if (heap[parent].deadline <= heap[i].deadline)
310
+ break;
311
+ [heap[parent], heap[i]] = [heap[i], heap[parent]];
312
+ i = parent;
313
+ }
314
+ }
315
+ #heapPop() {
316
+ const heap = this.#heap;
317
+ const top = heap[0];
318
+ const last = heap.pop();
319
+ if (top === undefined || heap.length === 0)
320
+ return top;
321
+ heap[0] = last;
322
+ for (let i = 0;; ) {
323
+ const left = 2 * i + 1;
324
+ const right = left + 1;
325
+ let smallest = i;
326
+ if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
327
+ smallest = left;
328
+ if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
329
+ smallest = right;
330
+ if (smallest === i)
331
+ break;
332
+ [heap[smallest], heap[i]] = [heap[i], heap[smallest]];
333
+ i = smallest;
334
+ }
335
+ return top;
336
+ }
4
337
  first() {
5
338
  for (const value of this.values())
6
339
  return value;
@@ -225,11 +558,40 @@ class Manager {
225
558
  has(id) {
226
559
  return this.cache.has(id);
227
560
  }
561
+ #inflight = new Map;
562
+ fetchOnce(id, load, store = (value) => {
563
+ this.set(id, value);
564
+ return value;
565
+ }) {
566
+ const pending = this.#inflight.get(id);
567
+ if (pending)
568
+ return pending.promise;
569
+ const entry = {
570
+ promise: new Promise((resolve) => resolve(load())),
571
+ dirty: false
572
+ };
573
+ this.#inflight.set(id, entry);
574
+ entry.promise = entry.promise.then((value) => {
575
+ this.#inflight.delete(id);
576
+ return entry.dirty ? this.get(id) ?? value : store(value);
577
+ }, (error) => {
578
+ this.#inflight.delete(id);
579
+ throw error;
580
+ });
581
+ return entry.promise;
582
+ }
583
+ #markDirty(id) {
584
+ const pending = this.#inflight.get(id);
585
+ if (pending)
586
+ pending.dirty = true;
587
+ }
228
588
  set(id, value) {
229
- this.cache.set(id, value);
589
+ this.#markDirty(id);
590
+ this.cache.setWithoutTTL(id, value);
230
591
  return this;
231
592
  }
232
593
  delete(id) {
594
+ this.#markDirty(id);
233
595
  return this.cache.delete(id);
234
596
  }
235
597
  clear() {
@@ -265,16 +627,20 @@ class ResourceManager extends Manager {
265
627
  async resolve(id) {
266
628
  return this.get(id) ?? this.fetch(id);
267
629
  }
268
- async fetch(id) {
269
- const resource = await this.#fetcher(id);
270
- this.set(id, resource);
271
- return resource;
630
+ fetch(id) {
631
+ return this.fetchOnce(id, () => this.#fetcher(id));
272
632
  }
273
633
  async fetchMany(ids) {
274
634
  return Promise.all([...ids].map((id) => this.resolve(id)));
275
635
  }
276
636
  upsert(resource) {
277
637
  const key = this.#key(resource);
638
+ const existing = this.get(key);
639
+ if (existing !== undefined && existing !== resource && typeof existing === "object" && existing !== null) {
640
+ Object.assign(existing, resource);
641
+ this.set(key, existing);
642
+ return existing;
643
+ }
278
644
  this.set(key, resource);
279
645
  return resource;
280
646
  }
@@ -285,7 +651,7 @@ class ResourceManager extends Manager {
285
651
  // packages/rest/package.json
286
652
  var package_default = {
287
653
  name: "@lunibee/rest",
288
- version: "0.1.8",
654
+ version: "0.2.0",
289
655
  type: "module",
290
656
  module: "./src/index.ts",
291
657
  types: "./src/index.ts",
@@ -352,8 +718,23 @@ var Routes = {
352
718
  invite: (code) => `/invites/${encodeURIComponent(code)}`,
353
719
  guildVanity: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/vanity-url`,
354
720
  guildEmoji: (guildId, emojiId) => emojiId ? `/guilds/${snowflake(guildId, "Guild ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/emojis`,
355
- applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`
721
+ applicationEmoji: (applicationId, emojiId) => emojiId ? `/applications/${snowflake(applicationId, "Application ID")}/emojis/${snowflake(emojiId, "Emoji ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/emojis`,
722
+ pollExpire: (channelId, messageId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/expire`,
723
+ pollAnswerVoters: (channelId, messageId, answerId) => `/channels/${snowflake(channelId, "Channel ID")}/polls/${snowflake(messageId, "Message ID")}/answers/${integer(answerId, "Answer ID")}`,
724
+ guildSticker: (guildId, stickerId) => stickerId ? `/guilds/${snowflake(guildId, "Guild ID")}/stickers/${snowflake(stickerId, "Sticker ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/stickers`,
725
+ sendSoundboardSound: (channelId) => `/channels/${snowflake(channelId, "Channel ID")}/send-soundboard-sound`,
726
+ soundboardDefaultSounds: () => "/soundboard-default-sounds",
727
+ guildSoundboardSound: (guildId, soundId) => soundId ? `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds/${snowflake(soundId, "Sound ID")}` : `/guilds/${snowflake(guildId, "Guild ID")}/soundboard-sounds`,
728
+ applicationSkus: (applicationId) => `/applications/${snowflake(applicationId, "Application ID")}/skus`,
729
+ applicationEntitlement: (applicationId, entitlementId) => entitlementId ? `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}` : `/applications/${snowflake(applicationId, "Application ID")}/entitlements`,
730
+ consumeEntitlement: (applicationId, entitlementId) => `/applications/${snowflake(applicationId, "Application ID")}/entitlements/${snowflake(entitlementId, "Entitlement ID")}/consume`,
731
+ skuSubscription: (skuId, subscriptionId) => subscriptionId ? `/skus/${snowflake(skuId, "SKU ID")}/subscriptions/${snowflake(subscriptionId, "Subscription ID")}` : `/skus/${snowflake(skuId, "SKU ID")}/subscriptions`
356
732
  };
733
+ function integer(value, field) {
734
+ if (!Number.isInteger(value) || value < 0)
735
+ throw new TypeError(`${field} must be a non-negative integer.`);
736
+ return String(value);
737
+ }
357
738
  function snowflake(value, field) {
358
739
  if (!/^\d{1,20}$/.test(value))
359
740
  throw new TypeError(`${field} must be a valid Discord snowflake.`);
@@ -446,6 +827,7 @@ class Channel extends BaseStructure {
446
827
  nsfw;
447
828
  rateLimitPerUser;
448
829
  position;
830
+ permissionOverwrites;
449
831
  #context;
450
832
  constructor(data, context) {
451
833
  super(data.id);
@@ -459,6 +841,7 @@ class Channel extends BaseStructure {
459
841
  this.nsfw = data.nsfw;
460
842
  this.rateLimitPerUser = data.rate_limit_per_user;
461
843
  this.position = data.position;
844
+ this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
462
845
  this.#context = context;
463
846
  }
464
847
  sendMessage(options) {
@@ -665,8 +1048,11 @@ var Permission = {
665
1048
  createEvents: 1n << 44n,
666
1049
  useExternalSounds: 1n << 45n,
667
1050
  sendVoiceMessages: 1n << 46n,
1051
+ setVoiceChannelStatus: 1n << 48n,
668
1052
  sendPolls: 1n << 49n,
669
- useExternalApps: 1n << 50n
1053
+ useExternalApps: 1n << 50n,
1054
+ pinMessages: 1n << 51n,
1055
+ bypassSlowmode: 1n << 52n
670
1056
  };
671
1057
  var Permissions = {
672
1058
  CreateInstantInvite: 1n << 0n,
@@ -716,8 +1102,11 @@ var Permissions = {
716
1102
  CreateEvents: 1n << 44n,
717
1103
  UseExternalSounds: 1n << 45n,
718
1104
  SendVoiceMessages: 1n << 46n,
1105
+ SetVoiceChannelStatus: 1n << 48n,
719
1106
  SendPolls: 1n << 49n,
720
- UseExternalApps: 1n << 50n
1107
+ UseExternalApps: 1n << 50n,
1108
+ PinMessages: 1n << 51n,
1109
+ BypassSlowmode: 1n << 52n
721
1110
  };
722
1111
  var PermissionFlagsBits = {
723
1112
  CreateInstantInvite: 1n << 0n,
@@ -767,8 +1156,11 @@ var PermissionFlagsBits = {
767
1156
  CreateEvents: 1n << 44n,
768
1157
  UseExternalSounds: 1n << 45n,
769
1158
  SendVoiceMessages: 1n << 46n,
1159
+ SetVoiceChannelStatus: 1n << 48n,
770
1160
  SendPolls: 1n << 49n,
771
- UseExternalApps: 1n << 50n
1161
+ UseExternalApps: 1n << 50n,
1162
+ PinMessages: 1n << 51n,
1163
+ BypassSlowmode: 1n << 52n
772
1164
  };
773
1165
 
774
1166
  class PermissionSet {
@@ -970,6 +1362,10 @@ class PermissionSet {
970
1362
  }
971
1363
  return false;
972
1364
  }
1365
+ missing(...permissions) {
1366
+ const wanted = new PermissionSet(permissions);
1367
+ return wanted.toArray().filter((name) => !this.has(name));
1368
+ }
973
1369
  add(...permissions) {
974
1370
  let bitfield = this.bitfield;
975
1371
  for (let i = 0;i < permissions.length; i++) {
@@ -1031,6 +1427,7 @@ class PermissionsBitField extends PermissionSet {
1031
1427
  super(value);
1032
1428
  }
1033
1429
  }
1430
+ var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
1034
1431
  // packages/types/src/gateway.ts
1035
1432
  var GatewayIntentBits = {
1036
1433
  Guilds: 1 << 0,
@@ -1367,7 +1764,7 @@ class ForumChannel extends Channel {
1367
1764
 
1368
1765
  class MediaChannel extends ForumChannel {
1369
1766
  }
1370
- function createChannel(data, context) {
1767
+ function createChannel2(data, context) {
1371
1768
  switch (data.type) {
1372
1769
  case 0:
1373
1770
  return new TextChannel(data, context);
@@ -1394,6 +1791,9 @@ function createChannel(data, context) {
1394
1791
  return new Channel(data, context);
1395
1792
  }
1396
1793
  }
1794
+ // packages/structures/src/interactions.ts
1795
+ var TOKEN_LIFETIME_MS = 15 * 60000;
1796
+
1397
1797
  // packages/structures/src/index.ts
1398
1798
  var NON_SYSTEM_MESSAGE_TYPES = new Set([0, 19, 20, 23]);
1399
1799
 
@@ -1551,16 +1951,22 @@ class Message extends BaseStructure {
1551
1951
 
1552
1952
  // packages/managers/src/message.ts
1553
1953
  class MessageManager {
1554
- cache = new Collection;
1954
+ cache;
1955
+ #caching;
1555
1956
  #rest;
1556
1957
  #context;
1557
1958
  #channelId;
1558
- constructor(rest, context, channelId) {
1959
+ constructor(rest, context, channelId, cache) {
1559
1960
  if (!channelId)
1560
1961
  throw new TypeError("Channel ID is required.");
1561
1962
  this.#rest = rest;
1562
1963
  this.#context = context;
1563
1964
  this.#channelId = channelId;
1965
+ this.#caching = cache !== undefined;
1966
+ this.cache = new Collection(null, {
1967
+ ttl: cache?.ttl,
1968
+ maxSize: cache ? cache.maxSize ?? 100 : undefined
1969
+ });
1564
1970
  }
1565
1971
  async resolve(messageId) {
1566
1972
  return this.cache.get(messageId) ?? this.fetch(messageId);
@@ -1577,13 +1983,14 @@ class MessageManager {
1577
1983
  return Promise.all(Array.from(messageIds, (messageId) => this.fetch(messageId)));
1578
1984
  }
1579
1985
  upsert(data) {
1580
- const existing = this.cache.get(data.id);
1986
+ const existing = this.cache.peek(data.id);
1581
1987
  const message = new Message(data, this.#context);
1582
1988
  if (existing) {
1583
1989
  Object.assign(existing, message);
1584
1990
  return existing;
1585
1991
  }
1586
- this.cache.set(message.id, message);
1992
+ if (this.#caching)
1993
+ this.cache.set(message.id, message);
1587
1994
  return message;
1588
1995
  }
1589
1996
  delete(messageId) {
@@ -1609,7 +2016,7 @@ class ThreadManager {
1609
2016
  auto_archive_duration: options.autoArchiveDuration,
1610
2017
  rate_limit_per_user: options.rateLimitPerUser
1611
2018
  });
1612
- return createChannel(data, this.#context);
2019
+ return createChannel2(data, this.#context);
1613
2020
  }
1614
2021
  }
1615
2022
 
@@ -1637,8 +2044,295 @@ class UserManager extends ResourceManager {
1637
2044
  });
1638
2045
  }
1639
2046
  }
2047
+ // packages/managers/src/emoji.ts
2048
+ class EmojiManager extends Manager {
2049
+ #rest;
2050
+ #guildId;
2051
+ constructor(rest, guildId) {
2052
+ super();
2053
+ this.#rest = rest;
2054
+ this.#guildId = guildId;
2055
+ }
2056
+ fetch(emojiId) {
2057
+ return this.fetchOnce(emojiId, async () => new Emoji(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId))), (emoji) => this.#merge(emojiId, emoji));
2058
+ }
2059
+ async fetchAll() {
2060
+ const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
2061
+ return data.map((item) => this.upsert(item));
2062
+ }
2063
+ async create(options) {
2064
+ return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
2065
+ }
2066
+ async edit(emojiId, options) {
2067
+ return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
2068
+ }
2069
+ async deleteEmoji(emojiId) {
2070
+ await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
2071
+ this.delete(emojiId);
2072
+ }
2073
+ upsert(data) {
2074
+ const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
2075
+ return this.#merge(key, new Emoji(data));
2076
+ }
2077
+ #merge(key, emoji) {
2078
+ const existing = this.get(key);
2079
+ if (existing) {
2080
+ Object.assign(existing, emoji);
2081
+ return existing;
2082
+ }
2083
+ this.set(key, emoji);
2084
+ return emoji;
2085
+ }
2086
+ }
2087
+
2088
+ // packages/managers/src/advanced.ts
2089
+ function withQuery(path, query) {
2090
+ const params = new URLSearchParams;
2091
+ for (const [key, value] of Object.entries(query))
2092
+ if (value !== undefined)
2093
+ params.set(key, String(value));
2094
+ const suffix = params.toString();
2095
+ return suffix ? `${path}?${suffix}` : path;
2096
+ }
2097
+
2098
+ class GuildStickerManager extends Manager {
2099
+ #rest;
2100
+ guildId;
2101
+ constructor(rest, guildId) {
2102
+ super();
2103
+ this.#rest = rest;
2104
+ this.guildId = guildId;
2105
+ }
2106
+ #store(sticker) {
2107
+ this.set(sticker.id, sticker);
2108
+ return sticker;
2109
+ }
2110
+ async fetchAll() {
2111
+ const stickers = await this.#rest.get(Routes.guildSticker(this.guildId));
2112
+ this.clear();
2113
+ return stickers.map((sticker) => this.#store(sticker));
2114
+ }
2115
+ async fetch(stickerId) {
2116
+ return this.#store(await this.#rest.get(Routes.guildSticker(this.guildId, stickerId)));
2117
+ }
2118
+ async create(options) {
2119
+ const form = new FormData;
2120
+ form.set("name", options.name);
2121
+ form.set("description", options.description);
2122
+ form.set("tags", options.tags);
2123
+ form.set("file", options.file);
2124
+ return this.#store(await this.#rest.post(Routes.guildSticker(this.guildId), form, { reason: options.reason }));
2125
+ }
2126
+ async edit(stickerId, options) {
2127
+ const { reason, ...body } = options;
2128
+ return this.#store(await this.#rest.patch(Routes.guildSticker(this.guildId, stickerId), body, { reason }));
2129
+ }
2130
+ async remove(stickerId, reason) {
2131
+ await this.#rest.delete(Routes.guildSticker(this.guildId, stickerId), {
2132
+ reason
2133
+ });
2134
+ this.delete(stickerId);
2135
+ }
2136
+ sync(stickers) {
2137
+ this.clear();
2138
+ for (const sticker of stickers)
2139
+ this.#store(sticker);
2140
+ }
2141
+ }
2142
+
2143
+ class GuildSoundboardManager extends Manager {
2144
+ #rest;
2145
+ guildId;
2146
+ constructor(rest, guildId) {
2147
+ super();
2148
+ this.#rest = rest;
2149
+ this.guildId = guildId;
2150
+ }
2151
+ #store(sound) {
2152
+ this.set(sound.sound_id, sound);
2153
+ return sound;
2154
+ }
2155
+ async fetchAll() {
2156
+ const { items } = await this.#rest.get(Routes.guildSoundboardSound(this.guildId));
2157
+ this.clear();
2158
+ return items.map((sound) => this.#store(sound));
2159
+ }
2160
+ async fetch(soundId) {
2161
+ return this.#store(await this.#rest.get(Routes.guildSoundboardSound(this.guildId, soundId)));
2162
+ }
2163
+ async create(options) {
2164
+ if (options.volume !== undefined && (options.volume < 0 || options.volume > 1))
2165
+ throw new RangeError("Soundboard volume must be between 0 and 1.");
2166
+ return this.#store(await this.#rest.post(Routes.guildSoundboardSound(this.guildId), {
2167
+ name: options.name,
2168
+ sound: options.sound,
2169
+ volume: options.volume,
2170
+ emoji_id: options.emojiId,
2171
+ emoji_name: options.emojiName
2172
+ }, { reason: options.reason }));
2173
+ }
2174
+ async edit(soundId, options) {
2175
+ return this.#store(await this.#rest.patch(Routes.guildSoundboardSound(this.guildId, soundId), {
2176
+ name: options.name,
2177
+ volume: options.volume,
2178
+ emoji_id: options.emojiId,
2179
+ emoji_name: options.emojiName
2180
+ }, { reason: options.reason }));
2181
+ }
2182
+ async remove(soundId, reason) {
2183
+ await this.#rest.delete(Routes.guildSoundboardSound(this.guildId, soundId), { reason });
2184
+ this.delete(soundId);
2185
+ }
2186
+ }
2187
+
2188
+ class MonetizationManager extends Manager {
2189
+ #rest;
2190
+ applicationId;
2191
+ constructor(rest, applicationId) {
2192
+ super();
2193
+ this.#rest = rest;
2194
+ this.applicationId = applicationId;
2195
+ }
2196
+ fetchSkus() {
2197
+ return this.#rest.get(Routes.applicationSkus(this.applicationId));
2198
+ }
2199
+ async fetchEntitlements(query = {}) {
2200
+ if (query.limit !== undefined && (!Number.isInteger(query.limit) || query.limit < 1 || query.limit > 100))
2201
+ throw new RangeError("Entitlement limit must be 1-100.");
2202
+ const entitlements = await this.#rest.get(withQuery(Routes.applicationEntitlement(this.applicationId), {
2203
+ user_id: query.userId,
2204
+ sku_ids: query.skuIds?.join(","),
2205
+ guild_id: query.guildId,
2206
+ before: query.before,
2207
+ after: query.after,
2208
+ limit: query.limit,
2209
+ exclude_ended: query.excludeEnded,
2210
+ exclude_deleted: query.excludeDeleted
2211
+ }));
2212
+ for (const entitlement of entitlements)
2213
+ this.set(entitlement.id, entitlement);
2214
+ return entitlements;
2215
+ }
2216
+ async fetch(entitlementId) {
2217
+ const entitlement = await this.#rest.get(Routes.applicationEntitlement(this.applicationId, entitlementId));
2218
+ this.set(entitlement.id, entitlement);
2219
+ return entitlement;
2220
+ }
2221
+ async consume(entitlementId) {
2222
+ await this.#rest.post(Routes.consumeEntitlement(this.applicationId, entitlementId));
2223
+ const cached = this.get(entitlementId);
2224
+ if (cached)
2225
+ cached.consumed = true;
2226
+ }
2227
+ async createTestEntitlement(options) {
2228
+ const entitlement = await this.#rest.post(Routes.applicationEntitlement(this.applicationId), {
2229
+ sku_id: options.skuId,
2230
+ owner_id: options.ownerId,
2231
+ owner_type: options.ownerType
2232
+ });
2233
+ this.set(entitlement.id, entitlement);
2234
+ return entitlement;
2235
+ }
2236
+ async deleteTestEntitlement(entitlementId) {
2237
+ await this.#rest.delete(Routes.applicationEntitlement(this.applicationId, entitlementId));
2238
+ this.delete(entitlementId);
2239
+ }
2240
+ fetchSubscriptions(skuId, query = {}) {
2241
+ return this.#rest.get(withQuery(Routes.skuSubscription(skuId), {
2242
+ user_id: query.userId,
2243
+ before: query.before,
2244
+ after: query.after,
2245
+ limit: query.limit
2246
+ }));
2247
+ }
2248
+ fetchSubscription(skuId, subscriptionId) {
2249
+ return this.#rest.get(Routes.skuSubscription(skuId, subscriptionId));
2250
+ }
2251
+ }
2252
+
2253
+ // packages/managers/src/member.ts
2254
+ class GuildMemberManager extends ResourceManager {
2255
+ #rest;
2256
+ guildId;
2257
+ constructor(guildId, rest) {
2258
+ super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId })), (member) => member.user.id);
2259
+ this.guildId = guildId;
2260
+ this.#rest = rest;
2261
+ }
2262
+ async kick(userId) {
2263
+ await this.#rest.delete(Routes.guildMember(this.guildId, userId));
2264
+ this.delete(userId);
2265
+ }
2266
+ async ban(userId, options = {}) {
2267
+ await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
2268
+ this.delete(userId);
2269
+ }
2270
+ async unban(userId) {
2271
+ await this.#rest.delete(Routes.guildBan(this.guildId, userId));
2272
+ }
2273
+ async edit(userId, options) {
2274
+ const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options);
2275
+ const member = new GuildMember({ ...data, guild_id: this.guildId });
2276
+ this.set(member.user.id, member);
2277
+ return member;
2278
+ }
2279
+ async addRole(userId, roleId) {
2280
+ await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId));
2281
+ }
2282
+ async removeRole(userId, roleId) {
2283
+ await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId));
2284
+ }
2285
+ async timeout(userId, milliseconds) {
2286
+ const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
2287
+ return this.edit(userId, { communication_disabled_until: timeoutDate });
2288
+ }
2289
+ }
2290
+
2291
+ // packages/managers/src/role.ts
2292
+ class RoleManager extends ResourceManager {
2293
+ #rest;
2294
+ guildId;
2295
+ constructor(guildId, rest) {
2296
+ super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
2297
+ this.guildId = guildId;
2298
+ this.#rest = rest;
2299
+ }
2300
+ async fetchAll() {
2301
+ const data = await this.#rest.get(Routes.guildRoles(this.guildId));
2302
+ return data.map((item) => {
2303
+ const role = new Role(item);
2304
+ this.set(role.id, role);
2305
+ return role;
2306
+ });
2307
+ }
2308
+ async create(options) {
2309
+ const { reason, ...payload } = options;
2310
+ const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
2311
+ ...payload,
2312
+ permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
2313
+ });
2314
+ const role = new Role(data);
2315
+ this.set(role.id, role);
2316
+ return role;
2317
+ }
2318
+ async edit(roleId, options) {
2319
+ const { reason, ...payload } = options;
2320
+ const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
2321
+ ...payload,
2322
+ permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
2323
+ });
2324
+ const role = new Role(data);
2325
+ this.set(role.id, role);
2326
+ return role;
2327
+ }
2328
+ async deleteRole(roleId) {
2329
+ await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
2330
+ this.delete(roleId);
2331
+ }
2332
+ }
2333
+
1640
2334
  // packages/managers/src/guild-resources.ts
1641
- function withQuery(path, params) {
2335
+ function withQuery2(path, params) {
1642
2336
  const query = new URLSearchParams;
1643
2337
  for (const [key, value] of Object.entries(params))
1644
2338
  if (value !== undefined)
@@ -1662,7 +2356,7 @@ class GuildBanManager extends Manager {
1662
2356
  }
1663
2357
  async fetchAll(options = {}) {
1664
2358
  const limit = options.limit === undefined ? undefined : Math.min(1000, Math.max(1, options.limit));
1665
- const bans = await this.#rest.get(withQuery(Routes.guildBans(this.guildId), {
2359
+ const bans = await this.#rest.get(withQuery2(Routes.guildBans(this.guildId), {
1666
2360
  limit,
1667
2361
  before: options.before,
1668
2362
  after: options.after
@@ -1695,12 +2389,12 @@ class GuildScheduledEventManager extends Manager {
1695
2389
  return event;
1696
2390
  }
1697
2391
  async fetch(eventId, options = {}) {
1698
- return this.#store(await this.#rest.get(withQuery(Routes.guildScheduledEvent(this.guildId, eventId), {
2392
+ return this.#store(await this.#rest.get(withQuery2(Routes.guildScheduledEvent(this.guildId, eventId), {
1699
2393
  with_user_count: options.withUserCount
1700
2394
  })));
1701
2395
  }
1702
2396
  async fetchAll(options = {}) {
1703
- const events = await this.#rest.get(withQuery(Routes.guildScheduledEvents(this.guildId), {
2397
+ const events = await this.#rest.get(withQuery2(Routes.guildScheduledEvents(this.guildId), {
1704
2398
  with_user_count: options.withUserCount
1705
2399
  }));
1706
2400
  return events.map((event) => this.#store(event));
@@ -1717,7 +2411,7 @@ class GuildScheduledEventManager extends Manager {
1717
2411
  }
1718
2412
  async fetchSubscribers(eventId, options = {}) {
1719
2413
  const limit = options.limit === undefined ? undefined : Math.min(100, Math.max(1, options.limit));
1720
- return this.#rest.get(withQuery(Routes.guildScheduledEventUsers(this.guildId, eventId), {
2414
+ return this.#rest.get(withQuery2(Routes.guildScheduledEventUsers(this.guildId, eventId), {
1721
2415
  limit,
1722
2416
  with_member: options.withMember,
1723
2417
  before: options.before,
@@ -1779,7 +2473,7 @@ class PermissionOverwriteManager {
1779
2473
  }
1780
2474
 
1781
2475
  // packages/managers/src/guild.ts
1782
- function withQuery2(path, params) {
2476
+ function withQuery3(path, params) {
1783
2477
  const suffix = params.toString();
1784
2478
  return suffix ? `${path}?${suffix}` : path;
1785
2479
  }
@@ -1788,6 +2482,20 @@ class GuildManager extends ResourceManager {
1788
2482
  #rest;
1789
2483
  #bans = new Map;
1790
2484
  #scheduledEvents = new Map;
2485
+ #members = new Map;
2486
+ #roles = new Map;
2487
+ #emojis = new Map;
2488
+ #stickers = new Map;
2489
+ #soundboard = new Map;
2490
+ #voiceStates = new Map;
2491
+ #autoModerationRules = new Map;
2492
+ #invites = new Map;
2493
+ #perGuild(map, guildId, create) {
2494
+ let manager = map.get(guildId);
2495
+ if (!manager)
2496
+ map.set(guildId, manager = create());
2497
+ return manager;
2498
+ }
1791
2499
  constructor(rest) {
1792
2500
  super(async (id) => new Guild(await rest.get(Routes.guild(id))), (guild) => guild.id);
1793
2501
  this.#rest = rest;
@@ -1804,6 +2512,68 @@ class GuildManager extends ResourceManager {
1804
2512
  this.#scheduledEvents.set(guildId, manager = new GuildScheduledEventManager(this.#rest, guildId));
1805
2513
  return manager;
1806
2514
  }
2515
+ members(guildId) {
2516
+ let manager = this.#members.get(guildId);
2517
+ if (!manager)
2518
+ this.#members.set(guildId, manager = new GuildMemberManager(guildId, this.#rest));
2519
+ return manager;
2520
+ }
2521
+ roles(guildId) {
2522
+ let manager = this.#roles.get(guildId);
2523
+ if (!manager)
2524
+ this.#roles.set(guildId, manager = new RoleManager(guildId, this.#rest));
2525
+ return manager;
2526
+ }
2527
+ emojis(guildId) {
2528
+ let manager = this.#emojis.get(guildId);
2529
+ if (!manager)
2530
+ this.#emojis.set(guildId, manager = new EmojiManager(this.#rest, guildId));
2531
+ return manager;
2532
+ }
2533
+ stickers(guildId) {
2534
+ let manager = this.#stickers.get(guildId);
2535
+ if (!manager)
2536
+ this.#stickers.set(guildId, manager = new GuildStickerManager(this.#rest, guildId));
2537
+ return manager;
2538
+ }
2539
+ soundboard(guildId) {
2540
+ let manager = this.#soundboard.get(guildId);
2541
+ if (!manager)
2542
+ this.#soundboard.set(guildId, manager = new GuildSoundboardManager(this.#rest, guildId));
2543
+ return manager;
2544
+ }
2545
+ voiceStates(guildId) {
2546
+ return this.#perGuild(this.#voiceStates, guildId, () => new Manager);
2547
+ }
2548
+ autoModerationRules(guildId) {
2549
+ return this.#perGuild(this.#autoModerationRules, guildId, () => new Manager);
2550
+ }
2551
+ invites(guildId) {
2552
+ return this.#perGuild(this.#invites, guildId, () => new Manager);
2553
+ }
2554
+ patch(data) {
2555
+ const guild = new Guild(data);
2556
+ const existing = this.get(guild.id);
2557
+ if (!existing)
2558
+ return this.upsert(guild);
2559
+ for (const [key, value] of Object.entries(guild))
2560
+ if (value !== undefined)
2561
+ existing[key] = value;
2562
+ return existing;
2563
+ }
2564
+ delete(id) {
2565
+ this.#bans.delete(id);
2566
+ this.#scheduledEvents.delete(id);
2567
+ this.#members.delete(id);
2568
+ this.#roles.delete(id);
2569
+ this.#emojis.delete(id);
2570
+ this.#stickers.delete(id);
2571
+ this.#soundboard.delete(id);
2572
+ this.#voiceStates.delete(id);
2573
+ this.#autoModerationRules.delete(id);
2574
+ this.#invites.delete(id);
2575
+ return super.delete(id);
2576
+ }
1807
2577
  async create(options) {
1808
2578
  const data = await this.#rest.post("/guilds", options);
1809
2579
  return this.upsert(new Guild(data));
@@ -1839,7 +2609,7 @@ class GuildManager extends ResourceManager {
1839
2609
  params.set("after", options.after);
1840
2610
  if (options.limit !== undefined)
1841
2611
  params.set("limit", String(Math.min(100, Math.max(1, options.limit))));
1842
- return this.#rest.get(withQuery2(Routes.guildAuditLog(guildId), params));
2612
+ return this.#rest.get(withQuery3(Routes.guildAuditLog(guildId), params));
1843
2613
  }
1844
2614
  async fetchMembers(guildId, options = {}) {
1845
2615
  const params = new URLSearchParams;
@@ -1847,7 +2617,7 @@ class GuildManager extends ResourceManager {
1847
2617
  params.set("limit", String(Math.min(1000, Math.max(1, options.limit))));
1848
2618
  if (options.after)
1849
2619
  params.set("after", options.after);
1850
- return this.#rest.get(withQuery2(Routes.guildMembers(guildId), params));
2620
+ return this.#rest.get(withQuery3(Routes.guildMembers(guildId), params));
1851
2621
  }
1852
2622
  async fetchAutoModerationRules(guildId) {
1853
2623
  const rules = await this.#rest.get(Routes.guildAutoModerationRules(guildId));
@@ -1922,85 +2692,6 @@ var AuditLogEvent = {
1922
2692
  AutoModerationRuleDelete: 142,
1923
2693
  AutoModerationBlockMessage: 143
1924
2694
  };
1925
- // packages/managers/src/role.ts
1926
- class RoleManager extends ResourceManager {
1927
- #rest;
1928
- guildId;
1929
- constructor(guildId, rest) {
1930
- super((id) => rest.get(Routes.guildRole(guildId, id)).then((data) => new Role(data)), (role) => role.id);
1931
- this.guildId = guildId;
1932
- this.#rest = rest;
1933
- }
1934
- async fetchAll() {
1935
- const data = await this.#rest.get(Routes.guildRoles(this.guildId));
1936
- return data.map((item) => {
1937
- const role = new Role(item);
1938
- this.set(role.id, role);
1939
- return role;
1940
- });
1941
- }
1942
- async create(options) {
1943
- const { reason, ...payload } = options;
1944
- const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
1945
- ...payload,
1946
- permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
1947
- });
1948
- const role = new Role(data);
1949
- this.set(role.id, role);
1950
- return role;
1951
- }
1952
- async edit(roleId, options) {
1953
- const { reason, ...payload } = options;
1954
- const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
1955
- ...payload,
1956
- permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
1957
- });
1958
- const role = new Role(data);
1959
- this.set(role.id, role);
1960
- return role;
1961
- }
1962
- async deleteRole(roleId) {
1963
- await this.#rest.delete(Routes.guildRole(this.guildId, roleId));
1964
- this.delete(roleId);
1965
- }
1966
- }
1967
- // packages/managers/src/member.ts
1968
- class GuildMemberManager extends ResourceManager {
1969
- #rest;
1970
- guildId;
1971
- constructor(guildId, rest) {
1972
- super((id) => rest.get(Routes.guildMember(guildId, id)).then((data) => new GuildMember({ ...data, guild_id: guildId })), (member) => member.user.id);
1973
- this.guildId = guildId;
1974
- this.#rest = rest;
1975
- }
1976
- async kick(userId) {
1977
- await this.#rest.delete(Routes.guildMember(this.guildId, userId));
1978
- this.delete(userId);
1979
- }
1980
- async ban(userId, options = {}) {
1981
- await this.#rest.put(Routes.guildBan(this.guildId, userId), { delete_message_seconds: options.deleteMessageSeconds }, { reason: options.reason });
1982
- this.delete(userId);
1983
- }
1984
- async unban(userId) {
1985
- await this.#rest.delete(Routes.guildBan(this.guildId, userId));
1986
- }
1987
- async edit(userId, options) {
1988
- const data = await this.#rest.patch(Routes.guildMember(this.guildId, userId), options);
1989
- const member = new GuildMember({ ...data, guild_id: this.guildId });
1990
- this.set(member.user.id, member);
1991
- return member;
1992
- }
1993
- async addRole(userId, roleId) {
1994
- await this.#rest.put(Routes.guildMemberRole(this.guildId, userId, roleId));
1995
- }
1996
- async removeRole(userId, roleId) {
1997
- await this.#rest.delete(Routes.guildMemberRole(this.guildId, userId, roleId));
1998
- }
1999
- async timeout(userId, milliseconds) {
2000
- const timeoutDate = milliseconds === null ? null : new Date(Date.now() + milliseconds).toISOString();
2001
- return this.edit(userId, { communication_disabled_until: timeoutDate });
2002
- }
2003
- }
2004
2695
  // packages/managers/src/application.ts
2005
2696
  class ApplicationCommandManager {
2006
2697
  #rest;
@@ -2040,53 +2731,22 @@ class ApplicationCommandManager {
2040
2731
  await this.#rest.delete(Routes.guildApplicationCommand(this.#applicationId, guildId, commandId));
2041
2732
  }
2042
2733
  }
2043
- // packages/managers/src/emoji.ts
2044
- class EmojiManager extends Manager {
2045
- #rest;
2046
- #guildId;
2047
- constructor(rest, guildId) {
2048
- super();
2049
- this.#rest = rest;
2050
- this.#guildId = guildId;
2051
- }
2052
- async fetch(emojiId) {
2053
- return this.upsert(await this.#rest.get(Routes.guildEmoji(this.#guildId, emojiId)));
2054
- }
2055
- async fetchAll() {
2056
- const data = await this.#rest.get(Routes.guildEmoji(this.#guildId));
2057
- return data.map((item) => this.upsert(item));
2058
- }
2059
- async create(options) {
2060
- return this.upsert(await this.#rest.post(Routes.guildEmoji(this.#guildId), options));
2061
- }
2062
- async edit(emojiId, options) {
2063
- return this.upsert(await this.#rest.patch(Routes.guildEmoji(this.#guildId, emojiId), options));
2064
- }
2065
- async deleteEmoji(emojiId) {
2066
- await this.#rest.delete(Routes.guildEmoji(this.#guildId, emojiId));
2067
- this.delete(emojiId);
2068
- }
2069
- upsert(data) {
2070
- const key = data.id != null ? data.id : `unicode:${data.name ?? ""}`;
2071
- const existing = this.get(key);
2072
- const emoji = new Emoji(data);
2073
- if (existing) {
2074
- Object.assign(existing, emoji);
2075
- return existing;
2076
- }
2077
- this.set(key, emoji);
2078
- return emoji;
2079
- }
2080
- }
2081
2734
 
2082
2735
  // packages/managers/src/index.ts
2736
+ var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
2737
+ function snowflakeTime(id) {
2738
+ return Number((BigInt(id) >> 22n) + 1420070400000n);
2739
+ }
2740
+
2083
2741
  class ChannelManager extends Manager {
2084
2742
  #rest;
2085
2743
  #context;
2086
2744
  #messageManagers = new Map;
2087
- constructor(rest) {
2745
+ #messageCache;
2746
+ constructor(rest, options = {}) {
2088
2747
  super();
2089
2748
  this.#rest = rest;
2749
+ this.#messageCache = options.messageCache;
2090
2750
  this.#context = {
2091
2751
  sendMessage: (channelId, options) => this.send(channelId, options),
2092
2752
  editMessage: (channelId, messageId, options) => this.editMessage(channelId, messageId, options),
@@ -2105,7 +2765,7 @@ class ChannelManager extends Manager {
2105
2765
  messages(channelId) {
2106
2766
  let manager = this.#messageManagers.get(channelId);
2107
2767
  if (!manager) {
2108
- manager = new MessageManager(this.#rest, this.#context, channelId);
2768
+ manager = new MessageManager(this.#rest, this.#context, channelId, this.#messageCache);
2109
2769
  this.#messageManagers.set(channelId, manager);
2110
2770
  }
2111
2771
  return manager;
@@ -2116,16 +2776,18 @@ class ChannelManager extends Manager {
2116
2776
  threads(channelId) {
2117
2777
  return new ThreadManager(this.#rest, this.#context, channelId);
2118
2778
  }
2119
- async fetch(channelId) {
2120
- return this.upsert(await this.#rest.get(Routes.channel(channelId)));
2779
+ fetch(channelId) {
2780
+ return this.fetchOnce(channelId, async () => createChannel2(await this.#rest.get(Routes.channel(channelId)), this.#context), (channel) => this.#merge(channel));
2121
2781
  }
2122
2782
  async resolve(channelId) {
2123
2783
  return this.get(channelId) ?? this.fetch(channelId);
2124
2784
  }
2125
2785
  upsert(data) {
2126
- const existing = this.get(data.id);
2127
- const channel = createChannel(data, this.#context);
2128
- if (existing) {
2786
+ return this.#merge(createChannel2(data, this.#context));
2787
+ }
2788
+ #merge(channel) {
2789
+ const existing = this.get(channel.id);
2790
+ if (existing && existing.type === channel.type) {
2129
2791
  Object.assign(existing, channel);
2130
2792
  return existing;
2131
2793
  }
@@ -2135,6 +2797,37 @@ class ChannelManager extends Manager {
2135
2797
  update(channel) {
2136
2798
  return this.set(channel.id, channel);
2137
2799
  }
2800
+ deleteGuildChannels(guildId) {
2801
+ let removed = 0;
2802
+ for (const channel of this.values())
2803
+ if (channel.guildId === guildId && this.delete(channel.id))
2804
+ removed++;
2805
+ return removed;
2806
+ }
2807
+ async endPoll(channelId, messageId) {
2808
+ return this.messages(channelId).upsert(await this.#rest.post(Routes.pollExpire(channelId, messageId)));
2809
+ }
2810
+ async fetchPollVoters(channelId, messageId, answerId, options = {}) {
2811
+ if (options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100))
2812
+ throw new RangeError("Poll voter limit must be 1-100.");
2813
+ const params = new URLSearchParams;
2814
+ if (options.after)
2815
+ params.set("after", options.after);
2816
+ if (options.limit !== undefined)
2817
+ params.set("limit", String(options.limit));
2818
+ const suffix = params.toString();
2819
+ const { users } = await this.#rest.get(`${Routes.pollAnswerVoters(channelId, messageId, answerId)}${suffix ? `?${suffix}` : ""}`);
2820
+ return users.map((user) => new User(user));
2821
+ }
2822
+ async sendSoundboardSound(channelId, options) {
2823
+ await this.#rest.post(Routes.sendSoundboardSound(channelId), {
2824
+ sound_id: options.soundId,
2825
+ source_guild_id: options.sourceGuildId
2826
+ });
2827
+ }
2828
+ cachedMessages(channelId) {
2829
+ return this.#messageManagers.get(channelId);
2830
+ }
2138
2831
  async create(guildId, options) {
2139
2832
  return this.upsert(await this.#rest.post(Routes.guildChannels(guildId), options));
2140
2833
  }
@@ -2191,15 +2884,37 @@ class ChannelManager extends Manager {
2191
2884
  return this.messages(channelId).upsert(await this.#rest.post(Routes.crosspostMessage(channelId, messageId)));
2192
2885
  }
2193
2886
  async bulkDeleteMessages(channelId, messageIds) {
2194
- const ids = [...messageIds];
2195
- if (ids.length < 2 || ids.length > 100)
2196
- throw new RangeError("bulkDelete requires between 2 and 100 message IDs.");
2887
+ const ids = [...new Set(messageIds)];
2888
+ if (ids.length < 1 || ids.length > 100)
2889
+ throw new RangeError("bulkDelete requires between 1 and 100 message IDs.");
2890
+ if (ids.length === 1)
2891
+ return this.deleteMessage(channelId, ids[0]);
2892
+ const cutoff = Date.now() - BULK_DELETE_MAX_AGE_MS;
2893
+ const tooOld = ids.filter((id) => snowflakeTime(id) < cutoff);
2894
+ if (tooOld.length)
2895
+ throw new RangeError(`bulkDelete cannot delete messages older than 14 days: ${tooOld.join(", ")}`);
2197
2896
  await this.#rest.post(Routes.channelBulkDelete(channelId), {
2198
2897
  messages: ids
2199
2898
  });
2200
2899
  for (const id of ids)
2201
2900
  this.messages(channelId).delete(id);
2202
2901
  }
2902
+ async* iterateMessages(channelId, options = {}) {
2903
+ let before = options.before;
2904
+ let remaining = options.limit ?? Infinity;
2905
+ while (remaining > 0) {
2906
+ const page = await this.fetchMessages(channelId, {
2907
+ before,
2908
+ limit: Math.min(100, remaining)
2909
+ });
2910
+ for (const message of page)
2911
+ yield message;
2912
+ remaining -= page.length;
2913
+ if (page.length < 100)
2914
+ return;
2915
+ before = page.at(-1).id;
2916
+ }
2917
+ }
2203
2918
  async addReaction(channelId, messageId, emoji) {
2204
2919
  await this.#rest.put(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
2205
2920
  }
@@ -2269,8 +2984,11 @@ export {
2269
2984
  GuildManager,
2270
2985
  GuildMemberManager,
2271
2986
  GuildScheduledEventManager,
2987
+ GuildSoundboardManager,
2988
+ GuildStickerManager,
2272
2989
  Manager,
2273
2990
  MessageManager,
2991
+ MonetizationManager,
2274
2992
  PermissionOverwriteManager,
2275
2993
  ResourceManager,
2276
2994
  RoleManager,
@@ -2279,4 +2997,4 @@ export {
2279
2997
  UserManager
2280
2998
  };
2281
2999
 
2282
- //# debugId=E5CAD3E6B2BD672164756E2164756E21
3000
+ //# debugId=DAACDF8C2AA7984564756E2164756E21