@stoatx/client 0.4.0 → 0.5.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
@@ -57,7 +57,7 @@ var Attachment = class extends Base {
57
57
  serverId;
58
58
  objectId;
59
59
  constructor(client, data) {
60
- super(client, { ...data, id: data._id });
60
+ super(client, { ...data, _id: data._id });
61
61
  this.id = data._id;
62
62
  this.tag = data.tag;
63
63
  this.filename = data.filename;
@@ -398,7 +398,7 @@ var Message = class extends Base {
398
398
  flags = 0;
399
399
  interactions = null;
400
400
  masquerade = null;
401
- mentions = [];
401
+ mentions = null;
402
402
  pinned = false;
403
403
  reactions = {};
404
404
  replies = [];
@@ -573,7 +573,7 @@ var Message = class extends Base {
573
573
  }
574
574
  _patch(data) {
575
575
  if (data.content !== void 0) this.content = data.content;
576
- if (data.edited !== void 0) this.editedAt = new Date(data.edited);
576
+ if (data.edited !== void 0) this.editedAt = new Date(data.edited ?? 0);
577
577
  if (data.pinned !== void 0) this.pinned = data.pinned;
578
578
  if (data.embeds !== void 0) this.embeds = data.embeds;
579
579
  if (data.flags !== void 0) this.flags = data.flags;
@@ -606,24 +606,6 @@ var Message = class extends Base {
606
606
  };
607
607
 
608
608
  // src/structures/User.ts
609
- var UserRelationship = /* @__PURE__ */ ((UserRelationship2) => {
610
- UserRelationship2["None"] = "None";
611
- UserRelationship2["User"] = "User";
612
- UserRelationship2["Friend"] = "Friend";
613
- UserRelationship2["Outgoing"] = "Outgoing";
614
- UserRelationship2["Incoming"] = "Incoming";
615
- UserRelationship2["Blocked"] = "Blocked";
616
- UserRelationship2["BlockedOther"] = "BlockedOther";
617
- return UserRelationship2;
618
- })(UserRelationship || {});
619
- var UserPresence = /* @__PURE__ */ ((UserPresence2) => {
620
- UserPresence2["Online"] = "Online";
621
- UserPresence2["Idle"] = "Idle";
622
- UserPresence2["Focus"] = "Focus";
623
- UserPresence2["Busy"] = "Busy";
624
- UserPresence2["Invisible"] = "Invisible";
625
- return UserPresence2;
626
- })(UserPresence || {});
627
609
  var User = class extends Base {
628
610
  discriminator;
629
611
  online;
@@ -657,7 +639,7 @@ var User = class extends Base {
657
639
  this.bot = data.bot ? { owner: data.bot.owner } : false;
658
640
  }
659
641
  if (data.avatar !== void 0) {
660
- this.avatar = new Attachment(this.client, data.avatar);
642
+ this.avatar = data.avatar ? new Attachment(this.client, data.avatar) : null;
661
643
  }
662
644
  if (clear && Array.isArray(clear)) {
663
645
  for (const field of clear) {
@@ -737,6 +719,7 @@ var GatewayManager = class {
737
719
  handleMessage(rawData) {
738
720
  const payload = JSON.parse(rawData.toString());
739
721
  const eventType = payload.type;
722
+ this.client.emit("raw", payload);
740
723
  switch (eventType) {
741
724
  case "Error":
742
725
  this.client.emit("error", new Error(`Gateway Error: ${payload.error || JSON.stringify(payload)}`));
@@ -814,7 +797,7 @@ var GatewayManager = class {
814
797
  const message = channel?.messages.cache.get(payload.id);
815
798
  if (message && payload.append.embeds) {
816
799
  const oldMessage = message._clone();
817
- message.embeds.push(...payload.append.embeds);
800
+ message.embeds = [...message.embeds || [], ...payload.append.embeds];
818
801
  this.client.emit("messageUpdate", oldMessage, message);
819
802
  }
820
803
  break;
@@ -954,13 +937,28 @@ var GatewayManager = class {
954
937
  }
955
938
  case "ServerMemberLeave": {
956
939
  const server = this.client.servers.cache.get(payload.id);
940
+ let member = null;
957
941
  if (server) {
958
- const member = server.members.cache.get(payload.user);
942
+ member = server.members.cache.get(payload.user);
959
943
  if (member) {
960
944
  server.members.cache.delete(payload.user);
961
- this.client.emit("serverMemberLeave", member);
962
945
  }
963
946
  }
947
+ const emitData = member || { serverId: payload.id, userId: payload.user };
948
+ if (payload.reason === "Ban") {
949
+ if (server) {
950
+ const dummyBanPayload = {
951
+ id: payload.user,
952
+ reason: null
953
+ };
954
+ server.bans._add(dummyBanPayload);
955
+ }
956
+ this.client.emit("serverBanAdd", emitData);
957
+ } else if (payload.reason === "Kick") {
958
+ this.client.emit("serverMemberKick", emitData);
959
+ } else {
960
+ this.client.emit("serverMemberLeave", emitData);
961
+ }
964
962
  break;
965
963
  }
966
964
  case "EmojiCreate": {
@@ -994,7 +992,8 @@ var GatewayManager = class {
994
992
  break;
995
993
  }
996
994
  default:
997
- this.client.emit("raw", payload);
995
+ this.client.emit("debug", `Unhandled Gateway Event Type: ${eventType}`);
996
+ break;
998
997
  }
999
998
  }
1000
999
  startPingLoop() {
@@ -1040,6 +1039,96 @@ var GatewayManager = class {
1040
1039
 
1041
1040
  // src/rest/RESTManager.ts
1042
1041
  import { request } from "undici";
1042
+
1043
+ // src/utils/schema.ts
1044
+ var queryParams = {
1045
+ "/": { get: [] },
1046
+ "/users/@me": { get: [] },
1047
+ "/users/{target}": { get: [], patch: [] },
1048
+ "/users/{target}/flags": { get: [] },
1049
+ "/users/@me/username": { patch: [] },
1050
+ "/users/{target}/default_avatar": { get: [] },
1051
+ "/users/{target}/profile": { get: [] },
1052
+ "/users/dms": { get: [] },
1053
+ "/users/{target}/dm": { get: [] },
1054
+ "/users/{target}/mutual": { get: [] },
1055
+ "/users/{target}/friend": { put: [], delete: [] },
1056
+ "/users/{target}/block": { put: [], delete: [] },
1057
+ "/users/friend": { post: [] },
1058
+ "/bots/create": { post: [] },
1059
+ "/bots/{target}/invite": { get: [], post: [] },
1060
+ "/bots/{bot_id}": { get: [], delete: [], patch: [] },
1061
+ "/bots/@me": { get: [] },
1062
+ "/channels/{target}/ack/{message}": { put: [] },
1063
+ "/channels/{target}": { get: [], delete: ["leave_silently"], patch: [] },
1064
+ "/channels/{target}/members": { get: [] },
1065
+ "/channels/{target}/invites": { post: [] },
1066
+ "/channels/{target}/messages": { get: ["limit", "before", "after", "sort", "nearby", "include_users"], post: [] },
1067
+ "/channels/{target}/search": { post: [] },
1068
+ "/channels/{target}/messages/{msg}/pin": { post: [], delete: [] },
1069
+ "/channels/{target}/messages/{msg}": { get: [], delete: [], patch: [] },
1070
+ "/channels/{target}/messages/bulk": { delete: [] },
1071
+ "/channels/create": { post: [] },
1072
+ "/channels/{group_id}/recipients/{member_id}": { put: [], delete: [] },
1073
+ "/channels/{target}/join_call": { post: [] },
1074
+ "/channels/{target}/end_ring/{target_user}": { put: [] },
1075
+ "/channels/{target}/permissions/{role_id}": { put: [] },
1076
+ "/channels/{target}/permissions/default": { put: [] },
1077
+ "/channels/{target}/messages/{msg}/reactions/{emoji}": { put: [], delete: ["user_id", "remove_all"] },
1078
+ "/channels/{target}/messages/{msg}/reactions": { delete: [] },
1079
+ "/channels/{channel_id}/webhooks": { get: [], post: [] },
1080
+ "/servers/create": { post: [] },
1081
+ "/servers/{target}": { get: ["include_channels"], delete: ["leave_silently"], patch: [] },
1082
+ "/servers/{target}/ack": { put: [] },
1083
+ "/servers/{server}/channels": { post: [] },
1084
+ "/servers/{target}/members": { get: ["exclude_offline"] },
1085
+ "/servers/{server_id}/members/{member_id}": { get: ["roles"], delete: [], patch: [] },
1086
+ "/servers/{target}/members_experimental_query": { get: ["query", "experimental_api"] },
1087
+ "/servers/{server}/bans/{target}": { put: [], delete: [] },
1088
+ "/servers/{target}/bans": { get: [] },
1089
+ "/servers/{target}/invites": { get: [] },
1090
+ "/servers/{target}/roles": { post: [] },
1091
+ "/servers/{target}/roles/{role_id}": { get: [], delete: [], patch: [] },
1092
+ "/servers/{target}/permissions/{role_id}": { put: [] },
1093
+ "/servers/{target}/permissions/default": { put: [] },
1094
+ "/servers/{target}/emojis": { get: [] },
1095
+ "/servers/{target}/roles/ranks": { patch: [] },
1096
+ "/invites/{target}": { get: [], post: [], delete: [] },
1097
+ "/custom/emoji/{emoji_id}": { get: [], put: [], delete: [], patch: [] },
1098
+ "/safety/report": { post: [] },
1099
+ "/auth/account/create": { post: [] },
1100
+ "/auth/account/reverify": { post: [] },
1101
+ "/auth/account/delete": { put: [], post: [] },
1102
+ "/auth/account/": { get: [] },
1103
+ "/auth/account/disable": { post: [] },
1104
+ "/auth/account/change/password": { patch: [] },
1105
+ "/auth/account/change/email": { patch: [] },
1106
+ "/auth/account/verify/{code}": { post: [] },
1107
+ "/auth/account/reset_password": { post: [], patch: [] },
1108
+ "/auth/session/login": { post: [] },
1109
+ "/auth/session/logout": { post: [] },
1110
+ "/auth/session/all": { get: [], delete: ["revoke_self"] },
1111
+ "/auth/session/{id}": { delete: [], patch: [] },
1112
+ "/auth/mfa/ticket": { put: [] },
1113
+ "/auth/mfa/": { get: [] },
1114
+ "/auth/mfa/recovery": { post: [], patch: [] },
1115
+ "/auth/mfa/methods": { get: [] },
1116
+ "/auth/mfa/totp": { put: [], post: [], delete: [] },
1117
+ "/onboard/hello": { get: [] },
1118
+ "/onboard/complete": { post: [] },
1119
+ "/policy/acknowledge": { post: [] },
1120
+ "/push/subscribe": { post: [] },
1121
+ "/push/unsubscribe": { post: [] },
1122
+ "/sync/settings/fetch": { post: [] },
1123
+ "/sync/settings/set": { post: ["timestamp"] },
1124
+ "/sync/unreads": { get: [] },
1125
+ "/webhooks/{webhook_id}/{token}/{message_id}": { delete: [], patch: [] },
1126
+ "/webhooks/{webhook_id}/{token}": { get: [], post: [], delete: [], patch: [] },
1127
+ "/webhooks/{webhook_id}": { get: [], delete: [], patch: [] },
1128
+ "/webhooks/{webhook_id}/{token}/github": { post: [] }
1129
+ };
1130
+
1131
+ // src/rest/RESTManager.ts
1043
1132
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1044
1133
  var AsyncBucket = class {
1045
1134
  remaining = 1;
@@ -1086,9 +1175,25 @@ var StoatAPIError = class _StoatAPIError extends Error {
1086
1175
  Object.setPrototypeOf(this, _StoatAPIError.prototype);
1087
1176
  }
1088
1177
  };
1178
+ var ALL_QUERY_KEYS = /* @__PURE__ */ new Set();
1179
+ for (const routes of Object.values(queryParams)) {
1180
+ for (const keys of Object.values(routes)) {
1181
+ for (const key of keys) {
1182
+ ALL_QUERY_KEYS.add(key);
1183
+ }
1184
+ }
1185
+ }
1089
1186
  var RESTManager = class {
1090
1187
  constructor(client) {
1091
1188
  this.client = client;
1189
+ setInterval(() => {
1190
+ const now = Date.now();
1191
+ for (const [key, bucket] of this.buckets.entries()) {
1192
+ if (now > bucket.resetAt && bucket.remaining > 0) {
1193
+ this.buckets.delete(key);
1194
+ }
1195
+ }
1196
+ }, 3e5).unref();
1092
1197
  }
1093
1198
  baseURL = "https://stoat.chat/api";
1094
1199
  token = null;
@@ -1102,17 +1207,35 @@ var RESTManager = class {
1102
1207
  getRouteKey(method, endpoint) {
1103
1208
  return `${method}:${endpoint}`;
1104
1209
  }
1105
- makeRequest(method, endpoint, body) {
1106
- const routeKey = this.getRouteKey(method, endpoint);
1107
- let bucket = this.buckets.get(routeKey);
1108
- if (!bucket) {
1109
- bucket = new AsyncBucket();
1110
- this.buckets.set(routeKey, bucket);
1210
+ makeRequest(method, endpoint, params) {
1211
+ let finalEndpoint = endpoint;
1212
+ let finalBody = void 0;
1213
+ if (params && typeof params === "object") {
1214
+ const query = new URLSearchParams();
1215
+ finalBody = {};
1216
+ for (const [key, value] of Object.entries(params)) {
1217
+ if (value !== void 0) {
1218
+ if (ALL_QUERY_KEYS.has(key)) {
1219
+ query.append(key, String(value));
1220
+ } else {
1221
+ finalBody[key] = value;
1222
+ }
1223
+ }
1224
+ }
1225
+ const qs = query.toString();
1226
+ if (qs) finalEndpoint += `?${qs}`;
1227
+ if (Object.keys(finalBody).length === 0) finalBody = void 0;
1111
1228
  }
1229
+ const routeKey = this.getRouteKey(method, finalEndpoint);
1112
1230
  return new Promise((resolve, reject) => {
1231
+ let bucket = this.buckets.get(routeKey);
1232
+ if (!bucket) {
1233
+ bucket = new AsyncBucket();
1234
+ this.buckets.set(routeKey, bucket);
1235
+ }
1113
1236
  bucket.queue = bucket.queue.then(async () => {
1114
1237
  try {
1115
- const result = await this.execute(method, endpoint, body, bucket);
1238
+ const result = await this.execute(method, finalEndpoint, finalBody, bucket);
1116
1239
  resolve(result);
1117
1240
  } catch (error) {
1118
1241
  reject(error);
@@ -1193,20 +1316,20 @@ var RESTManager = class {
1193
1316
  const data = await response.json();
1194
1317
  return data.id;
1195
1318
  }
1196
- get(endpoint) {
1197
- return this.makeRequest("GET", endpoint);
1319
+ get(endpoint, params) {
1320
+ return this.makeRequest("get", endpoint, params);
1198
1321
  }
1199
- post(endpoint, body) {
1200
- return this.makeRequest("POST", endpoint, body);
1322
+ post(endpoint, params) {
1323
+ return this.makeRequest("post", endpoint, params);
1201
1324
  }
1202
- patch(endpoint, body) {
1203
- return this.makeRequest("PATCH", endpoint, body);
1325
+ patch(endpoint, params) {
1326
+ return this.makeRequest("patch", endpoint, params);
1204
1327
  }
1205
- delete(endpoint, body) {
1206
- return this.makeRequest("DELETE", endpoint, body);
1328
+ delete(endpoint, params) {
1329
+ return this.makeRequest("delete", endpoint, params);
1207
1330
  }
1208
- async put(endpoint, body) {
1209
- return this.makeRequest("PUT", endpoint, body);
1331
+ put(endpoint, params) {
1332
+ return this.makeRequest("put", endpoint, params);
1210
1333
  }
1211
1334
  };
1212
1335
 
@@ -1284,7 +1407,7 @@ var MessageManager = class extends BaseManager {
1284
1407
  * Tell BaseManager how to find the ID for Messages
1285
1408
  */
1286
1409
  extractId(data) {
1287
- return data._id ?? data.id;
1410
+ return data._id;
1288
1411
  }
1289
1412
  /**
1290
1413
  * Tell BaseManager how to build a Message
@@ -1309,20 +1432,31 @@ var MessageManager = class extends BaseManager {
1309
1432
  * const history = await channel.messages.fetchMany({ limit: 20, before: "01H..." });
1310
1433
  */
1311
1434
  async fetchMany(options = {}) {
1312
- const params = new URLSearchParams();
1313
- if (options.limit !== void 0) params.append("limit", options.limit.toString());
1314
- if (options.before !== void 0) params.append("before", options.before);
1315
- if (options.after !== void 0) params.append("after", options.after);
1316
- if (options.sort !== void 0) params.append("sort", options.sort);
1317
- if (options.nearby !== void 0) params.append("nearby", options.nearby);
1318
- if (options.includeUsers !== void 0) params.append("include_users", options.includeUsers.toString());
1319
- const queryString = params.toString();
1320
- const endpoint = `/channels/${this.channel.id}/messages${queryString ? `?${queryString}` : ""}`;
1321
- const data = await this.client.rest.get(endpoint);
1322
- const rawMessages = Array.isArray(data) ? data : data.messages || [];
1323
- if (!Array.isArray(data) && data.users) {
1324
- for (const userData of data.users) {
1325
- this.client.users._add(userData);
1435
+ const endpoint = `/channels/${this.channel.id}/messages`;
1436
+ const query = {};
1437
+ if (options.limit !== void 0) query.limit = options.limit;
1438
+ if (options.before !== void 0) query.before = options.before;
1439
+ if (options.after !== void 0) query.after = options.after;
1440
+ if (options.sort !== void 0) query.sort = options.sort;
1441
+ if (options.nearby !== void 0) query.nearby = options.nearby;
1442
+ if (options.includeUsers !== void 0) query.include_users = options.includeUsers;
1443
+ const data = await this.client.rest.get(endpoint, query);
1444
+ let rawMessages;
1445
+ if (Array.isArray(data)) {
1446
+ rawMessages = data;
1447
+ } else {
1448
+ rawMessages = data.messages;
1449
+ if (data.users) {
1450
+ for (const userData of data.users) {
1451
+ this.client.users._add(userData);
1452
+ }
1453
+ }
1454
+ if (data.members && this.channel.isText()) {
1455
+ const serverId = this.channel.serverId;
1456
+ const server = await this.client.servers.fetch(serverId);
1457
+ for (const memberData of data.members) {
1458
+ server.members._add(memberData);
1459
+ }
1326
1460
  }
1327
1461
  }
1328
1462
  const fetched = new Collection();
@@ -1343,18 +1477,19 @@ var MessageManager = class extends BaseManager {
1343
1477
  * @returns A promise that resolves to the sent Message.
1344
1478
  */
1345
1479
  async send(contentOrOptions) {
1346
- const payload = typeof contentOrOptions === "string" ? { content: contentOrOptions } : { ...contentOrOptions };
1347
- if (payload.embeds) {
1348
- payload.embeds = payload.embeds.map(
1349
- (embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
1350
- );
1480
+ const opts = typeof contentOrOptions === "string" ? { content: contentOrOptions } : contentOrOptions;
1481
+ const payload = {};
1482
+ if (opts.embeds && opts.embeds.length) {
1483
+ payload.embeds = opts.embeds.map((embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed);
1351
1484
  }
1352
- if (payload.attachments) {
1353
- payload.attachments = await Promise.all(
1354
- payload.attachments.map(
1355
- (attachment) => resolveAttachment(this.client.rest, attachment, "attachments")
1356
- )
1485
+ if (opts.attachments && opts.attachments.length > 0) {
1486
+ const resolved = await Promise.all(
1487
+ opts.attachments.map((attachment) => resolveAttachment(this.client.rest, attachment, "attachments"))
1357
1488
  );
1489
+ const validAttachments = resolved.filter((id) => id !== void 0);
1490
+ if (validAttachments.length > 0) {
1491
+ payload.attachments = validAttachments;
1492
+ }
1358
1493
  }
1359
1494
  const data = await this.client.rest.post(`/channels/${this.channel.id}/messages`, payload);
1360
1495
  return new Message(this.client, data);
@@ -1367,19 +1502,20 @@ var MessageManager = class extends BaseManager {
1367
1502
  */
1368
1503
  async edit(message, contentOrOptions) {
1369
1504
  const id = this.resolveId(message);
1370
- const payload = typeof contentOrOptions === "string" ? { content: contentOrOptions } : { ...contentOrOptions };
1371
- if (payload.embeds) {
1372
- payload.embeds = payload.embeds.map(
1373
- (embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
1374
- );
1505
+ const opts = typeof contentOrOptions === "string" ? { content: contentOrOptions } : contentOrOptions;
1506
+ const payload = {};
1507
+ if (opts.content !== void 0) {
1508
+ payload.content = opts.content;
1375
1509
  }
1376
- const data = await this.client.rest.patch(`/channels/${this.channel.id}/messages/${id}`, payload);
1377
- const existing = this.cache.get(id);
1378
- if (existing) {
1379
- existing._patch(data);
1380
- return existing;
1510
+ if (opts.embeds !== void 0) {
1511
+ if (opts.embeds === null) {
1512
+ payload.embeds = [];
1513
+ } else {
1514
+ payload.embeds = opts.embeds.map((embed) => "toJSON" in embed ? embed.toJSON() : embed);
1515
+ }
1381
1516
  }
1382
- return new Message(this.client, data);
1517
+ const data = await this.client.rest.patch(`/channels/${this.channel.id}/messages/${id}`, payload);
1518
+ return this._add(data);
1383
1519
  }
1384
1520
  /**
1385
1521
  * Deletes a message from the channel.
@@ -1396,7 +1532,7 @@ var MessageManager = class extends BaseManager {
1396
1532
  */
1397
1533
  async pin(message) {
1398
1534
  const id = this.resolveId(message);
1399
- await this.client.rest.post(`/channels/${this.channel.id}/messages/${id}/pin`, {});
1535
+ await this.client.rest.post(`/channels/${this.channel.id}/messages/${id}/pin`);
1400
1536
  const existing = this.cache.get(id);
1401
1537
  if (existing) existing.pinned = true;
1402
1538
  }
@@ -1442,12 +1578,14 @@ var MessageManager = class extends BaseManager {
1442
1578
  async removeReaction(message, reaction, userId, removeAll) {
1443
1579
  const id = this.resolveId(message);
1444
1580
  const targetUser = userId ? this.client.users.resolveId(userId) : void 0;
1445
- const params = new URLSearchParams();
1446
- if (targetUser) params.append("user_id", targetUser);
1447
- if (removeAll) params.append("remove_all", "true");
1448
- const queryString = params.toString();
1449
- const endpoint = `/channels/${this.channel.id}/messages/${id}/reactions/${encodeURIComponent(reaction)}${queryString ? `?${queryString}` : ""}`;
1450
- await this.client.rest.delete(endpoint);
1581
+ const endpoint = `/channels/${this.channel.id}/messages/${id}/reactions/${reaction}`;
1582
+ const query = {};
1583
+ if (targetUser) {
1584
+ query.user_id = targetUser;
1585
+ } else if (removeAll) {
1586
+ query.remove_all = true;
1587
+ }
1588
+ await this.client.rest.delete(endpoint, query);
1451
1589
  }
1452
1590
  /**
1453
1591
  * Remove all reactions from a message
@@ -1510,12 +1648,6 @@ var MessageCollector = class extends Collector {
1510
1648
  };
1511
1649
 
1512
1650
  // src/structures/BaseChannel.ts
1513
- var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
1514
- ChannelType2["TEXT"] = "TextChannel";
1515
- ChannelType2["DM"] = "DirectMessage";
1516
- ChannelType2["GROUP"] = "Group";
1517
- return ChannelType2;
1518
- })(ChannelType || {});
1519
1651
  var BaseChannel = class extends Base {
1520
1652
  type;
1521
1653
  messages;
@@ -1639,13 +1771,13 @@ var BaseChannel = class extends Base {
1639
1771
  });
1640
1772
  }
1641
1773
  isText() {
1642
- return this.type === "TextChannel" /* TEXT */;
1774
+ return this.type === "TextChannel";
1643
1775
  }
1644
1776
  isDM() {
1645
- return this.type === "DirectMessage" /* DM */;
1777
+ return this.type === "DirectMessage";
1646
1778
  }
1647
1779
  isGroup() {
1648
- return this.type === "Group" /* GROUP */;
1780
+ return this.type === "Group";
1649
1781
  }
1650
1782
  };
1651
1783
 
@@ -1665,7 +1797,9 @@ var TextChannel = class extends BaseChannel {
1665
1797
  this.serverId = data.server;
1666
1798
  this.defaultPermissions = data.default_permissions;
1667
1799
  this.description = data.description;
1668
- this.icon = data.icon;
1800
+ if (data.icon !== void 0) {
1801
+ this.icon = data.icon ? new Attachment(this.client, data.icon) : null;
1802
+ }
1669
1803
  this.lastMessageId = data.last_message_id;
1670
1804
  this.nsfw = data.nsfw ?? false;
1671
1805
  this.slowmode = data.slowmode ?? 0;
@@ -1735,6 +1869,9 @@ var TextChannel = class extends BaseChannel {
1735
1869
  async setCategory(category) {
1736
1870
  const serverId = this.serverId;
1737
1871
  const server = await this.client.servers.fetch(serverId);
1872
+ if (!server.categories || server.categories.length === 0) {
1873
+ throw new Error("This server has no categories to move the channel into.");
1874
+ }
1738
1875
  const categories = server.categories.map((c) => ({
1739
1876
  id: c.id,
1740
1877
  title: c.title,
@@ -1765,6 +1902,9 @@ var TextChannel = class extends BaseChannel {
1765
1902
  async setPosition(position) {
1766
1903
  const serverId = this.serverId;
1767
1904
  const server = await this.client.servers.fetch(serverId);
1905
+ if (!server.categories || server.categories.length === 0) {
1906
+ throw new Error("This server has no categories to move the channel into.");
1907
+ }
1768
1908
  const categories = server.categories.map((c) => ({
1769
1909
  id: c.id,
1770
1910
  title: c.title,
@@ -1952,14 +2092,14 @@ var GroupChannel = class extends BaseChannel {
1952
2092
  // src/utils/ChannelFactory.ts
1953
2093
  function createChannel(client, data) {
1954
2094
  switch (data.channel_type) {
1955
- case "TextChannel" /* TEXT */:
2095
+ case "TextChannel":
1956
2096
  return new TextChannel(client, data);
1957
- case "DirectMessage" /* DM */:
2097
+ case "DirectMessage":
1958
2098
  return new DMChannel(client, data);
1959
- case "Group" /* GROUP */:
2099
+ case "Group":
1960
2100
  return new GroupChannel(client, data);
1961
2101
  default:
1962
- client.emit("debug", `Received unknown channel type: ${data.type}`);
2102
+ client.emit("debug", `Received unknown channel type: ${data.channel_type}`);
1963
2103
  return new UnknownChannel(client, data);
1964
2104
  }
1965
2105
  }
@@ -2268,7 +2408,7 @@ var ChannelManager = class extends BaseManager {
2268
2408
  super(client, limit);
2269
2409
  }
2270
2410
  extractId(data) {
2271
- return data._id ?? data.id;
2411
+ return data._id;
2272
2412
  }
2273
2413
  construct(data) {
2274
2414
  return createChannel(this.client, data);
@@ -2361,8 +2501,14 @@ var ChannelManager = class extends BaseManager {
2361
2501
  else payload.description = options.description;
2362
2502
  }
2363
2503
  if (options.icon !== void 0) {
2364
- if (options.icon === null) remove.push("Icon");
2365
- else payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
2504
+ if (options.icon === null) {
2505
+ remove.push("Icon");
2506
+ } else {
2507
+ const resolvedIcon = await resolveAttachment(this.client.rest, options.icon, "icons");
2508
+ if (resolvedIcon !== void 0) {
2509
+ payload.icon = resolvedIcon;
2510
+ }
2511
+ }
2366
2512
  }
2367
2513
  if (remove.length > 0) payload.remove = remove;
2368
2514
  if (Object.keys(payload).length === 0) return this.fetch(channel);
@@ -2447,7 +2593,7 @@ var ChannelManager = class extends BaseManager {
2447
2593
  * await client.channels.pin("CHANNEL_ID", "MESSAGE_ID");
2448
2594
  */
2449
2595
  async pin(id, messageId) {
2450
- await this.client.rest.post(`/channels/${id}/pins/${messageId}`);
2596
+ await this.client.rest.post(`/channels/${id}/messages/${messageId}/pin`);
2451
2597
  }
2452
2598
  /**
2453
2599
  * Unpin a message
@@ -2477,7 +2623,7 @@ var ChannelManager = class extends BaseManager {
2477
2623
  if ("id" in msg) return msg.id;
2478
2624
  throw new TypeError("Invalid MessageResolvable provided. Expected a Message object or a string ID/Mention.");
2479
2625
  });
2480
- await this.client.rest.delete(`/channels/${id}/messages/bulk`, { messages: messageIds });
2626
+ await this.client.rest.delete(`/channels/${id}/messages/bulk`, { ids: messageIds });
2481
2627
  }
2482
2628
  };
2483
2629
 
@@ -2576,20 +2722,20 @@ var Member = class extends Base {
2576
2722
  canRecieve = false;
2577
2723
  // Member roles manager
2578
2724
  roles;
2579
- constructor(client, data) {
2580
- super(client, { _id: data.user._id });
2581
- this.serverId = data.serverId || data.server_id;
2582
- this.joinedAt = new Date(data.joinedAt || data.joined_at);
2725
+ constructor(client, data, serverId) {
2726
+ super(client, { _id: data._id?.user });
2727
+ this.serverId = data._id?.server ?? serverId;
2728
+ this.joinedAt = new Date(data.joined_at);
2583
2729
  this.roles = new MemberRoleManager(this);
2584
2730
  this._patch(data);
2585
2731
  }
2586
2732
  _patch(data) {
2587
2733
  if (data.nickname !== void 0) this.nickname = data.nickname;
2588
- if (data.avatar !== void 0) this.avatar = data.avatar;
2734
+ if (data.avatar !== void 0) this.avatar = data.avatar ? new Attachment(this.client, data.avatar) : null;
2589
2735
  if (data.roles !== void 0) this._roles = data.roles;
2590
2736
  if (data.timeout !== void 0) this.timeout = data.timeout ? new Date(data.timeout) : null;
2591
- if (data.can_publish !== void 0) this.canPublish = data.canPublish;
2592
- if (data.can_recieve !== void 0) this.canRecieve = data.canRecieve;
2737
+ if (data.can_publish !== void 0) this.canPublish = data.can_publish;
2738
+ if (data.can_receive !== void 0) this.canRecieve = data.can_receive;
2593
2739
  }
2594
2740
  /**
2595
2741
  * Get member role IDs
@@ -2734,17 +2880,14 @@ var MemberManager = class extends BaseManager {
2734
2880
  * @internal
2735
2881
  */
2736
2882
  extractId(data) {
2737
- return data.user_id ?? data.id ?? (typeof data._id === "string" ? data._id : data._id?.user);
2883
+ return data._id?.user;
2738
2884
  }
2739
2885
  /**
2740
2886
  * Tell BaseManager how to build a Member
2741
2887
  * @internal
2742
2888
  */
2743
2889
  construct(data) {
2744
- if (!data.server_id && !data.serverId) {
2745
- data.serverId = this.server.id;
2746
- }
2747
- return new Member(this.client, data);
2890
+ return new Member(this.client, data, this.server.id);
2748
2891
  }
2749
2892
  /**
2750
2893
  * Resolve a string or mention to Member
@@ -2803,23 +2946,22 @@ var MemberManager = class extends BaseManager {
2803
2946
  * const onlineMembers = await server.members.fetchMany({ exclude_offline: true });
2804
2947
  */
2805
2948
  async fetchMany(options = {}) {
2806
- const params = new URLSearchParams();
2807
- if (options.exclude_offline !== void 0) {
2808
- params.append("exclude_offline", options.exclude_offline.toString());
2949
+ const query = {};
2950
+ if (options.excludeOffline !== void 0) {
2951
+ query.exclude_offline = options.excludeOffline;
2809
2952
  }
2810
- const queryString = params.toString();
2811
- const endpoint = `/servers/${this.server.id}/members${queryString ? `?${queryString}` : ""}`;
2812
- const data = await this.client.rest.get(endpoint);
2813
- if (data.users && Array.isArray(data.users)) {
2953
+ const data = await this.client.rest.get(`/servers/${this.server.id}/members`, query);
2954
+ if (data.users) {
2814
2955
  for (const userData of data.users) {
2815
2956
  this.client.users._add(userData);
2816
2957
  }
2817
2958
  }
2818
2959
  const fetched = new Collection();
2819
- const rawMembers = data.members || (Array.isArray(data) ? data : []);
2820
- for (const rawMember of rawMembers) {
2821
- const member = this._add(rawMember);
2822
- fetched.set(member.id, member);
2960
+ if (data.members) {
2961
+ for (const rawMember of data.members) {
2962
+ const member = this._add(rawMember);
2963
+ fetched.set(member.id, member);
2964
+ }
2823
2965
  }
2824
2966
  return fetched;
2825
2967
  }
@@ -2922,11 +3064,17 @@ var ServerChannelManager = class {
2922
3064
  async create(options) {
2923
3065
  if (!options.name) throw new Error("A channel name must be provided.");
2924
3066
  const payload = {
2925
- name: options.name,
2926
- type: options.type ?? "Text",
2927
- description: options.description,
2928
- nsfw: options.nsfw ?? false
3067
+ name: options.name
2929
3068
  };
3069
+ if (options.nsfw !== void 0) {
3070
+ payload.nsfw = options.nsfw;
3071
+ }
3072
+ if (options.type !== void 0) {
3073
+ payload.type = options.type;
3074
+ }
3075
+ if (options.description !== void 0) {
3076
+ payload.description = options.description;
3077
+ }
2930
3078
  if (options.type === "Voice" && options.voice?.max_users) {
2931
3079
  payload.voice = { max_users: options.voice.max_users };
2932
3080
  }
@@ -2959,14 +3107,14 @@ var Role = class extends Base {
2959
3107
  */
2960
3108
  _patch(data) {
2961
3109
  if (data.name !== void 0) this.name = data.name;
2962
- if (data.color !== void 0) this.color = data.color;
3110
+ if (data.colour !== void 0) this.color = data.colour;
2963
3111
  if (data.hoist !== void 0) this.hoist = data.hoist;
2964
3112
  if (data.rank !== void 0) this.rank = data.rank;
2965
- if (data.icon !== void 0) this.icon = new Attachment(this.client, data.icon);
3113
+ if (data.icon !== void 0) this.icon = data.icon !== null ? new Attachment(this.client, data.icon) : null;
2966
3114
  if (data.permissions !== void 0) {
2967
3115
  try {
2968
3116
  if (typeof data.permissions === "object" && data.permissions !== null) {
2969
- const allowPerms = data.permissions.a ?? data.permissions[0] ?? 0;
3117
+ const allowPerms = data.permissions.a ?? 0;
2970
3118
  this._permissions = BigInt(allowPerms);
2971
3119
  } else {
2972
3120
  this._permissions = BigInt(data.permissions);
@@ -3169,7 +3317,7 @@ var RoleManager = class extends BaseManager {
3169
3317
  * Tell BaseManager how to find the ID for Roles
3170
3318
  */
3171
3319
  extractId(data) {
3172
- return data._id ?? data.id;
3320
+ return data._id;
3173
3321
  }
3174
3322
  /**
3175
3323
  * Tell BaseManager how to build a Role
@@ -3185,7 +3333,7 @@ var RoleManager = class extends BaseManager {
3185
3333
  * @returns The newly created or updated Role object.
3186
3334
  */
3187
3335
  _add(data, idParam) {
3188
- const id = idParam ?? data._id ?? data.id;
3336
+ const id = idParam ?? data._id;
3189
3337
  const existing = this.cache.get(id);
3190
3338
  if (existing) {
3191
3339
  existing._patch(data);
@@ -3248,7 +3396,7 @@ var RoleManager = class extends BaseManager {
3248
3396
  name: options.name
3249
3397
  };
3250
3398
  const data = await this.client.rest.post(`/servers/${this.server.id}/roles`, payload);
3251
- return this._add(data);
3399
+ return this._add(data.role);
3252
3400
  }
3253
3401
  /**
3254
3402
  * Fetches a Role from the API or resolves it from the local cache.
@@ -3313,7 +3461,10 @@ var RoleManager = class extends BaseManager {
3313
3461
  if (options.icon === null) {
3314
3462
  remove.push("Icon");
3315
3463
  } else {
3316
- payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
3464
+ const resolvedIcon = await resolveAttachment(this.client.rest, options.icon, "icons");
3465
+ if (resolvedIcon !== void 0) {
3466
+ payload.icon = resolvedIcon;
3467
+ }
3317
3468
  }
3318
3469
  }
3319
3470
  if (remove.length > 0) {
@@ -3322,7 +3473,8 @@ var RoleManager = class extends BaseManager {
3322
3473
  if (Object.keys(payload).length === 0) {
3323
3474
  return this.fetch(id);
3324
3475
  }
3325
- const data = await this.client.rest.patch(`/servers/${this.server.id}/roles/${id}`, payload);
3476
+ const endpoint = `/servers/${this.server.id}/roles/${id}`;
3477
+ const data = await this.client.rest.patch(endpoint, payload);
3326
3478
  return this._add(data, id);
3327
3479
  }
3328
3480
  /**
@@ -3398,7 +3550,7 @@ var RoleManager = class extends BaseManager {
3398
3550
  const payload = {
3399
3551
  ranks: mappedIds
3400
3552
  };
3401
- const data = await this.client.rest.put(`/servers/${this.server.id}/roles`, payload);
3553
+ const data = await this.client.rest.patch(`/servers/${this.server.id}/roles/ranks`, payload);
3402
3554
  this.server._patch(data);
3403
3555
  return this.server;
3404
3556
  }
@@ -3410,7 +3562,7 @@ var ServerInvite = class {
3410
3562
  creatorId;
3411
3563
  channelId;
3412
3564
  constructor(data) {
3413
- this.code = data._id ?? data.code;
3565
+ this.code = data._id;
3414
3566
  this.creatorId = data.creator;
3415
3567
  this.channelId = data.channel;
3416
3568
  }
@@ -3427,7 +3579,7 @@ var ServerInviteManager = class extends BaseManager {
3427
3579
  this.server = server;
3428
3580
  }
3429
3581
  extractId(data) {
3430
- return data._id ?? data.code;
3582
+ return data._id;
3431
3583
  }
3432
3584
  construct(data) {
3433
3585
  return new ServerInvite(data);
@@ -3437,9 +3589,8 @@ var ServerInviteManager = class extends BaseManager {
3437
3589
  */
3438
3590
  async fetch() {
3439
3591
  const data = await this.client.rest.get(`/servers/${this.server.id}/invites`);
3440
- const rawInvites = Array.isArray(data) ? data : [];
3441
3592
  const fetched = new Collection();
3442
- for (const raw of rawInvites) {
3593
+ for (const raw of data) {
3443
3594
  const invite = this._add(raw);
3444
3595
  fetched.set(invite.code, invite);
3445
3596
  }
@@ -3452,7 +3603,7 @@ var ServerBan = class {
3452
3603
  userId;
3453
3604
  reason;
3454
3605
  constructor(data) {
3455
- this.userId = data._id?.user ?? data.id;
3606
+ this.userId = data._id?.user;
3456
3607
  this.reason = data.reason ?? null;
3457
3608
  }
3458
3609
  _patch(data) {
@@ -3559,7 +3710,7 @@ var Server = class extends Base {
3559
3710
  ownerId;
3560
3711
  analytics = false;
3561
3712
  banner = null;
3562
- categories = [];
3713
+ categories = null;
3563
3714
  description = null;
3564
3715
  discoverable = false;
3565
3716
  flags = 0;
@@ -3612,13 +3763,6 @@ var Server = class extends Base {
3612
3763
  this.roles._add({ id, ...roleData });
3613
3764
  }
3614
3765
  }
3615
- if (data.emojis !== void 0) {
3616
- if (Array.isArray(data.emojis)) {
3617
- for (const emoji of data.emojis) {
3618
- this.emojis._add(emoji);
3619
- }
3620
- }
3621
- }
3622
3766
  if (clear && Array.isArray(clear)) {
3623
3767
  for (const field of clear) {
3624
3768
  switch (field) {
@@ -3666,7 +3810,7 @@ var ServerManager = class extends BaseManager {
3666
3810
  * Tell BaseManager how to find the ID for Servers
3667
3811
  */
3668
3812
  extractId(data) {
3669
- return data._id ?? data.id;
3813
+ return data._id;
3670
3814
  }
3671
3815
  /**
3672
3816
  * Tell BaseManager how to build a Server
@@ -3707,21 +3851,19 @@ var ServerManager = class extends BaseManager {
3707
3851
  payload.system_messages = {};
3708
3852
  const sm = options.systemMessages;
3709
3853
  if (sm.userJoined !== void 0) {
3710
- if (sm.userJoined === null) remove.push("SystemMessageUserJoined");
3711
- else payload.system_messages.user_joined = sm.userJoined;
3854
+ payload.system_messages.user_joined = sm.userJoined;
3712
3855
  }
3713
3856
  if (sm.userLeft !== void 0) {
3714
- if (sm.userLeft === null) remove.push("SystemMessageUserLeft");
3715
- else payload.system_messages.user_left = sm.userLeft;
3857
+ payload.system_messages.user_left = sm.userLeft;
3716
3858
  }
3717
3859
  if (sm.userKicked !== void 0) {
3718
- if (sm.userKicked === null) remove.push("SystemMessageUserKicked");
3719
- else payload.system_messages.user_kicked = sm.userKicked;
3860
+ payload.system_messages.user_kicked = sm.userKicked;
3720
3861
  }
3721
3862
  if (sm.userBanned !== void 0) {
3722
- if (sm.userBanned === null) remove.push("SystemMessageUserBanned");
3723
- else payload.system_messages.user_banned = sm.userBanned;
3863
+ payload.system_messages.user_banned = sm.userBanned;
3724
3864
  }
3865
+ } else if (options.systemMessages === null) {
3866
+ remove.push("SystemMessages");
3725
3867
  }
3726
3868
  if (options.categories !== void 0) payload.categories = options.categories;
3727
3869
  if (options.analytics !== void 0) payload.analytics = options.analytics;
@@ -3744,7 +3886,7 @@ var UserManager = class extends BaseManager {
3744
3886
  * Tell BaseManager how to find the ID for Users
3745
3887
  */
3746
3888
  extractId(data) {
3747
- return data._id ?? data.id;
3889
+ return data._id;
3748
3890
  }
3749
3891
  /**
3750
3892
  * Tell BaseManager how to build a User
@@ -3879,7 +4021,7 @@ var UserManager = class extends BaseManager {
3879
4021
  if (Object.keys(payload).length === 0) {
3880
4022
  return this.fetch("@me");
3881
4023
  }
3882
- const data = await this.client.rest.patch(`/users/@me`, payload);
4024
+ const data = await this.client.rest.patch(`/users/${this.client.user?.id}`, payload);
3883
4025
  return this._add(data);
3884
4026
  }
3885
4027
  /**
@@ -4039,14 +4181,17 @@ var EmbedBuilder = class {
4039
4181
  return { ...this.data };
4040
4182
  }
4041
4183
  };
4184
+
4185
+ // src/index.ts
4186
+ import * as API from "stoat-api";
4042
4187
  export {
4188
+ API,
4043
4189
  Attachment,
4044
4190
  AttachmentBuilder,
4045
4191
  Base,
4046
4192
  BaseChannel,
4047
4193
  BitField,
4048
4194
  ChannelManager,
4049
- ChannelType,
4050
4195
  Client,
4051
4196
  ClientUser,
4052
4197
  Collection,
@@ -4076,8 +4221,6 @@ export {
4076
4221
  TextChannel,
4077
4222
  UnknownChannel,
4078
4223
  User,
4079
- UserManager,
4080
- UserPresence,
4081
- UserRelationship
4224
+ UserManager
4082
4225
  };
4083
4226
  //# sourceMappingURL=index.js.map