@impulsedev/chameleon 2.0.0 → 3.0.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.
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  buildGuild,
16
16
  buildIntegration,
17
17
  buildInteraction,
18
+ buildInvite,
18
19
  buildMember,
19
20
  buildMessage,
20
21
  buildRole,
@@ -24,13 +25,15 @@ import {
24
25
  buildStickerItem,
25
26
  buildUser,
26
27
  buildVoiceState,
28
+ buildWebhook,
27
29
  resolveChannel,
28
30
  resolveGuild,
29
31
  resolveRole,
30
32
  resolveUser,
31
33
  serializeComponent,
34
+ toCamelCase,
32
35
  toSnakeCase
33
- } from "./chunk-F2RRJ7OJ.js";
36
+ } from "./chunk-G4SUOXGV.js";
34
37
 
35
38
  // src/types/user/index.ts
36
39
  var UserFlag = {
@@ -602,49 +605,97 @@ var WebhookType = {
602
605
  APPLICATION: 3
603
606
  };
604
607
 
608
+ // src/utils/collection.ts
609
+ var Collection = class _Collection extends Map {
610
+ first() {
611
+ return this.values().next().value;
612
+ }
613
+ last() {
614
+ const arr = Array.from(this.values());
615
+ return arr[arr.length - 1];
616
+ }
617
+ random() {
618
+ const arr = Array.from(this.values());
619
+ return arr[Math.floor(Math.random() * arr.length)];
620
+ }
621
+ find(fn) {
622
+ for (const [key, val] of this) {
623
+ if (fn(val, key, this)) return val;
624
+ }
625
+ return void 0;
626
+ }
627
+ filter(fn) {
628
+ const results = new _Collection();
629
+ for (const [key, val] of this) {
630
+ if (fn(val, key, this)) results.set(key, val);
631
+ }
632
+ return results;
633
+ }
634
+ map(fn) {
635
+ const results = [];
636
+ for (const [key, val] of this) {
637
+ results.push(fn(val, key, this));
638
+ }
639
+ return results;
640
+ }
641
+ some(fn) {
642
+ for (const [key, val] of this) {
643
+ if (fn(val, key, this)) return true;
644
+ }
645
+ return false;
646
+ }
647
+ every(fn) {
648
+ for (const [key, val] of this) {
649
+ if (!fn(val, key, this)) return false;
650
+ }
651
+ return true;
652
+ }
653
+ reduce(fn, initialValue) {
654
+ let accumulator;
655
+ let init = false;
656
+ if (initialValue !== void 0) {
657
+ accumulator = initialValue;
658
+ init = true;
659
+ }
660
+ for (const [key, val] of this) {
661
+ if (!init) {
662
+ accumulator = val;
663
+ init = true;
664
+ } else {
665
+ accumulator = fn(accumulator, val, key, this);
666
+ }
667
+ }
668
+ return accumulator;
669
+ }
670
+ toArray() {
671
+ return Array.from(this.values());
672
+ }
673
+ };
674
+
605
675
  // src/utils/tongue.ts
606
- var Tongue = class {
607
- map;
676
+ var Tongue = class extends Collection {
608
677
  max;
609
678
  constructor(maxSize = Infinity) {
610
- this.map = /* @__PURE__ */ new Map();
679
+ super();
611
680
  this.max = maxSize;
612
681
  }
613
682
  get(key) {
614
- if (!this.map.has(key)) return void 0;
615
- const val = this.map.get(key);
616
- this.map.delete(key);
617
- this.map.set(key, val);
683
+ if (!super.has(key)) return void 0;
684
+ const val = super.get(key);
685
+ super.delete(key);
686
+ super.set(key, val);
618
687
  return val;
619
688
  }
620
689
  set(key, val) {
621
- if (this.map.has(key)) {
622
- this.map.delete(key);
623
- } else if (this.map.size >= this.max) {
624
- const firstKey = this.map.keys().next().value;
625
- if (firstKey !== void 0) this.map.delete(firstKey);
690
+ if (super.has(key)) {
691
+ super.delete(key);
692
+ } else if (this.size >= this.max) {
693
+ const firstKey = this.keys().next().value;
694
+ if (firstKey !== void 0) super.delete(firstKey);
626
695
  }
627
- this.map.set(key, val);
696
+ super.set(key, val);
628
697
  return this;
629
698
  }
630
- has(key) {
631
- return this.map.has(key);
632
- }
633
- delete(key) {
634
- return this.map.delete(key);
635
- }
636
- clear() {
637
- this.map.clear();
638
- }
639
- get size() {
640
- return this.map.size;
641
- }
642
- values() {
643
- return this.map.values();
644
- }
645
- keys() {
646
- return this.map.keys();
647
- }
648
699
  };
649
700
 
650
701
  // src/client/store.ts
@@ -661,19 +712,21 @@ var TongueStore = class {
661
712
  scheduledEvents;
662
713
  autoModRules;
663
714
  integrations;
715
+ voiceStates;
664
716
  constructor(options) {
665
- this.guilds = new Tongue(options?.guilds ?? Infinity);
666
- this.roles = new Tongue(options?.roles ?? Infinity);
667
- this.channels = new Tongue(options?.channels ?? Infinity);
717
+ this.guilds = new Tongue(options?.guilds ?? 100);
718
+ this.roles = new Tongue(options?.roles ?? 5e3);
719
+ this.channels = new Tongue(options?.channels ?? 5e3);
668
720
  this.members = new Tongue(options?.members ?? 1e3);
669
721
  this.messages = new Tongue(options?.messages ?? 100);
670
- this.users = new Tongue(options?.users ?? Infinity);
671
- this.emojis = new Tongue(options?.emojis ?? Infinity);
672
- this.stickers = new Tongue(options?.stickers ?? Infinity);
673
- this.stageInstances = new Tongue(options?.stageInstances ?? Infinity);
674
- this.scheduledEvents = new Tongue(options?.scheduledEvents ?? Infinity);
675
- this.autoModRules = new Tongue(options?.autoModRules ?? Infinity);
676
- this.integrations = new Tongue(options?.integrations ?? Infinity);
722
+ this.users = new Tongue(options?.users ?? 1e4);
723
+ this.emojis = new Tongue(options?.emojis ?? 5e3);
724
+ this.stickers = new Tongue(options?.stickers ?? 5e3);
725
+ this.stageInstances = new Tongue(options?.stageInstances ?? 1e3);
726
+ this.scheduledEvents = new Tongue(options?.scheduledEvents ?? 1e3);
727
+ this.autoModRules = new Tongue(options?.autoModRules ?? 1e3);
728
+ this.integrations = new Tongue(options?.integrations ?? 1e3);
729
+ this.voiceStates = new Tongue(options?.voiceStates ?? 5e3);
677
730
  }
678
731
  static memberKey(guildId, userId) {
679
732
  return `${guildId}_${userId}`;
@@ -695,7 +748,7 @@ var Bucket = class {
695
748
  resetTimestamp = 0;
696
749
  promiseQueue = Promise.resolve();
697
750
  async queue(fn) {
698
- return new Promise((resolve2, reject) => {
751
+ return new Promise((resolve4, reject) => {
699
752
  this.promiseQueue = this.promiseQueue.then(async () => {
700
753
  while (true) {
701
754
  if (this.remaining <= 0 && Date.now() < this.resetTimestamp) {
@@ -704,7 +757,7 @@ var Bucket = class {
704
757
  this.remaining--;
705
758
  try {
706
759
  const res = await fn();
707
- resolve2(res);
760
+ resolve4(res);
708
761
  break;
709
762
  } catch (e) {
710
763
  if (e instanceof RateLimitError) {
@@ -724,13 +777,13 @@ var RateLimiter = class {
724
777
  routeToBucket = /* @__PURE__ */ new Map();
725
778
  buckets = /* @__PURE__ */ new Map();
726
779
  getRoute(method, endpoint) {
727
- const path2 = endpoint.replace(/\/([a-z-]+)\/(?:[0-9]{17,19})/g, (match, p1) => {
780
+ const path4 = endpoint.replace(/\/([a-z-]+)\/(?:[0-9]{17,19})/g, (match, p1) => {
728
781
  if (["channels", "guilds", "webhooks"].includes(p1)) {
729
782
  return match;
730
783
  }
731
784
  return `/${p1}/:id`;
732
785
  });
733
- const reactionRoute = path2.replace(/\/reactions\/[^/]+\/?(@me|[0-9]{17,19})?/g, "/reactions/:emoji/:id");
786
+ const reactionRoute = path4.replace(/\/reactions\/[^/]+\/?(@me|[0-9]{17,19})?/g, "/reactions/:emoji/:id");
734
787
  return `${method} ${reactionRoute}`;
735
788
  }
736
789
  async execute(method, endpoint, requestFn) {
@@ -797,8 +850,8 @@ var ChameleonREST = class {
797
850
  * Internal generic request handler that doesn't throw, returning `{ ok: boolean, ... }` shape
798
851
  */
799
852
  async request(method, endpoint, body, headers) {
800
- const path2 = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
801
- const url = `${this.baseUrl}${path2}`;
853
+ const path4 = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
854
+ const url = `${this.baseUrl}${path4}`;
802
855
  const reqHeaders = {
803
856
  "Authorization": `Bot ${this.token}`,
804
857
  "User-Agent": "Chameleon (https://github.com/impulsedoes/chameleon)",
@@ -810,7 +863,7 @@ var ChameleonREST = class {
810
863
  reqBody = JSON.stringify(body);
811
864
  }
812
865
  try {
813
- const response = await this.limiter.execute(method, path2, () => fetch(url, {
866
+ const response = await this.limiter.execute(method, path4, () => fetch(url, {
814
867
  method,
815
868
  headers: reqHeaders,
816
869
  ...reqBody !== void 0 ? { body: reqBody } : {}
@@ -860,6 +913,62 @@ var ChameleonREST = class {
860
913
  delete(endpoint, headers) {
861
914
  return this.request("DELETE", endpoint, void 0, headers);
862
915
  }
916
+ async requestWithFiles(method, endpoint, body, files, headers) {
917
+ const routePath = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
918
+ const url = `${this.baseUrl}${routePath}`;
919
+ const reqHeaders = {
920
+ "Authorization": `Bot ${this.token}`,
921
+ "User-Agent": "Chameleon (https://github.com/impulsedoes/chameleon)",
922
+ ...headers
923
+ };
924
+ const formData = new FormData();
925
+ const jsonPayload = {
926
+ ...body ?? {},
927
+ attachments: files.map((f, i) => f.toAttachmentJSON(i))
928
+ };
929
+ formData.append("payload_json", JSON.stringify(jsonPayload));
930
+ for (let i = 0; i < files.length; i++) {
931
+ const file = files[i];
932
+ const uint8 = file.data instanceof Uint8Array ? file.data : new Uint8Array(file.data);
933
+ const blob = new Blob([uint8], { type: file.contentType ?? "application/octet-stream" });
934
+ formData.append(`files[${i}]`, blob, file.name);
935
+ }
936
+ try {
937
+ const response = await this.limiter.execute(method, routePath, () => fetch(url, {
938
+ method,
939
+ headers: reqHeaders,
940
+ body: formData
941
+ }));
942
+ let data = null;
943
+ if (response.status !== 204) {
944
+ const text = await response.text();
945
+ if (text) {
946
+ try {
947
+ data = JSON.parse(text);
948
+ } catch {
949
+ data = text;
950
+ }
951
+ }
952
+ }
953
+ if (response.ok) {
954
+ return { ok: true, data };
955
+ }
956
+ const errData = data;
957
+ return {
958
+ ok: false,
959
+ status: response.status,
960
+ ...typeof errData?.code === "number" ? { code: errData.code } : {},
961
+ message: typeof errData?.message === "string" ? errData.message : response.statusText,
962
+ raw: data
963
+ };
964
+ } catch (error) {
965
+ return {
966
+ ok: false,
967
+ status: 0,
968
+ message: error instanceof Error ? error.message : "Unknown network error"
969
+ };
970
+ }
971
+ }
863
972
  };
864
973
 
865
974
  // src/gateway/index.ts
@@ -1542,6 +1651,12 @@ var CommandManager = class {
1542
1651
  }
1543
1652
  this._deployCommands(commands).catch(console.error);
1544
1653
  }
1654
+ registerGuild(guildId, ...commands) {
1655
+ for (const cmd of commands) {
1656
+ this._commands.set(cmd.name, cmd);
1657
+ }
1658
+ this._deployCommands(commands, guildId).catch(console.error);
1659
+ }
1545
1660
  registerComponent(handler) {
1546
1661
  this._components.push(handler);
1547
1662
  }
@@ -1572,13 +1687,15 @@ var CommandManager = class {
1572
1687
  this.register(...commands);
1573
1688
  }
1574
1689
  }
1575
- async _deployCommands(commands) {
1690
+ async _deployCommands(commands, guildId) {
1576
1691
  const payload = commands.map((c) => this._transformCommand(c));
1577
1692
  if (this._client.user?.id) {
1578
- await this._client.rest.put(`/applications/${this._client.user.id}/commands`, payload);
1693
+ const url = guildId ? `/applications/${this._client.user.id}/guilds/${guildId}/commands` : `/applications/${this._client.user.id}/commands`;
1694
+ await this._client.rest.put(url, payload);
1579
1695
  } else {
1580
1696
  this._client.on("READY", async () => {
1581
- await this._client.rest.put(`/applications/${this._client.user.id}/commands`, payload);
1697
+ const url = guildId ? `/applications/${this._client.user.id}/guilds/${guildId}/commands` : `/applications/${this._client.user.id}/commands`;
1698
+ await this._client.rest.put(url, payload);
1582
1699
  });
1583
1700
  }
1584
1701
  }
@@ -1957,7 +2074,14 @@ var UserManager = class extends BaseManager {
1957
2074
  async createDM(userId) {
1958
2075
  const result = await this.rest.post("/users/@me/channels", { recipient_id: userId });
1959
2076
  if (!result.ok) return result;
1960
- return { ok: true, data: (await import("./builders-CCZQJXF6.js")).buildChannel(result.data) };
2077
+ return { ok: true, data: (await import("./builders-WHD6LQWX.js")).buildChannel(result.data) };
2078
+ }
2079
+ async editCurrent(payload) {
2080
+ const result = await this.rest.patch("/users/@me", toSnakeCase(payload));
2081
+ if (!result.ok) return result;
2082
+ const user = this.build(result.data);
2083
+ this.store.users.set(user.id, user);
2084
+ return { ok: true, data: user };
1961
2085
  }
1962
2086
  };
1963
2087
 
@@ -2054,6 +2178,56 @@ var MemberManager = class {
2054
2178
  this.store.members.set(cacheKey, member);
2055
2179
  return { ok: true, data: member };
2056
2180
  }
2181
+ async list(options) {
2182
+ let url = `/guilds/${this.guildId}/members`;
2183
+ if (options) {
2184
+ const params = new URLSearchParams();
2185
+ if (options.limit) params.append("limit", options.limit.toString());
2186
+ if (options.after) params.append("after", options.after);
2187
+ const qs = params.toString();
2188
+ if (qs) url += `?${qs}`;
2189
+ }
2190
+ const result = await this.rest.get(url);
2191
+ if (!result.ok) return result;
2192
+ const members = result.data.map((m) => {
2193
+ const member = buildMember(m, this.guildId, this.store);
2194
+ if (member.user) {
2195
+ this.store.members.set(TongueStore.memberKey(this.guildId, member.user.id), member);
2196
+ }
2197
+ return member;
2198
+ });
2199
+ return { ok: true, data: members };
2200
+ }
2201
+ async search(query, limit) {
2202
+ const params = new URLSearchParams({ query });
2203
+ if (limit) params.append("limit", limit.toString());
2204
+ const result = await this.rest.get(`/guilds/${this.guildId}/members/search?${params.toString()}`);
2205
+ if (!result.ok) return result;
2206
+ const members = result.data.map((m) => {
2207
+ const member = buildMember(m, this.guildId, this.store);
2208
+ if (member.user) {
2209
+ this.store.members.set(TongueStore.memberKey(this.guildId, member.user.id), member);
2210
+ }
2211
+ return member;
2212
+ });
2213
+ return { ok: true, data: members };
2214
+ }
2215
+ async addRole(userId, roleId, reason) {
2216
+ const headers = {};
2217
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2218
+ const result = await this.rest.put(`/guilds/${this.guildId}/members/${userId}/roles/${roleId}`, void 0, headers);
2219
+ return result;
2220
+ }
2221
+ async removeRole(userId, roleId, reason) {
2222
+ const headers = {};
2223
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2224
+ const result = await this.rest.delete(`/guilds/${this.guildId}/members/${userId}/roles/${roleId}`, headers);
2225
+ return result;
2226
+ }
2227
+ async timeout(userId, until, reason) {
2228
+ const isoString = until ? until instanceof Date ? until.toISOString() : new Date(until).toISOString() : null;
2229
+ return this.edit(userId, { communicationDisabledUntil: isoString }, reason);
2230
+ }
2057
2231
  };
2058
2232
 
2059
2233
  // src/managers/guild.ts
@@ -2115,6 +2289,148 @@ var GuildManager = class extends BaseManager {
2115
2289
  if (result.ok) this.store.guilds.delete(guildId);
2116
2290
  return result;
2117
2291
  }
2292
+ async listEmojis(guildId) {
2293
+ const result = await this.rest.get(`/guilds/${guildId}/emojis`);
2294
+ if (!result.ok) return result;
2295
+ const emojis = result.data.map((e) => {
2296
+ const emoji = buildEmoji(e);
2297
+ this.store.emojis.set(emoji.id, emoji);
2298
+ return emoji;
2299
+ });
2300
+ return { ok: true, data: emojis };
2301
+ }
2302
+ async fetchEmoji(guildId, emojiId) {
2303
+ const cached = this.store.emojis.get(emojiId);
2304
+ if (cached) return { ok: true, data: cached };
2305
+ const result = await this.rest.get(`/guilds/${guildId}/emojis/${emojiId}`);
2306
+ if (!result.ok) return result;
2307
+ const emoji = buildEmoji(result.data);
2308
+ this.store.emojis.set(emoji.id, emoji);
2309
+ return { ok: true, data: emoji };
2310
+ }
2311
+ async createEmoji(guildId, payload, reason) {
2312
+ const headers = {};
2313
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2314
+ const result = await this.rest.post(`/guilds/${guildId}/emojis`, toSnakeCase(payload), headers);
2315
+ if (!result.ok) return result;
2316
+ const emoji = buildEmoji(result.data);
2317
+ this.store.emojis.set(emoji.id, emoji);
2318
+ return { ok: true, data: emoji };
2319
+ }
2320
+ async editEmoji(guildId, emojiId, payload, reason) {
2321
+ const headers = {};
2322
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2323
+ const result = await this.rest.patch(`/guilds/${guildId}/emojis/${emojiId}`, toSnakeCase(payload), headers);
2324
+ if (!result.ok) return result;
2325
+ const emoji = buildEmoji(result.data);
2326
+ this.store.emojis.set(emoji.id, emoji);
2327
+ return { ok: true, data: emoji };
2328
+ }
2329
+ async deleteEmoji(guildId, emojiId, reason) {
2330
+ const headers = {};
2331
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2332
+ const result = await this.rest.delete(`/guilds/${guildId}/emojis/${emojiId}`, headers);
2333
+ if (result.ok) this.store.emojis.delete(emojiId);
2334
+ return result;
2335
+ }
2336
+ async listStickers(guildId) {
2337
+ const result = await this.rest.get(`/guilds/${guildId}/stickers`);
2338
+ if (!result.ok) return result;
2339
+ const stickers = result.data.map((s) => {
2340
+ const sticker = buildSticker(s);
2341
+ this.store.stickers.set(sticker.id, sticker);
2342
+ return sticker;
2343
+ });
2344
+ return { ok: true, data: stickers };
2345
+ }
2346
+ async fetchSticker(guildId, stickerId) {
2347
+ const cached = this.store.stickers.get(stickerId);
2348
+ if (cached) return { ok: true, data: cached };
2349
+ const result = await this.rest.get(`/guilds/${guildId}/stickers/${stickerId}`);
2350
+ if (!result.ok) return result;
2351
+ const sticker = buildSticker(result.data);
2352
+ this.store.stickers.set(sticker.id, sticker);
2353
+ return { ok: true, data: sticker };
2354
+ }
2355
+ async listBans(guildId, options) {
2356
+ let url = `/guilds/${guildId}/bans`;
2357
+ if (options) {
2358
+ const params = new URLSearchParams();
2359
+ if (options.limit) params.append("limit", options.limit.toString());
2360
+ if (options.before) params.append("before", options.before);
2361
+ if (options.after) params.append("after", options.after);
2362
+ const qs = params.toString();
2363
+ if (qs) url += `?${qs}`;
2364
+ }
2365
+ const result = await this.rest.get(url);
2366
+ if (!result.ok) return result;
2367
+ const bans = result.data.map((b) => ({
2368
+ reason: b.reason ?? null,
2369
+ user: buildUser(b.user)
2370
+ }));
2371
+ return { ok: true, data: bans };
2372
+ }
2373
+ async fetchBan(guildId, userId) {
2374
+ const result = await this.rest.get(`/guilds/${guildId}/bans/${userId}`);
2375
+ if (!result.ok) return result;
2376
+ const b = result.data;
2377
+ return {
2378
+ ok: true,
2379
+ data: { reason: b.reason ?? null, user: buildUser(b.user) }
2380
+ };
2381
+ }
2382
+ async getInvites(guildId) {
2383
+ const result = await this.rest.get(`/guilds/${guildId}/invites`);
2384
+ if (!result.ok) return result;
2385
+ const invites = result.data.map((i) => buildInvite(i));
2386
+ return { ok: true, data: invites };
2387
+ }
2388
+ async getVanityURL(guildId) {
2389
+ const result = await this.rest.get(`/guilds/${guildId}/vanity-url`);
2390
+ if (!result.ok) return result;
2391
+ const data = result.data;
2392
+ return { ok: true, data: { code: data.code ?? null, uses: data.uses ?? 0 } };
2393
+ }
2394
+ async getPruneCount(guildId, options) {
2395
+ let url = `/guilds/${guildId}/prune`;
2396
+ if (options) {
2397
+ const params = new URLSearchParams();
2398
+ if (options.days) params.append("days", options.days.toString());
2399
+ if (options.includeRoles) params.append("include_roles", options.includeRoles.join(","));
2400
+ const qs = params.toString();
2401
+ if (qs) url += `?${qs}`;
2402
+ }
2403
+ const result = await this.rest.get(url);
2404
+ if (!result.ok) return result;
2405
+ return { ok: true, data: result.data.pruned ?? 0 };
2406
+ }
2407
+ async beginPrune(guildId, options, reason) {
2408
+ const headers = {};
2409
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2410
+ const result = await this.rest.post(`/guilds/${guildId}/prune`, toSnakeCase(options ?? {}), headers);
2411
+ if (!result.ok) return result;
2412
+ return { ok: true, data: result.data.pruned ?? null };
2413
+ }
2414
+ async fetchAuditLog(guildId, options) {
2415
+ let url = `/guilds/${guildId}/audit-logs`;
2416
+ if (options) {
2417
+ const params = new URLSearchParams();
2418
+ if (options.userId) params.append("user_id", options.userId);
2419
+ if (options.actionType !== void 0) params.append("action_type", options.actionType.toString());
2420
+ if (options.before) params.append("before", options.before);
2421
+ if (options.after) params.append("after", options.after);
2422
+ if (options.limit) params.append("limit", options.limit.toString());
2423
+ const qs = params.toString();
2424
+ if (qs) url += `?${qs}`;
2425
+ }
2426
+ const result = await this.rest.get(url);
2427
+ if (!result.ok) return result;
2428
+ return { ok: true, data: toCamelCase(result.data) };
2429
+ }
2430
+ async leave(guildId) {
2431
+ const result = await this.rest.delete(`/users/@me/guilds/${guildId}`);
2432
+ return result;
2433
+ }
2118
2434
  };
2119
2435
 
2120
2436
  // src/managers/channel.ts
@@ -2149,6 +2465,35 @@ var ChannelManager = class extends BaseManager {
2149
2465
  if (result.ok) this.store.channels.delete(channelId);
2150
2466
  return result;
2151
2467
  }
2468
+ async clone(channelId, options, reason) {
2469
+ const cached = this.store.channels.get(channelId);
2470
+ if (!cached) return { ok: false, status: 404, message: "Channel not found in cache" };
2471
+ const payload = { ...options };
2472
+ if (cached.name !== void 0) payload.name = cached.name;
2473
+ if (cached.type !== void 0) payload.type = cached.type;
2474
+ if (cached.topic !== void 0) payload.topic = cached.topic;
2475
+ if (cached.bitrate !== void 0) payload.bitrate = cached.bitrate;
2476
+ if (cached.userLimit !== void 0) payload.userLimit = cached.userLimit;
2477
+ if (cached.rateLimitPerUser !== void 0) payload.rateLimitPerUser = cached.rateLimitPerUser;
2478
+ if (cached.nsfw !== void 0) payload.nsfw = cached.nsfw;
2479
+ if (cached.position !== void 0) payload.position = cached.position;
2480
+ if (cached.parentId !== void 0) payload.parentId = cached.parentId;
2481
+ if (cached.permissionOverwrites !== void 0) payload.permissionOverwrites = cached.permissionOverwrites;
2482
+ if (!cached.guildId) return { ok: false, status: 400, message: "Cannot clone a DM channel" };
2483
+ return this.create(cached.guildId, payload, reason);
2484
+ }
2485
+ async setPositions(guildId, positions, reason) {
2486
+ const headers = {};
2487
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2488
+ const payload = positions.map((p) => ({
2489
+ id: p.id,
2490
+ ...p.position !== void 0 ? { position: p.position } : {},
2491
+ ...p.lockPermissions !== void 0 ? { lock_permissions: p.lockPermissions } : {},
2492
+ ...p.parentId !== void 0 ? { parent_id: p.parentId } : {}
2493
+ }));
2494
+ const result = await this.rest.patch(`/guilds/${guildId}/channels`, payload, headers);
2495
+ return result;
2496
+ }
2152
2497
  async updatePermissions(channelId, overwriteId, payload, reason) {
2153
2498
  const headers = {};
2154
2499
  if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
@@ -2159,6 +2504,125 @@ var ChannelManager = class extends BaseManager {
2159
2504
  if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2160
2505
  return await this.rest.delete(`/channels/${channelId}/permissions/${overwriteId}`, headers);
2161
2506
  }
2507
+ async sendTyping(channelId) {
2508
+ const result = await this.rest.post(`/channels/${channelId}/typing`);
2509
+ return result;
2510
+ }
2511
+ async getInvites(channelId) {
2512
+ const result = await this.rest.get(`/channels/${channelId}/invites`);
2513
+ if (!result.ok) return result;
2514
+ const invites = result.data.map((i) => buildInvite(i));
2515
+ return { ok: true, data: invites };
2516
+ }
2517
+ async createInvite(channelId, options, reason) {
2518
+ const headers = {};
2519
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2520
+ const payload = options ? toSnakeCase(options) : {};
2521
+ const result = await this.rest.post(`/channels/${channelId}/invites`, payload, headers);
2522
+ if (!result.ok) return result;
2523
+ return { ok: true, data: buildInvite(result.data) };
2524
+ }
2525
+ async followAnnouncementChannel(channelId, webhookChannelId) {
2526
+ const result = await this.rest.post(`/channels/${channelId}/followers`, { webhook_channel_id: webhookChannelId });
2527
+ if (!result.ok) return result;
2528
+ const data = result.data;
2529
+ return { ok: true, data: { channelId: data.channel_id, webhookId: data.webhook_id } };
2530
+ }
2531
+ async createThread(channelId, options, reason) {
2532
+ const headers = {};
2533
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2534
+ const result = await this.rest.post(`/channels/${channelId}/threads`, toSnakeCase(options), headers);
2535
+ if (!result.ok) return result;
2536
+ const channel = this.build(result.data);
2537
+ this.store.channels.set(channel.id, channel);
2538
+ return { ok: true, data: channel };
2539
+ }
2540
+ async createThreadFromMessage(channelId, messageId, options, reason) {
2541
+ const headers = {};
2542
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2543
+ const result = await this.rest.post(`/channels/${channelId}/messages/${messageId}/threads`, toSnakeCase(options), headers);
2544
+ if (!result.ok) return result;
2545
+ const channel = this.build(result.data);
2546
+ this.store.channels.set(channel.id, channel);
2547
+ return { ok: true, data: channel };
2548
+ }
2549
+ async joinThread(channelId) {
2550
+ const result = await this.rest.put(`/channels/${channelId}/thread-members/@me`);
2551
+ return result;
2552
+ }
2553
+ async leaveThread(channelId) {
2554
+ const result = await this.rest.delete(`/channels/${channelId}/thread-members/@me`);
2555
+ return result;
2556
+ }
2557
+ async listActiveThreads(guildId) {
2558
+ const result = await this.rest.get(`/guilds/${guildId}/threads/active`);
2559
+ if (!result.ok) return result;
2560
+ const data = result.data;
2561
+ const threads = data.threads.map((t) => {
2562
+ const channel = this.build(t, guildId);
2563
+ this.store.channels.set(channel.id, channel);
2564
+ return channel;
2565
+ });
2566
+ return { ok: true, data: { threads, members: data.members } };
2567
+ }
2568
+ async listArchivedThreads(channelId, type, options) {
2569
+ let url = `/channels/${channelId}/threads/archived/${type}`;
2570
+ if (options) {
2571
+ const params = new URLSearchParams();
2572
+ if (options.before) params.append("before", options.before);
2573
+ if (options.limit) params.append("limit", options.limit.toString());
2574
+ const qs = params.toString();
2575
+ if (qs) url += `?${qs}`;
2576
+ }
2577
+ const result = await this.rest.get(url);
2578
+ if (!result.ok) return result;
2579
+ const data = result.data;
2580
+ const threads = data.threads.map((t) => {
2581
+ const channel = this.build(t);
2582
+ this.store.channels.set(channel.id, channel);
2583
+ return channel;
2584
+ });
2585
+ return { ok: true, data: { threads, members: data.members, hasMore: data.has_more } };
2586
+ }
2587
+ async addThreadMember(channelId, userId) {
2588
+ const result = await this.rest.put(`/channels/${channelId}/thread-members/${userId}`);
2589
+ return result;
2590
+ }
2591
+ async removeThreadMember(channelId, userId) {
2592
+ const result = await this.rest.delete(`/channels/${channelId}/thread-members/${userId}`);
2593
+ return result;
2594
+ }
2595
+ async createForumThread(channelId, options, reason) {
2596
+ const headers = {};
2597
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2598
+ const messagePayload = {};
2599
+ if (options.message.content) messagePayload.content = options.message.content;
2600
+ if (options.message.embeds) {
2601
+ messagePayload.embeds = options.message.embeds.map(
2602
+ (e) => e && typeof e.toJSON === "function" ? e.toJSON() : e
2603
+ );
2604
+ }
2605
+ if (options.message.components) {
2606
+ messagePayload.components = options.message.components.map((c) => serializeComponent(c));
2607
+ }
2608
+ const payload = {
2609
+ name: options.name,
2610
+ message: messagePayload,
2611
+ ...options.autoArchiveDuration !== void 0 ? { auto_archive_duration: options.autoArchiveDuration } : {},
2612
+ ...options.rateLimitPerUser !== void 0 ? { rate_limit_per_user: options.rateLimitPerUser } : {},
2613
+ ...options.appliedTags ? { applied_tags: options.appliedTags } : {}
2614
+ };
2615
+ let result;
2616
+ if (options.message.files && options.message.files.length > 0) {
2617
+ result = await this.rest.requestWithFiles("POST", `/channels/${channelId}/threads`, payload, options.message.files, headers);
2618
+ } else {
2619
+ result = await this.rest.post(`/channels/${channelId}/threads`, payload, headers);
2620
+ }
2621
+ if (!result.ok) return result;
2622
+ const channel = this.build(result.data);
2623
+ this.store.channels.set(channel.id, channel);
2624
+ return { ok: true, data: channel };
2625
+ }
2162
2626
  };
2163
2627
 
2164
2628
  // src/managers/message.ts
@@ -2182,6 +2646,7 @@ var MessageManager = class {
2182
2646
  }
2183
2647
  async send(channelId, payload) {
2184
2648
  const data = typeof payload === "string" ? { content: payload } : { ...payload };
2649
+ let files;
2185
2650
  if (typeof payload === "object") {
2186
2651
  if (payload.embeds) {
2187
2652
  data.embeds = payload.embeds.map((e) => e && typeof e.toJSON === "function" ? e.toJSON() : e);
@@ -2193,8 +2658,37 @@ var MessageManager = class {
2193
2658
  data.message_reference = { message_id: payload.reply.messageId, fail_if_not_exists: payload.reply.failIfNotExists ?? true };
2194
2659
  delete data.reply;
2195
2660
  }
2661
+ if (payload.poll) {
2662
+ data.poll = {
2663
+ question: payload.poll.question,
2664
+ answers: payload.poll.answers.map((a) => ({
2665
+ ...a.answerId !== void 0 ? { answer_id: a.answerId } : {},
2666
+ poll_media: a.pollMedia
2667
+ })),
2668
+ ...payload.poll.duration !== void 0 ? { duration: payload.poll.duration } : {},
2669
+ ...payload.poll.allowMultiselect !== void 0 ? { allow_multiselect: payload.poll.allowMultiselect } : {},
2670
+ ...payload.poll.layoutType !== void 0 ? { layout_type: payload.poll.layoutType } : {}
2671
+ };
2672
+ }
2673
+ if (payload.tts !== void 0) data.tts = payload.tts;
2674
+ if (payload.flags !== void 0) data.flags = payload.flags;
2675
+ if (payload.nonce !== void 0) data.nonce = payload.nonce;
2676
+ if (payload.enforceNonce !== void 0) data.enforce_nonce = payload.enforceNonce;
2677
+ if (payload.stickerIds && payload.stickerIds.length > 0) {
2678
+ data.sticker_ids = payload.stickerIds;
2679
+ delete data.stickerIds;
2680
+ }
2681
+ if (payload.files && payload.files.length > 0) {
2682
+ files = payload.files;
2683
+ delete data.files;
2684
+ }
2685
+ }
2686
+ let result;
2687
+ if (files && files.length > 0) {
2688
+ result = await this.rest.requestWithFiles("POST", `/channels/${channelId}/messages`, data, files);
2689
+ } else {
2690
+ result = await this.rest.post(`/channels/${channelId}/messages`, data);
2196
2691
  }
2197
- const result = await this.rest.post(`/channels/${channelId}/messages`, data);
2198
2692
  if (!result.ok) return result;
2199
2693
  const message = buildMessage(result.data, this.store);
2200
2694
  this.store.messages.set(message.id, message);
@@ -2202,6 +2696,7 @@ var MessageManager = class {
2202
2696
  }
2203
2697
  async edit(channelId, messageId, payload) {
2204
2698
  const data = typeof payload === "string" ? { content: payload } : { ...payload };
2699
+ let files;
2205
2700
  if (typeof payload === "object") {
2206
2701
  if (payload.embeds) {
2207
2702
  data.embeds = payload.embeds.map((e) => e && typeof e.toJSON === "function" ? e.toJSON() : e);
@@ -2209,8 +2704,17 @@ var MessageManager = class {
2209
2704
  if (payload.components) {
2210
2705
  data.components = payload.components.map((c) => serializeComponent(c));
2211
2706
  }
2707
+ if (payload.files && payload.files.length > 0) {
2708
+ files = payload.files;
2709
+ delete data.files;
2710
+ }
2711
+ }
2712
+ let result;
2713
+ if (files && files.length > 0) {
2714
+ result = await this.rest.requestWithFiles("PATCH", `/channels/${channelId}/messages/${messageId}`, data, files);
2715
+ } else {
2716
+ result = await this.rest.patch(`/channels/${channelId}/messages/${messageId}`, data);
2212
2717
  }
2213
- const result = await this.rest.patch(`/channels/${channelId}/messages/${messageId}`, data);
2214
2718
  if (!result.ok) return result;
2215
2719
  const oldMsg = this.store.messages.get(messageId);
2216
2720
  const message = buildMessage(result.data, this.store, oldMsg);
@@ -2244,43 +2748,139 @@ var MessageManager = class {
2244
2748
  });
2245
2749
  return { ok: true, data: messages };
2246
2750
  }
2247
- };
2248
-
2249
- // src/managers/collector.ts
2250
- var CollectorManager = class {
2251
- constructor(client) {
2252
- this.client = client;
2751
+ async react(channelId, messageId, emoji) {
2752
+ const encodedEmoji = encodeURIComponent(emoji);
2753
+ const result = await this.rest.put(`/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/@me`);
2754
+ return result;
2253
2755
  }
2254
- client;
2255
- /**
2256
- * Waits for a specified number of messages in a given channel that pass the filter, if the time limit
2257
- * is reached, resolves with the messages collected so far
2258
- */
2259
- async awaitMessages(channelId, options = {}) {
2260
- const { filter, max = 1, time = 15e3 } = options;
2261
- return new Promise((resolve2) => {
2262
- const messages = [];
2263
- let timeoutId = null;
2264
- const handler = (data) => {
2265
- const msg = data.message;
2266
- if (msg.channelId !== channelId) return;
2267
- if (filter && !filter(msg)) return;
2268
- messages.push(msg);
2269
- if (messages.length >= max) {
2270
- cleanup();
2271
- resolve2(messages);
2272
- }
2273
- };
2274
- const cleanup = () => {
2275
- if (timeoutId) clearTimeout(timeoutId);
2276
- this.client.off("MESSAGE_CREATE", handler);
2277
- };
2278
- this.client.on("MESSAGE_CREATE", handler);
2279
- if (time > 0) {
2280
- timeoutId = setTimeout(() => {
2281
- cleanup();
2282
- resolve2(messages);
2283
- }, time);
2756
+ async removeReaction(channelId, messageId, emoji, userId = "@me") {
2757
+ const encodedEmoji = encodeURIComponent(emoji);
2758
+ const result = await this.rest.delete(`/channels/${channelId}/messages/${messageId}/reactions/${encodedEmoji}/${userId}`);
2759
+ return result;
2760
+ }
2761
+ async removeAllReactions(channelId, messageId, emoji) {
2762
+ let url = `/channels/${channelId}/messages/${messageId}/reactions`;
2763
+ if (emoji) url += `/${encodeURIComponent(emoji)}`;
2764
+ const result = await this.rest.delete(url);
2765
+ return result;
2766
+ }
2767
+ async getReactions(channelId, messageId, emoji, options) {
2768
+ let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`;
2769
+ if (options) {
2770
+ const params = new URLSearchParams();
2771
+ if (options.after) params.append("after", options.after);
2772
+ if (options.limit) params.append("limit", options.limit.toString());
2773
+ if (options.type !== void 0) params.append("type", options.type.toString());
2774
+ const qs = params.toString();
2775
+ if (qs) url += `?${qs}`;
2776
+ }
2777
+ const result = await this.rest.get(url);
2778
+ if (!result.ok) return result;
2779
+ const users = result.data.map((userData) => {
2780
+ const user = buildUser(userData);
2781
+ this.store.users.set(user.id, user);
2782
+ return user;
2783
+ });
2784
+ return { ok: true, data: users };
2785
+ }
2786
+ async pin(channelId, messageId) {
2787
+ const result = await this.rest.put(`/channels/${channelId}/pins/${messageId}`);
2788
+ return result;
2789
+ }
2790
+ async unpin(channelId, messageId) {
2791
+ const result = await this.rest.delete(`/channels/${channelId}/pins/${messageId}`);
2792
+ return result;
2793
+ }
2794
+ async getPins(channelId) {
2795
+ const result = await this.rest.get(`/channels/${channelId}/pins`);
2796
+ if (!result.ok) return result;
2797
+ const messages = result.data.map((msgData) => {
2798
+ const msg = buildMessage(msgData, this.store);
2799
+ this.store.messages.set(msg.id, msg);
2800
+ return msg;
2801
+ });
2802
+ return { ok: true, data: messages };
2803
+ }
2804
+ async bulkDelete(channelId, messageIds) {
2805
+ const result = await this.rest.post(`/channels/${channelId}/messages/bulk-delete`, { messages: messageIds });
2806
+ if (result.ok) {
2807
+ for (const id of messageIds) {
2808
+ this.store.messages.delete(id);
2809
+ }
2810
+ }
2811
+ return result;
2812
+ }
2813
+ async forward(channelId, messageId) {
2814
+ const result = await this.rest.post(`/channels/${channelId}/messages/${messageId}/crosspost`);
2815
+ if (!result.ok) return result;
2816
+ const oldMsg = this.store.messages.get(messageId);
2817
+ const message = buildMessage(result.data, this.store, oldMsg);
2818
+ this.store.messages.set(message.id, message);
2819
+ return { ok: true, data: message };
2820
+ }
2821
+ async endPoll(channelId, messageId) {
2822
+ const result = await this.rest.post(`/channels/${channelId}/polls/${messageId}/expire`);
2823
+ if (!result.ok) return result;
2824
+ const message = buildMessage(result.data, this.store);
2825
+ this.store.messages.set(message.id, message);
2826
+ return { ok: true, data: message };
2827
+ }
2828
+ async getPollAnswerVoters(channelId, messageId, answerId, options) {
2829
+ let url = `/channels/${channelId}/polls/${messageId}/answers/${answerId}`;
2830
+ if (options) {
2831
+ const params = new URLSearchParams();
2832
+ if (options.after) params.append("after", options.after);
2833
+ if (options.limit) params.append("limit", options.limit.toString());
2834
+ const qs = params.toString();
2835
+ if (qs) url += `?${qs}`;
2836
+ }
2837
+ const result = await this.rest.get(url);
2838
+ if (!result.ok) return result;
2839
+ const data = result.data;
2840
+ const users = data.users.map((u) => {
2841
+ const user = buildUser(u);
2842
+ this.store.users.set(user.id, user);
2843
+ return user;
2844
+ });
2845
+ return { ok: true, data: users };
2846
+ }
2847
+ };
2848
+
2849
+ // src/managers/collector.ts
2850
+ var CollectorManager = class {
2851
+ constructor(client) {
2852
+ this.client = client;
2853
+ }
2854
+ client;
2855
+ /**
2856
+ * Waits for a specified number of messages in a given channel that pass the filter, if the time limit
2857
+ * is reached, resolves with the messages collected so far
2858
+ */
2859
+ async awaitMessages(channelId, options = {}) {
2860
+ const { filter, max = 1, time = 15e3 } = options;
2861
+ return new Promise((resolve4) => {
2862
+ const messages = [];
2863
+ let timeoutId = null;
2864
+ const handler = (data) => {
2865
+ const msg = data.message;
2866
+ if (msg.channelId !== channelId) return;
2867
+ if (filter && !filter(msg)) return;
2868
+ messages.push(msg);
2869
+ if (messages.length >= max) {
2870
+ cleanup();
2871
+ resolve4(messages);
2872
+ }
2873
+ };
2874
+ const cleanup = () => {
2875
+ if (timeoutId) clearTimeout(timeoutId);
2876
+ this.client.off("MESSAGE_CREATE", handler);
2877
+ };
2878
+ this.client.on("MESSAGE_CREATE", handler);
2879
+ if (time > 0) {
2880
+ timeoutId = setTimeout(() => {
2881
+ cleanup();
2882
+ resolve4(messages);
2883
+ }, time);
2284
2884
  }
2285
2885
  });
2286
2886
  }
@@ -2290,7 +2890,7 @@ var CollectorManager = class {
2290
2890
  */
2291
2891
  async awaitComponent(messageId, options = {}) {
2292
2892
  const { filter, time = 15e3 } = options;
2293
- return new Promise((resolve2) => {
2893
+ return new Promise((resolve4) => {
2294
2894
  let timeoutId = null;
2295
2895
  const handler = (data) => {
2296
2896
  if (data.type !== "INTERACTION_CREATE") return;
@@ -2309,7 +2909,7 @@ var CollectorManager = class {
2309
2909
  );
2310
2910
  if (filter && !filter(ctx)) return;
2311
2911
  cleanup();
2312
- resolve2(ctx);
2912
+ resolve4(ctx);
2313
2913
  };
2314
2914
  const cleanup = () => {
2315
2915
  if (timeoutId) clearTimeout(timeoutId);
@@ -2319,13 +2919,539 @@ var CollectorManager = class {
2319
2919
  if (time > 0) {
2320
2920
  timeoutId = setTimeout(() => {
2321
2921
  cleanup();
2322
- resolve2(null);
2922
+ resolve4(null);
2323
2923
  }, time);
2324
2924
  }
2325
2925
  });
2326
2926
  }
2327
2927
  };
2328
2928
 
2929
+ // src/managers/webhook.ts
2930
+ var WebhookManager = class {
2931
+ constructor(rest, store) {
2932
+ this.rest = rest;
2933
+ this.store = store;
2934
+ }
2935
+ rest;
2936
+ store;
2937
+ async fetch(webhookId, token) {
2938
+ const url = token ? `/webhooks/${webhookId}/${token}` : `/webhooks/${webhookId}`;
2939
+ const result = await this.rest.get(url);
2940
+ if (!result.ok) return result;
2941
+ return { ok: true, data: buildWebhook(result.data) };
2942
+ }
2943
+ async fetchByChannel(channelId) {
2944
+ const result = await this.rest.get(`/channels/${channelId}/webhooks`);
2945
+ if (!result.ok) return result;
2946
+ const webhooks = result.data.map((w) => buildWebhook(w));
2947
+ return { ok: true, data: webhooks };
2948
+ }
2949
+ async fetchByGuild(guildId) {
2950
+ const result = await this.rest.get(`/guilds/${guildId}/webhooks`);
2951
+ if (!result.ok) return result;
2952
+ const webhooks = result.data.map((w) => buildWebhook(w));
2953
+ return { ok: true, data: webhooks };
2954
+ }
2955
+ async create(channelId, payload, reason) {
2956
+ const headers = {};
2957
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2958
+ const result = await this.rest.post(`/channels/${channelId}/webhooks`, toSnakeCase(payload), headers);
2959
+ if (!result.ok) return result;
2960
+ return { ok: true, data: buildWebhook(result.data) };
2961
+ }
2962
+ async edit(webhookId, payload, token, reason) {
2963
+ const headers = {};
2964
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2965
+ const url = token ? `/webhooks/${webhookId}/${token}` : `/webhooks/${webhookId}`;
2966
+ const result = await this.rest.patch(url, toSnakeCase(payload), headers);
2967
+ if (!result.ok) return result;
2968
+ return { ok: true, data: buildWebhook(result.data) };
2969
+ }
2970
+ async delete(webhookId, token, reason) {
2971
+ const headers = {};
2972
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
2973
+ const url = token ? `/webhooks/${webhookId}/${token}` : `/webhooks/${webhookId}`;
2974
+ const result = await this.rest.delete(url, headers);
2975
+ return result;
2976
+ }
2977
+ async execute(webhookId, token, payload, options) {
2978
+ const data = typeof payload === "string" ? { content: payload } : { ...toSnakeCase(payload) };
2979
+ let files;
2980
+ if (typeof payload === "object") {
2981
+ if (payload.embeds) {
2982
+ data.embeds = payload.embeds.map((e) => e && typeof e.toJSON === "function" ? e.toJSON() : e);
2983
+ }
2984
+ if (payload.components) {
2985
+ data.components = payload.components.map((c) => serializeComponent(c));
2986
+ }
2987
+ if (payload.poll) {
2988
+ data.poll = {
2989
+ question: payload.poll.question,
2990
+ answers: payload.poll.answers.map((a) => ({
2991
+ ...a.answerId !== void 0 ? { answer_id: a.answerId } : {},
2992
+ poll_media: a.pollMedia
2993
+ })),
2994
+ ...payload.poll.duration !== void 0 ? { duration: payload.poll.duration } : {},
2995
+ ...payload.poll.allowMultiselect !== void 0 ? { allow_multiselect: payload.poll.allowMultiselect } : {},
2996
+ ...payload.poll.layoutType !== void 0 ? { layout_type: payload.poll.layoutType } : {}
2997
+ };
2998
+ }
2999
+ if (payload.files && payload.files.length > 0) {
3000
+ files = payload.files;
3001
+ delete data.files;
3002
+ }
3003
+ }
3004
+ let url = `/webhooks/${webhookId}/${token}`;
3005
+ const params = new URLSearchParams();
3006
+ if (options?.wait) params.append("wait", "true");
3007
+ if (options?.threadId) params.append("thread_id", options.threadId);
3008
+ const qs = params.toString();
3009
+ if (qs) url += `?${qs}`;
3010
+ let result;
3011
+ if (files && files.length > 0) {
3012
+ result = await this.rest.requestWithFiles("POST", url, data, files);
3013
+ } else {
3014
+ result = await this.rest.post(url, data);
3015
+ }
3016
+ if (!result.ok) return result;
3017
+ if (options?.wait && result.data) {
3018
+ const message = buildMessage(result.data, this.store);
3019
+ this.store.messages.set(message.id, message);
3020
+ return { ok: true, data: message };
3021
+ }
3022
+ return { ok: true, data: void 0 };
3023
+ }
3024
+ };
3025
+
3026
+ // src/managers/invite.ts
3027
+ var InviteManager = class {
3028
+ constructor(rest) {
3029
+ this.rest = rest;
3030
+ }
3031
+ rest;
3032
+ async fetch(code, options) {
3033
+ let url = `/invites/${code}`;
3034
+ if (options) {
3035
+ const params = new URLSearchParams();
3036
+ if (options.withCounts) params.append("with_counts", "true");
3037
+ if (options.withExpiration) params.append("with_expiration", "true");
3038
+ if (options.guildScheduledEventId) params.append("guild_scheduled_event_id", options.guildScheduledEventId);
3039
+ const qs = params.toString();
3040
+ if (qs) url += `?${qs}`;
3041
+ }
3042
+ const result = await this.rest.get(url);
3043
+ if (!result.ok) return result;
3044
+ return { ok: true, data: buildInvite(result.data) };
3045
+ }
3046
+ async delete(code, reason) {
3047
+ const headers = {};
3048
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3049
+ const result = await this.rest.delete(`/invites/${code}`, headers);
3050
+ if (!result.ok) return result;
3051
+ return { ok: true, data: buildInvite(result.data) };
3052
+ }
3053
+ };
3054
+
3055
+ // src/managers/automod.ts
3056
+ var AutoModerationManager = class {
3057
+ constructor(rest, store) {
3058
+ this.rest = rest;
3059
+ this.store = store;
3060
+ }
3061
+ rest;
3062
+ store;
3063
+ async list(guildId) {
3064
+ const result = await this.rest.get(`/guilds/${guildId}/auto-moderation/rules`);
3065
+ if (!result.ok) return result;
3066
+ const rules = result.data.map((r) => {
3067
+ const rule = buildAutoModRule(r);
3068
+ this.store.autoModRules.set(rule.id, rule);
3069
+ return rule;
3070
+ });
3071
+ return { ok: true, data: rules };
3072
+ }
3073
+ async fetch(guildId, ruleId) {
3074
+ const cached = this.store.autoModRules.get(ruleId);
3075
+ if (cached) return { ok: true, data: cached };
3076
+ const result = await this.rest.get(`/guilds/${guildId}/auto-moderation/rules/${ruleId}`);
3077
+ if (!result.ok) return result;
3078
+ const rule = buildAutoModRule(result.data);
3079
+ this.store.autoModRules.set(rule.id, rule);
3080
+ return { ok: true, data: rule };
3081
+ }
3082
+ async create(guildId, payload, reason) {
3083
+ const headers = {};
3084
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3085
+ const result = await this.rest.post(`/guilds/${guildId}/auto-moderation/rules`, toSnakeCase(payload), headers);
3086
+ if (!result.ok) return result;
3087
+ const rule = buildAutoModRule(result.data);
3088
+ this.store.autoModRules.set(rule.id, rule);
3089
+ return { ok: true, data: rule };
3090
+ }
3091
+ async edit(guildId, ruleId, payload, reason) {
3092
+ const headers = {};
3093
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3094
+ const result = await this.rest.patch(`/guilds/${guildId}/auto-moderation/rules/${ruleId}`, toSnakeCase(payload), headers);
3095
+ if (!result.ok) return result;
3096
+ const rule = buildAutoModRule(result.data);
3097
+ this.store.autoModRules.set(rule.id, rule);
3098
+ return { ok: true, data: rule };
3099
+ }
3100
+ async delete(guildId, ruleId, reason) {
3101
+ const headers = {};
3102
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3103
+ const result = await this.rest.delete(`/guilds/${guildId}/auto-moderation/rules/${ruleId}`, headers);
3104
+ if (result.ok) this.store.autoModRules.delete(ruleId);
3105
+ return result;
3106
+ }
3107
+ };
3108
+
3109
+ // src/managers/scheduled.ts
3110
+ var ScheduledEventManager = class {
3111
+ constructor(rest, store) {
3112
+ this.rest = rest;
3113
+ this.store = store;
3114
+ }
3115
+ rest;
3116
+ store;
3117
+ async list(guildId, withUserCount) {
3118
+ let url = `/guilds/${guildId}/scheduled-events`;
3119
+ if (withUserCount) url += "?with_user_count=true";
3120
+ const result = await this.rest.get(url);
3121
+ if (!result.ok) return result;
3122
+ const events = result.data.map((e) => {
3123
+ const event = buildScheduledEvent(e);
3124
+ this.store.scheduledEvents.set(event.id, event);
3125
+ return event;
3126
+ });
3127
+ return { ok: true, data: events };
3128
+ }
3129
+ async fetch(guildId, eventId, withUserCount) {
3130
+ const cached = this.store.scheduledEvents.get(eventId);
3131
+ if (cached && !withUserCount) return { ok: true, data: cached };
3132
+ let url = `/guilds/${guildId}/scheduled-events/${eventId}`;
3133
+ if (withUserCount) url += "?with_user_count=true";
3134
+ const result = await this.rest.get(url);
3135
+ if (!result.ok) return result;
3136
+ const event = buildScheduledEvent(result.data);
3137
+ this.store.scheduledEvents.set(event.id, event);
3138
+ return { ok: true, data: event };
3139
+ }
3140
+ async create(guildId, payload, reason) {
3141
+ const headers = {};
3142
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3143
+ const result = await this.rest.post(`/guilds/${guildId}/scheduled-events`, toSnakeCase(payload), headers);
3144
+ if (!result.ok) return result;
3145
+ const event = buildScheduledEvent(result.data);
3146
+ this.store.scheduledEvents.set(event.id, event);
3147
+ return { ok: true, data: event };
3148
+ }
3149
+ async edit(guildId, eventId, payload, reason) {
3150
+ const headers = {};
3151
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3152
+ const result = await this.rest.patch(`/guilds/${guildId}/scheduled-events/${eventId}`, toSnakeCase(payload), headers);
3153
+ if (!result.ok) return result;
3154
+ const event = buildScheduledEvent(result.data);
3155
+ this.store.scheduledEvents.set(event.id, event);
3156
+ return { ok: true, data: event };
3157
+ }
3158
+ async delete(guildId, eventId) {
3159
+ const result = await this.rest.delete(`/guilds/${guildId}/scheduled-events/${eventId}`);
3160
+ if (result.ok) this.store.scheduledEvents.delete(eventId);
3161
+ return result;
3162
+ }
3163
+ async getUsers(guildId, eventId, options) {
3164
+ let url = `/guilds/${guildId}/scheduled-events/${eventId}/users`;
3165
+ if (options) {
3166
+ const params = new URLSearchParams();
3167
+ if (options.limit) params.append("limit", options.limit.toString());
3168
+ if (options.withMember) params.append("with_member", "true");
3169
+ if (options.before) params.append("before", options.before);
3170
+ if (options.after) params.append("after", options.after);
3171
+ const qs = params.toString();
3172
+ if (qs) url += `?${qs}`;
3173
+ }
3174
+ const result = await this.rest.get(url);
3175
+ if (!result.ok) return result;
3176
+ const users = result.data.map((data) => {
3177
+ return {
3178
+ guildScheduledEventId: data.guild_scheduled_event_id,
3179
+ user: buildUser(data.user),
3180
+ member: data.member
3181
+ };
3182
+ });
3183
+ return { ok: true, data: users };
3184
+ }
3185
+ };
3186
+
3187
+ // src/managers/entitlement.ts
3188
+ var EntitlementManager = class {
3189
+ constructor(rest, store) {
3190
+ this.rest = rest;
3191
+ this.store = store;
3192
+ }
3193
+ rest;
3194
+ store;
3195
+ async list(applicationId, options) {
3196
+ let url = `/applications/${applicationId}/entitlements`;
3197
+ if (options) {
3198
+ const params = new URLSearchParams();
3199
+ if (options.userId) params.append("user_id", options.userId);
3200
+ if (options.skuIds) params.append("sku_ids", options.skuIds.join(","));
3201
+ if (options.before) params.append("before", options.before);
3202
+ if (options.after) params.append("after", options.after);
3203
+ if (options.limit) params.append("limit", options.limit.toString());
3204
+ if (options.guildId) params.append("guild_id", options.guildId);
3205
+ if (options.excludeEnded) params.append("exclude_ended", "true");
3206
+ const qs = params.toString();
3207
+ if (qs) url += `?${qs}`;
3208
+ }
3209
+ const result = await this.rest.get(url);
3210
+ if (!result.ok) return result;
3211
+ const entitlements = result.data.map((e) => buildEntitlement(e));
3212
+ return { ok: true, data: entitlements };
3213
+ }
3214
+ async fetch(applicationId, entitlementId) {
3215
+ const result = await this.rest.get(`/applications/${applicationId}/entitlements/${entitlementId}`);
3216
+ if (!result.ok) return result;
3217
+ return { ok: true, data: buildEntitlement(result.data) };
3218
+ }
3219
+ async createTest(applicationId, payload) {
3220
+ const result = await this.rest.post(`/applications/${applicationId}/entitlements`, toSnakeCase(payload));
3221
+ if (!result.ok) return result;
3222
+ return { ok: true, data: buildEntitlement(result.data) };
3223
+ }
3224
+ async deleteTest(applicationId, entitlementId) {
3225
+ const result = await this.rest.delete(`/applications/${applicationId}/entitlements/${entitlementId}`);
3226
+ return result;
3227
+ }
3228
+ };
3229
+
3230
+ // src/managers/stage.ts
3231
+ var StageInstanceManager = class {
3232
+ constructor(rest, store) {
3233
+ this.rest = rest;
3234
+ this.store = store;
3235
+ }
3236
+ rest;
3237
+ store;
3238
+ async fetch(channelId) {
3239
+ const cached = Array.from(this.store.stageInstances.values()).find((s) => s.channelId === channelId);
3240
+ if (cached) return { ok: true, data: cached };
3241
+ const result = await this.rest.get(`/stage-instances/${channelId}`);
3242
+ if (!result.ok) return result;
3243
+ const stage = buildStageInstance(result.data);
3244
+ this.store.stageInstances.set(stage.id, stage);
3245
+ return { ok: true, data: stage };
3246
+ }
3247
+ async create(payload, reason) {
3248
+ const headers = {};
3249
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3250
+ const result = await this.rest.post(`/stage-instances`, toSnakeCase(payload), headers);
3251
+ if (!result.ok) return result;
3252
+ const stage = buildStageInstance(result.data);
3253
+ this.store.stageInstances.set(stage.id, stage);
3254
+ return { ok: true, data: stage };
3255
+ }
3256
+ async edit(channelId, payload, reason) {
3257
+ const headers = {};
3258
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3259
+ const result = await this.rest.patch(`/stage-instances/${channelId}`, toSnakeCase(payload), headers);
3260
+ if (!result.ok) return result;
3261
+ const stage = buildStageInstance(result.data);
3262
+ this.store.stageInstances.set(stage.id, stage);
3263
+ return { ok: true, data: stage };
3264
+ }
3265
+ async delete(channelId, reason) {
3266
+ const headers = {};
3267
+ if (reason) headers["X-Audit-Log-Reason"] = encodeURIComponent(reason);
3268
+ const result = await this.rest.delete(`/stage-instances/${channelId}`, headers);
3269
+ if (result.ok) {
3270
+ const cached = Array.from(this.store.stageInstances.values()).find((s) => s.channelId === channelId);
3271
+ if (cached) this.store.stageInstances.delete(cached.id);
3272
+ }
3273
+ return result;
3274
+ }
3275
+ };
3276
+
3277
+ // src/managers/template.ts
3278
+ var TemplateManager = class {
3279
+ constructor(rest) {
3280
+ this.rest = rest;
3281
+ }
3282
+ rest;
3283
+ async fetch(code) {
3284
+ const result = await this.rest.get(`/guilds/templates/${code}`);
3285
+ if (!result.ok) return result;
3286
+ return { ok: true, data: toCamelCase(result.data) };
3287
+ }
3288
+ async createGuildFromTemplate(code, payload) {
3289
+ const result = await this.rest.post(`/guilds/templates/${code}`, toSnakeCase(payload));
3290
+ return result;
3291
+ }
3292
+ async list(guildId) {
3293
+ const result = await this.rest.get(`/guilds/${guildId}/templates`);
3294
+ if (!result.ok) return result;
3295
+ return { ok: true, data: result.data.map((t) => toCamelCase(t)) };
3296
+ }
3297
+ async create(guildId, payload) {
3298
+ const result = await this.rest.post(`/guilds/${guildId}/templates`, toSnakeCase(payload));
3299
+ if (!result.ok) return result;
3300
+ return { ok: true, data: toCamelCase(result.data) };
3301
+ }
3302
+ async sync(guildId, code) {
3303
+ const result = await this.rest.put(`/guilds/${guildId}/templates/${code}`);
3304
+ if (!result.ok) return result;
3305
+ return { ok: true, data: toCamelCase(result.data) };
3306
+ }
3307
+ async edit(guildId, code, payload) {
3308
+ const result = await this.rest.patch(`/guilds/${guildId}/templates/${code}`, toSnakeCase(payload));
3309
+ if (!result.ok) return result;
3310
+ return { ok: true, data: toCamelCase(result.data) };
3311
+ }
3312
+ async delete(guildId, code) {
3313
+ const result = await this.rest.delete(`/guilds/${guildId}/templates/${code}`);
3314
+ if (!result.ok) return result;
3315
+ return { ok: true, data: toCamelCase(result.data) };
3316
+ }
3317
+ };
3318
+
3319
+ // src/managers/application.ts
3320
+ var ApplicationManager = class {
3321
+ constructor(rest, _client) {
3322
+ this.rest = rest;
3323
+ this._client = _client;
3324
+ }
3325
+ rest;
3326
+ _client;
3327
+ async fetch() {
3328
+ const result = await this.rest.get("/oauth2/applications/@me");
3329
+ if (!result.ok) return result;
3330
+ return { ok: true, data: result.data };
3331
+ }
3332
+ async fetchRoleConnectionMetadata() {
3333
+ if (!this._client.user?.id) {
3334
+ return { ok: false, status: 400, message: "Client not ready" };
3335
+ }
3336
+ const result = await this.rest.get(`/applications/${this._client.user.id}/role-connections/metadata`);
3337
+ if (!result.ok) return result;
3338
+ return { ok: true, data: result.data };
3339
+ }
3340
+ async editRoleConnectionMetadata(records) {
3341
+ if (!this._client.user?.id) {
3342
+ return { ok: false, status: 400, message: "Client not ready" };
3343
+ }
3344
+ const result = await this.rest.put(`/applications/${this._client.user.id}/role-connections/metadata`, records);
3345
+ if (!result.ok) return result;
3346
+ return { ok: true, data: result.data };
3347
+ }
3348
+ };
3349
+
3350
+ // src/builders/attachment.ts
3351
+ import * as fs2 from "fs";
3352
+ import * as path2 from "path";
3353
+ var AttachmentBuilder = class {
3354
+ name;
3355
+ data;
3356
+ description;
3357
+ contentType;
3358
+ constructor(data, options) {
3359
+ if (typeof data === "string") {
3360
+ const resolved = path2.resolve(data);
3361
+ this.data = fs2.readFileSync(resolved);
3362
+ this.name = options?.name ?? path2.basename(resolved);
3363
+ } else {
3364
+ this.data = data;
3365
+ this.name = options?.name ?? "file.bin";
3366
+ }
3367
+ if (options?.description !== void 0) this.description = options.description;
3368
+ if (options?.contentType !== void 0) this.contentType = options.contentType;
3369
+ }
3370
+ setName(name) {
3371
+ this.name = name;
3372
+ return this;
3373
+ }
3374
+ setDescription(description) {
3375
+ this.description = description;
3376
+ return this;
3377
+ }
3378
+ toAttachmentJSON(index) {
3379
+ return {
3380
+ id: index,
3381
+ filename: this.name,
3382
+ ...this.description ? { description: this.description } : {}
3383
+ };
3384
+ }
3385
+ };
3386
+
3387
+ // src/managers/soundboard.ts
3388
+ var SoundboardManager = class {
3389
+ constructor(rest) {
3390
+ this.rest = rest;
3391
+ }
3392
+ rest;
3393
+ async send(channelId, soundId, sourceGuildId) {
3394
+ const payload = {
3395
+ sound_id: soundId
3396
+ };
3397
+ if (sourceGuildId !== void 0) payload.source_guild_id = sourceGuildId;
3398
+ const result = await this.rest.post(`/channels/${channelId}/send-soundboard-sound`, payload);
3399
+ return result;
3400
+ }
3401
+ async fetchDefault() {
3402
+ const result = await this.rest.get("/soundboard-default-sounds");
3403
+ if (!result.ok) return result;
3404
+ return { ok: true, data: result.data };
3405
+ }
3406
+ async fetch(guildId, soundId) {
3407
+ if (soundId) {
3408
+ const result = await this.rest.get(`/guilds/${guildId}/soundboard-sounds/${soundId}`);
3409
+ if (!result.ok) return result;
3410
+ return { ok: true, data: result.data };
3411
+ } else {
3412
+ const result = await this.rest.get(`/guilds/${guildId}/soundboard-sounds`);
3413
+ if (!result.ok) return result;
3414
+ return { ok: true, data: result.data.items };
3415
+ }
3416
+ }
3417
+ async create(guildId, options, reason) {
3418
+ let soundData = options.sound;
3419
+ if (options.sound instanceof AttachmentBuilder) {
3420
+ soundData = `data:${options.sound.contentType ?? "audio/ogg"};base64,${Buffer.from(options.sound.data).toString("base64")}`;
3421
+ }
3422
+ const payload = {
3423
+ name: options.name,
3424
+ sound: soundData
3425
+ };
3426
+ if (options.volume !== void 0) payload.volume = options.volume;
3427
+ if (options.emojiId !== void 0) payload.emoji_id = options.emojiId;
3428
+ if (options.emojiName !== void 0) payload.emoji_name = options.emojiName;
3429
+ const headers = {};
3430
+ if (reason) headers["X-Audit-Log-Reason"] = reason;
3431
+ const result = await this.rest.post(`/guilds/${guildId}/soundboard-sounds`, payload, headers);
3432
+ if (!result.ok) return result;
3433
+ return { ok: true, data: result.data };
3434
+ }
3435
+ async edit(guildId, soundId, options, reason) {
3436
+ const payload = {};
3437
+ if (options.name !== void 0) payload.name = options.name;
3438
+ if (options.volume !== void 0) payload.volume = options.volume;
3439
+ if (options.emojiId !== void 0) payload.emoji_id = options.emojiId;
3440
+ if (options.emojiName !== void 0) payload.emoji_name = options.emojiName;
3441
+ const headers = {};
3442
+ if (reason) headers["X-Audit-Log-Reason"] = reason;
3443
+ const result = await this.rest.patch(`/guilds/${guildId}/soundboard-sounds/${soundId}`, payload, headers);
3444
+ if (!result.ok) return result;
3445
+ return { ok: true, data: result.data };
3446
+ }
3447
+ async delete(guildId, soundId, reason) {
3448
+ const headers = {};
3449
+ if (reason) headers["X-Audit-Log-Reason"] = reason;
3450
+ const result = await this.rest.delete(`/guilds/${guildId}/soundboard-sounds/${soundId}`, headers);
3451
+ return result;
3452
+ }
3453
+ };
3454
+
2329
3455
  // src/client/client.ts
2330
3456
  var Client = class {
2331
3457
  token;
@@ -2347,6 +3473,15 @@ var Client = class {
2347
3473
  channels;
2348
3474
  messages;
2349
3475
  collectors;
3476
+ webhooks;
3477
+ invites;
3478
+ autoMod;
3479
+ scheduledEvents;
3480
+ entitlements;
3481
+ stageInstances;
3482
+ templates;
3483
+ application;
3484
+ soundboard;
2350
3485
  listeners = /* @__PURE__ */ new Map();
2351
3486
  middlewares = [];
2352
3487
  constructor(options) {
@@ -2363,6 +3498,16 @@ var Client = class {
2363
3498
  this.channels = new ChannelManager(this.rest, this.cache);
2364
3499
  this.messages = new MessageManager(this.rest, this.cache);
2365
3500
  this.collectors = new CollectorManager(this);
3501
+ this.webhooks = new WebhookManager(this.rest, this.cache);
3502
+ this.invites = new InviteManager(this.rest);
3503
+ this.autoMod = new AutoModerationManager(this.rest, this.cache);
3504
+ this.scheduledEvents = new ScheduledEventManager(this.rest, this.cache);
3505
+ this.entitlements = new EntitlementManager(this.rest, this.cache);
3506
+ this.stageInstances = new StageInstanceManager(this.rest, this.cache);
3507
+ this.templates = new TemplateManager(this.rest);
3508
+ this.application = new ApplicationManager(this.rest, this);
3509
+ this.soundboard = new SoundboardManager(this.rest);
3510
+ this.gateway = new ChameleonGateway({ token: this.token, intents: this.intents });
2366
3511
  let shards = [0];
2367
3512
  let totalShards = 1;
2368
3513
  if (options.sharding === "auto") {
@@ -2890,9 +4035,20 @@ var Client = class {
2890
4035
  break;
2891
4036
  }
2892
4037
  case "VOICE_STATE_UPDATE": {
4038
+ const guildId = d.guild_id;
4039
+ const userId = d.user_id;
4040
+ const key = guildId ? TongueStore.memberKey(guildId, userId) : userId;
4041
+ const oldVoiceState = this.cache.voiceStates.get(key);
4042
+ const voiceState = buildVoiceState(d, this.cache);
4043
+ if (!d.channel_id) {
4044
+ this.cache.voiceStates.delete(key);
4045
+ } else {
4046
+ this.cache.voiceStates.set(key, voiceState);
4047
+ }
2893
4048
  this.dispatch("VOICE_STATE_UPDATE", {
2894
4049
  type: "VOICE_STATE_UPDATE",
2895
- voiceState: buildVoiceState(d, this.cache)
4050
+ voiceState,
4051
+ ...oldVoiceState ? { oldVoiceState } : {}
2896
4052
  });
2897
4053
  break;
2898
4054
  }
@@ -3254,6 +4410,301 @@ var Chameleon = class {
3254
4410
  };
3255
4411
  }
3256
4412
  };
4413
+
4414
+ // src/utils/bitfield.ts
4415
+ var BitField = class _BitField {
4416
+ static FLAGS = {};
4417
+ bitfield;
4418
+ constructor(bits = 0n) {
4419
+ this.bitfield = this.constructor.resolve(bits);
4420
+ }
4421
+ has(bit) {
4422
+ const resolved = this.constructor.resolve(bit);
4423
+ return (this.bitfield & resolved) === resolved;
4424
+ }
4425
+ any(bit) {
4426
+ const resolved = this.constructor.resolve(bit);
4427
+ return (this.bitfield & resolved) !== 0n;
4428
+ }
4429
+ add(...bits) {
4430
+ let total = 0n;
4431
+ for (const bit of bits) {
4432
+ total |= this.constructor.resolve(bit);
4433
+ }
4434
+ this.bitfield |= total;
4435
+ return this;
4436
+ }
4437
+ remove(...bits) {
4438
+ let total = 0n;
4439
+ for (const bit of bits) {
4440
+ total |= this.constructor.resolve(bit);
4441
+ }
4442
+ this.bitfield &= ~total;
4443
+ return this;
4444
+ }
4445
+ toArray() {
4446
+ const flags = this.constructor.FLAGS;
4447
+ return Object.keys(flags).filter((flag) => this.has(flags[flag]));
4448
+ }
4449
+ serialize() {
4450
+ const flags = this.constructor.FLAGS;
4451
+ const result = {};
4452
+ for (const [flag, value] of Object.entries(flags)) {
4453
+ result[flag] = this.has(value);
4454
+ }
4455
+ return result;
4456
+ }
4457
+ equals(other) {
4458
+ return this.bitfield === this.constructor.resolve(other);
4459
+ }
4460
+ freeze() {
4461
+ return Object.freeze(this);
4462
+ }
4463
+ toString() {
4464
+ return this.bitfield.toString();
4465
+ }
4466
+ toJSON() {
4467
+ return this.toString();
4468
+ }
4469
+ static resolve(bit) {
4470
+ if (typeof bit === "bigint") return bit;
4471
+ if (typeof bit === "number") return BigInt(bit);
4472
+ if (bit instanceof _BitField) return bit.bitfield;
4473
+ if (typeof bit === "string") {
4474
+ const flag = this.FLAGS[bit];
4475
+ if (flag !== void 0) return flag;
4476
+ const parsed = BigInt(bit);
4477
+ return parsed;
4478
+ }
4479
+ if (Array.isArray(bit)) {
4480
+ return bit.reduce((acc, b) => acc | this.resolve(b), 0n);
4481
+ }
4482
+ throw new TypeError(`Cannot resolve BitField from: ${bit}`);
4483
+ }
4484
+ };
4485
+
4486
+ // src/types/permissions.ts
4487
+ var PermissionsBitField = class _PermissionsBitField extends BitField {
4488
+ static FLAGS = { ...DISCORD_PERMISSIONS };
4489
+ static ALL = Object.values(DISCORD_PERMISSIONS).reduce((a, b) => a | b, 0n);
4490
+ get isAdmin() {
4491
+ return this.has("ADMINISTRATOR");
4492
+ }
4493
+ static from(bits) {
4494
+ return new _PermissionsBitField(bits);
4495
+ }
4496
+ };
4497
+ var UserFlagsBitField = class extends BitField {
4498
+ static FLAGS = {
4499
+ STAFF: 1n << 0n,
4500
+ PARTNER: 1n << 1n,
4501
+ HYPESQUAD: 1n << 2n,
4502
+ BUG_HUNTER_LEVEL_1: 1n << 3n,
4503
+ HYPESQUAD_ONLINE_HOUSE_1: 1n << 6n,
4504
+ HYPESQUAD_ONLINE_HOUSE_2: 1n << 7n,
4505
+ HYPESQUAD_ONLINE_HOUSE_3: 1n << 8n,
4506
+ PREMIUM_EARLY_SUPPORTER: 1n << 9n,
4507
+ TEAM_PSEUDO_USER: 1n << 10n,
4508
+ BUG_HUNTER_LEVEL_2: 1n << 14n,
4509
+ VERIFIED_BOT: 1n << 16n,
4510
+ VERIFIED_DEVELOPER: 1n << 17n,
4511
+ CERTIFIED_MODERATOR: 1n << 18n,
4512
+ BOT_HTTP_INTERACTIONS: 1n << 19n,
4513
+ ACTIVE_DEVELOPER: 1n << 22n
4514
+ };
4515
+ };
4516
+ var IntentsBitField = class extends BitField {
4517
+ static FLAGS = {
4518
+ Guilds: 1n << 0n,
4519
+ GuildMembers: 1n << 1n,
4520
+ GuildModeration: 1n << 2n,
4521
+ GuildEmojisAndStickers: 1n << 3n,
4522
+ GuildIntegrations: 1n << 4n,
4523
+ GuildWebhooks: 1n << 5n,
4524
+ GuildInvites: 1n << 6n,
4525
+ GuildVoiceStates: 1n << 7n,
4526
+ GuildPresences: 1n << 8n,
4527
+ GuildMessages: 1n << 9n,
4528
+ GuildMessageReactions: 1n << 10n,
4529
+ GuildMessageTyping: 1n << 11n,
4530
+ DirectMessages: 1n << 12n,
4531
+ DirectMessageReactions: 1n << 13n,
4532
+ DirectMessageTyping: 1n << 14n,
4533
+ MessageContent: 1n << 15n,
4534
+ GuildScheduledEvents: 1n << 16n,
4535
+ AutoModerationConfiguration: 1n << 20n,
4536
+ AutoModerationExecution: 1n << 21n,
4537
+ GuildMessagePolls: 1n << 24n,
4538
+ DirectMessagePolls: 1n << 25n
4539
+ };
4540
+ };
4541
+ function computeBasePermissions(member, guild) {
4542
+ if (member.roles === void 0) return 0n;
4543
+ const userId = member.user?.id;
4544
+ if (userId && userId === guild.ownerId) return PermissionsBitField.ALL;
4545
+ const everyoneRole = guild.roles.find((r) => r.id === guild.id);
4546
+ let permissions = everyoneRole ? BigInt(everyoneRole.permissions) : 0n;
4547
+ for (const roleId of member.roles) {
4548
+ const role = guild.roles.find((r) => r.id === roleId);
4549
+ if (role) permissions |= BigInt(role.permissions);
4550
+ }
4551
+ if ((permissions & DISCORD_PERMISSIONS.ADMINISTRATOR) === DISCORD_PERMISSIONS.ADMINISTRATOR) {
4552
+ return PermissionsBitField.ALL;
4553
+ }
4554
+ return permissions;
4555
+ }
4556
+ function computeChannelPermissions(basePermissions, overwrites, memberRoles, memberId) {
4557
+ if ((basePermissions & DISCORD_PERMISSIONS.ADMINISTRATOR) === DISCORD_PERMISSIONS.ADMINISTRATOR) {
4558
+ return PermissionsBitField.ALL;
4559
+ }
4560
+ let permissions = basePermissions;
4561
+ let allow = 0n;
4562
+ let deny = 0n;
4563
+ for (const overwrite of overwrites) {
4564
+ if (overwrite.type === 0) {
4565
+ if (memberRoles.includes(overwrite.id) || overwrites.indexOf(overwrite) === 0) {
4566
+ if (overwrites.indexOf(overwrite) === 0 && !memberRoles.includes(overwrite.id)) {
4567
+ permissions &= ~BigInt(overwrite.deny);
4568
+ permissions |= BigInt(overwrite.allow);
4569
+ } else {
4570
+ allow |= BigInt(overwrite.allow);
4571
+ deny |= BigInt(overwrite.deny);
4572
+ }
4573
+ }
4574
+ }
4575
+ }
4576
+ permissions &= ~deny;
4577
+ permissions |= allow;
4578
+ if (memberId) {
4579
+ const memberOverwrite = overwrites.find((ow) => ow.type === 1 && ow.id === memberId);
4580
+ if (memberOverwrite) {
4581
+ permissions &= ~BigInt(memberOverwrite.deny);
4582
+ permissions |= BigInt(memberOverwrite.allow);
4583
+ }
4584
+ }
4585
+ return permissions;
4586
+ }
4587
+
4588
+ // src/sharding/manager.ts
4589
+ import { EventEmitter } from "events";
4590
+ import { fork } from "child_process";
4591
+ import * as path3 from "path";
4592
+ var Shard = class extends EventEmitter {
4593
+ id;
4594
+ manager;
4595
+ process = null;
4596
+ ready = false;
4597
+ constructor(manager, id) {
4598
+ super();
4599
+ this.manager = manager;
4600
+ this.id = id;
4601
+ }
4602
+ spawn() {
4603
+ return new Promise((resolve4, reject) => {
4604
+ const env = {
4605
+ ...process.env,
4606
+ SHARD_ID: this.id.toString(),
4607
+ SHARD_COUNT: this.manager.totalShards.toString(),
4608
+ DISCORD_TOKEN: this.manager.token
4609
+ };
4610
+ this.process = fork(this.manager.file, [], {
4611
+ env
4612
+ });
4613
+ this.process.on("message", (message) => {
4614
+ this.emit("message", message);
4615
+ this.manager.emit("message", this, message);
4616
+ if (message?.type === "ready") {
4617
+ this.ready = true;
4618
+ this.emit("ready");
4619
+ resolve4(this.process);
4620
+ }
4621
+ });
4622
+ this.process.on("exit", (code, signal) => {
4623
+ this.emit("death", this.process);
4624
+ this.manager.emit("shardDeath", this);
4625
+ this.process = null;
4626
+ this.ready = false;
4627
+ if (this.manager.respawn) {
4628
+ console.warn(`[C-Shard] Shard ${this.id} exited with code ${code} (signal: ${signal})`);
4629
+ setTimeout(() => this.spawn().catch(console.error), 5e3);
4630
+ }
4631
+ });
4632
+ this.process.on("error", (err) => {
4633
+ reject(err);
4634
+ });
4635
+ setTimeout(() => {
4636
+ if (!this.ready) {
4637
+ this.ready = true;
4638
+ this.emit("ready");
4639
+ resolve4(this.process);
4640
+ }
4641
+ }, 3e4);
4642
+ });
4643
+ }
4644
+ send(message) {
4645
+ return new Promise((resolve4, reject) => {
4646
+ if (!this.process) return reject(new Error("Shard is not running"));
4647
+ this.process.send(message, (err) => {
4648
+ if (err) reject(err);
4649
+ else resolve4();
4650
+ });
4651
+ });
4652
+ }
4653
+ kill() {
4654
+ if (this.process) {
4655
+ this.process.removeAllListeners();
4656
+ this.process.kill();
4657
+ this.process = null;
4658
+ this.ready = false;
4659
+ }
4660
+ }
4661
+ };
4662
+ var CShard = class extends EventEmitter {
4663
+ file;
4664
+ totalShards;
4665
+ token;
4666
+ shards = /* @__PURE__ */ new Map();
4667
+ respawn;
4668
+ constructor(file, options) {
4669
+ super();
4670
+ this.file = path3.resolve(file);
4671
+ this.token = options.token;
4672
+ this.totalShards = typeof options.totalShards === "number" ? options.totalShards : 1;
4673
+ this.respawn = options.respawn ?? true;
4674
+ if (options.totalShards === "auto") {
4675
+ this.totalShards = -1;
4676
+ }
4677
+ }
4678
+ async fetchRecommendedShards() {
4679
+ const rest = new ChameleonREST({ token: this.token });
4680
+ const result = await rest.get("/gateway/bot");
4681
+ if (result.ok && result.data && typeof result.data.shards === "number") {
4682
+ return result.data.shards;
4683
+ }
4684
+ console.warn("[Chameleon Sharding] Failed to fetch recommended shards from Discord API. Falling back to 1.");
4685
+ return 1;
4686
+ }
4687
+ async spawn() {
4688
+ if (this.totalShards === -1) {
4689
+ this.totalShards = await this.fetchRecommendedShards();
4690
+ }
4691
+ for (let i = 0; i < this.totalShards; i++) {
4692
+ const shard = new Shard(this, i);
4693
+ this.shards.set(i, shard);
4694
+ this.emit("shardCreate", shard);
4695
+ await shard.spawn();
4696
+ await new Promise((r) => setTimeout(r, 5e3));
4697
+ }
4698
+ return this.shards;
4699
+ }
4700
+ async broadcast(message) {
4701
+ const promises = [];
4702
+ for (const shard of this.shards.values()) {
4703
+ promises.push(shard.send(message));
4704
+ }
4705
+ return Promise.all(promises);
4706
+ }
4707
+ };
3257
4708
  export {
3258
4709
  AUDIT_LOG_EVENT_TYPES,
3259
4710
  ActionRow,
@@ -3265,17 +4716,22 @@ export {
3265
4716
  ApplicationEventWebhookStatus,
3266
4717
  ApplicationFlag,
3267
4718
  ApplicationIntegrationType,
4719
+ ApplicationManager,
3268
4720
  ApplicationRoleConnectionMetadataType,
4721
+ AttachmentBuilder,
3269
4722
  AttachmentFlag,
3270
4723
  AutoModerationActionType,
3271
4724
  AutoModerationEventType,
3272
4725
  AutoModerationKeywordPresetType,
4726
+ AutoModerationManager,
3273
4727
  AutoModerationTriggerType,
3274
4728
  BaseInteractionContext,
3275
4729
  BaseManager,
4730
+ BitField,
3276
4731
  ButtonBuilder,
3277
4732
  ButtonStyle,
3278
4733
  CHAMELEON_SELF_MAP,
4734
+ CShard,
3279
4735
  Chameleon,
3280
4736
  ChameleonGateway,
3281
4737
  ChameleonREST,
@@ -3283,6 +4739,7 @@ export {
3283
4739
  ChannelManager,
3284
4740
  ChannelType,
3285
4741
  Client,
4742
+ Collection,
3286
4743
  CollectorManager,
3287
4744
  Colors,
3288
4745
  CommandContext,
@@ -3295,6 +4752,7 @@ export {
3295
4752
  DefaultMessageNotificationLevel,
3296
4753
  EmbedBuilder,
3297
4754
  EmbedType,
4755
+ EntitlementManager,
3298
4756
  EntitlementType,
3299
4757
  ExplicitContentFilterLevel,
3300
4758
  ForumLayoutType,
@@ -3308,6 +4766,8 @@ export {
3308
4766
  IntegrationExpireBehavior,
3309
4767
  IntentBits,
3310
4768
  Intents,
4769
+ IntentsBitField,
4770
+ InviteManager,
3311
4771
  InviteTargetType,
3312
4772
  InviteType,
3313
4773
  LobbyMemberFlag,
@@ -3319,26 +4779,34 @@ export {
3319
4779
  MessageReferenceType,
3320
4780
  MessageType,
3321
4781
  ModalBuilder,
4782
+ PermissionsBitField,
3322
4783
  PremiumTier,
3323
4784
  PremiumType,
3324
4785
  RoleManager,
4786
+ ScheduledEventManager,
3325
4787
  SelectMenuBuilder,
4788
+ Shard,
3326
4789
  SkuFlag,
3327
4790
  SkuType,
3328
4791
  SortOrderType,
4792
+ SoundboardManager,
4793
+ StageInstanceManager,
3329
4794
  StagePrivacyLevel,
3330
4795
  StickerFormatType,
3331
4796
  StickerType,
3332
4797
  SubscriptionStatus,
3333
4798
  SystemChannelFlag,
4799
+ TemplateManager,
3334
4800
  TextInputBuilder,
3335
4801
  Tongue,
3336
4802
  TongueStore,
3337
4803
  UserFlag,
4804
+ UserFlagsBitField,
3338
4805
  UserManager,
3339
4806
  VerificationLevel,
3340
4807
  VideoQualityMode,
3341
4808
  VisibilityType,
4809
+ WebhookManager,
3342
4810
  WebhookType,
3343
4811
  buildAutoModRule,
3344
4812
  buildChannel,
@@ -3347,6 +4815,7 @@ export {
3347
4815
  buildGuild,
3348
4816
  buildIntegration,
3349
4817
  buildInteraction,
4818
+ buildInvite,
3350
4819
  buildMember,
3351
4820
  buildMessage,
3352
4821
  buildRole,
@@ -3356,7 +4825,10 @@ export {
3356
4825
  buildStickerItem,
3357
4826
  buildUser,
3358
4827
  buildVoiceState,
4828
+ buildWebhook,
3359
4829
  combinePermissions,
4830
+ computeBasePermissions,
4831
+ computeChannelPermissions,
3360
4832
  defineButton,
3361
4833
  defineChannelSelect,
3362
4834
  defineCommand,