@stoatx/client 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1353 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +854 -193
- package/dist/index.d.ts +854 -193
- package/dist/index.js +1345 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,23 +31,31 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
Attachment: () => Attachment,
|
|
34
|
+
AttachmentBuilder: () => AttachmentBuilder,
|
|
34
35
|
Base: () => Base,
|
|
35
36
|
BaseChannel: () => BaseChannel,
|
|
37
|
+
BitField: () => BitField,
|
|
36
38
|
ChannelManager: () => ChannelManager,
|
|
37
39
|
ChannelType: () => ChannelType,
|
|
38
40
|
Client: () => Client,
|
|
39
41
|
ClientUser: () => ClientUser,
|
|
40
42
|
Collection: () => Collection,
|
|
43
|
+
Collector: () => Collector,
|
|
41
44
|
DMChannel: () => DMChannel,
|
|
42
45
|
EmbedBuilder: () => EmbedBuilder,
|
|
46
|
+
Emoji: () => Emoji,
|
|
47
|
+
EmojiManager: () => EmojiManager,
|
|
43
48
|
GatewayManager: () => GatewayManager,
|
|
44
49
|
Member: () => Member,
|
|
45
50
|
MemberManager: () => MemberManager,
|
|
46
51
|
Message: () => Message,
|
|
52
|
+
MessageCollector: () => MessageCollector,
|
|
47
53
|
MessageManager: () => MessageManager,
|
|
54
|
+
MessageReaction: () => MessageReaction,
|
|
48
55
|
PermissionFlags: () => PermissionFlags,
|
|
49
56
|
Permissions: () => Permissions,
|
|
50
57
|
RESTManager: () => RESTManager,
|
|
58
|
+
ReactionCollector: () => ReactionCollector,
|
|
51
59
|
Role: () => Role,
|
|
52
60
|
RoleManager: () => RoleManager,
|
|
53
61
|
Server: () => Server,
|
|
@@ -65,7 +73,7 @@ __export(index_exports, {
|
|
|
65
73
|
module.exports = __toCommonJS(index_exports);
|
|
66
74
|
|
|
67
75
|
// src/client/Client.ts
|
|
68
|
-
var
|
|
76
|
+
var import_events2 = require("events");
|
|
69
77
|
|
|
70
78
|
// src/gateway/GatewayManager.ts
|
|
71
79
|
var import_ws = __toESM(require("ws"), 1);
|
|
@@ -106,7 +114,7 @@ var Base = class _Base {
|
|
|
106
114
|
};
|
|
107
115
|
|
|
108
116
|
// src/structures/Message.ts
|
|
109
|
-
var
|
|
117
|
+
var util2 = __toESM(require("util"), 1);
|
|
110
118
|
|
|
111
119
|
// src/structures/Attachment.ts
|
|
112
120
|
var Attachment = class extends Base {
|
|
@@ -153,6 +161,306 @@ var Attachment = class extends Base {
|
|
|
153
161
|
|
|
154
162
|
// src/structures/Message.ts
|
|
155
163
|
var import_ulid = require("ulid");
|
|
164
|
+
|
|
165
|
+
// src/utils/Collector.ts
|
|
166
|
+
var import_events = require("events");
|
|
167
|
+
|
|
168
|
+
// src/utils/Collection.ts
|
|
169
|
+
var Collection = class _Collection extends Map {
|
|
170
|
+
limit;
|
|
171
|
+
constructor(limit = Infinity) {
|
|
172
|
+
super();
|
|
173
|
+
this.limit = limit;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Overrides the default set method to enforce the maximum cache size.
|
|
177
|
+
*/
|
|
178
|
+
set(key, value) {
|
|
179
|
+
if (this.limit === 0) return this;
|
|
180
|
+
if (this.size >= this.limit && !this.has(key)) {
|
|
181
|
+
const oldestKey = this.keys().next().value;
|
|
182
|
+
if (oldestKey !== void 0) {
|
|
183
|
+
this.delete(oldestKey);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return super.set(key, value);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Finds the first item where the given function returns true.
|
|
190
|
+
*/
|
|
191
|
+
find(fn) {
|
|
192
|
+
for (const [key, val] of this) {
|
|
193
|
+
if (fn(val, key, this)) return val;
|
|
194
|
+
}
|
|
195
|
+
return void 0;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Returns a new Collection containing only the items where the function returns true.
|
|
199
|
+
*/
|
|
200
|
+
filter(fn) {
|
|
201
|
+
const results = new _Collection();
|
|
202
|
+
for (const [key, val] of this) {
|
|
203
|
+
if (fn(val, key, this)) results.set(key, val);
|
|
204
|
+
}
|
|
205
|
+
return results;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Maps each item to a new array of values.
|
|
209
|
+
*/
|
|
210
|
+
map(fn) {
|
|
211
|
+
const results = [];
|
|
212
|
+
for (const [key, val] of this) {
|
|
213
|
+
results.push(fn(val, key, this));
|
|
214
|
+
}
|
|
215
|
+
return results;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Gets the very first value in the Collection (based on insertion order).
|
|
219
|
+
*/
|
|
220
|
+
first() {
|
|
221
|
+
return this.values().next().value;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Gets the very last value in the Collection.
|
|
225
|
+
*/
|
|
226
|
+
last() {
|
|
227
|
+
const arr = Array.from(this.values());
|
|
228
|
+
return arr[arr.length - 1];
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Checks if at least one item matches the condition.
|
|
232
|
+
*/
|
|
233
|
+
some(fn) {
|
|
234
|
+
for (const [key, val] of this) {
|
|
235
|
+
if (fn(val, key, this)) return true;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// src/utils/Collector.ts
|
|
242
|
+
var Collector = class extends import_events.EventEmitter {
|
|
243
|
+
client;
|
|
244
|
+
filter;
|
|
245
|
+
options;
|
|
246
|
+
collected;
|
|
247
|
+
ended = false;
|
|
248
|
+
_timeout = null;
|
|
249
|
+
_idletimeout = null;
|
|
250
|
+
constructor(client, options = {}) {
|
|
251
|
+
super();
|
|
252
|
+
this.client = client;
|
|
253
|
+
this.options = options;
|
|
254
|
+
this.filter = options.filter ?? (() => true);
|
|
255
|
+
this.collected = new Collection();
|
|
256
|
+
if (options.time) {
|
|
257
|
+
this._timeout = setTimeout(() => this.stop("time"), options.time);
|
|
258
|
+
}
|
|
259
|
+
if (options.idle) {
|
|
260
|
+
this._idletimeout = setTimeout(() => this.stop("idle"), options.idle);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Evaluates an item and possibly passes it to the collector
|
|
265
|
+
*/
|
|
266
|
+
handleCollect(item, ...args) {
|
|
267
|
+
if (this.ended) return;
|
|
268
|
+
if (!this.filter(item, ...args)) return;
|
|
269
|
+
const key = this.collect(item, ...args);
|
|
270
|
+
if (key !== null && key !== void 0) {
|
|
271
|
+
this.collected.set(key, item);
|
|
272
|
+
this.emit("collect", item, ...args);
|
|
273
|
+
if (this._idletimeout) {
|
|
274
|
+
clearTimeout(this._idletimeout);
|
|
275
|
+
this._idletimeout = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
276
|
+
}
|
|
277
|
+
this.checkEnd();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Evaluates an item and possibly removes it from the collector
|
|
282
|
+
*/
|
|
283
|
+
handleDispose(item, ...args) {
|
|
284
|
+
if (this.ended) return;
|
|
285
|
+
if (!this.options.dispose) return;
|
|
286
|
+
const key = this.dispose(item, ...args);
|
|
287
|
+
if (key !== null && key !== void 0) {
|
|
288
|
+
this.collected.delete(key);
|
|
289
|
+
this.emit("dispose", item, ...args);
|
|
290
|
+
this.checkEnd();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Stops the collector.
|
|
295
|
+
*/
|
|
296
|
+
stop(reason = "user") {
|
|
297
|
+
if (this.ended) return;
|
|
298
|
+
this.ended = true;
|
|
299
|
+
if (this._timeout) clearTimeout(this._timeout);
|
|
300
|
+
if (this._idletimeout) clearTimeout(this._idletimeout);
|
|
301
|
+
this.removeAllListeners("collect");
|
|
302
|
+
this.removeAllListeners("dispose");
|
|
303
|
+
this.emit("end", this.collected, reason);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check if we should end upon collecting/disposing
|
|
307
|
+
*/
|
|
308
|
+
checkEnd() {
|
|
309
|
+
const reason = this.endReason();
|
|
310
|
+
if (reason) this.stop(reason);
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Check if there's a reason to end
|
|
314
|
+
*/
|
|
315
|
+
endReason() {
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Allows iterating over collected items asynchronously.
|
|
320
|
+
* @example
|
|
321
|
+
* for await (const [id, message] of collector) {
|
|
322
|
+
* console.log(`Received message: ${message.content}`);
|
|
323
|
+
* }
|
|
324
|
+
*/
|
|
325
|
+
async *[Symbol.asyncIterator]() {
|
|
326
|
+
const queue = [];
|
|
327
|
+
let resolve = null;
|
|
328
|
+
const onCollect = (item, ...args) => {
|
|
329
|
+
const key = this.collect(item, ...args);
|
|
330
|
+
if (key !== null && key !== void 0) {
|
|
331
|
+
queue.push([key, item]);
|
|
332
|
+
}
|
|
333
|
+
if (resolve) {
|
|
334
|
+
resolve();
|
|
335
|
+
resolve = null;
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
const onEnd = () => {
|
|
339
|
+
if (resolve) {
|
|
340
|
+
resolve();
|
|
341
|
+
resolve = null;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
this.on("collect", onCollect);
|
|
345
|
+
this.on("end", onEnd);
|
|
346
|
+
try {
|
|
347
|
+
while (true) {
|
|
348
|
+
if (queue.length > 0) {
|
|
349
|
+
yield queue.shift();
|
|
350
|
+
} else if (this.ended) {
|
|
351
|
+
break;
|
|
352
|
+
} else {
|
|
353
|
+
await new Promise((res) => {
|
|
354
|
+
resolve = res;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
} finally {
|
|
359
|
+
this.removeListener("collect", onCollect);
|
|
360
|
+
this.removeListener("end", onEnd);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// src/structures/MessageReaction.ts
|
|
366
|
+
var util = __toESM(require("util"), 1);
|
|
367
|
+
var MessageReaction = class {
|
|
368
|
+
constructor(client, data) {
|
|
369
|
+
this.client = client;
|
|
370
|
+
this.message = data.message;
|
|
371
|
+
this.emoji = this.client.emojis.cache.get(data.emojiId) || data.emojiId;
|
|
372
|
+
this.users = new Collection();
|
|
373
|
+
if (data.users) {
|
|
374
|
+
for (const userId of data.users) {
|
|
375
|
+
const user = this.client.users.cache.get(userId) || { id: userId };
|
|
376
|
+
this.users.set(userId, user);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
message;
|
|
381
|
+
emoji;
|
|
382
|
+
users;
|
|
383
|
+
get count() {
|
|
384
|
+
return this.users.size;
|
|
385
|
+
}
|
|
386
|
+
async remove() {
|
|
387
|
+
if (this.message instanceof Message) {
|
|
388
|
+
const emojiId = typeof this.emoji === "string" ? this.emoji : this.emoji.id;
|
|
389
|
+
await this.message.removeReaction(emojiId);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
[util.inspect.custom]() {
|
|
393
|
+
const data = {
|
|
394
|
+
messageId: this.message.id,
|
|
395
|
+
emoji: this.emoji,
|
|
396
|
+
count: this.count,
|
|
397
|
+
users: Array.from(this.users.keys())
|
|
398
|
+
};
|
|
399
|
+
return `MessageReaction ${util.inspect(data)}`;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// src/utils/ReactionCollector.ts
|
|
404
|
+
var ReactionCollector = class extends Collector {
|
|
405
|
+
constructor(message, options = {}) {
|
|
406
|
+
super(message.client, options);
|
|
407
|
+
this.message = message;
|
|
408
|
+
this.messageId = message.id;
|
|
409
|
+
const boundHandleCollect = this.handleMessageReact.bind(this);
|
|
410
|
+
const boundHandleDispose = this.handleMessageUnreact.bind(this);
|
|
411
|
+
this.client.on("messageReact", boundHandleCollect);
|
|
412
|
+
this.client.on("messageUnreact", boundHandleDispose);
|
|
413
|
+
this.once("end", () => {
|
|
414
|
+
this.client.removeListener("messageReact", boundHandleCollect);
|
|
415
|
+
this.client.removeListener("messageUnreact", boundHandleDispose);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
messageId;
|
|
419
|
+
total = 0;
|
|
420
|
+
users = /* @__PURE__ */ new Set();
|
|
421
|
+
collect(reaction) {
|
|
422
|
+
if (reaction.message.id !== this.messageId) return null;
|
|
423
|
+
return typeof reaction.emoji === "string" ? reaction.emoji : reaction.emoji.id;
|
|
424
|
+
}
|
|
425
|
+
dispose(reaction) {
|
|
426
|
+
if (reaction.message.id !== this.messageId) return null;
|
|
427
|
+
return typeof reaction.emoji === "string" ? reaction.emoji : reaction.emoji.id;
|
|
428
|
+
}
|
|
429
|
+
handleMessageReact(message, emojiId, userId) {
|
|
430
|
+
if (message.id !== this.messageId) return;
|
|
431
|
+
let reaction = this.collected.get(emojiId);
|
|
432
|
+
if (!reaction) {
|
|
433
|
+
reaction = new MessageReaction(this.client, { message, emojiId, users: [userId] });
|
|
434
|
+
} else {
|
|
435
|
+
const user = this.client.users.cache.get(userId) || { id: userId };
|
|
436
|
+
reaction.users.set(userId, user);
|
|
437
|
+
}
|
|
438
|
+
super.handleCollect(reaction);
|
|
439
|
+
if (!this.ended && this.collected.has(emojiId)) {
|
|
440
|
+
this.total++;
|
|
441
|
+
this.users.add(userId);
|
|
442
|
+
this.checkEnd();
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
handleMessageUnreact(message, emojiId, userId) {
|
|
446
|
+
if (message.id !== this.messageId) return;
|
|
447
|
+
const reaction = this.collected.get(emojiId);
|
|
448
|
+
if (reaction) {
|
|
449
|
+
reaction.users.delete(userId);
|
|
450
|
+
if (reaction.users.size === 0) {
|
|
451
|
+
super.handleDispose(reaction);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
endReason() {
|
|
456
|
+
const options = this.options;
|
|
457
|
+
if (options.max && this.total >= options.max) return "limit";
|
|
458
|
+
if (options.maxUsers && this.users.size >= options.maxUsers) return "userLimit";
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// src/structures/Message.ts
|
|
156
464
|
var Message = class extends Base {
|
|
157
465
|
content = null;
|
|
158
466
|
authorId;
|
|
@@ -166,7 +474,7 @@ var Message = class extends Base {
|
|
|
166
474
|
masquerade = null;
|
|
167
475
|
mentions = [];
|
|
168
476
|
pinned = false;
|
|
169
|
-
reactions =
|
|
477
|
+
reactions = {};
|
|
170
478
|
replies = [];
|
|
171
479
|
role_mentions = [];
|
|
172
480
|
constructor(client, data) {
|
|
@@ -234,6 +542,78 @@ var Message = class extends Base {
|
|
|
234
542
|
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
235
543
|
await channel.messages.unpin(this.id);
|
|
236
544
|
}
|
|
545
|
+
/**
|
|
546
|
+
* React to this message
|
|
547
|
+
* @param reaction The emoji to react with. Can be a Unicode emoji or a custom emoji ID.
|
|
548
|
+
* @throws {Error} If the API request fails.
|
|
549
|
+
* @example
|
|
550
|
+
* await message.react("👍");
|
|
551
|
+
* await message.react("customEmojiId");
|
|
552
|
+
*/
|
|
553
|
+
async react(reaction) {
|
|
554
|
+
let channel = this.channel;
|
|
555
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
556
|
+
await channel.messages.react(this.id, reaction);
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Remove a reaction from this message
|
|
560
|
+
* @param reaction The emoji to remove. Can be a Unicode emoji or a custom emoji ID.
|
|
561
|
+
* @param userId The ID of the user whose reaction to remove. If not provided, removes the current user's reaction.
|
|
562
|
+
* @param removeAll Remove all reactions of this type.
|
|
563
|
+
* @throws {Error} If both userId and removeAll are provided, or if the API request fails.
|
|
564
|
+
* @example
|
|
565
|
+
* // Remove the current user's reaction
|
|
566
|
+
* await message.removeReaction("👍");
|
|
567
|
+
* // Remove a specific user's reaction
|
|
568
|
+
* await message.removeReaction("👍", userId);
|
|
569
|
+
* // Remove all reactions of this type
|
|
570
|
+
* await message.removeReaction("👍", undefined, true);
|
|
571
|
+
*/
|
|
572
|
+
async removeReaction(reaction, userId, removeAll) {
|
|
573
|
+
let channel = this.channel;
|
|
574
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
575
|
+
await channel.messages.removeReaction(this.id, reaction, userId, removeAll);
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Remove all reactions from this message
|
|
579
|
+
* @throws {Error} If the API request fails.
|
|
580
|
+
* @example
|
|
581
|
+
* await message.clearReactions();
|
|
582
|
+
*/
|
|
583
|
+
async clearReactions() {
|
|
584
|
+
let channel = this.channel;
|
|
585
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
586
|
+
await channel.messages.clearReactions(this.id);
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Creates a ReactionCollector to collect reactions on this message.
|
|
590
|
+
* @param options The options for the collector.
|
|
591
|
+
* @returns A new ReactionCollector instance.
|
|
592
|
+
* @example
|
|
593
|
+
* const collector = message.createReactionCollector({ time: 15000 });
|
|
594
|
+
* collector.on('collect', (reaction) => console.log(`Collected ${reaction.emojiId} from ${reaction.userId}`));
|
|
595
|
+
* collector.on('end', (collected) => console.log(`Collected ${collected.size} items`));
|
|
596
|
+
*/
|
|
597
|
+
createReactionCollector(options) {
|
|
598
|
+
return new ReactionCollector(this, options);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Awaits reactions on this message.
|
|
602
|
+
* @param options The options for the collector.
|
|
603
|
+
* @returns A promise that resolves to a collection of reactions collected.
|
|
604
|
+
* @example
|
|
605
|
+
* // Await reactions
|
|
606
|
+
* const filter = (reaction) => reaction.emoji.id === '123' && reaction.users.has(author.id);
|
|
607
|
+
* message.awaitReactions({ filter, max: 1, time: 60000 })
|
|
608
|
+
* .then(collected => console.log(collected.size))
|
|
609
|
+
* .catch(console.error);
|
|
610
|
+
*/
|
|
611
|
+
awaitReactions(options) {
|
|
612
|
+
return new Promise((resolve) => {
|
|
613
|
+
const collector = this.createReactionCollector(options);
|
|
614
|
+
collector.once("end", (collected) => resolve(collected));
|
|
615
|
+
});
|
|
616
|
+
}
|
|
237
617
|
/** Gets the Channel object from cache */
|
|
238
618
|
get channel() {
|
|
239
619
|
return this.client.channels.cache.get(this.channelId);
|
|
@@ -271,7 +651,9 @@ var Message = class extends Base {
|
|
|
271
651
|
if (data.pinned !== void 0) this.pinned = data.pinned;
|
|
272
652
|
if (data.embeds !== void 0) this.embeds = data.embeds;
|
|
273
653
|
if (data.flags !== void 0) this.flags = data.flags;
|
|
274
|
-
if (data.reactions !== void 0)
|
|
654
|
+
if (data.reactions !== void 0) {
|
|
655
|
+
this.reactions = Array.isArray(data.reactions) ? {} : data.reactions;
|
|
656
|
+
}
|
|
275
657
|
if (data.interactions !== void 0) {
|
|
276
658
|
if (data.interactions) {
|
|
277
659
|
this.interactions = {
|
|
@@ -284,7 +666,7 @@ var Message = class extends Base {
|
|
|
284
666
|
}
|
|
285
667
|
}
|
|
286
668
|
// This tells Node.js exactly how to print this object in console.log()
|
|
287
|
-
[
|
|
669
|
+
[util2.inspect.custom](depth, options, inspect12) {
|
|
288
670
|
const { client, authorId, channelId, ...props } = this;
|
|
289
671
|
const data = {
|
|
290
672
|
...props,
|
|
@@ -293,7 +675,7 @@ var Message = class extends Base {
|
|
|
293
675
|
server: this.server,
|
|
294
676
|
member: this.member
|
|
295
677
|
};
|
|
296
|
-
return `${this.constructor.name} ${
|
|
678
|
+
return `${this.constructor.name} ${inspect12(data, { ...options, depth: depth ?? options.depth })}`;
|
|
297
679
|
}
|
|
298
680
|
};
|
|
299
681
|
|
|
@@ -455,6 +837,17 @@ var GatewayManager = class {
|
|
|
455
837
|
}
|
|
456
838
|
}
|
|
457
839
|
}
|
|
840
|
+
if (payload.emojis) {
|
|
841
|
+
for (const rawEmoji of payload.emojis) {
|
|
842
|
+
const emoji = this.client.emojis._add(rawEmoji);
|
|
843
|
+
if (rawEmoji.parent && rawEmoji.parent.type === "Server") {
|
|
844
|
+
const server = this.client.servers.cache.get(rawEmoji.parent.id);
|
|
845
|
+
if (server) {
|
|
846
|
+
server.emojis._add(emoji);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
458
851
|
this.client.emit("ready", payload);
|
|
459
852
|
break;
|
|
460
853
|
}
|
|
@@ -514,6 +907,60 @@ var GatewayManager = class {
|
|
|
514
907
|
}
|
|
515
908
|
break;
|
|
516
909
|
}
|
|
910
|
+
case "MessageReact": {
|
|
911
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
912
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
913
|
+
if (message) {
|
|
914
|
+
if (!message.reactions) message.reactions = {};
|
|
915
|
+
if (!message.reactions[payload.emoji_id]) {
|
|
916
|
+
message.reactions[payload.emoji_id] = [];
|
|
917
|
+
}
|
|
918
|
+
const reactions = message.reactions[payload.emoji_id];
|
|
919
|
+
if (reactions && !reactions.includes(payload.user_id)) {
|
|
920
|
+
reactions.push(payload.user_id);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
this.client.emit(
|
|
924
|
+
"messageReact",
|
|
925
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
926
|
+
payload.emoji_id,
|
|
927
|
+
payload.user_id
|
|
928
|
+
);
|
|
929
|
+
break;
|
|
930
|
+
}
|
|
931
|
+
case "MessageUnreact": {
|
|
932
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
933
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
934
|
+
if (message && message.reactions && message.reactions[payload.emoji_id]) {
|
|
935
|
+
const reactions = message.reactions[payload.emoji_id];
|
|
936
|
+
if (reactions) {
|
|
937
|
+
message.reactions[payload.emoji_id] = reactions.filter((userId) => userId !== payload.user_id);
|
|
938
|
+
if (message.reactions[payload.emoji_id].length === 0) {
|
|
939
|
+
delete message.reactions[payload.emoji_id];
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
this.client.emit(
|
|
944
|
+
"messageUnreact",
|
|
945
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
946
|
+
payload.emoji_id,
|
|
947
|
+
payload.user_id
|
|
948
|
+
);
|
|
949
|
+
break;
|
|
950
|
+
}
|
|
951
|
+
case "MessageRemoveReaction": {
|
|
952
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
953
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
954
|
+
if (message && message.reactions) {
|
|
955
|
+
delete message.reactions[payload.emoji_id];
|
|
956
|
+
}
|
|
957
|
+
this.client.emit(
|
|
958
|
+
"messageRemoveReaction",
|
|
959
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
960
|
+
payload.emoji_id
|
|
961
|
+
);
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
517
964
|
case "Pong":
|
|
518
965
|
this.client.emit("debug", "Received Pong from server.");
|
|
519
966
|
break;
|
|
@@ -590,6 +1037,27 @@ var GatewayManager = class {
|
|
|
590
1037
|
}
|
|
591
1038
|
break;
|
|
592
1039
|
}
|
|
1040
|
+
case "EmojiCreate": {
|
|
1041
|
+
const emoji = this.client.emojis._add(payload);
|
|
1042
|
+
if (payload.parent?.type === "Server") {
|
|
1043
|
+
const server = this.client.servers.cache.get(payload.parent.id);
|
|
1044
|
+
if (server) {
|
|
1045
|
+
server.emojis._add(emoji);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
case "EmojiDelete": {
|
|
1051
|
+
this.client.emojis.cache.delete(payload.id);
|
|
1052
|
+
for (const server of this.client.servers.cache.values()) {
|
|
1053
|
+
const emoji = server.emojis.cache.get(payload.id);
|
|
1054
|
+
if (emoji) {
|
|
1055
|
+
server.emojis.cache.delete(payload.id);
|
|
1056
|
+
break;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
break;
|
|
1060
|
+
}
|
|
593
1061
|
case "UserUpdate": {
|
|
594
1062
|
const existing = this.client.users.cache.get(payload.id);
|
|
595
1063
|
if (existing) {
|
|
@@ -774,9 +1242,9 @@ var RESTManager = class {
|
|
|
774
1242
|
/**
|
|
775
1243
|
* Uploads a file to Stoat's CDN and returns the File ID
|
|
776
1244
|
*/
|
|
777
|
-
async uploadFile(
|
|
1245
|
+
async uploadFile(tag, fileBuffer, filename) {
|
|
778
1246
|
if (!this.token) throw new Error("REST_NOT_READY: No token available.");
|
|
779
|
-
const url =
|
|
1247
|
+
const url = `https://cdn.stoatusercontent.com/${tag}`;
|
|
780
1248
|
const formData = new FormData();
|
|
781
1249
|
formData.append("file", new Blob([fileBuffer]), filename);
|
|
782
1250
|
const response = await fetch(url, {
|
|
@@ -808,89 +1276,16 @@ var RESTManager = class {
|
|
|
808
1276
|
patch(endpoint, body) {
|
|
809
1277
|
return this.makeRequest("PATCH", endpoint, body);
|
|
810
1278
|
}
|
|
811
|
-
delete(endpoint) {
|
|
812
|
-
return this.makeRequest("DELETE", endpoint);
|
|
1279
|
+
delete(endpoint, body) {
|
|
1280
|
+
return this.makeRequest("DELETE", endpoint, body);
|
|
813
1281
|
}
|
|
814
1282
|
async put(endpoint, body) {
|
|
815
1283
|
return this.makeRequest("PUT", endpoint, body);
|
|
816
1284
|
}
|
|
817
1285
|
};
|
|
818
1286
|
|
|
819
|
-
// src/utils/Collection.ts
|
|
820
|
-
var Collection = class _Collection extends Map {
|
|
821
|
-
limit;
|
|
822
|
-
constructor(limit = Infinity) {
|
|
823
|
-
super();
|
|
824
|
-
this.limit = limit;
|
|
825
|
-
}
|
|
826
|
-
/**
|
|
827
|
-
* Overrides the default set method to enforce the maximum cache size.
|
|
828
|
-
*/
|
|
829
|
-
set(key, value) {
|
|
830
|
-
if (this.limit === 0) return this;
|
|
831
|
-
if (this.size >= this.limit && !this.has(key)) {
|
|
832
|
-
const oldestKey = this.keys().next().value;
|
|
833
|
-
if (oldestKey !== void 0) {
|
|
834
|
-
this.delete(oldestKey);
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
return super.set(key, value);
|
|
838
|
-
}
|
|
839
|
-
/**
|
|
840
|
-
* Finds the first item where the given function returns true.
|
|
841
|
-
*/
|
|
842
|
-
find(fn) {
|
|
843
|
-
for (const [key, val] of this) {
|
|
844
|
-
if (fn(val, key, this)) return val;
|
|
845
|
-
}
|
|
846
|
-
return void 0;
|
|
847
|
-
}
|
|
848
|
-
/**
|
|
849
|
-
* Returns a new Collection containing only the items where the function returns true.
|
|
850
|
-
*/
|
|
851
|
-
filter(fn) {
|
|
852
|
-
const results = new _Collection();
|
|
853
|
-
for (const [key, val] of this) {
|
|
854
|
-
if (fn(val, key, this)) results.set(key, val);
|
|
855
|
-
}
|
|
856
|
-
return results;
|
|
857
|
-
}
|
|
858
|
-
/**
|
|
859
|
-
* Maps each item to a new array of values.
|
|
860
|
-
*/
|
|
861
|
-
map(fn) {
|
|
862
|
-
const results = [];
|
|
863
|
-
for (const [key, val] of this) {
|
|
864
|
-
results.push(fn(val, key, this));
|
|
865
|
-
}
|
|
866
|
-
return results;
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
|
-
* Gets the very first value in the Collection (based on insertion order).
|
|
870
|
-
*/
|
|
871
|
-
first() {
|
|
872
|
-
return this.values().next().value;
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
* Gets the very last value in the Collection.
|
|
876
|
-
*/
|
|
877
|
-
last() {
|
|
878
|
-
const arr = Array.from(this.values());
|
|
879
|
-
return arr[arr.length - 1];
|
|
880
|
-
}
|
|
881
|
-
/**
|
|
882
|
-
* Checks if at least one item matches the condition.
|
|
883
|
-
*/
|
|
884
|
-
some(fn) {
|
|
885
|
-
for (const [key, val] of this) {
|
|
886
|
-
if (fn(val, key, this)) return true;
|
|
887
|
-
}
|
|
888
|
-
return false;
|
|
889
|
-
}
|
|
890
|
-
};
|
|
891
|
-
|
|
892
1287
|
// src/managers/MessageManager.ts
|
|
893
|
-
var
|
|
1288
|
+
var util3 = __toESM(require("util"), 1);
|
|
894
1289
|
|
|
895
1290
|
// src/managers/BaseManager.ts
|
|
896
1291
|
var BaseManager = class {
|
|
@@ -917,6 +1312,42 @@ var BaseManager = class {
|
|
|
917
1312
|
}
|
|
918
1313
|
};
|
|
919
1314
|
|
|
1315
|
+
// src/builders/AttachmentBuilder.ts
|
|
1316
|
+
var AttachmentBuilder = class {
|
|
1317
|
+
// Filename for CDN to use, optional but recommended
|
|
1318
|
+
filename = void 0;
|
|
1319
|
+
file;
|
|
1320
|
+
/**
|
|
1321
|
+
* Creates a new AttachmentBuilder with the given file and optional filename.
|
|
1322
|
+
* @param file The file data as a Buffer or Blob.
|
|
1323
|
+
* @param filename An optional filename to use for the uploaded file. If not provided, the CDN will assign a default name.
|
|
1324
|
+
* Providing a filename can help with organization and debugging, but is not strictly required.
|
|
1325
|
+
* @example
|
|
1326
|
+
* // Create an attachment from a Buffer with a custom filename
|
|
1327
|
+
* const buffer = Buffer.from("Hello, world!");
|
|
1328
|
+
* const attachment = new AttachmentBuilder(buffer, "greeting.txt");
|
|
1329
|
+
*/
|
|
1330
|
+
constructor(file, filename) {
|
|
1331
|
+
this.filename = filename;
|
|
1332
|
+
this.file = file;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Uploads this attachment to the Stoat CDN and returns the resulting file ID.
|
|
1336
|
+
* @internal — use `resolveAttachment()` instead of calling this directly.
|
|
1337
|
+
*/
|
|
1338
|
+
async upload(rest, tag) {
|
|
1339
|
+
return rest.uploadFile(tag, this.file, this.filename);
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
// src/utils/resolveAttachment.ts
|
|
1344
|
+
async function resolveAttachment(rest, value, tag) {
|
|
1345
|
+
if (value instanceof AttachmentBuilder) {
|
|
1346
|
+
return value.upload(rest, tag);
|
|
1347
|
+
}
|
|
1348
|
+
return value;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
920
1351
|
// src/managers/MessageManager.ts
|
|
921
1352
|
var MessageManager = class extends BaseManager {
|
|
922
1353
|
constructor(client, channel, limit = Infinity) {
|
|
@@ -992,6 +1423,13 @@ var MessageManager = class extends BaseManager {
|
|
|
992
1423
|
(embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
|
|
993
1424
|
);
|
|
994
1425
|
}
|
|
1426
|
+
if (payload.attachments) {
|
|
1427
|
+
payload.attachments = await Promise.all(
|
|
1428
|
+
payload.attachments.map(
|
|
1429
|
+
(attachment) => resolveAttachment(this.client.rest, attachment, "attachments")
|
|
1430
|
+
)
|
|
1431
|
+
);
|
|
1432
|
+
}
|
|
995
1433
|
const data = await this.client.rest.post(`/channels/${this.channel.id}/messages`, payload);
|
|
996
1434
|
return new Message(this.client, data);
|
|
997
1435
|
}
|
|
@@ -1046,11 +1484,105 @@ var MessageManager = class extends BaseManager {
|
|
|
1046
1484
|
const existing = this.cache.get(id);
|
|
1047
1485
|
if (existing) existing.pinned = false;
|
|
1048
1486
|
}
|
|
1049
|
-
|
|
1487
|
+
/**
|
|
1488
|
+
* React to a message
|
|
1489
|
+
* @param message The MessageResolvable to react to.
|
|
1490
|
+
* @param reaction The emoji to react with. Can be a Unicode emoji or a custom emoji ID.
|
|
1491
|
+
* @throws {Error} If the API request fails.
|
|
1492
|
+
* @example
|
|
1493
|
+
* await channel.messages.react(messageId, "👍");
|
|
1494
|
+
* await channel.messages.react(messageId, "customEmojiId");
|
|
1495
|
+
*/
|
|
1496
|
+
async react(message, reaction) {
|
|
1497
|
+
const id = this.resolveId(message);
|
|
1498
|
+
await this.client.rest.put(`/channels/${this.channel.id}/messages/${id}/reactions/${encodeURIComponent(reaction)}`);
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Remove a reaction(s) from a message
|
|
1502
|
+
* Requires ManageMessages if changing others' reactions.
|
|
1503
|
+
* @param reaction The emoji to remove. Can be a unicode emoji or a custom emoji ID.
|
|
1504
|
+
* @param message The MessageResolvable to remove the reaction from.
|
|
1505
|
+
* @param userId The ID of the user whose reaction to remove. If not provided, removes the current user's reaction.
|
|
1506
|
+
* @param removeAll Remove all reactions of this type.
|
|
1507
|
+
* @throws {Error} If both userId and removeAll are provided, or if the API request fails.
|
|
1508
|
+
* @example
|
|
1509
|
+
* // Remove the current user's reaction
|
|
1510
|
+
* await channel.messages.removeReaction(messageId, "👍");
|
|
1511
|
+
* // Remove a specific user's reaction
|
|
1512
|
+
* await channel.messages.removeReaction(messageId, "👍", userId);
|
|
1513
|
+
* // Remove all reactions of this type
|
|
1514
|
+
* await channel.messages.removeReaction(messageId, "👍", undefined, true);
|
|
1515
|
+
*/
|
|
1516
|
+
async removeReaction(message, reaction, userId, removeAll) {
|
|
1517
|
+
const id = this.resolveId(message);
|
|
1518
|
+
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);
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Remove all reactions from a message
|
|
1528
|
+
* Requires ManageMessages permission.
|
|
1529
|
+
* @param message The MessageResolvable to clear reactions from.
|
|
1530
|
+
* @throws {Error} If the API request fails.
|
|
1531
|
+
* @example
|
|
1532
|
+
* await channel.messages.clearReactions(messageId);
|
|
1533
|
+
*/
|
|
1534
|
+
async clearReactions(message) {
|
|
1535
|
+
const id = this.resolveId(message);
|
|
1536
|
+
await this.client.rest.delete(`/channels/${this.channel.id}/messages/${id}/reactions`);
|
|
1537
|
+
}
|
|
1538
|
+
[util3.inspect.custom]() {
|
|
1050
1539
|
return this.cache;
|
|
1051
1540
|
}
|
|
1052
1541
|
};
|
|
1053
1542
|
|
|
1543
|
+
// src/utils/MessageCollector.ts
|
|
1544
|
+
var MessageCollector = class extends Collector {
|
|
1545
|
+
constructor(channel, options = {}) {
|
|
1546
|
+
super(channel.client, options);
|
|
1547
|
+
this.channel = channel;
|
|
1548
|
+
this.channelId = channel.id;
|
|
1549
|
+
const boundHandleCollect = this.handleCollect.bind(this);
|
|
1550
|
+
const boundHandleDispose = this.handleDispose.bind(this);
|
|
1551
|
+
this.client.on("messageCreate", boundHandleCollect);
|
|
1552
|
+
this.client.on("messageDelete", boundHandleDispose);
|
|
1553
|
+
this.once("end", () => {
|
|
1554
|
+
this.client.removeListener("messageCreate", boundHandleCollect);
|
|
1555
|
+
this.client.removeListener("messageDelete", boundHandleDispose);
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
channelId;
|
|
1559
|
+
total = 0;
|
|
1560
|
+
processed = 0;
|
|
1561
|
+
collect(message) {
|
|
1562
|
+
if (message.channelId !== this.channelId) return null;
|
|
1563
|
+
return message.id;
|
|
1564
|
+
}
|
|
1565
|
+
dispose(message) {
|
|
1566
|
+
if (message.channelId !== this.channelId) return null;
|
|
1567
|
+
return message.id;
|
|
1568
|
+
}
|
|
1569
|
+
handleCollect(message) {
|
|
1570
|
+
if (message.channelId !== this.channelId) return;
|
|
1571
|
+
this.processed++;
|
|
1572
|
+
super.handleCollect(message);
|
|
1573
|
+
if (!this.ended && this.collected.has(message.id)) {
|
|
1574
|
+
this.total++;
|
|
1575
|
+
this.checkEnd();
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
endReason() {
|
|
1579
|
+
const options = this.options;
|
|
1580
|
+
if (options.max && this.total >= options.max) return "limit";
|
|
1581
|
+
if (options.maxProcessed && this.processed >= options.maxProcessed) return "processedLimit";
|
|
1582
|
+
return null;
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
|
|
1054
1586
|
// src/structures/BaseChannel.ts
|
|
1055
1587
|
var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
|
|
1056
1588
|
ChannelType2["TEXT"] = "TextChannel";
|
|
@@ -1077,12 +1609,36 @@ var BaseChannel = class extends Base {
|
|
|
1077
1609
|
async send(contentOrOptions) {
|
|
1078
1610
|
return this.messages.send(contentOrOptions);
|
|
1079
1611
|
}
|
|
1080
|
-
|
|
1612
|
+
/**
|
|
1613
|
+
* Fetch this channel
|
|
1614
|
+
* @param force Whether to skip the cache check and force a direct API request. Defaults to false
|
|
1615
|
+
* @throws {Error} If the API request fails
|
|
1616
|
+
* @returns {BaseChannel}
|
|
1617
|
+
* @example
|
|
1618
|
+
* // Force fetch channel to update its data
|
|
1619
|
+
* await channel.fetch(true);
|
|
1620
|
+
*/
|
|
1621
|
+
async fetch(force = false) {
|
|
1081
1622
|
return await this.client.channels.fetch(this.id, force);
|
|
1082
1623
|
}
|
|
1083
1624
|
/**
|
|
1084
1625
|
* Fetches multiple messages from this channel.
|
|
1085
1626
|
* @param options The query parameters to filter the messages.
|
|
1627
|
+
* @throws {Error} If the API request fails
|
|
1628
|
+
* @returns A Collection of Messages, keyed by their ID.
|
|
1629
|
+
* @example
|
|
1630
|
+
* // Fetch the last 50 messages in the channel
|
|
1631
|
+
* const messages = await channel.fetchMessages({ limit: 50 });
|
|
1632
|
+
* console.log(`Fetched ${messages.size} messages`);
|
|
1633
|
+
* // Fetch messages before a specific message ID
|
|
1634
|
+
* const messages = await channel.fetchMessages({ before: "MESSAGE_ID" });
|
|
1635
|
+
* console.log(`Fetched ${messages.size} messages sent before the specified message`);
|
|
1636
|
+
* // Fetch messages after a specific message ID
|
|
1637
|
+
* const messages = await channel.fetchMessages({ after: "MESSAGE_ID" });
|
|
1638
|
+
* console.log(`Fetched ${messages.size} messages sent after the specified message`);
|
|
1639
|
+
* // Fetch messages around a specific message ID
|
|
1640
|
+
* const messages = await channel.fetchMessages({ around: "MESSAGE_ID", limit: 10 });
|
|
1641
|
+
* console.log(`Fetched ${messages.size} messages sent around the specified message`);
|
|
1086
1642
|
*/
|
|
1087
1643
|
async fetchMessages(options) {
|
|
1088
1644
|
return this.messages.fetchMany(options);
|
|
@@ -1090,16 +1646,72 @@ var BaseChannel = class extends Base {
|
|
|
1090
1646
|
/**
|
|
1091
1647
|
* Edits this channel.
|
|
1092
1648
|
* @param options The fields to update
|
|
1649
|
+
* @throws {Error} If the API request fails
|
|
1650
|
+
* @returns BaseChannel
|
|
1651
|
+
* @example
|
|
1652
|
+
* // Edit the channel's name
|
|
1653
|
+
* await channel.edit({name: "New Cool Name"});
|
|
1093
1654
|
*/
|
|
1094
1655
|
async edit(options) {
|
|
1095
1656
|
return await this.client.channels.edit(this.id, options);
|
|
1096
1657
|
}
|
|
1097
1658
|
/**
|
|
1098
1659
|
* Deletes this channel.
|
|
1660
|
+
* @throws {Error} If the API request fails
|
|
1661
|
+
* @example
|
|
1662
|
+
* // Delete the channel
|
|
1663
|
+
* await channel.delete();
|
|
1099
1664
|
*/
|
|
1100
1665
|
async delete() {
|
|
1101
1666
|
await this.client.channels.delete(this.id);
|
|
1102
1667
|
}
|
|
1668
|
+
/**
|
|
1669
|
+
* Bulk delete messages from this channel
|
|
1670
|
+
* @param messages MessageResolvable to delete
|
|
1671
|
+
* @throws {Error} If the API request fails
|
|
1672
|
+
* @example
|
|
1673
|
+
* // Delete messages by their ID's
|
|
1674
|
+
* await channel.bulkDelete(["MESSAGE_ID_1", "MESSAGE_ID_2", "MESSAGE_ID_3"]);
|
|
1675
|
+
* // Delete messages by their Message objects
|
|
1676
|
+
* await channel.bulkDelete([message1, message2, message3]);
|
|
1677
|
+
*/
|
|
1678
|
+
async bulkDelete(messages) {
|
|
1679
|
+
await this.client.channels.bulkDelete(this.id, messages);
|
|
1680
|
+
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Creates a MessageCollector to collect messages in this channel.
|
|
1683
|
+
* @param options The options for the collector.
|
|
1684
|
+
* @returns The instantiated MessageCollector
|
|
1685
|
+
* @example
|
|
1686
|
+
* const collector = channel.createMessageCollector({ filter: m => m.authorId === '123', time: 15000 });
|
|
1687
|
+
* collector.on('collect', m => console.log(`Collected ${m.content}`));
|
|
1688
|
+
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
|
1689
|
+
*/
|
|
1690
|
+
createMessageCollector(options) {
|
|
1691
|
+
return new MessageCollector(this, options);
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Awaits messages in this channel that meet certain criteria.
|
|
1695
|
+
* @param options The options for the collector.
|
|
1696
|
+
* @returns A promise that resolves to a collection of messages.
|
|
1697
|
+
* @example
|
|
1698
|
+
* // Await !vote messages
|
|
1699
|
+
* const filter = m => m.content.startsWith('!vote');
|
|
1700
|
+
* channel.awaitMessages({ filter, max: 4, time: 60000 })
|
|
1701
|
+
* .then(collected => console.log(collected.size))
|
|
1702
|
+
* .catch(console.error);
|
|
1703
|
+
*/
|
|
1704
|
+
awaitMessages(options = {}) {
|
|
1705
|
+
return new Promise((resolve, reject) => {
|
|
1706
|
+
const collector = this.createMessageCollector(options);
|
|
1707
|
+
collector.once("end", (collected, reason) => {
|
|
1708
|
+
if (options.max && reason !== "limit" && reason !== "time") {
|
|
1709
|
+
return reject(new Error(`Collector ended with reason: ${reason}`));
|
|
1710
|
+
}
|
|
1711
|
+
resolve(collected);
|
|
1712
|
+
});
|
|
1713
|
+
});
|
|
1714
|
+
}
|
|
1103
1715
|
isText() {
|
|
1104
1716
|
return this.type === "TextChannel" /* TEXT */;
|
|
1105
1717
|
}
|
|
@@ -1143,36 +1755,175 @@ var TextChannel = class extends BaseChannel {
|
|
|
1143
1755
|
case "Description":
|
|
1144
1756
|
this.description = null;
|
|
1145
1757
|
break;
|
|
1758
|
+
case "Icon":
|
|
1759
|
+
this.icon = null;
|
|
1760
|
+
break;
|
|
1761
|
+
case "DefaultPermissions":
|
|
1762
|
+
this.defaultPermissions = data.default_permissions;
|
|
1763
|
+
break;
|
|
1764
|
+
case "Voice":
|
|
1765
|
+
this.voice = data.voice;
|
|
1766
|
+
break;
|
|
1146
1767
|
}
|
|
1147
1768
|
}
|
|
1148
1769
|
}
|
|
1149
1770
|
}
|
|
1150
1771
|
/**
|
|
1151
|
-
* Updates the permission overrides for the channel.
|
|
1152
|
-
* @param roleId The raw string ID of the role to update.
|
|
1153
|
-
* @param options The allow and deny permissions to set.
|
|
1154
|
-
* @returns A promise that resolves to the updated BaseChannel.
|
|
1155
|
-
* @throws {TypeError} If the channel is not a Server Channel, or options are invalid.
|
|
1156
|
-
* @throws {Error} If the API request fails.
|
|
1772
|
+
* Updates the permission overrides for the channel.
|
|
1773
|
+
* @param roleId The raw string ID of the role to update.
|
|
1774
|
+
* @param options The allow and deny permissions to set.
|
|
1775
|
+
* @returns A promise that resolves to the updated BaseChannel.
|
|
1776
|
+
* @throws {TypeError} If the channel is not a Server Channel, or options are invalid.
|
|
1777
|
+
* @throws {Error} If the API request fails.
|
|
1778
|
+
* @example
|
|
1779
|
+
* // Deny a role the ability to send messages in this channel
|
|
1780
|
+
* await channel.setRolePermissions("ROLE_ID", { deny: ["SendMessage"] });
|
|
1781
|
+
*/
|
|
1782
|
+
async setRolePermissions(roleId, options) {
|
|
1783
|
+
return await this.client.channels.setRolePermissions(this.id, roleId, options);
|
|
1784
|
+
}
|
|
1785
|
+
/**
|
|
1786
|
+
* Updates the default (everyone) permissions for this channel.
|
|
1787
|
+
* @param permissions The default permissions to grant globally in this channel.
|
|
1788
|
+
* @returns A promise that resolves to the updated BaseChannel.
|
|
1789
|
+
* @throws {TypeError} If invalid permissions are provided.
|
|
1790
|
+
* @throws {Error} If the API request fails.
|
|
1791
|
+
* @example
|
|
1792
|
+
* // Set the default permission to allow everyone to view the channel
|
|
1793
|
+
* await channel.setDefaultPermissions(["ViewChannel", "ReadMessageHistory"]);
|
|
1794
|
+
*/
|
|
1795
|
+
async setDefaultPermissions(permissions) {
|
|
1796
|
+
return await this.client.channels.setDefaultPermissions(this.id, permissions);
|
|
1797
|
+
}
|
|
1798
|
+
/**
|
|
1799
|
+
* Edits the category of this channel. Only applicable to server channels.
|
|
1800
|
+
* @param category The ID of the category to move this channel into, or "default" to remove from any category.
|
|
1801
|
+
* @returns The updated TextChannel with the new category.
|
|
1802
|
+
* @throws {Error} If the channel is not a server channel, if the category is not found in the server, or if the API request fails.
|
|
1803
|
+
* @example
|
|
1804
|
+
* // Move this channel into a category
|
|
1805
|
+
* await channel.setCategory("CATEGORY_ID");
|
|
1806
|
+
* // Remove this channel from its category
|
|
1807
|
+
* await channel.setCategory("default");
|
|
1808
|
+
*/
|
|
1809
|
+
async setCategory(category) {
|
|
1810
|
+
const serverId = this.serverId;
|
|
1811
|
+
const server = await this.client.servers.fetch(serverId);
|
|
1812
|
+
const categories = server.categories.map((c) => ({
|
|
1813
|
+
id: c.id,
|
|
1814
|
+
title: c.title,
|
|
1815
|
+
channels: [...c.channels]
|
|
1816
|
+
}));
|
|
1817
|
+
for (const cat of categories) {
|
|
1818
|
+
cat.channels = cat.channels.filter((id) => id !== this.id);
|
|
1819
|
+
}
|
|
1820
|
+
if (category !== "default") {
|
|
1821
|
+
const targetCategory = categories.find((c) => c.id === category);
|
|
1822
|
+
if (!targetCategory) {
|
|
1823
|
+
throw new Error(`Category ${category} not found in server.`);
|
|
1824
|
+
}
|
|
1825
|
+
targetCategory.channels.push(this.id);
|
|
1826
|
+
}
|
|
1827
|
+
await this.client.servers.edit(serverId, { categories });
|
|
1828
|
+
return this;
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Sets the position of this channel within its current category.
|
|
1832
|
+
* @param position The new index position for the channel within its category.
|
|
1833
|
+
* @returns The updated TextChannel.
|
|
1834
|
+
* @throws {Error} If the channel is not in a category, or if the API request fails.
|
|
1835
|
+
* @example
|
|
1836
|
+
* // Move channel to the top of its category
|
|
1837
|
+
* await channel.setPosition(0);
|
|
1838
|
+
*/
|
|
1839
|
+
async setPosition(position) {
|
|
1840
|
+
const serverId = this.serverId;
|
|
1841
|
+
const server = await this.client.servers.fetch(serverId);
|
|
1842
|
+
const categories = server.categories.map((c) => ({
|
|
1843
|
+
id: c.id,
|
|
1844
|
+
title: c.title,
|
|
1845
|
+
channels: [...c.channels]
|
|
1846
|
+
}));
|
|
1847
|
+
const currentCategory = categories.find((c) => c.channels.includes(this.id));
|
|
1848
|
+
if (!currentCategory) {
|
|
1849
|
+
throw new Error("This channel is not currently inside any category.");
|
|
1850
|
+
}
|
|
1851
|
+
currentCategory.channels = currentCategory.channels.filter((id) => id !== this.id);
|
|
1852
|
+
const safePosition = Math.max(0, Math.min(position, currentCategory.channels.length));
|
|
1853
|
+
currentCategory.channels.splice(safePosition, 0, this.id);
|
|
1854
|
+
await this.client.servers.edit(serverId, { categories });
|
|
1855
|
+
return this;
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Edit the description of this channel
|
|
1859
|
+
* @param description
|
|
1860
|
+
* @throws {Error} If the API request fails
|
|
1861
|
+
* @returns The updated TextChannel
|
|
1862
|
+
* @example
|
|
1863
|
+
* // Set the channel description
|
|
1864
|
+
* await channel.setDescription("This is a channel about cats!");
|
|
1865
|
+
* // Remove the channel description
|
|
1866
|
+
* await channel.setDescription(null);
|
|
1867
|
+
*/
|
|
1868
|
+
async setDescription(description) {
|
|
1869
|
+
await this.edit({ description });
|
|
1870
|
+
return this;
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Edit the name of this channel
|
|
1874
|
+
* @param name
|
|
1875
|
+
* @throws {Error} If the API request fails
|
|
1876
|
+
* @returns The updated TextChannel
|
|
1157
1877
|
* @example
|
|
1158
|
-
*
|
|
1159
|
-
* await channel.setRolePermissions("ROLE_ID", { deny: ["SendMessage"] });
|
|
1878
|
+
* await channel.setName("New Name");
|
|
1160
1879
|
*/
|
|
1161
|
-
async
|
|
1162
|
-
|
|
1880
|
+
async setName(name) {
|
|
1881
|
+
await this.edit({ name });
|
|
1882
|
+
return this;
|
|
1163
1883
|
}
|
|
1164
1884
|
/**
|
|
1165
|
-
*
|
|
1166
|
-
* @param
|
|
1167
|
-
* @
|
|
1168
|
-
* @
|
|
1169
|
-
* @throws {Error} If the API request fails.
|
|
1885
|
+
* Set whether this channel is NSFW
|
|
1886
|
+
* @param nsfw
|
|
1887
|
+
* @throws {Error} If the API request fails
|
|
1888
|
+
* @returns The updated TextChannel
|
|
1170
1889
|
* @example
|
|
1171
|
-
* //
|
|
1172
|
-
* await channel.
|
|
1890
|
+
* // Mark the channel as NSFW
|
|
1891
|
+
* await channel.setNSFW(true);
|
|
1892
|
+
* // Mark the channel as SFW
|
|
1893
|
+
* await channel.setNSFW(false);
|
|
1173
1894
|
*/
|
|
1174
|
-
async
|
|
1175
|
-
|
|
1895
|
+
async setNSFW(nsfw) {
|
|
1896
|
+
await this.edit({ nsfw });
|
|
1897
|
+
return this;
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Set the channel slowmode in seconds
|
|
1901
|
+
* @param slowmode
|
|
1902
|
+
* @throws {Error} If the API request fails
|
|
1903
|
+
* @returns The updated TextChannel
|
|
1904
|
+
* @example
|
|
1905
|
+
* // Set the slowmode to 5 seconds
|
|
1906
|
+
* await channel.setSlowmode(5);
|
|
1907
|
+
* // Remove slowmode
|
|
1908
|
+
* await channel.setSlowmode(0);
|
|
1909
|
+
*/
|
|
1910
|
+
async setSlowmode(slowmode) {
|
|
1911
|
+
await this.edit({ slowmode });
|
|
1912
|
+
return this;
|
|
1913
|
+
}
|
|
1914
|
+
/**
|
|
1915
|
+
* Set the channel Icon
|
|
1916
|
+
* @param id Autumn ID to use
|
|
1917
|
+
* @throws {Error} If the API request fails
|
|
1918
|
+
* @returns The updated TextChannel
|
|
1919
|
+
* @example
|
|
1920
|
+
* await channel.setIcon("123");
|
|
1921
|
+
* // Remove the channel icon
|
|
1922
|
+
* await channel.setIcon(null);
|
|
1923
|
+
*/
|
|
1924
|
+
async setIcon(id) {
|
|
1925
|
+
await this.edit({ icon: id });
|
|
1926
|
+
return this;
|
|
1176
1927
|
}
|
|
1177
1928
|
};
|
|
1178
1929
|
|
|
@@ -1199,7 +1950,7 @@ var DMChannel = class extends BaseChannel {
|
|
|
1199
1950
|
};
|
|
1200
1951
|
|
|
1201
1952
|
// src/structures/GroupChannel.ts
|
|
1202
|
-
var
|
|
1953
|
+
var util4 = __toESM(require("util"), 1);
|
|
1203
1954
|
var GroupChannel = class extends BaseChannel {
|
|
1204
1955
|
name;
|
|
1205
1956
|
ownerId;
|
|
@@ -1259,9 +2010,9 @@ var GroupChannel = class extends BaseChannel {
|
|
|
1259
2010
|
async setDefaultPermissions(permissions) {
|
|
1260
2011
|
return await this.client.channels.setDefaultPermissions(this.id, permissions);
|
|
1261
2012
|
}
|
|
1262
|
-
[
|
|
2013
|
+
[util4.inspect.custom](_depth, options, inspect12) {
|
|
1263
2014
|
const { client, ...props } = this;
|
|
1264
|
-
return `${this.constructor.name} ${
|
|
2015
|
+
return `${this.constructor.name} ${inspect12(
|
|
1265
2016
|
{
|
|
1266
2017
|
...props,
|
|
1267
2018
|
owner: this.owner,
|
|
@@ -1287,6 +2038,233 @@ function createChannel(client, data) {
|
|
|
1287
2038
|
}
|
|
1288
2039
|
}
|
|
1289
2040
|
|
|
2041
|
+
// src/utils/BitField.ts
|
|
2042
|
+
var BitField = class _BitField {
|
|
2043
|
+
static Flags = {};
|
|
2044
|
+
static DefaultBit = 0;
|
|
2045
|
+
bitfield;
|
|
2046
|
+
constructor(bits) {
|
|
2047
|
+
this.bitfield = this.constructor.resolve(
|
|
2048
|
+
bits ?? this.constructor.DefaultBit
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
/**
|
|
2052
|
+
* Checks whether this bitfield has any of the given bits set.
|
|
2053
|
+
*
|
|
2054
|
+
* @param bit The bit(s) to test against.
|
|
2055
|
+
* @returns `true` if at least one of the provided bits is set.
|
|
2056
|
+
*
|
|
2057
|
+
* @example
|
|
2058
|
+
* perms.any(['SendMessage', 'ManageChannel']); // true if either is set
|
|
2059
|
+
*/
|
|
2060
|
+
any(bit) {
|
|
2061
|
+
const resolved = this.constructor.resolve(bit);
|
|
2062
|
+
if (typeof this.bitfield === "bigint" && typeof resolved === "bigint") {
|
|
2063
|
+
return (this.bitfield & resolved) !== BigInt(0);
|
|
2064
|
+
}
|
|
2065
|
+
return (Number(this.bitfield) & Number(resolved)) !== 0;
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Checks whether this bitfield is exactly equal to the given bit value.
|
|
2069
|
+
*
|
|
2070
|
+
* @param bit The bit(s) to compare against.
|
|
2071
|
+
* @returns `true` if the resolved bit value is identical to this bitfield.
|
|
2072
|
+
*
|
|
2073
|
+
* @example
|
|
2074
|
+
* new Permissions(0n).equals(0n); // true
|
|
2075
|
+
*/
|
|
2076
|
+
equals(bit) {
|
|
2077
|
+
return this.bitfield === this.constructor.resolve(bit);
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* Checks whether this bitfield has *all* of the given bits set.
|
|
2081
|
+
*
|
|
2082
|
+
* @param bit The bit(s) to check for.
|
|
2083
|
+
* @returns `true` if every provided bit is set in this bitfield.
|
|
2084
|
+
*
|
|
2085
|
+
* @example
|
|
2086
|
+
* perms.has('SendMessage');
|
|
2087
|
+
* perms.has(['SendMessage', 'ViewChannel']); // true only if both are set
|
|
2088
|
+
*/
|
|
2089
|
+
has(bit, ..._hasParams) {
|
|
2090
|
+
const resolvedBit = this.constructor.resolve(bit);
|
|
2091
|
+
if (typeof this.bitfield === "bigint" && typeof resolvedBit === "bigint") {
|
|
2092
|
+
return (this.bitfield & resolvedBit) === resolvedBit;
|
|
2093
|
+
}
|
|
2094
|
+
return (Number(this.bitfield) & Number(resolvedBit)) === Number(resolvedBit);
|
|
2095
|
+
}
|
|
2096
|
+
/**
|
|
2097
|
+
* Returns the flag names present in `bits` that are *missing* from this bitfield.
|
|
2098
|
+
*
|
|
2099
|
+
* @param bits The bits to check against.
|
|
2100
|
+
* @returns An array of flag name strings that are in `bits` but not in this bitfield.
|
|
2101
|
+
*
|
|
2102
|
+
* @example
|
|
2103
|
+
* // If perms only has SendMessage:
|
|
2104
|
+
* perms.missing(['SendMessage', 'ManageChannel']); // ['ManageChannel']
|
|
2105
|
+
*/
|
|
2106
|
+
missing(bits, ...hasParams) {
|
|
2107
|
+
return new this.constructor(bits).remove(this).toArray(...hasParams);
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Freezes this BitField instance, making it immutable.
|
|
2111
|
+
* Subsequent calls to `add()` or `remove()` will return a new instance instead of mutating this one.
|
|
2112
|
+
*
|
|
2113
|
+
* @returns This instance, frozen.
|
|
2114
|
+
*/
|
|
2115
|
+
freeze() {
|
|
2116
|
+
return Object.freeze(this);
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Adds one or more bits to this bitfield.
|
|
2120
|
+
* If the instance is frozen, returns a new BitField with the bits added.
|
|
2121
|
+
*
|
|
2122
|
+
* @param bits The bit(s) to add.
|
|
2123
|
+
* @returns This instance (or a new one if frozen), with the bits added.
|
|
2124
|
+
*
|
|
2125
|
+
* @example
|
|
2126
|
+
* perms.add('SendMessage', 'ViewChannel');
|
|
2127
|
+
*/
|
|
2128
|
+
add(...bits) {
|
|
2129
|
+
let total = this.constructor.DefaultBit;
|
|
2130
|
+
for (const bit of bits) {
|
|
2131
|
+
const resolved = this.constructor.resolve(bit);
|
|
2132
|
+
if (typeof total === "bigint" && typeof resolved === "bigint") {
|
|
2133
|
+
total |= resolved;
|
|
2134
|
+
} else {
|
|
2135
|
+
total = Number(total) | Number(resolved);
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
if (typeof this.bitfield === "bigint" && typeof total === "bigint") {
|
|
2139
|
+
if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
|
|
2140
|
+
this.bitfield |= total;
|
|
2141
|
+
} else {
|
|
2142
|
+
if (Object.isFrozen(this))
|
|
2143
|
+
return new this.constructor(Number(this.bitfield) | Number(total));
|
|
2144
|
+
this.bitfield = Number(this.bitfield) | Number(total);
|
|
2145
|
+
}
|
|
2146
|
+
return this;
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Removes one or more bits from this bitfield.
|
|
2150
|
+
* If the instance is frozen, returns a new BitField with the bits removed.
|
|
2151
|
+
*
|
|
2152
|
+
* @param bits The bit(s) to remove.
|
|
2153
|
+
* @returns This instance (or a new one if frozen), with the bits cleared.
|
|
2154
|
+
*
|
|
2155
|
+
* @example
|
|
2156
|
+
* perms.remove('ManageChannel');
|
|
2157
|
+
*/
|
|
2158
|
+
remove(...bits) {
|
|
2159
|
+
let total = this.constructor.DefaultBit;
|
|
2160
|
+
for (const bit of bits) {
|
|
2161
|
+
const resolved = this.constructor.resolve(bit);
|
|
2162
|
+
if (typeof total === "bigint" && typeof resolved === "bigint") {
|
|
2163
|
+
total |= resolved;
|
|
2164
|
+
} else {
|
|
2165
|
+
total = Number(total) | Number(resolved);
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
if (typeof this.bitfield === "bigint" && typeof total === "bigint") {
|
|
2169
|
+
if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
|
|
2170
|
+
this.bitfield &= ~total;
|
|
2171
|
+
} else {
|
|
2172
|
+
if (Object.isFrozen(this))
|
|
2173
|
+
return new this.constructor(Number(this.bitfield) & ~Number(total));
|
|
2174
|
+
this.bitfield = Number(this.bitfield) & ~Number(total);
|
|
2175
|
+
}
|
|
2176
|
+
return this;
|
|
2177
|
+
}
|
|
2178
|
+
/**
|
|
2179
|
+
* Serializes this bitfield to a plain object mapping each flag name to a boolean
|
|
2180
|
+
* indicating whether that flag is set.
|
|
2181
|
+
*
|
|
2182
|
+
* @returns A record of `{ [flagName]: boolean }` for all defined flags.
|
|
2183
|
+
*
|
|
2184
|
+
* @example
|
|
2185
|
+
* perms.serialize();
|
|
2186
|
+
* // { SendMessage: true, ManageChannel: false, ... }
|
|
2187
|
+
*/
|
|
2188
|
+
serialize(...hasParams) {
|
|
2189
|
+
const serialized = {};
|
|
2190
|
+
for (const [flag, bit] of Object.entries(this.constructor.Flags)) {
|
|
2191
|
+
if (isNaN(Number(flag))) serialized[flag] = this.has(bit, ...hasParams);
|
|
2192
|
+
}
|
|
2193
|
+
return serialized;
|
|
2194
|
+
}
|
|
2195
|
+
/**
|
|
2196
|
+
* Returns an array of flag names that are set in this bitfield.
|
|
2197
|
+
*
|
|
2198
|
+
* @returns An array of string flag names.
|
|
2199
|
+
*
|
|
2200
|
+
* @example
|
|
2201
|
+
* perms.toArray(); // ['SendMessage', 'ViewChannel']
|
|
2202
|
+
*/
|
|
2203
|
+
toArray(...hasParams) {
|
|
2204
|
+
return [...this[Symbol.iterator](...hasParams)];
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* Returns the bitfield value as a JSON-safe primitive.
|
|
2208
|
+
* Numbers are returned as-is; bigints are converted to their string representation
|
|
2209
|
+
* to avoid JSON serialization errors.
|
|
2210
|
+
*/
|
|
2211
|
+
toJSON() {
|
|
2212
|
+
return typeof this.bitfield === "number" ? this.bitfield : this.bitfield.toString();
|
|
2213
|
+
}
|
|
2214
|
+
/**
|
|
2215
|
+
* Returns the underlying numeric value of this bitfield.
|
|
2216
|
+
* Allows BitField instances to be used directly in arithmetic expressions.
|
|
2217
|
+
*/
|
|
2218
|
+
valueOf() {
|
|
2219
|
+
return this.bitfield;
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Iterates over the names of all flags that are set in this bitfield.
|
|
2223
|
+
*
|
|
2224
|
+
* @example
|
|
2225
|
+
* for (const flag of perms) {
|
|
2226
|
+
* console.log(flag); // 'SendMessage', 'ViewChannel', etc.
|
|
2227
|
+
* }
|
|
2228
|
+
*/
|
|
2229
|
+
*[Symbol.iterator](...hasParams) {
|
|
2230
|
+
for (const bitName of Object.keys(this.constructor.Flags)) {
|
|
2231
|
+
if (isNaN(Number(bitName)) && this.has(bitName, ...hasParams)) yield bitName;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
/**
|
|
2235
|
+
* Resolves a {@link BitFieldResolvable} into a raw `number | bigint`.
|
|
2236
|
+
*
|
|
2237
|
+
* Resolution rules (in order):
|
|
2238
|
+
* - `undefined` → `DefaultBit`
|
|
2239
|
+
* - A number or bigint matching `DefaultBit`'s type and >= 0 → returned as-is
|
|
2240
|
+
* - A `BitField` instance → its `.bitfield` value
|
|
2241
|
+
* - An array → each element resolved and OR'd together
|
|
2242
|
+
* - A numeric string → parsed as `BigInt` or `Number` depending on `DefaultBit`'s type
|
|
2243
|
+
* - A named string flag → looked up in `Flags`
|
|
2244
|
+
* - Anything else → throws `RangeError`
|
|
2245
|
+
*
|
|
2246
|
+
* @param bit The value to resolve.
|
|
2247
|
+
* @throws {RangeError} If the value cannot be resolved to a valid bit.
|
|
2248
|
+
*/
|
|
2249
|
+
static resolve(bit) {
|
|
2250
|
+
const { DefaultBit } = this;
|
|
2251
|
+
if (bit === void 0) return DefaultBit;
|
|
2252
|
+
if (typeof DefaultBit === typeof bit && bit >= DefaultBit) return bit;
|
|
2253
|
+
if (bit instanceof _BitField) return bit.bitfield;
|
|
2254
|
+
if (Array.isArray(bit)) {
|
|
2255
|
+
return bit.map((b) => this.resolve(b)).reduce((prev, b) => {
|
|
2256
|
+
if (typeof prev === "bigint" && typeof b === "bigint") return prev | b;
|
|
2257
|
+
return Number(prev) | Number(b);
|
|
2258
|
+
}, DefaultBit);
|
|
2259
|
+
}
|
|
2260
|
+
if (typeof bit === "string") {
|
|
2261
|
+
if (!isNaN(Number(bit))) return typeof DefaultBit === "bigint" ? BigInt(bit) : Number(bit);
|
|
2262
|
+
if (this.Flags[bit] !== void 0) return this.Flags[bit];
|
|
2263
|
+
}
|
|
2264
|
+
throw new RangeError(`Invalid bitfield flag or number: ${String(bit)}`);
|
|
2265
|
+
}
|
|
2266
|
+
};
|
|
2267
|
+
|
|
1290
2268
|
// src/utils/permissions.ts
|
|
1291
2269
|
var PermissionFlags = {
|
|
1292
2270
|
// Server permissions
|
|
@@ -1330,26 +2308,26 @@ var PermissionFlags = {
|
|
|
1330
2308
|
// Grant all
|
|
1331
2309
|
GrantAllSafe: 0x000fffffffffffffn
|
|
1332
2310
|
};
|
|
1333
|
-
var Permissions = class {
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
if (typeof permission === "bigint") return permission;
|
|
1339
|
-
if (typeof permission === "string") {
|
|
1340
|
-
return PermissionFlags[permission] ?? 0n;
|
|
1341
|
-
}
|
|
1342
|
-
if (Array.isArray(permission)) {
|
|
1343
|
-
return permission.reduce((acc, p) => acc | this.resolve(p), 0n);
|
|
1344
|
-
}
|
|
1345
|
-
return 0n;
|
|
2311
|
+
var Permissions = class extends BitField {
|
|
2312
|
+
static Flags = PermissionFlags;
|
|
2313
|
+
static DefaultBit = 0n;
|
|
2314
|
+
static resolve(bit) {
|
|
2315
|
+
return super.resolve(bit);
|
|
1346
2316
|
}
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
2317
|
+
has(bit) {
|
|
2318
|
+
return super.has(bit);
|
|
2319
|
+
}
|
|
2320
|
+
any(bit) {
|
|
2321
|
+
return super.any(bit);
|
|
2322
|
+
}
|
|
2323
|
+
missing(bits) {
|
|
2324
|
+
return super.missing(bits);
|
|
2325
|
+
}
|
|
2326
|
+
add(...bits) {
|
|
2327
|
+
return super.add(...bits);
|
|
2328
|
+
}
|
|
2329
|
+
remove(...bits) {
|
|
2330
|
+
return super.remove(...bits);
|
|
1353
2331
|
}
|
|
1354
2332
|
};
|
|
1355
2333
|
|
|
@@ -1412,7 +2390,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1412
2390
|
/**
|
|
1413
2391
|
* Fetches a Channel from the API or resolves it from the local cache.
|
|
1414
2392
|
* @param channel The ID, mention, or Channel object to fetch.
|
|
1415
|
-
* @param force Whether to skip the cache check and force a direct API request. Defaults to
|
|
2393
|
+
* @param force Whether to skip the cache check and force a direct API request. Defaults to false.
|
|
1416
2394
|
* @returns A promise that resolves to the fetched BaseChannel object.
|
|
1417
2395
|
* @throws {TypeError} If an invalid ChannelResolvable is provided.
|
|
1418
2396
|
* @throws {Error} If the API request fails.
|
|
@@ -1420,7 +2398,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1420
2398
|
* // Fetch a channel, bypassing cache
|
|
1421
2399
|
* const channel = await client.channels.fetch("01H...");
|
|
1422
2400
|
*/
|
|
1423
|
-
async fetch(channel, force =
|
|
2401
|
+
async fetch(channel, force = false) {
|
|
1424
2402
|
if (!force) {
|
|
1425
2403
|
const cached = this.resolve(channel);
|
|
1426
2404
|
if (cached) return cached;
|
|
@@ -1458,7 +2436,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1458
2436
|
}
|
|
1459
2437
|
if (options.icon !== void 0) {
|
|
1460
2438
|
if (options.icon === null) remove.push("Icon");
|
|
1461
|
-
else payload.icon = options.icon;
|
|
2439
|
+
else payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
|
|
1462
2440
|
}
|
|
1463
2441
|
if (remove.length > 0) payload.remove = remove;
|
|
1464
2442
|
if (Object.keys(payload).length === 0) return this.fetch(channel);
|
|
@@ -1534,10 +2512,51 @@ var ChannelManager = class extends BaseManager {
|
|
|
1534
2512
|
await this.client.rest.delete(`/channels/${id}`);
|
|
1535
2513
|
this.cache.delete(id);
|
|
1536
2514
|
}
|
|
2515
|
+
/**
|
|
2516
|
+
* Pin a message
|
|
2517
|
+
* @param id Channel ID
|
|
2518
|
+
* @param messageId Message ID
|
|
2519
|
+
* @throws {Error} If the API request fails.
|
|
2520
|
+
* @example
|
|
2521
|
+
* await client.channels.pin("CHANNEL_ID", "MESSAGE_ID");
|
|
2522
|
+
*/
|
|
2523
|
+
async pin(id, messageId) {
|
|
2524
|
+
await this.client.rest.post(`/channels/${id}/pins/${messageId}`);
|
|
2525
|
+
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Unpin a message
|
|
2528
|
+
* @param id Channel ID
|
|
2529
|
+
* @param messageId Message ID
|
|
2530
|
+
* @throws {Error} If the API request fails
|
|
2531
|
+
* @example
|
|
2532
|
+
* await client.channels.unpin("CHANNEL_ID", "MESSAGE_ID");
|
|
2533
|
+
*/
|
|
2534
|
+
async unpin(id, messageId) {
|
|
2535
|
+
await this.client.rest.delete(`/channels/${id}/pins/${messageId}`);
|
|
2536
|
+
}
|
|
2537
|
+
/**
|
|
2538
|
+
* Bulk delete up to 100 messages
|
|
2539
|
+
* @param id Channel ID
|
|
2540
|
+
* @param messages An array of MessageResolvable
|
|
2541
|
+
* @throws {Error} If the API request fails
|
|
2542
|
+
* @example
|
|
2543
|
+
* await client.channels.bulkDelete("CHANNEL_ID", ["MESSAGE_ID_1", "MESSAGE_ID_2", "MESSAGE_ID_3"]);
|
|
2544
|
+
*/
|
|
2545
|
+
async bulkDelete(id, messages) {
|
|
2546
|
+
if (!Array.isArray(messages) || messages.length === 0 || messages.length > 100) {
|
|
2547
|
+
throw new TypeError("Messages must be an array of 1-100 MessageResolvable items.");
|
|
2548
|
+
}
|
|
2549
|
+
const messageIds = messages.map((msg) => {
|
|
2550
|
+
if (typeof msg === "string") return msg.replace(/[<#>]/g, "");
|
|
2551
|
+
if ("id" in msg) return msg.id;
|
|
2552
|
+
throw new TypeError("Invalid MessageResolvable provided. Expected a Message object or a string ID/Mention.");
|
|
2553
|
+
});
|
|
2554
|
+
await this.client.rest.delete(`/channels/${id}/messages/bulk`, { messages: messageIds });
|
|
2555
|
+
}
|
|
1537
2556
|
};
|
|
1538
2557
|
|
|
1539
2558
|
// src/structures/Member.ts
|
|
1540
|
-
var
|
|
2559
|
+
var util5 = __toESM(require("util"), 1);
|
|
1541
2560
|
|
|
1542
2561
|
// src/managers/MemberRoleManager.ts
|
|
1543
2562
|
var MemberRoleManager = class {
|
|
@@ -1663,15 +2682,15 @@ var Member = class extends Base {
|
|
|
1663
2682
|
/** Calculates the member's total permissions using BigInt */
|
|
1664
2683
|
get permissions() {
|
|
1665
2684
|
const server = this.server;
|
|
1666
|
-
if (!server) return 0n;
|
|
2685
|
+
if (!server) return new Permissions(0n);
|
|
2686
|
+
if (server.ownerId === this.id) {
|
|
2687
|
+
return new Permissions(PermissionFlags.GrantAllSafe);
|
|
2688
|
+
}
|
|
1667
2689
|
let totalPerms = server.defaultPermissions ?? 0n;
|
|
1668
2690
|
for (const role of this.roles.cache.values()) {
|
|
1669
|
-
totalPerms |= BigInt(role.permissions);
|
|
1670
|
-
}
|
|
1671
|
-
if (server.ownerId === this.id) {
|
|
1672
|
-
return PermissionFlags.GrantAllSafe;
|
|
2691
|
+
totalPerms |= BigInt(role.permissions.bitfield);
|
|
1673
2692
|
}
|
|
1674
|
-
return totalPerms;
|
|
2693
|
+
return new Permissions(totalPerms);
|
|
1675
2694
|
}
|
|
1676
2695
|
/** Get avatar URL for this member, or null if they don't have one.
|
|
1677
2696
|
* @example
|
|
@@ -1716,13 +2735,24 @@ var Member = class extends Base {
|
|
|
1716
2735
|
* await member.setTimeout(600000);
|
|
1717
2736
|
*/
|
|
1718
2737
|
async setTimeout(duration) {
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
2738
|
+
await this.edit({ timeout: new Date(Date.now() + duration).toISOString() });
|
|
2739
|
+
}
|
|
2740
|
+
/**
|
|
2741
|
+
* Send a message to this member.
|
|
2742
|
+
* @param options The content or options for the message to send.
|
|
2743
|
+
* @returns A promise that resolves to the sent Message object.
|
|
2744
|
+
* @throws {Error} If the API request fails.
|
|
2745
|
+
* @example
|
|
2746
|
+
* // Send a message to this member
|
|
2747
|
+
* const message = await member.send("Hello!");
|
|
2748
|
+
* console.log(`Sent message ID: ${message.id}`);
|
|
2749
|
+
*/
|
|
2750
|
+
async send(options) {
|
|
2751
|
+
let dmChannel = await this.client.users.createDM(this.id);
|
|
2752
|
+
return dmChannel.messages.send(options);
|
|
1722
2753
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
return Permissions.has(this.permissions, permission);
|
|
2754
|
+
async setNickname(nickname) {
|
|
2755
|
+
return this.edit({ nickname });
|
|
1726
2756
|
}
|
|
1727
2757
|
/**
|
|
1728
2758
|
* Edit this member.
|
|
@@ -1734,6 +2764,16 @@ var Member = class extends Base {
|
|
|
1734
2764
|
if (!server) server = await this.client.servers.fetch(this.serverId);
|
|
1735
2765
|
return await server.members.edit(this.id, options);
|
|
1736
2766
|
}
|
|
2767
|
+
/**
|
|
2768
|
+
* When concatenated with a string, this automatically returns the user's mention instead of the GuildMember object.
|
|
2769
|
+
* @returns {string}
|
|
2770
|
+
* @example
|
|
2771
|
+
* // Logs: Hello from <@01JE2MM759J5D7CHJF084R7MJ2>!
|
|
2772
|
+
* console.log(`Hello from ${member}!`);
|
|
2773
|
+
*/
|
|
2774
|
+
toString() {
|
|
2775
|
+
return `<@${this.id}>`;
|
|
2776
|
+
}
|
|
1737
2777
|
/**
|
|
1738
2778
|
* Kick this member from the server.
|
|
1739
2779
|
*/
|
|
@@ -1743,9 +2783,9 @@ var Member = class extends Base {
|
|
|
1743
2783
|
await server.members.kick(this.id);
|
|
1744
2784
|
}
|
|
1745
2785
|
/** @internal */
|
|
1746
|
-
[
|
|
2786
|
+
[util5.inspect.custom](depth, options, inspect12) {
|
|
1747
2787
|
const { client, serverId, ...props } = this;
|
|
1748
|
-
return `${this.constructor.name} ${
|
|
2788
|
+
return `${this.constructor.name} ${inspect12(
|
|
1749
2789
|
{
|
|
1750
2790
|
...props,
|
|
1751
2791
|
user: this.user,
|
|
@@ -1757,7 +2797,7 @@ var Member = class extends Base {
|
|
|
1757
2797
|
};
|
|
1758
2798
|
|
|
1759
2799
|
// src/managers/MemberManager.ts
|
|
1760
|
-
var
|
|
2800
|
+
var util6 = __toESM(require("util"), 1);
|
|
1761
2801
|
var MemberManager = class extends BaseManager {
|
|
1762
2802
|
constructor(client, server, limit = Infinity) {
|
|
1763
2803
|
super(client, limit);
|
|
@@ -1931,25 +2971,13 @@ var MemberManager = class extends BaseManager {
|
|
|
1931
2971
|
const id = this.resolveId(member);
|
|
1932
2972
|
await this.client.rest.delete(`/servers/${this.server.id}/bans/${id}`);
|
|
1933
2973
|
}
|
|
1934
|
-
|
|
1935
|
-
* Timeouts a member in the server for a specified duration.
|
|
1936
|
-
* @param member The MemberResolvable to timeout
|
|
1937
|
-
* @param duration The duration of the timeout in milliseconds
|
|
1938
|
-
* @example
|
|
1939
|
-
* // Timeout a member for 10 minutes
|
|
1940
|
-
* await server.members.setTimeout("1234567890", 10 * 60 * 1000);
|
|
1941
|
-
*/
|
|
1942
|
-
async setTimeout(member, duration) {
|
|
1943
|
-
const id = this.resolveId(member);
|
|
1944
|
-
await this.edit(id, { timeout: new Date(Date.now() + duration).toISOString() });
|
|
1945
|
-
}
|
|
1946
|
-
[util5.inspect.custom]() {
|
|
2974
|
+
[util6.inspect.custom]() {
|
|
1947
2975
|
return this.cache;
|
|
1948
2976
|
}
|
|
1949
2977
|
};
|
|
1950
2978
|
|
|
1951
2979
|
// src/managers/ServerChannelManager.ts
|
|
1952
|
-
var
|
|
2980
|
+
var util7 = __toESM(require("util"), 1);
|
|
1953
2981
|
var ServerChannelManager = class {
|
|
1954
2982
|
client;
|
|
1955
2983
|
server;
|
|
@@ -1979,20 +3007,21 @@ var ServerChannelManager = class {
|
|
|
1979
3007
|
const data = await this.client.rest.post(`/servers/${this.server.id}/channels`, payload);
|
|
1980
3008
|
return this.client.channels._add(data);
|
|
1981
3009
|
}
|
|
1982
|
-
[
|
|
3010
|
+
[util7.inspect.custom]() {
|
|
1983
3011
|
return this.cache;
|
|
1984
3012
|
}
|
|
1985
3013
|
};
|
|
1986
3014
|
|
|
1987
3015
|
// src/structures/Role.ts
|
|
1988
|
-
var
|
|
3016
|
+
var util8 = __toESM(require("util"), 1);
|
|
1989
3017
|
var Role = class extends Base {
|
|
1990
3018
|
serverId;
|
|
1991
3019
|
name;
|
|
1992
3020
|
color = null;
|
|
1993
3021
|
hoist = false;
|
|
1994
3022
|
rank = 0;
|
|
1995
|
-
|
|
3023
|
+
icon = null;
|
|
3024
|
+
_permissions = 0n;
|
|
1996
3025
|
constructor(client, data, serverId) {
|
|
1997
3026
|
super(client, data);
|
|
1998
3027
|
this.serverId = serverId;
|
|
@@ -2007,16 +3036,17 @@ var Role = class extends Base {
|
|
|
2007
3036
|
if (data.color !== void 0) this.color = data.color;
|
|
2008
3037
|
if (data.hoist !== void 0) this.hoist = data.hoist;
|
|
2009
3038
|
if (data.rank !== void 0) this.rank = data.rank;
|
|
3039
|
+
if (data.icon !== void 0) this.icon = new Attachment(this.client, data.icon);
|
|
2010
3040
|
if (data.permissions !== void 0) {
|
|
2011
3041
|
try {
|
|
2012
3042
|
if (typeof data.permissions === "object" && data.permissions !== null) {
|
|
2013
3043
|
const allowPerms = data.permissions.a ?? data.permissions[0] ?? 0;
|
|
2014
|
-
this.
|
|
3044
|
+
this._permissions = BigInt(allowPerms);
|
|
2015
3045
|
} else {
|
|
2016
|
-
this.
|
|
3046
|
+
this._permissions = BigInt(data.permissions);
|
|
2017
3047
|
}
|
|
2018
3048
|
} catch {
|
|
2019
|
-
this.
|
|
3049
|
+
this._permissions = 0n;
|
|
2020
3050
|
}
|
|
2021
3051
|
}
|
|
2022
3052
|
}
|
|
@@ -2028,12 +3058,10 @@ var Role = class extends Base {
|
|
|
2028
3058
|
return this.client.servers.cache.get(this.serverId);
|
|
2029
3059
|
}
|
|
2030
3060
|
/**
|
|
2031
|
-
*
|
|
2032
|
-
* @param permission The permission to check for.
|
|
2033
|
-
* @returns True if the role has the permission.
|
|
3061
|
+
* Permissions for this role
|
|
2034
3062
|
*/
|
|
2035
|
-
|
|
2036
|
-
return Permissions
|
|
3063
|
+
get permissions() {
|
|
3064
|
+
return new Permissions(this._permissions);
|
|
2037
3065
|
}
|
|
2038
3066
|
/**
|
|
2039
3067
|
* Fetches this role directly from the API to ensure data is up to date.
|
|
@@ -2061,10 +3089,10 @@ var Role = class extends Base {
|
|
|
2061
3089
|
* @throws {Error} If the API request fails (e.g., lack of permissions).
|
|
2062
3090
|
* @example
|
|
2063
3091
|
* // Change the role's name and color
|
|
2064
|
-
* await role.edit({ name: "Senior Admin",
|
|
3092
|
+
* await role.edit({ name: "Senior Admin", color: "#FFD700" });
|
|
2065
3093
|
*
|
|
2066
3094
|
* // Remove the custom color from the role
|
|
2067
|
-
* await role.edit({
|
|
3095
|
+
* await role.edit({ color: null });
|
|
2068
3096
|
*/
|
|
2069
3097
|
async edit(options) {
|
|
2070
3098
|
let server = this.server;
|
|
@@ -2123,19 +3151,86 @@ var Role = class extends Base {
|
|
|
2123
3151
|
await server.roles.setRanks(filteredRoles);
|
|
2124
3152
|
return this;
|
|
2125
3153
|
}
|
|
3154
|
+
/**
|
|
3155
|
+
* Change the name for this role
|
|
3156
|
+
* @param name The new name for the role
|
|
3157
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3158
|
+
* @throws {Error} If API request fails.
|
|
3159
|
+
* @example
|
|
3160
|
+
* // Change the role's name
|
|
3161
|
+
* await role.setName("New Role Name");
|
|
3162
|
+
* console.log(`Role's new name: ${role.name}`);
|
|
3163
|
+
*/
|
|
3164
|
+
async setName(name) {
|
|
3165
|
+
return await this.edit({ name });
|
|
3166
|
+
}
|
|
3167
|
+
/**
|
|
3168
|
+
* Change the color for this role, it can be a HEX or CSS colours
|
|
3169
|
+
* @param {[string]} color The new color for the role
|
|
3170
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3171
|
+
* @throws {Error} If API request fails
|
|
3172
|
+
* @example
|
|
3173
|
+
* // Change the role's color
|
|
3174
|
+
* await role.setColour("#FF0000");
|
|
3175
|
+
* console.log(`Role's new color: ${role.color}`);
|
|
3176
|
+
*
|
|
3177
|
+
* // Use CSS color linear-graident
|
|
3178
|
+
* await role.setColour("linear-gradient(90deg, #FF0000, #0000FF)");
|
|
3179
|
+
* console.log(`Role's new color: ${role.color}`);
|
|
3180
|
+
*
|
|
3181
|
+
* // Remove the custom color from the role
|
|
3182
|
+
* await role.setColour(null);
|
|
3183
|
+
* console.log(`Role's color removed, current color: ${role.color}`);
|
|
3184
|
+
*/
|
|
3185
|
+
async setColor(color) {
|
|
3186
|
+
return await this.edit({ color });
|
|
3187
|
+
}
|
|
3188
|
+
/**
|
|
3189
|
+
* Edit the icon of this role
|
|
3190
|
+
* @param icon Autumn ID for the new icon, or null to remove the custom icon
|
|
3191
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3192
|
+
* @throws {Error} If API request fails
|
|
3193
|
+
* @example
|
|
3194
|
+
* // Set a new icon for the role
|
|
3195
|
+
* await role.setIcon("AUTUMN_ID_FOR_ICON");
|
|
3196
|
+
* console.log(`Role's new icon: ${role.icon}`);
|
|
3197
|
+
*
|
|
3198
|
+
* // Use AttachmentBuilder to upload a new icon file
|
|
3199
|
+
* import { readFile } from "node:fs/promises";
|
|
3200
|
+
* const iconFile = await readFile("./a.jpg");
|
|
3201
|
+
* const attachment = new AttachmentBuilder(iconFile, "a.jpg");
|
|
3202
|
+
* await role.setIcon(attachment);
|
|
3203
|
+
* console.log(`Role's new icon: ${role.icon}`);
|
|
3204
|
+
*/
|
|
3205
|
+
async setIcon(icon) {
|
|
3206
|
+
return await this.edit({ icon });
|
|
3207
|
+
}
|
|
3208
|
+
/**
|
|
3209
|
+
* Change the hoist status for this role
|
|
3210
|
+
* @param hoist The new hoist status for the role
|
|
3211
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3212
|
+
* @throws {Error} If API request fails
|
|
3213
|
+
* @example
|
|
3214
|
+
* // Enable hoisting for the role
|
|
3215
|
+
* await role.setHoist(true);
|
|
3216
|
+
* console.log(`Role is now hoisted: ${role.hoist}`);
|
|
3217
|
+
*/
|
|
3218
|
+
async setHoist(hoist) {
|
|
3219
|
+
return await this.edit({ hoist });
|
|
3220
|
+
}
|
|
2126
3221
|
/**
|
|
2127
3222
|
* Customizer for Node.js `console.log` and `util.inspect`.
|
|
2128
3223
|
* Hides the cyclic client reference and raw serverId for a cleaner output.
|
|
2129
3224
|
* @internal
|
|
2130
3225
|
*/
|
|
2131
|
-
[
|
|
3226
|
+
[util8.inspect.custom]() {
|
|
2132
3227
|
const { client, serverId, ...props } = this;
|
|
2133
|
-
return `${this.constructor.name} ${
|
|
3228
|
+
return `${this.constructor.name} ${util8.inspect(props)}`;
|
|
2134
3229
|
}
|
|
2135
3230
|
};
|
|
2136
3231
|
|
|
2137
3232
|
// src/managers/RoleManager.ts
|
|
2138
|
-
var
|
|
3233
|
+
var util9 = __toESM(require("util"), 1);
|
|
2139
3234
|
var RoleManager = class extends BaseManager {
|
|
2140
3235
|
/**
|
|
2141
3236
|
* Manages API methods and caching for server roles.
|
|
@@ -2174,7 +3269,7 @@ var RoleManager = class extends BaseManager {
|
|
|
2174
3269
|
this.cache.set(role.id, role);
|
|
2175
3270
|
return role;
|
|
2176
3271
|
}
|
|
2177
|
-
[
|
|
3272
|
+
[util9.inspect.custom]() {
|
|
2178
3273
|
return this.cache;
|
|
2179
3274
|
}
|
|
2180
3275
|
/**
|
|
@@ -2260,7 +3355,7 @@ var RoleManager = class extends BaseManager {
|
|
|
2260
3355
|
}
|
|
2261
3356
|
/**
|
|
2262
3357
|
* Edits an existing role in the server.
|
|
2263
|
-
* @param role The RoleResolvable to edit.
|
|
3358
|
+
* @param role The {@link RoleResolvable} to edit.
|
|
2264
3359
|
* @param options The fields to update.
|
|
2265
3360
|
* @returns A promise that resolves to the updated Role.
|
|
2266
3361
|
* @throws {TypeError} If invalid options or RoleResolvable are provided.
|
|
@@ -2281,11 +3376,18 @@ var RoleManager = class extends BaseManager {
|
|
|
2281
3376
|
const remove = [];
|
|
2282
3377
|
if (options.name !== void 0) payload.name = options.name;
|
|
2283
3378
|
if (options.hoist !== void 0) payload.hoist = options.hoist;
|
|
2284
|
-
if (options.
|
|
2285
|
-
if (options.
|
|
3379
|
+
if (options.color !== void 0) {
|
|
3380
|
+
if (options.color === null) {
|
|
2286
3381
|
remove.push("Colour");
|
|
2287
3382
|
} else {
|
|
2288
|
-
payload.colour = options.
|
|
3383
|
+
payload.colour = options.color;
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
if (options.icon !== void 0) {
|
|
3387
|
+
if (options.icon === null) {
|
|
3388
|
+
remove.push("Icon");
|
|
3389
|
+
} else {
|
|
3390
|
+
payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
|
|
2289
3391
|
}
|
|
2290
3392
|
}
|
|
2291
3393
|
if (remove.length > 0) {
|
|
@@ -2475,6 +3577,54 @@ var ServerBanManager = class extends BaseManager {
|
|
|
2475
3577
|
}
|
|
2476
3578
|
};
|
|
2477
3579
|
|
|
3580
|
+
// src/structures/Emoji.ts
|
|
3581
|
+
var Emoji = class extends Base {
|
|
3582
|
+
creatorId;
|
|
3583
|
+
name;
|
|
3584
|
+
parent;
|
|
3585
|
+
animated = false;
|
|
3586
|
+
nsfw = false;
|
|
3587
|
+
constructor(client, data) {
|
|
3588
|
+
super(client, data);
|
|
3589
|
+
this._patch(data);
|
|
3590
|
+
}
|
|
3591
|
+
_patch(data) {
|
|
3592
|
+
if (data.creator_id !== void 0) this.creatorId = data.creator_id;
|
|
3593
|
+
if (data.name !== void 0) this.name = data.name;
|
|
3594
|
+
if (data.parent !== void 0) this.parent = data.parent;
|
|
3595
|
+
if (data.animated !== void 0) this.animated = data.animated;
|
|
3596
|
+
if (data.nsfw !== void 0) this.nsfw = data.nsfw;
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
|
|
3600
|
+
// src/managers/EmojiManager.ts
|
|
3601
|
+
var util10 = __toESM(require("util"), 1);
|
|
3602
|
+
var EmojiManager = class extends BaseManager {
|
|
3603
|
+
constructor(client, server, limit = Infinity) {
|
|
3604
|
+
super(client, limit);
|
|
3605
|
+
this.server = server;
|
|
3606
|
+
}
|
|
3607
|
+
/**
|
|
3608
|
+
* Tell BaseManager how to find the ID for Emojis
|
|
3609
|
+
*/
|
|
3610
|
+
extractId(data) {
|
|
3611
|
+
return data._id ?? data.id;
|
|
3612
|
+
}
|
|
3613
|
+
/**
|
|
3614
|
+
* Tell BaseManager how to build an Emoji
|
|
3615
|
+
*/
|
|
3616
|
+
construct(data) {
|
|
3617
|
+
return new Emoji(this.client, data);
|
|
3618
|
+
}
|
|
3619
|
+
async fetch(id) {
|
|
3620
|
+
const data = await this.client.rest.get(`/custom/emoji/${id}`);
|
|
3621
|
+
return this._add(data);
|
|
3622
|
+
}
|
|
3623
|
+
[util10.inspect.custom]() {
|
|
3624
|
+
return this.cache;
|
|
3625
|
+
}
|
|
3626
|
+
};
|
|
3627
|
+
|
|
2478
3628
|
// src/structures/Server.ts
|
|
2479
3629
|
var Server = class extends Base {
|
|
2480
3630
|
channelIds = [];
|
|
@@ -2494,6 +3644,7 @@ var Server = class extends Base {
|
|
|
2494
3644
|
roles;
|
|
2495
3645
|
bans;
|
|
2496
3646
|
invites;
|
|
3647
|
+
emojis;
|
|
2497
3648
|
constructor(client, data) {
|
|
2498
3649
|
super(client, data);
|
|
2499
3650
|
this.channels = new ServerChannelManager(client, this);
|
|
@@ -2501,6 +3652,7 @@ var Server = class extends Base {
|
|
|
2501
3652
|
this.roles = new RoleManager(client, this);
|
|
2502
3653
|
this.bans = new ServerBanManager(this.client, this);
|
|
2503
3654
|
this.invites = new ServerInviteManager(this.client, this);
|
|
3655
|
+
this.emojis = new EmojiManager(this.client, this);
|
|
2504
3656
|
this._patch(data);
|
|
2505
3657
|
}
|
|
2506
3658
|
/**
|
|
@@ -2534,6 +3686,13 @@ var Server = class extends Base {
|
|
|
2534
3686
|
this.roles._add({ id, ...roleData });
|
|
2535
3687
|
}
|
|
2536
3688
|
}
|
|
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
|
+
}
|
|
2537
3696
|
if (clear && Array.isArray(clear)) {
|
|
2538
3697
|
for (const field of clear) {
|
|
2539
3698
|
switch (field) {
|
|
@@ -2572,7 +3731,7 @@ var Server = class extends Base {
|
|
|
2572
3731
|
};
|
|
2573
3732
|
|
|
2574
3733
|
// src/managers/ServerManager.ts
|
|
2575
|
-
var
|
|
3734
|
+
var util11 = __toESM(require("util"), 1);
|
|
2576
3735
|
var ServerManager = class extends BaseManager {
|
|
2577
3736
|
constructor(client, limit = Infinity) {
|
|
2578
3737
|
super(client, limit);
|
|
@@ -2645,7 +3804,7 @@ var ServerManager = class extends BaseManager {
|
|
|
2645
3804
|
const data = await this.client.rest.patch(`/servers/${serverId}`, payload);
|
|
2646
3805
|
return this._add(data);
|
|
2647
3806
|
}
|
|
2648
|
-
[
|
|
3807
|
+
[util11.inspect.custom]() {
|
|
2649
3808
|
return this.cache;
|
|
2650
3809
|
}
|
|
2651
3810
|
};
|
|
@@ -2874,7 +4033,7 @@ var SweeperManager = class {
|
|
|
2874
4033
|
};
|
|
2875
4034
|
|
|
2876
4035
|
// src/client/Client.ts
|
|
2877
|
-
var Client = class extends
|
|
4036
|
+
var Client = class extends import_events2.EventEmitter {
|
|
2878
4037
|
constructor(options = {}) {
|
|
2879
4038
|
super({ captureRejections: true });
|
|
2880
4039
|
this.options = options;
|
|
@@ -2883,6 +4042,7 @@ var Client = class extends import_events.EventEmitter {
|
|
|
2883
4042
|
this.channels = new ChannelManager(this, options.cacheLimits?.channels);
|
|
2884
4043
|
this.servers = new ServerManager(this, options.cacheLimits?.servers);
|
|
2885
4044
|
this.users = new UserManager(this, options.cacheLimits?.users);
|
|
4045
|
+
this.emojis = new EmojiManager(this, void 0, options.cacheLimits?.emojis);
|
|
2886
4046
|
this.sweepers = new SweeperManager(this, options.sweepers ?? {});
|
|
2887
4047
|
}
|
|
2888
4048
|
rest;
|
|
@@ -2891,6 +4051,7 @@ var Client = class extends import_events.EventEmitter {
|
|
|
2891
4051
|
servers;
|
|
2892
4052
|
users;
|
|
2893
4053
|
sweepers;
|
|
4054
|
+
emojis;
|
|
2894
4055
|
user = null;
|
|
2895
4056
|
/**
|
|
2896
4057
|
* Connects the bot to the Stoat Gateway
|
|
@@ -2955,23 +4116,31 @@ var EmbedBuilder = class {
|
|
|
2955
4116
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2956
4117
|
0 && (module.exports = {
|
|
2957
4118
|
Attachment,
|
|
4119
|
+
AttachmentBuilder,
|
|
2958
4120
|
Base,
|
|
2959
4121
|
BaseChannel,
|
|
4122
|
+
BitField,
|
|
2960
4123
|
ChannelManager,
|
|
2961
4124
|
ChannelType,
|
|
2962
4125
|
Client,
|
|
2963
4126
|
ClientUser,
|
|
2964
4127
|
Collection,
|
|
4128
|
+
Collector,
|
|
2965
4129
|
DMChannel,
|
|
2966
4130
|
EmbedBuilder,
|
|
4131
|
+
Emoji,
|
|
4132
|
+
EmojiManager,
|
|
2967
4133
|
GatewayManager,
|
|
2968
4134
|
Member,
|
|
2969
4135
|
MemberManager,
|
|
2970
4136
|
Message,
|
|
4137
|
+
MessageCollector,
|
|
2971
4138
|
MessageManager,
|
|
4139
|
+
MessageReaction,
|
|
2972
4140
|
PermissionFlags,
|
|
2973
4141
|
Permissions,
|
|
2974
4142
|
RESTManager,
|
|
4143
|
+
ReactionCollector,
|
|
2975
4144
|
Role,
|
|
2976
4145
|
RoleManager,
|
|
2977
4146
|
Server,
|