@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.cjs CHANGED
@@ -30,13 +30,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ API: () => API,
33
34
  Attachment: () => Attachment,
34
35
  AttachmentBuilder: () => AttachmentBuilder,
35
36
  Base: () => Base,
36
37
  BaseChannel: () => BaseChannel,
37
38
  BitField: () => BitField,
38
39
  ChannelManager: () => ChannelManager,
39
- ChannelType: () => ChannelType,
40
40
  Client: () => Client,
41
41
  ClientUser: () => ClientUser,
42
42
  Collection: () => Collection,
@@ -66,9 +66,7 @@ __export(index_exports, {
66
66
  TextChannel: () => TextChannel,
67
67
  UnknownChannel: () => UnknownChannel,
68
68
  User: () => User,
69
- UserManager: () => UserManager,
70
- UserPresence: () => UserPresence,
71
- UserRelationship: () => UserRelationship
69
+ UserManager: () => UserManager
72
70
  });
73
71
  module.exports = __toCommonJS(index_exports);
74
72
 
@@ -131,7 +129,7 @@ var Attachment = class extends Base {
131
129
  serverId;
132
130
  objectId;
133
131
  constructor(client, data) {
134
- super(client, { ...data, id: data._id });
132
+ super(client, { ...data, _id: data._id });
135
133
  this.id = data._id;
136
134
  this.tag = data.tag;
137
135
  this.filename = data.filename;
@@ -472,7 +470,7 @@ var Message = class extends Base {
472
470
  flags = 0;
473
471
  interactions = null;
474
472
  masquerade = null;
475
- mentions = [];
473
+ mentions = null;
476
474
  pinned = false;
477
475
  reactions = {};
478
476
  replies = [];
@@ -647,7 +645,7 @@ var Message = class extends Base {
647
645
  }
648
646
  _patch(data) {
649
647
  if (data.content !== void 0) this.content = data.content;
650
- if (data.edited !== void 0) this.editedAt = new Date(data.edited);
648
+ if (data.edited !== void 0) this.editedAt = new Date(data.edited ?? 0);
651
649
  if (data.pinned !== void 0) this.pinned = data.pinned;
652
650
  if (data.embeds !== void 0) this.embeds = data.embeds;
653
651
  if (data.flags !== void 0) this.flags = data.flags;
@@ -680,24 +678,6 @@ var Message = class extends Base {
680
678
  };
681
679
 
682
680
  // src/structures/User.ts
683
- var UserRelationship = /* @__PURE__ */ ((UserRelationship2) => {
684
- UserRelationship2["None"] = "None";
685
- UserRelationship2["User"] = "User";
686
- UserRelationship2["Friend"] = "Friend";
687
- UserRelationship2["Outgoing"] = "Outgoing";
688
- UserRelationship2["Incoming"] = "Incoming";
689
- UserRelationship2["Blocked"] = "Blocked";
690
- UserRelationship2["BlockedOther"] = "BlockedOther";
691
- return UserRelationship2;
692
- })(UserRelationship || {});
693
- var UserPresence = /* @__PURE__ */ ((UserPresence2) => {
694
- UserPresence2["Online"] = "Online";
695
- UserPresence2["Idle"] = "Idle";
696
- UserPresence2["Focus"] = "Focus";
697
- UserPresence2["Busy"] = "Busy";
698
- UserPresence2["Invisible"] = "Invisible";
699
- return UserPresence2;
700
- })(UserPresence || {});
701
681
  var User = class extends Base {
702
682
  discriminator;
703
683
  online;
@@ -731,7 +711,7 @@ var User = class extends Base {
731
711
  this.bot = data.bot ? { owner: data.bot.owner } : false;
732
712
  }
733
713
  if (data.avatar !== void 0) {
734
- this.avatar = new Attachment(this.client, data.avatar);
714
+ this.avatar = data.avatar ? new Attachment(this.client, data.avatar) : null;
735
715
  }
736
716
  if (clear && Array.isArray(clear)) {
737
717
  for (const field of clear) {
@@ -811,6 +791,7 @@ var GatewayManager = class {
811
791
  handleMessage(rawData) {
812
792
  const payload = JSON.parse(rawData.toString());
813
793
  const eventType = payload.type;
794
+ this.client.emit("raw", payload);
814
795
  switch (eventType) {
815
796
  case "Error":
816
797
  this.client.emit("error", new Error(`Gateway Error: ${payload.error || JSON.stringify(payload)}`));
@@ -888,7 +869,7 @@ var GatewayManager = class {
888
869
  const message = channel?.messages.cache.get(payload.id);
889
870
  if (message && payload.append.embeds) {
890
871
  const oldMessage = message._clone();
891
- message.embeds.push(...payload.append.embeds);
872
+ message.embeds = [...message.embeds || [], ...payload.append.embeds];
892
873
  this.client.emit("messageUpdate", oldMessage, message);
893
874
  }
894
875
  break;
@@ -1028,13 +1009,28 @@ var GatewayManager = class {
1028
1009
  }
1029
1010
  case "ServerMemberLeave": {
1030
1011
  const server = this.client.servers.cache.get(payload.id);
1012
+ let member = null;
1031
1013
  if (server) {
1032
- const member = server.members.cache.get(payload.user);
1014
+ member = server.members.cache.get(payload.user);
1033
1015
  if (member) {
1034
1016
  server.members.cache.delete(payload.user);
1035
- this.client.emit("serverMemberLeave", member);
1036
1017
  }
1037
1018
  }
1019
+ const emitData = member || { serverId: payload.id, userId: payload.user };
1020
+ if (payload.reason === "Ban") {
1021
+ if (server) {
1022
+ const dummyBanPayload = {
1023
+ id: payload.user,
1024
+ reason: null
1025
+ };
1026
+ server.bans._add(dummyBanPayload);
1027
+ }
1028
+ this.client.emit("serverBanAdd", emitData);
1029
+ } else if (payload.reason === "Kick") {
1030
+ this.client.emit("serverMemberKick", emitData);
1031
+ } else {
1032
+ this.client.emit("serverMemberLeave", emitData);
1033
+ }
1038
1034
  break;
1039
1035
  }
1040
1036
  case "EmojiCreate": {
@@ -1068,7 +1064,8 @@ var GatewayManager = class {
1068
1064
  break;
1069
1065
  }
1070
1066
  default:
1071
- this.client.emit("raw", payload);
1067
+ this.client.emit("debug", `Unhandled Gateway Event Type: ${eventType}`);
1068
+ break;
1072
1069
  }
1073
1070
  }
1074
1071
  startPingLoop() {
@@ -1114,6 +1111,96 @@ var GatewayManager = class {
1114
1111
 
1115
1112
  // src/rest/RESTManager.ts
1116
1113
  var import_undici = require("undici");
1114
+
1115
+ // src/utils/schema.ts
1116
+ var queryParams = {
1117
+ "/": { get: [] },
1118
+ "/users/@me": { get: [] },
1119
+ "/users/{target}": { get: [], patch: [] },
1120
+ "/users/{target}/flags": { get: [] },
1121
+ "/users/@me/username": { patch: [] },
1122
+ "/users/{target}/default_avatar": { get: [] },
1123
+ "/users/{target}/profile": { get: [] },
1124
+ "/users/dms": { get: [] },
1125
+ "/users/{target}/dm": { get: [] },
1126
+ "/users/{target}/mutual": { get: [] },
1127
+ "/users/{target}/friend": { put: [], delete: [] },
1128
+ "/users/{target}/block": { put: [], delete: [] },
1129
+ "/users/friend": { post: [] },
1130
+ "/bots/create": { post: [] },
1131
+ "/bots/{target}/invite": { get: [], post: [] },
1132
+ "/bots/{bot_id}": { get: [], delete: [], patch: [] },
1133
+ "/bots/@me": { get: [] },
1134
+ "/channels/{target}/ack/{message}": { put: [] },
1135
+ "/channels/{target}": { get: [], delete: ["leave_silently"], patch: [] },
1136
+ "/channels/{target}/members": { get: [] },
1137
+ "/channels/{target}/invites": { post: [] },
1138
+ "/channels/{target}/messages": { get: ["limit", "before", "after", "sort", "nearby", "include_users"], post: [] },
1139
+ "/channels/{target}/search": { post: [] },
1140
+ "/channels/{target}/messages/{msg}/pin": { post: [], delete: [] },
1141
+ "/channels/{target}/messages/{msg}": { get: [], delete: [], patch: [] },
1142
+ "/channels/{target}/messages/bulk": { delete: [] },
1143
+ "/channels/create": { post: [] },
1144
+ "/channels/{group_id}/recipients/{member_id}": { put: [], delete: [] },
1145
+ "/channels/{target}/join_call": { post: [] },
1146
+ "/channels/{target}/end_ring/{target_user}": { put: [] },
1147
+ "/channels/{target}/permissions/{role_id}": { put: [] },
1148
+ "/channels/{target}/permissions/default": { put: [] },
1149
+ "/channels/{target}/messages/{msg}/reactions/{emoji}": { put: [], delete: ["user_id", "remove_all"] },
1150
+ "/channels/{target}/messages/{msg}/reactions": { delete: [] },
1151
+ "/channels/{channel_id}/webhooks": { get: [], post: [] },
1152
+ "/servers/create": { post: [] },
1153
+ "/servers/{target}": { get: ["include_channels"], delete: ["leave_silently"], patch: [] },
1154
+ "/servers/{target}/ack": { put: [] },
1155
+ "/servers/{server}/channels": { post: [] },
1156
+ "/servers/{target}/members": { get: ["exclude_offline"] },
1157
+ "/servers/{server_id}/members/{member_id}": { get: ["roles"], delete: [], patch: [] },
1158
+ "/servers/{target}/members_experimental_query": { get: ["query", "experimental_api"] },
1159
+ "/servers/{server}/bans/{target}": { put: [], delete: [] },
1160
+ "/servers/{target}/bans": { get: [] },
1161
+ "/servers/{target}/invites": { get: [] },
1162
+ "/servers/{target}/roles": { post: [] },
1163
+ "/servers/{target}/roles/{role_id}": { get: [], delete: [], patch: [] },
1164
+ "/servers/{target}/permissions/{role_id}": { put: [] },
1165
+ "/servers/{target}/permissions/default": { put: [] },
1166
+ "/servers/{target}/emojis": { get: [] },
1167
+ "/servers/{target}/roles/ranks": { patch: [] },
1168
+ "/invites/{target}": { get: [], post: [], delete: [] },
1169
+ "/custom/emoji/{emoji_id}": { get: [], put: [], delete: [], patch: [] },
1170
+ "/safety/report": { post: [] },
1171
+ "/auth/account/create": { post: [] },
1172
+ "/auth/account/reverify": { post: [] },
1173
+ "/auth/account/delete": { put: [], post: [] },
1174
+ "/auth/account/": { get: [] },
1175
+ "/auth/account/disable": { post: [] },
1176
+ "/auth/account/change/password": { patch: [] },
1177
+ "/auth/account/change/email": { patch: [] },
1178
+ "/auth/account/verify/{code}": { post: [] },
1179
+ "/auth/account/reset_password": { post: [], patch: [] },
1180
+ "/auth/session/login": { post: [] },
1181
+ "/auth/session/logout": { post: [] },
1182
+ "/auth/session/all": { get: [], delete: ["revoke_self"] },
1183
+ "/auth/session/{id}": { delete: [], patch: [] },
1184
+ "/auth/mfa/ticket": { put: [] },
1185
+ "/auth/mfa/": { get: [] },
1186
+ "/auth/mfa/recovery": { post: [], patch: [] },
1187
+ "/auth/mfa/methods": { get: [] },
1188
+ "/auth/mfa/totp": { put: [], post: [], delete: [] },
1189
+ "/onboard/hello": { get: [] },
1190
+ "/onboard/complete": { post: [] },
1191
+ "/policy/acknowledge": { post: [] },
1192
+ "/push/subscribe": { post: [] },
1193
+ "/push/unsubscribe": { post: [] },
1194
+ "/sync/settings/fetch": { post: [] },
1195
+ "/sync/settings/set": { post: ["timestamp"] },
1196
+ "/sync/unreads": { get: [] },
1197
+ "/webhooks/{webhook_id}/{token}/{message_id}": { delete: [], patch: [] },
1198
+ "/webhooks/{webhook_id}/{token}": { get: [], post: [], delete: [], patch: [] },
1199
+ "/webhooks/{webhook_id}": { get: [], delete: [], patch: [] },
1200
+ "/webhooks/{webhook_id}/{token}/github": { post: [] }
1201
+ };
1202
+
1203
+ // src/rest/RESTManager.ts
1117
1204
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1118
1205
  var AsyncBucket = class {
1119
1206
  remaining = 1;
@@ -1160,9 +1247,25 @@ var StoatAPIError = class _StoatAPIError extends Error {
1160
1247
  Object.setPrototypeOf(this, _StoatAPIError.prototype);
1161
1248
  }
1162
1249
  };
1250
+ var ALL_QUERY_KEYS = /* @__PURE__ */ new Set();
1251
+ for (const routes of Object.values(queryParams)) {
1252
+ for (const keys of Object.values(routes)) {
1253
+ for (const key of keys) {
1254
+ ALL_QUERY_KEYS.add(key);
1255
+ }
1256
+ }
1257
+ }
1163
1258
  var RESTManager = class {
1164
1259
  constructor(client) {
1165
1260
  this.client = client;
1261
+ setInterval(() => {
1262
+ const now = Date.now();
1263
+ for (const [key, bucket] of this.buckets.entries()) {
1264
+ if (now > bucket.resetAt && bucket.remaining > 0) {
1265
+ this.buckets.delete(key);
1266
+ }
1267
+ }
1268
+ }, 3e5).unref();
1166
1269
  }
1167
1270
  baseURL = "https://stoat.chat/api";
1168
1271
  token = null;
@@ -1176,17 +1279,35 @@ var RESTManager = class {
1176
1279
  getRouteKey(method, endpoint) {
1177
1280
  return `${method}:${endpoint}`;
1178
1281
  }
1179
- makeRequest(method, endpoint, body) {
1180
- const routeKey = this.getRouteKey(method, endpoint);
1181
- let bucket = this.buckets.get(routeKey);
1182
- if (!bucket) {
1183
- bucket = new AsyncBucket();
1184
- this.buckets.set(routeKey, bucket);
1282
+ makeRequest(method, endpoint, params) {
1283
+ let finalEndpoint = endpoint;
1284
+ let finalBody = void 0;
1285
+ if (params && typeof params === "object") {
1286
+ const query = new URLSearchParams();
1287
+ finalBody = {};
1288
+ for (const [key, value] of Object.entries(params)) {
1289
+ if (value !== void 0) {
1290
+ if (ALL_QUERY_KEYS.has(key)) {
1291
+ query.append(key, String(value));
1292
+ } else {
1293
+ finalBody[key] = value;
1294
+ }
1295
+ }
1296
+ }
1297
+ const qs = query.toString();
1298
+ if (qs) finalEndpoint += `?${qs}`;
1299
+ if (Object.keys(finalBody).length === 0) finalBody = void 0;
1185
1300
  }
1301
+ const routeKey = this.getRouteKey(method, finalEndpoint);
1186
1302
  return new Promise((resolve, reject) => {
1303
+ let bucket = this.buckets.get(routeKey);
1304
+ if (!bucket) {
1305
+ bucket = new AsyncBucket();
1306
+ this.buckets.set(routeKey, bucket);
1307
+ }
1187
1308
  bucket.queue = bucket.queue.then(async () => {
1188
1309
  try {
1189
- const result = await this.execute(method, endpoint, body, bucket);
1310
+ const result = await this.execute(method, finalEndpoint, finalBody, bucket);
1190
1311
  resolve(result);
1191
1312
  } catch (error) {
1192
1313
  reject(error);
@@ -1267,20 +1388,20 @@ var RESTManager = class {
1267
1388
  const data = await response.json();
1268
1389
  return data.id;
1269
1390
  }
1270
- get(endpoint) {
1271
- return this.makeRequest("GET", endpoint);
1391
+ get(endpoint, params) {
1392
+ return this.makeRequest("get", endpoint, params);
1272
1393
  }
1273
- post(endpoint, body) {
1274
- return this.makeRequest("POST", endpoint, body);
1394
+ post(endpoint, params) {
1395
+ return this.makeRequest("post", endpoint, params);
1275
1396
  }
1276
- patch(endpoint, body) {
1277
- return this.makeRequest("PATCH", endpoint, body);
1397
+ patch(endpoint, params) {
1398
+ return this.makeRequest("patch", endpoint, params);
1278
1399
  }
1279
- delete(endpoint, body) {
1280
- return this.makeRequest("DELETE", endpoint, body);
1400
+ delete(endpoint, params) {
1401
+ return this.makeRequest("delete", endpoint, params);
1281
1402
  }
1282
- async put(endpoint, body) {
1283
- return this.makeRequest("PUT", endpoint, body);
1403
+ put(endpoint, params) {
1404
+ return this.makeRequest("put", endpoint, params);
1284
1405
  }
1285
1406
  };
1286
1407
 
@@ -1358,7 +1479,7 @@ var MessageManager = class extends BaseManager {
1358
1479
  * Tell BaseManager how to find the ID for Messages
1359
1480
  */
1360
1481
  extractId(data) {
1361
- return data._id ?? data.id;
1482
+ return data._id;
1362
1483
  }
1363
1484
  /**
1364
1485
  * Tell BaseManager how to build a Message
@@ -1383,20 +1504,31 @@ var MessageManager = class extends BaseManager {
1383
1504
  * const history = await channel.messages.fetchMany({ limit: 20, before: "01H..." });
1384
1505
  */
1385
1506
  async fetchMany(options = {}) {
1386
- const params = new URLSearchParams();
1387
- if (options.limit !== void 0) params.append("limit", options.limit.toString());
1388
- if (options.before !== void 0) params.append("before", options.before);
1389
- if (options.after !== void 0) params.append("after", options.after);
1390
- if (options.sort !== void 0) params.append("sort", options.sort);
1391
- if (options.nearby !== void 0) params.append("nearby", options.nearby);
1392
- if (options.includeUsers !== void 0) params.append("include_users", options.includeUsers.toString());
1393
- const queryString = params.toString();
1394
- const endpoint = `/channels/${this.channel.id}/messages${queryString ? `?${queryString}` : ""}`;
1395
- const data = await this.client.rest.get(endpoint);
1396
- const rawMessages = Array.isArray(data) ? data : data.messages || [];
1397
- if (!Array.isArray(data) && data.users) {
1398
- for (const userData of data.users) {
1399
- this.client.users._add(userData);
1507
+ const endpoint = `/channels/${this.channel.id}/messages`;
1508
+ const query = {};
1509
+ if (options.limit !== void 0) query.limit = options.limit;
1510
+ if (options.before !== void 0) query.before = options.before;
1511
+ if (options.after !== void 0) query.after = options.after;
1512
+ if (options.sort !== void 0) query.sort = options.sort;
1513
+ if (options.nearby !== void 0) query.nearby = options.nearby;
1514
+ if (options.includeUsers !== void 0) query.include_users = options.includeUsers;
1515
+ const data = await this.client.rest.get(endpoint, query);
1516
+ let rawMessages;
1517
+ if (Array.isArray(data)) {
1518
+ rawMessages = data;
1519
+ } else {
1520
+ rawMessages = data.messages;
1521
+ if (data.users) {
1522
+ for (const userData of data.users) {
1523
+ this.client.users._add(userData);
1524
+ }
1525
+ }
1526
+ if (data.members && this.channel.isText()) {
1527
+ const serverId = this.channel.serverId;
1528
+ const server = await this.client.servers.fetch(serverId);
1529
+ for (const memberData of data.members) {
1530
+ server.members._add(memberData);
1531
+ }
1400
1532
  }
1401
1533
  }
1402
1534
  const fetched = new Collection();
@@ -1417,18 +1549,19 @@ var MessageManager = class extends BaseManager {
1417
1549
  * @returns A promise that resolves to the sent Message.
1418
1550
  */
1419
1551
  async send(contentOrOptions) {
1420
- const payload = typeof contentOrOptions === "string" ? { content: contentOrOptions } : { ...contentOrOptions };
1421
- if (payload.embeds) {
1422
- payload.embeds = payload.embeds.map(
1423
- (embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
1424
- );
1552
+ const opts = typeof contentOrOptions === "string" ? { content: contentOrOptions } : contentOrOptions;
1553
+ const payload = {};
1554
+ if (opts.embeds && opts.embeds.length) {
1555
+ payload.embeds = opts.embeds.map((embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed);
1425
1556
  }
1426
- if (payload.attachments) {
1427
- payload.attachments = await Promise.all(
1428
- payload.attachments.map(
1429
- (attachment) => resolveAttachment(this.client.rest, attachment, "attachments")
1430
- )
1557
+ if (opts.attachments && opts.attachments.length > 0) {
1558
+ const resolved = await Promise.all(
1559
+ opts.attachments.map((attachment) => resolveAttachment(this.client.rest, attachment, "attachments"))
1431
1560
  );
1561
+ const validAttachments = resolved.filter((id) => id !== void 0);
1562
+ if (validAttachments.length > 0) {
1563
+ payload.attachments = validAttachments;
1564
+ }
1432
1565
  }
1433
1566
  const data = await this.client.rest.post(`/channels/${this.channel.id}/messages`, payload);
1434
1567
  return new Message(this.client, data);
@@ -1441,19 +1574,20 @@ var MessageManager = class extends BaseManager {
1441
1574
  */
1442
1575
  async edit(message, contentOrOptions) {
1443
1576
  const id = this.resolveId(message);
1444
- const payload = typeof contentOrOptions === "string" ? { content: contentOrOptions } : { ...contentOrOptions };
1445
- if (payload.embeds) {
1446
- payload.embeds = payload.embeds.map(
1447
- (embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
1448
- );
1577
+ const opts = typeof contentOrOptions === "string" ? { content: contentOrOptions } : contentOrOptions;
1578
+ const payload = {};
1579
+ if (opts.content !== void 0) {
1580
+ payload.content = opts.content;
1449
1581
  }
1450
- const data = await this.client.rest.patch(`/channels/${this.channel.id}/messages/${id}`, payload);
1451
- const existing = this.cache.get(id);
1452
- if (existing) {
1453
- existing._patch(data);
1454
- return existing;
1582
+ if (opts.embeds !== void 0) {
1583
+ if (opts.embeds === null) {
1584
+ payload.embeds = [];
1585
+ } else {
1586
+ payload.embeds = opts.embeds.map((embed) => "toJSON" in embed ? embed.toJSON() : embed);
1587
+ }
1455
1588
  }
1456
- return new Message(this.client, data);
1589
+ const data = await this.client.rest.patch(`/channels/${this.channel.id}/messages/${id}`, payload);
1590
+ return this._add(data);
1457
1591
  }
1458
1592
  /**
1459
1593
  * Deletes a message from the channel.
@@ -1470,7 +1604,7 @@ var MessageManager = class extends BaseManager {
1470
1604
  */
1471
1605
  async pin(message) {
1472
1606
  const id = this.resolveId(message);
1473
- await this.client.rest.post(`/channels/${this.channel.id}/messages/${id}/pin`, {});
1607
+ await this.client.rest.post(`/channels/${this.channel.id}/messages/${id}/pin`);
1474
1608
  const existing = this.cache.get(id);
1475
1609
  if (existing) existing.pinned = true;
1476
1610
  }
@@ -1516,12 +1650,14 @@ var MessageManager = class extends BaseManager {
1516
1650
  async removeReaction(message, reaction, userId, removeAll) {
1517
1651
  const id = this.resolveId(message);
1518
1652
  const targetUser = userId ? this.client.users.resolveId(userId) : void 0;
1519
- const params = new URLSearchParams();
1520
- if (targetUser) params.append("user_id", targetUser);
1521
- if (removeAll) params.append("remove_all", "true");
1522
- const queryString = params.toString();
1523
- const endpoint = `/channels/${this.channel.id}/messages/${id}/reactions/${encodeURIComponent(reaction)}${queryString ? `?${queryString}` : ""}`;
1524
- await this.client.rest.delete(endpoint);
1653
+ const endpoint = `/channels/${this.channel.id}/messages/${id}/reactions/${reaction}`;
1654
+ const query = {};
1655
+ if (targetUser) {
1656
+ query.user_id = targetUser;
1657
+ } else if (removeAll) {
1658
+ query.remove_all = true;
1659
+ }
1660
+ await this.client.rest.delete(endpoint, query);
1525
1661
  }
1526
1662
  /**
1527
1663
  * Remove all reactions from a message
@@ -1584,12 +1720,6 @@ var MessageCollector = class extends Collector {
1584
1720
  };
1585
1721
 
1586
1722
  // src/structures/BaseChannel.ts
1587
- var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
1588
- ChannelType2["TEXT"] = "TextChannel";
1589
- ChannelType2["DM"] = "DirectMessage";
1590
- ChannelType2["GROUP"] = "Group";
1591
- return ChannelType2;
1592
- })(ChannelType || {});
1593
1723
  var BaseChannel = class extends Base {
1594
1724
  type;
1595
1725
  messages;
@@ -1713,13 +1843,13 @@ var BaseChannel = class extends Base {
1713
1843
  });
1714
1844
  }
1715
1845
  isText() {
1716
- return this.type === "TextChannel" /* TEXT */;
1846
+ return this.type === "TextChannel";
1717
1847
  }
1718
1848
  isDM() {
1719
- return this.type === "DirectMessage" /* DM */;
1849
+ return this.type === "DirectMessage";
1720
1850
  }
1721
1851
  isGroup() {
1722
- return this.type === "Group" /* GROUP */;
1852
+ return this.type === "Group";
1723
1853
  }
1724
1854
  };
1725
1855
 
@@ -1739,7 +1869,9 @@ var TextChannel = class extends BaseChannel {
1739
1869
  this.serverId = data.server;
1740
1870
  this.defaultPermissions = data.default_permissions;
1741
1871
  this.description = data.description;
1742
- this.icon = data.icon;
1872
+ if (data.icon !== void 0) {
1873
+ this.icon = data.icon ? new Attachment(this.client, data.icon) : null;
1874
+ }
1743
1875
  this.lastMessageId = data.last_message_id;
1744
1876
  this.nsfw = data.nsfw ?? false;
1745
1877
  this.slowmode = data.slowmode ?? 0;
@@ -1809,6 +1941,9 @@ var TextChannel = class extends BaseChannel {
1809
1941
  async setCategory(category) {
1810
1942
  const serverId = this.serverId;
1811
1943
  const server = await this.client.servers.fetch(serverId);
1944
+ if (!server.categories || server.categories.length === 0) {
1945
+ throw new Error("This server has no categories to move the channel into.");
1946
+ }
1812
1947
  const categories = server.categories.map((c) => ({
1813
1948
  id: c.id,
1814
1949
  title: c.title,
@@ -1839,6 +1974,9 @@ var TextChannel = class extends BaseChannel {
1839
1974
  async setPosition(position) {
1840
1975
  const serverId = this.serverId;
1841
1976
  const server = await this.client.servers.fetch(serverId);
1977
+ if (!server.categories || server.categories.length === 0) {
1978
+ throw new Error("This server has no categories to move the channel into.");
1979
+ }
1842
1980
  const categories = server.categories.map((c) => ({
1843
1981
  id: c.id,
1844
1982
  title: c.title,
@@ -2026,14 +2164,14 @@ var GroupChannel = class extends BaseChannel {
2026
2164
  // src/utils/ChannelFactory.ts
2027
2165
  function createChannel(client, data) {
2028
2166
  switch (data.channel_type) {
2029
- case "TextChannel" /* TEXT */:
2167
+ case "TextChannel":
2030
2168
  return new TextChannel(client, data);
2031
- case "DirectMessage" /* DM */:
2169
+ case "DirectMessage":
2032
2170
  return new DMChannel(client, data);
2033
- case "Group" /* GROUP */:
2171
+ case "Group":
2034
2172
  return new GroupChannel(client, data);
2035
2173
  default:
2036
- client.emit("debug", `Received unknown channel type: ${data.type}`);
2174
+ client.emit("debug", `Received unknown channel type: ${data.channel_type}`);
2037
2175
  return new UnknownChannel(client, data);
2038
2176
  }
2039
2177
  }
@@ -2342,7 +2480,7 @@ var ChannelManager = class extends BaseManager {
2342
2480
  super(client, limit);
2343
2481
  }
2344
2482
  extractId(data) {
2345
- return data._id ?? data.id;
2483
+ return data._id;
2346
2484
  }
2347
2485
  construct(data) {
2348
2486
  return createChannel(this.client, data);
@@ -2435,8 +2573,14 @@ var ChannelManager = class extends BaseManager {
2435
2573
  else payload.description = options.description;
2436
2574
  }
2437
2575
  if (options.icon !== void 0) {
2438
- if (options.icon === null) remove.push("Icon");
2439
- else payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
2576
+ if (options.icon === null) {
2577
+ remove.push("Icon");
2578
+ } else {
2579
+ const resolvedIcon = await resolveAttachment(this.client.rest, options.icon, "icons");
2580
+ if (resolvedIcon !== void 0) {
2581
+ payload.icon = resolvedIcon;
2582
+ }
2583
+ }
2440
2584
  }
2441
2585
  if (remove.length > 0) payload.remove = remove;
2442
2586
  if (Object.keys(payload).length === 0) return this.fetch(channel);
@@ -2521,7 +2665,7 @@ var ChannelManager = class extends BaseManager {
2521
2665
  * await client.channels.pin("CHANNEL_ID", "MESSAGE_ID");
2522
2666
  */
2523
2667
  async pin(id, messageId) {
2524
- await this.client.rest.post(`/channels/${id}/pins/${messageId}`);
2668
+ await this.client.rest.post(`/channels/${id}/messages/${messageId}/pin`);
2525
2669
  }
2526
2670
  /**
2527
2671
  * Unpin a message
@@ -2551,7 +2695,7 @@ var ChannelManager = class extends BaseManager {
2551
2695
  if ("id" in msg) return msg.id;
2552
2696
  throw new TypeError("Invalid MessageResolvable provided. Expected a Message object or a string ID/Mention.");
2553
2697
  });
2554
- await this.client.rest.delete(`/channels/${id}/messages/bulk`, { messages: messageIds });
2698
+ await this.client.rest.delete(`/channels/${id}/messages/bulk`, { ids: messageIds });
2555
2699
  }
2556
2700
  };
2557
2701
 
@@ -2650,20 +2794,20 @@ var Member = class extends Base {
2650
2794
  canRecieve = false;
2651
2795
  // Member roles manager
2652
2796
  roles;
2653
- constructor(client, data) {
2654
- super(client, { _id: data.user._id });
2655
- this.serverId = data.serverId || data.server_id;
2656
- this.joinedAt = new Date(data.joinedAt || data.joined_at);
2797
+ constructor(client, data, serverId) {
2798
+ super(client, { _id: data._id?.user });
2799
+ this.serverId = data._id?.server ?? serverId;
2800
+ this.joinedAt = new Date(data.joined_at);
2657
2801
  this.roles = new MemberRoleManager(this);
2658
2802
  this._patch(data);
2659
2803
  }
2660
2804
  _patch(data) {
2661
2805
  if (data.nickname !== void 0) this.nickname = data.nickname;
2662
- if (data.avatar !== void 0) this.avatar = data.avatar;
2806
+ if (data.avatar !== void 0) this.avatar = data.avatar ? new Attachment(this.client, data.avatar) : null;
2663
2807
  if (data.roles !== void 0) this._roles = data.roles;
2664
2808
  if (data.timeout !== void 0) this.timeout = data.timeout ? new Date(data.timeout) : null;
2665
- if (data.can_publish !== void 0) this.canPublish = data.canPublish;
2666
- if (data.can_recieve !== void 0) this.canRecieve = data.canRecieve;
2809
+ if (data.can_publish !== void 0) this.canPublish = data.can_publish;
2810
+ if (data.can_receive !== void 0) this.canRecieve = data.can_receive;
2667
2811
  }
2668
2812
  /**
2669
2813
  * Get member role IDs
@@ -2808,17 +2952,14 @@ var MemberManager = class extends BaseManager {
2808
2952
  * @internal
2809
2953
  */
2810
2954
  extractId(data) {
2811
- return data.user_id ?? data.id ?? (typeof data._id === "string" ? data._id : data._id?.user);
2955
+ return data._id?.user;
2812
2956
  }
2813
2957
  /**
2814
2958
  * Tell BaseManager how to build a Member
2815
2959
  * @internal
2816
2960
  */
2817
2961
  construct(data) {
2818
- if (!data.server_id && !data.serverId) {
2819
- data.serverId = this.server.id;
2820
- }
2821
- return new Member(this.client, data);
2962
+ return new Member(this.client, data, this.server.id);
2822
2963
  }
2823
2964
  /**
2824
2965
  * Resolve a string or mention to Member
@@ -2877,23 +3018,22 @@ var MemberManager = class extends BaseManager {
2877
3018
  * const onlineMembers = await server.members.fetchMany({ exclude_offline: true });
2878
3019
  */
2879
3020
  async fetchMany(options = {}) {
2880
- const params = new URLSearchParams();
2881
- if (options.exclude_offline !== void 0) {
2882
- params.append("exclude_offline", options.exclude_offline.toString());
3021
+ const query = {};
3022
+ if (options.excludeOffline !== void 0) {
3023
+ query.exclude_offline = options.excludeOffline;
2883
3024
  }
2884
- const queryString = params.toString();
2885
- const endpoint = `/servers/${this.server.id}/members${queryString ? `?${queryString}` : ""}`;
2886
- const data = await this.client.rest.get(endpoint);
2887
- if (data.users && Array.isArray(data.users)) {
3025
+ const data = await this.client.rest.get(`/servers/${this.server.id}/members`, query);
3026
+ if (data.users) {
2888
3027
  for (const userData of data.users) {
2889
3028
  this.client.users._add(userData);
2890
3029
  }
2891
3030
  }
2892
3031
  const fetched = new Collection();
2893
- const rawMembers = data.members || (Array.isArray(data) ? data : []);
2894
- for (const rawMember of rawMembers) {
2895
- const member = this._add(rawMember);
2896
- fetched.set(member.id, member);
3032
+ if (data.members) {
3033
+ for (const rawMember of data.members) {
3034
+ const member = this._add(rawMember);
3035
+ fetched.set(member.id, member);
3036
+ }
2897
3037
  }
2898
3038
  return fetched;
2899
3039
  }
@@ -2996,11 +3136,17 @@ var ServerChannelManager = class {
2996
3136
  async create(options) {
2997
3137
  if (!options.name) throw new Error("A channel name must be provided.");
2998
3138
  const payload = {
2999
- name: options.name,
3000
- type: options.type ?? "Text",
3001
- description: options.description,
3002
- nsfw: options.nsfw ?? false
3139
+ name: options.name
3003
3140
  };
3141
+ if (options.nsfw !== void 0) {
3142
+ payload.nsfw = options.nsfw;
3143
+ }
3144
+ if (options.type !== void 0) {
3145
+ payload.type = options.type;
3146
+ }
3147
+ if (options.description !== void 0) {
3148
+ payload.description = options.description;
3149
+ }
3004
3150
  if (options.type === "Voice" && options.voice?.max_users) {
3005
3151
  payload.voice = { max_users: options.voice.max_users };
3006
3152
  }
@@ -3033,14 +3179,14 @@ var Role = class extends Base {
3033
3179
  */
3034
3180
  _patch(data) {
3035
3181
  if (data.name !== void 0) this.name = data.name;
3036
- if (data.color !== void 0) this.color = data.color;
3182
+ if (data.colour !== void 0) this.color = data.colour;
3037
3183
  if (data.hoist !== void 0) this.hoist = data.hoist;
3038
3184
  if (data.rank !== void 0) this.rank = data.rank;
3039
- if (data.icon !== void 0) this.icon = new Attachment(this.client, data.icon);
3185
+ if (data.icon !== void 0) this.icon = data.icon !== null ? new Attachment(this.client, data.icon) : null;
3040
3186
  if (data.permissions !== void 0) {
3041
3187
  try {
3042
3188
  if (typeof data.permissions === "object" && data.permissions !== null) {
3043
- const allowPerms = data.permissions.a ?? data.permissions[0] ?? 0;
3189
+ const allowPerms = data.permissions.a ?? 0;
3044
3190
  this._permissions = BigInt(allowPerms);
3045
3191
  } else {
3046
3192
  this._permissions = BigInt(data.permissions);
@@ -3243,7 +3389,7 @@ var RoleManager = class extends BaseManager {
3243
3389
  * Tell BaseManager how to find the ID for Roles
3244
3390
  */
3245
3391
  extractId(data) {
3246
- return data._id ?? data.id;
3392
+ return data._id;
3247
3393
  }
3248
3394
  /**
3249
3395
  * Tell BaseManager how to build a Role
@@ -3259,7 +3405,7 @@ var RoleManager = class extends BaseManager {
3259
3405
  * @returns The newly created or updated Role object.
3260
3406
  */
3261
3407
  _add(data, idParam) {
3262
- const id = idParam ?? data._id ?? data.id;
3408
+ const id = idParam ?? data._id;
3263
3409
  const existing = this.cache.get(id);
3264
3410
  if (existing) {
3265
3411
  existing._patch(data);
@@ -3322,7 +3468,7 @@ var RoleManager = class extends BaseManager {
3322
3468
  name: options.name
3323
3469
  };
3324
3470
  const data = await this.client.rest.post(`/servers/${this.server.id}/roles`, payload);
3325
- return this._add(data);
3471
+ return this._add(data.role);
3326
3472
  }
3327
3473
  /**
3328
3474
  * Fetches a Role from the API or resolves it from the local cache.
@@ -3387,7 +3533,10 @@ var RoleManager = class extends BaseManager {
3387
3533
  if (options.icon === null) {
3388
3534
  remove.push("Icon");
3389
3535
  } else {
3390
- payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
3536
+ const resolvedIcon = await resolveAttachment(this.client.rest, options.icon, "icons");
3537
+ if (resolvedIcon !== void 0) {
3538
+ payload.icon = resolvedIcon;
3539
+ }
3391
3540
  }
3392
3541
  }
3393
3542
  if (remove.length > 0) {
@@ -3396,7 +3545,8 @@ var RoleManager = class extends BaseManager {
3396
3545
  if (Object.keys(payload).length === 0) {
3397
3546
  return this.fetch(id);
3398
3547
  }
3399
- const data = await this.client.rest.patch(`/servers/${this.server.id}/roles/${id}`, payload);
3548
+ const endpoint = `/servers/${this.server.id}/roles/${id}`;
3549
+ const data = await this.client.rest.patch(endpoint, payload);
3400
3550
  return this._add(data, id);
3401
3551
  }
3402
3552
  /**
@@ -3472,7 +3622,7 @@ var RoleManager = class extends BaseManager {
3472
3622
  const payload = {
3473
3623
  ranks: mappedIds
3474
3624
  };
3475
- const data = await this.client.rest.put(`/servers/${this.server.id}/roles`, payload);
3625
+ const data = await this.client.rest.patch(`/servers/${this.server.id}/roles/ranks`, payload);
3476
3626
  this.server._patch(data);
3477
3627
  return this.server;
3478
3628
  }
@@ -3484,7 +3634,7 @@ var ServerInvite = class {
3484
3634
  creatorId;
3485
3635
  channelId;
3486
3636
  constructor(data) {
3487
- this.code = data._id ?? data.code;
3637
+ this.code = data._id;
3488
3638
  this.creatorId = data.creator;
3489
3639
  this.channelId = data.channel;
3490
3640
  }
@@ -3501,7 +3651,7 @@ var ServerInviteManager = class extends BaseManager {
3501
3651
  this.server = server;
3502
3652
  }
3503
3653
  extractId(data) {
3504
- return data._id ?? data.code;
3654
+ return data._id;
3505
3655
  }
3506
3656
  construct(data) {
3507
3657
  return new ServerInvite(data);
@@ -3511,9 +3661,8 @@ var ServerInviteManager = class extends BaseManager {
3511
3661
  */
3512
3662
  async fetch() {
3513
3663
  const data = await this.client.rest.get(`/servers/${this.server.id}/invites`);
3514
- const rawInvites = Array.isArray(data) ? data : [];
3515
3664
  const fetched = new Collection();
3516
- for (const raw of rawInvites) {
3665
+ for (const raw of data) {
3517
3666
  const invite = this._add(raw);
3518
3667
  fetched.set(invite.code, invite);
3519
3668
  }
@@ -3526,7 +3675,7 @@ var ServerBan = class {
3526
3675
  userId;
3527
3676
  reason;
3528
3677
  constructor(data) {
3529
- this.userId = data._id?.user ?? data.id;
3678
+ this.userId = data._id?.user;
3530
3679
  this.reason = data.reason ?? null;
3531
3680
  }
3532
3681
  _patch(data) {
@@ -3633,7 +3782,7 @@ var Server = class extends Base {
3633
3782
  ownerId;
3634
3783
  analytics = false;
3635
3784
  banner = null;
3636
- categories = [];
3785
+ categories = null;
3637
3786
  description = null;
3638
3787
  discoverable = false;
3639
3788
  flags = 0;
@@ -3686,13 +3835,6 @@ var Server = class extends Base {
3686
3835
  this.roles._add({ id, ...roleData });
3687
3836
  }
3688
3837
  }
3689
- if (data.emojis !== void 0) {
3690
- if (Array.isArray(data.emojis)) {
3691
- for (const emoji of data.emojis) {
3692
- this.emojis._add(emoji);
3693
- }
3694
- }
3695
- }
3696
3838
  if (clear && Array.isArray(clear)) {
3697
3839
  for (const field of clear) {
3698
3840
  switch (field) {
@@ -3740,7 +3882,7 @@ var ServerManager = class extends BaseManager {
3740
3882
  * Tell BaseManager how to find the ID for Servers
3741
3883
  */
3742
3884
  extractId(data) {
3743
- return data._id ?? data.id;
3885
+ return data._id;
3744
3886
  }
3745
3887
  /**
3746
3888
  * Tell BaseManager how to build a Server
@@ -3781,21 +3923,19 @@ var ServerManager = class extends BaseManager {
3781
3923
  payload.system_messages = {};
3782
3924
  const sm = options.systemMessages;
3783
3925
  if (sm.userJoined !== void 0) {
3784
- if (sm.userJoined === null) remove.push("SystemMessageUserJoined");
3785
- else payload.system_messages.user_joined = sm.userJoined;
3926
+ payload.system_messages.user_joined = sm.userJoined;
3786
3927
  }
3787
3928
  if (sm.userLeft !== void 0) {
3788
- if (sm.userLeft === null) remove.push("SystemMessageUserLeft");
3789
- else payload.system_messages.user_left = sm.userLeft;
3929
+ payload.system_messages.user_left = sm.userLeft;
3790
3930
  }
3791
3931
  if (sm.userKicked !== void 0) {
3792
- if (sm.userKicked === null) remove.push("SystemMessageUserKicked");
3793
- else payload.system_messages.user_kicked = sm.userKicked;
3932
+ payload.system_messages.user_kicked = sm.userKicked;
3794
3933
  }
3795
3934
  if (sm.userBanned !== void 0) {
3796
- if (sm.userBanned === null) remove.push("SystemMessageUserBanned");
3797
- else payload.system_messages.user_banned = sm.userBanned;
3935
+ payload.system_messages.user_banned = sm.userBanned;
3798
3936
  }
3937
+ } else if (options.systemMessages === null) {
3938
+ remove.push("SystemMessages");
3799
3939
  }
3800
3940
  if (options.categories !== void 0) payload.categories = options.categories;
3801
3941
  if (options.analytics !== void 0) payload.analytics = options.analytics;
@@ -3818,7 +3958,7 @@ var UserManager = class extends BaseManager {
3818
3958
  * Tell BaseManager how to find the ID for Users
3819
3959
  */
3820
3960
  extractId(data) {
3821
- return data._id ?? data.id;
3961
+ return data._id;
3822
3962
  }
3823
3963
  /**
3824
3964
  * Tell BaseManager how to build a User
@@ -3953,7 +4093,7 @@ var UserManager = class extends BaseManager {
3953
4093
  if (Object.keys(payload).length === 0) {
3954
4094
  return this.fetch("@me");
3955
4095
  }
3956
- const data = await this.client.rest.patch(`/users/@me`, payload);
4096
+ const data = await this.client.rest.patch(`/users/${this.client.user?.id}`, payload);
3957
4097
  return this._add(data);
3958
4098
  }
3959
4099
  /**
@@ -4113,15 +4253,18 @@ var EmbedBuilder = class {
4113
4253
  return { ...this.data };
4114
4254
  }
4115
4255
  };
4256
+
4257
+ // src/index.ts
4258
+ var API = __toESM(require("stoat-api"), 1);
4116
4259
  // Annotate the CommonJS export names for ESM import in node:
4117
4260
  0 && (module.exports = {
4261
+ API,
4118
4262
  Attachment,
4119
4263
  AttachmentBuilder,
4120
4264
  Base,
4121
4265
  BaseChannel,
4122
4266
  BitField,
4123
4267
  ChannelManager,
4124
- ChannelType,
4125
4268
  Client,
4126
4269
  ClientUser,
4127
4270
  Collection,
@@ -4151,8 +4294,6 @@ var EmbedBuilder = class {
4151
4294
  TextChannel,
4152
4295
  UnknownChannel,
4153
4296
  User,
4154
- UserManager,
4155
- UserPresence,
4156
- UserRelationship
4297
+ UserManager
4157
4298
  });
4158
4299
  //# sourceMappingURL=index.cjs.map