@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.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/client/Client.ts
|
|
2
|
-
import { EventEmitter } from "events";
|
|
2
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
3
3
|
|
|
4
4
|
// src/gateway/GatewayManager.ts
|
|
5
5
|
import WebSocket from "ws";
|
|
@@ -40,7 +40,7 @@ var Base = class _Base {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
// src/structures/Message.ts
|
|
43
|
-
import * as
|
|
43
|
+
import * as util2 from "util";
|
|
44
44
|
|
|
45
45
|
// src/structures/Attachment.ts
|
|
46
46
|
var Attachment = class extends Base {
|
|
@@ -87,6 +87,306 @@ var Attachment = class extends Base {
|
|
|
87
87
|
|
|
88
88
|
// src/structures/Message.ts
|
|
89
89
|
import { decodeTime } from "ulid";
|
|
90
|
+
|
|
91
|
+
// src/utils/Collector.ts
|
|
92
|
+
import { EventEmitter } from "events";
|
|
93
|
+
|
|
94
|
+
// src/utils/Collection.ts
|
|
95
|
+
var Collection = class _Collection extends Map {
|
|
96
|
+
limit;
|
|
97
|
+
constructor(limit = Infinity) {
|
|
98
|
+
super();
|
|
99
|
+
this.limit = limit;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Overrides the default set method to enforce the maximum cache size.
|
|
103
|
+
*/
|
|
104
|
+
set(key, value) {
|
|
105
|
+
if (this.limit === 0) return this;
|
|
106
|
+
if (this.size >= this.limit && !this.has(key)) {
|
|
107
|
+
const oldestKey = this.keys().next().value;
|
|
108
|
+
if (oldestKey !== void 0) {
|
|
109
|
+
this.delete(oldestKey);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return super.set(key, value);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Finds the first item where the given function returns true.
|
|
116
|
+
*/
|
|
117
|
+
find(fn) {
|
|
118
|
+
for (const [key, val] of this) {
|
|
119
|
+
if (fn(val, key, this)) return val;
|
|
120
|
+
}
|
|
121
|
+
return void 0;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns a new Collection containing only the items where the function returns true.
|
|
125
|
+
*/
|
|
126
|
+
filter(fn) {
|
|
127
|
+
const results = new _Collection();
|
|
128
|
+
for (const [key, val] of this) {
|
|
129
|
+
if (fn(val, key, this)) results.set(key, val);
|
|
130
|
+
}
|
|
131
|
+
return results;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Maps each item to a new array of values.
|
|
135
|
+
*/
|
|
136
|
+
map(fn) {
|
|
137
|
+
const results = [];
|
|
138
|
+
for (const [key, val] of this) {
|
|
139
|
+
results.push(fn(val, key, this));
|
|
140
|
+
}
|
|
141
|
+
return results;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gets the very first value in the Collection (based on insertion order).
|
|
145
|
+
*/
|
|
146
|
+
first() {
|
|
147
|
+
return this.values().next().value;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Gets the very last value in the Collection.
|
|
151
|
+
*/
|
|
152
|
+
last() {
|
|
153
|
+
const arr = Array.from(this.values());
|
|
154
|
+
return arr[arr.length - 1];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Checks if at least one item matches the condition.
|
|
158
|
+
*/
|
|
159
|
+
some(fn) {
|
|
160
|
+
for (const [key, val] of this) {
|
|
161
|
+
if (fn(val, key, this)) return true;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/utils/Collector.ts
|
|
168
|
+
var Collector = class extends EventEmitter {
|
|
169
|
+
client;
|
|
170
|
+
filter;
|
|
171
|
+
options;
|
|
172
|
+
collected;
|
|
173
|
+
ended = false;
|
|
174
|
+
_timeout = null;
|
|
175
|
+
_idletimeout = null;
|
|
176
|
+
constructor(client, options = {}) {
|
|
177
|
+
super();
|
|
178
|
+
this.client = client;
|
|
179
|
+
this.options = options;
|
|
180
|
+
this.filter = options.filter ?? (() => true);
|
|
181
|
+
this.collected = new Collection();
|
|
182
|
+
if (options.time) {
|
|
183
|
+
this._timeout = setTimeout(() => this.stop("time"), options.time);
|
|
184
|
+
}
|
|
185
|
+
if (options.idle) {
|
|
186
|
+
this._idletimeout = setTimeout(() => this.stop("idle"), options.idle);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Evaluates an item and possibly passes it to the collector
|
|
191
|
+
*/
|
|
192
|
+
handleCollect(item, ...args) {
|
|
193
|
+
if (this.ended) return;
|
|
194
|
+
if (!this.filter(item, ...args)) return;
|
|
195
|
+
const key = this.collect(item, ...args);
|
|
196
|
+
if (key !== null && key !== void 0) {
|
|
197
|
+
this.collected.set(key, item);
|
|
198
|
+
this.emit("collect", item, ...args);
|
|
199
|
+
if (this._idletimeout) {
|
|
200
|
+
clearTimeout(this._idletimeout);
|
|
201
|
+
this._idletimeout = setTimeout(() => this.stop("idle"), this.options.idle);
|
|
202
|
+
}
|
|
203
|
+
this.checkEnd();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Evaluates an item and possibly removes it from the collector
|
|
208
|
+
*/
|
|
209
|
+
handleDispose(item, ...args) {
|
|
210
|
+
if (this.ended) return;
|
|
211
|
+
if (!this.options.dispose) return;
|
|
212
|
+
const key = this.dispose(item, ...args);
|
|
213
|
+
if (key !== null && key !== void 0) {
|
|
214
|
+
this.collected.delete(key);
|
|
215
|
+
this.emit("dispose", item, ...args);
|
|
216
|
+
this.checkEnd();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Stops the collector.
|
|
221
|
+
*/
|
|
222
|
+
stop(reason = "user") {
|
|
223
|
+
if (this.ended) return;
|
|
224
|
+
this.ended = true;
|
|
225
|
+
if (this._timeout) clearTimeout(this._timeout);
|
|
226
|
+
if (this._idletimeout) clearTimeout(this._idletimeout);
|
|
227
|
+
this.removeAllListeners("collect");
|
|
228
|
+
this.removeAllListeners("dispose");
|
|
229
|
+
this.emit("end", this.collected, reason);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check if we should end upon collecting/disposing
|
|
233
|
+
*/
|
|
234
|
+
checkEnd() {
|
|
235
|
+
const reason = this.endReason();
|
|
236
|
+
if (reason) this.stop(reason);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Check if there's a reason to end
|
|
240
|
+
*/
|
|
241
|
+
endReason() {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Allows iterating over collected items asynchronously.
|
|
246
|
+
* @example
|
|
247
|
+
* for await (const [id, message] of collector) {
|
|
248
|
+
* console.log(`Received message: ${message.content}`);
|
|
249
|
+
* }
|
|
250
|
+
*/
|
|
251
|
+
async *[Symbol.asyncIterator]() {
|
|
252
|
+
const queue = [];
|
|
253
|
+
let resolve = null;
|
|
254
|
+
const onCollect = (item, ...args) => {
|
|
255
|
+
const key = this.collect(item, ...args);
|
|
256
|
+
if (key !== null && key !== void 0) {
|
|
257
|
+
queue.push([key, item]);
|
|
258
|
+
}
|
|
259
|
+
if (resolve) {
|
|
260
|
+
resolve();
|
|
261
|
+
resolve = null;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
const onEnd = () => {
|
|
265
|
+
if (resolve) {
|
|
266
|
+
resolve();
|
|
267
|
+
resolve = null;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
this.on("collect", onCollect);
|
|
271
|
+
this.on("end", onEnd);
|
|
272
|
+
try {
|
|
273
|
+
while (true) {
|
|
274
|
+
if (queue.length > 0) {
|
|
275
|
+
yield queue.shift();
|
|
276
|
+
} else if (this.ended) {
|
|
277
|
+
break;
|
|
278
|
+
} else {
|
|
279
|
+
await new Promise((res) => {
|
|
280
|
+
resolve = res;
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
} finally {
|
|
285
|
+
this.removeListener("collect", onCollect);
|
|
286
|
+
this.removeListener("end", onEnd);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/structures/MessageReaction.ts
|
|
292
|
+
import * as util from "util";
|
|
293
|
+
var MessageReaction = class {
|
|
294
|
+
constructor(client, data) {
|
|
295
|
+
this.client = client;
|
|
296
|
+
this.message = data.message;
|
|
297
|
+
this.emoji = this.client.emojis.cache.get(data.emojiId) || data.emojiId;
|
|
298
|
+
this.users = new Collection();
|
|
299
|
+
if (data.users) {
|
|
300
|
+
for (const userId of data.users) {
|
|
301
|
+
const user = this.client.users.cache.get(userId) || { id: userId };
|
|
302
|
+
this.users.set(userId, user);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
message;
|
|
307
|
+
emoji;
|
|
308
|
+
users;
|
|
309
|
+
get count() {
|
|
310
|
+
return this.users.size;
|
|
311
|
+
}
|
|
312
|
+
async remove() {
|
|
313
|
+
if (this.message instanceof Message) {
|
|
314
|
+
const emojiId = typeof this.emoji === "string" ? this.emoji : this.emoji.id;
|
|
315
|
+
await this.message.removeReaction(emojiId);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
[util.inspect.custom]() {
|
|
319
|
+
const data = {
|
|
320
|
+
messageId: this.message.id,
|
|
321
|
+
emoji: this.emoji,
|
|
322
|
+
count: this.count,
|
|
323
|
+
users: Array.from(this.users.keys())
|
|
324
|
+
};
|
|
325
|
+
return `MessageReaction ${util.inspect(data)}`;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/utils/ReactionCollector.ts
|
|
330
|
+
var ReactionCollector = class extends Collector {
|
|
331
|
+
constructor(message, options = {}) {
|
|
332
|
+
super(message.client, options);
|
|
333
|
+
this.message = message;
|
|
334
|
+
this.messageId = message.id;
|
|
335
|
+
const boundHandleCollect = this.handleMessageReact.bind(this);
|
|
336
|
+
const boundHandleDispose = this.handleMessageUnreact.bind(this);
|
|
337
|
+
this.client.on("messageReact", boundHandleCollect);
|
|
338
|
+
this.client.on("messageUnreact", boundHandleDispose);
|
|
339
|
+
this.once("end", () => {
|
|
340
|
+
this.client.removeListener("messageReact", boundHandleCollect);
|
|
341
|
+
this.client.removeListener("messageUnreact", boundHandleDispose);
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
messageId;
|
|
345
|
+
total = 0;
|
|
346
|
+
users = /* @__PURE__ */ new Set();
|
|
347
|
+
collect(reaction) {
|
|
348
|
+
if (reaction.message.id !== this.messageId) return null;
|
|
349
|
+
return typeof reaction.emoji === "string" ? reaction.emoji : reaction.emoji.id;
|
|
350
|
+
}
|
|
351
|
+
dispose(reaction) {
|
|
352
|
+
if (reaction.message.id !== this.messageId) return null;
|
|
353
|
+
return typeof reaction.emoji === "string" ? reaction.emoji : reaction.emoji.id;
|
|
354
|
+
}
|
|
355
|
+
handleMessageReact(message, emojiId, userId) {
|
|
356
|
+
if (message.id !== this.messageId) return;
|
|
357
|
+
let reaction = this.collected.get(emojiId);
|
|
358
|
+
if (!reaction) {
|
|
359
|
+
reaction = new MessageReaction(this.client, { message, emojiId, users: [userId] });
|
|
360
|
+
} else {
|
|
361
|
+
const user = this.client.users.cache.get(userId) || { id: userId };
|
|
362
|
+
reaction.users.set(userId, user);
|
|
363
|
+
}
|
|
364
|
+
super.handleCollect(reaction);
|
|
365
|
+
if (!this.ended && this.collected.has(emojiId)) {
|
|
366
|
+
this.total++;
|
|
367
|
+
this.users.add(userId);
|
|
368
|
+
this.checkEnd();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
handleMessageUnreact(message, emojiId, userId) {
|
|
372
|
+
if (message.id !== this.messageId) return;
|
|
373
|
+
const reaction = this.collected.get(emojiId);
|
|
374
|
+
if (reaction) {
|
|
375
|
+
reaction.users.delete(userId);
|
|
376
|
+
if (reaction.users.size === 0) {
|
|
377
|
+
super.handleDispose(reaction);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
endReason() {
|
|
382
|
+
const options = this.options;
|
|
383
|
+
if (options.max && this.total >= options.max) return "limit";
|
|
384
|
+
if (options.maxUsers && this.users.size >= options.maxUsers) return "userLimit";
|
|
385
|
+
return null;
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// src/structures/Message.ts
|
|
90
390
|
var Message = class extends Base {
|
|
91
391
|
content = null;
|
|
92
392
|
authorId;
|
|
@@ -100,7 +400,7 @@ var Message = class extends Base {
|
|
|
100
400
|
masquerade = null;
|
|
101
401
|
mentions = [];
|
|
102
402
|
pinned = false;
|
|
103
|
-
reactions =
|
|
403
|
+
reactions = {};
|
|
104
404
|
replies = [];
|
|
105
405
|
role_mentions = [];
|
|
106
406
|
constructor(client, data) {
|
|
@@ -168,6 +468,78 @@ var Message = class extends Base {
|
|
|
168
468
|
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
169
469
|
await channel.messages.unpin(this.id);
|
|
170
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* React to this message
|
|
473
|
+
* @param reaction The emoji to react with. Can be a Unicode emoji or a custom emoji ID.
|
|
474
|
+
* @throws {Error} If the API request fails.
|
|
475
|
+
* @example
|
|
476
|
+
* await message.react("👍");
|
|
477
|
+
* await message.react("customEmojiId");
|
|
478
|
+
*/
|
|
479
|
+
async react(reaction) {
|
|
480
|
+
let channel = this.channel;
|
|
481
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
482
|
+
await channel.messages.react(this.id, reaction);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Remove a reaction from this message
|
|
486
|
+
* @param reaction The emoji to remove. Can be a Unicode emoji or a custom emoji ID.
|
|
487
|
+
* @param userId The ID of the user whose reaction to remove. If not provided, removes the current user's reaction.
|
|
488
|
+
* @param removeAll Remove all reactions of this type.
|
|
489
|
+
* @throws {Error} If both userId and removeAll are provided, or if the API request fails.
|
|
490
|
+
* @example
|
|
491
|
+
* // Remove the current user's reaction
|
|
492
|
+
* await message.removeReaction("👍");
|
|
493
|
+
* // Remove a specific user's reaction
|
|
494
|
+
* await message.removeReaction("👍", userId);
|
|
495
|
+
* // Remove all reactions of this type
|
|
496
|
+
* await message.removeReaction("👍", undefined, true);
|
|
497
|
+
*/
|
|
498
|
+
async removeReaction(reaction, userId, removeAll) {
|
|
499
|
+
let channel = this.channel;
|
|
500
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
501
|
+
await channel.messages.removeReaction(this.id, reaction, userId, removeAll);
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Remove all reactions from this message
|
|
505
|
+
* @throws {Error} If the API request fails.
|
|
506
|
+
* @example
|
|
507
|
+
* await message.clearReactions();
|
|
508
|
+
*/
|
|
509
|
+
async clearReactions() {
|
|
510
|
+
let channel = this.channel;
|
|
511
|
+
if (!channel) channel = await this.client.channels.fetch(this.channelId);
|
|
512
|
+
await channel.messages.clearReactions(this.id);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Creates a ReactionCollector to collect reactions on this message.
|
|
516
|
+
* @param options The options for the collector.
|
|
517
|
+
* @returns A new ReactionCollector instance.
|
|
518
|
+
* @example
|
|
519
|
+
* const collector = message.createReactionCollector({ time: 15000 });
|
|
520
|
+
* collector.on('collect', (reaction) => console.log(`Collected ${reaction.emojiId} from ${reaction.userId}`));
|
|
521
|
+
* collector.on('end', (collected) => console.log(`Collected ${collected.size} items`));
|
|
522
|
+
*/
|
|
523
|
+
createReactionCollector(options) {
|
|
524
|
+
return new ReactionCollector(this, options);
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Awaits reactions on this message.
|
|
528
|
+
* @param options The options for the collector.
|
|
529
|
+
* @returns A promise that resolves to a collection of reactions collected.
|
|
530
|
+
* @example
|
|
531
|
+
* // Await reactions
|
|
532
|
+
* const filter = (reaction) => reaction.emoji.id === '123' && reaction.users.has(author.id);
|
|
533
|
+
* message.awaitReactions({ filter, max: 1, time: 60000 })
|
|
534
|
+
* .then(collected => console.log(collected.size))
|
|
535
|
+
* .catch(console.error);
|
|
536
|
+
*/
|
|
537
|
+
awaitReactions(options) {
|
|
538
|
+
return new Promise((resolve) => {
|
|
539
|
+
const collector = this.createReactionCollector(options);
|
|
540
|
+
collector.once("end", (collected) => resolve(collected));
|
|
541
|
+
});
|
|
542
|
+
}
|
|
171
543
|
/** Gets the Channel object from cache */
|
|
172
544
|
get channel() {
|
|
173
545
|
return this.client.channels.cache.get(this.channelId);
|
|
@@ -205,7 +577,9 @@ var Message = class extends Base {
|
|
|
205
577
|
if (data.pinned !== void 0) this.pinned = data.pinned;
|
|
206
578
|
if (data.embeds !== void 0) this.embeds = data.embeds;
|
|
207
579
|
if (data.flags !== void 0) this.flags = data.flags;
|
|
208
|
-
if (data.reactions !== void 0)
|
|
580
|
+
if (data.reactions !== void 0) {
|
|
581
|
+
this.reactions = Array.isArray(data.reactions) ? {} : data.reactions;
|
|
582
|
+
}
|
|
209
583
|
if (data.interactions !== void 0) {
|
|
210
584
|
if (data.interactions) {
|
|
211
585
|
this.interactions = {
|
|
@@ -218,7 +592,7 @@ var Message = class extends Base {
|
|
|
218
592
|
}
|
|
219
593
|
}
|
|
220
594
|
// This tells Node.js exactly how to print this object in console.log()
|
|
221
|
-
[
|
|
595
|
+
[util2.inspect.custom](depth, options, inspect12) {
|
|
222
596
|
const { client, authorId, channelId, ...props } = this;
|
|
223
597
|
const data = {
|
|
224
598
|
...props,
|
|
@@ -227,7 +601,7 @@ var Message = class extends Base {
|
|
|
227
601
|
server: this.server,
|
|
228
602
|
member: this.member
|
|
229
603
|
};
|
|
230
|
-
return `${this.constructor.name} ${
|
|
604
|
+
return `${this.constructor.name} ${inspect12(data, { ...options, depth: depth ?? options.depth })}`;
|
|
231
605
|
}
|
|
232
606
|
};
|
|
233
607
|
|
|
@@ -389,6 +763,17 @@ var GatewayManager = class {
|
|
|
389
763
|
}
|
|
390
764
|
}
|
|
391
765
|
}
|
|
766
|
+
if (payload.emojis) {
|
|
767
|
+
for (const rawEmoji of payload.emojis) {
|
|
768
|
+
const emoji = this.client.emojis._add(rawEmoji);
|
|
769
|
+
if (rawEmoji.parent && rawEmoji.parent.type === "Server") {
|
|
770
|
+
const server = this.client.servers.cache.get(rawEmoji.parent.id);
|
|
771
|
+
if (server) {
|
|
772
|
+
server.emojis._add(emoji);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
392
777
|
this.client.emit("ready", payload);
|
|
393
778
|
break;
|
|
394
779
|
}
|
|
@@ -448,6 +833,60 @@ var GatewayManager = class {
|
|
|
448
833
|
}
|
|
449
834
|
break;
|
|
450
835
|
}
|
|
836
|
+
case "MessageReact": {
|
|
837
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
838
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
839
|
+
if (message) {
|
|
840
|
+
if (!message.reactions) message.reactions = {};
|
|
841
|
+
if (!message.reactions[payload.emoji_id]) {
|
|
842
|
+
message.reactions[payload.emoji_id] = [];
|
|
843
|
+
}
|
|
844
|
+
const reactions = message.reactions[payload.emoji_id];
|
|
845
|
+
if (reactions && !reactions.includes(payload.user_id)) {
|
|
846
|
+
reactions.push(payload.user_id);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
this.client.emit(
|
|
850
|
+
"messageReact",
|
|
851
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
852
|
+
payload.emoji_id,
|
|
853
|
+
payload.user_id
|
|
854
|
+
);
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
case "MessageUnreact": {
|
|
858
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
859
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
860
|
+
if (message && message.reactions && message.reactions[payload.emoji_id]) {
|
|
861
|
+
const reactions = message.reactions[payload.emoji_id];
|
|
862
|
+
if (reactions) {
|
|
863
|
+
message.reactions[payload.emoji_id] = reactions.filter((userId) => userId !== payload.user_id);
|
|
864
|
+
if (message.reactions[payload.emoji_id].length === 0) {
|
|
865
|
+
delete message.reactions[payload.emoji_id];
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
this.client.emit(
|
|
870
|
+
"messageUnreact",
|
|
871
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
872
|
+
payload.emoji_id,
|
|
873
|
+
payload.user_id
|
|
874
|
+
);
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
case "MessageRemoveReaction": {
|
|
878
|
+
const channel = this.client.channels.cache.get(payload.channel_id);
|
|
879
|
+
const message = channel?.messages.cache.get(payload.id);
|
|
880
|
+
if (message && message.reactions) {
|
|
881
|
+
delete message.reactions[payload.emoji_id];
|
|
882
|
+
}
|
|
883
|
+
this.client.emit(
|
|
884
|
+
"messageRemoveReaction",
|
|
885
|
+
message || { id: payload.id, channelId: payload.channel_id },
|
|
886
|
+
payload.emoji_id
|
|
887
|
+
);
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
451
890
|
case "Pong":
|
|
452
891
|
this.client.emit("debug", "Received Pong from server.");
|
|
453
892
|
break;
|
|
@@ -524,6 +963,27 @@ var GatewayManager = class {
|
|
|
524
963
|
}
|
|
525
964
|
break;
|
|
526
965
|
}
|
|
966
|
+
case "EmojiCreate": {
|
|
967
|
+
const emoji = this.client.emojis._add(payload);
|
|
968
|
+
if (payload.parent?.type === "Server") {
|
|
969
|
+
const server = this.client.servers.cache.get(payload.parent.id);
|
|
970
|
+
if (server) {
|
|
971
|
+
server.emojis._add(emoji);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
break;
|
|
975
|
+
}
|
|
976
|
+
case "EmojiDelete": {
|
|
977
|
+
this.client.emojis.cache.delete(payload.id);
|
|
978
|
+
for (const server of this.client.servers.cache.values()) {
|
|
979
|
+
const emoji = server.emojis.cache.get(payload.id);
|
|
980
|
+
if (emoji) {
|
|
981
|
+
server.emojis.cache.delete(payload.id);
|
|
982
|
+
break;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
527
987
|
case "UserUpdate": {
|
|
528
988
|
const existing = this.client.users.cache.get(payload.id);
|
|
529
989
|
if (existing) {
|
|
@@ -708,9 +1168,9 @@ var RESTManager = class {
|
|
|
708
1168
|
/**
|
|
709
1169
|
* Uploads a file to Stoat's CDN and returns the File ID
|
|
710
1170
|
*/
|
|
711
|
-
async uploadFile(
|
|
1171
|
+
async uploadFile(tag, fileBuffer, filename) {
|
|
712
1172
|
if (!this.token) throw new Error("REST_NOT_READY: No token available.");
|
|
713
|
-
const url =
|
|
1173
|
+
const url = `https://cdn.stoatusercontent.com/${tag}`;
|
|
714
1174
|
const formData = new FormData();
|
|
715
1175
|
formData.append("file", new Blob([fileBuffer]), filename);
|
|
716
1176
|
const response = await fetch(url, {
|
|
@@ -742,89 +1202,16 @@ var RESTManager = class {
|
|
|
742
1202
|
patch(endpoint, body) {
|
|
743
1203
|
return this.makeRequest("PATCH", endpoint, body);
|
|
744
1204
|
}
|
|
745
|
-
delete(endpoint) {
|
|
746
|
-
return this.makeRequest("DELETE", endpoint);
|
|
1205
|
+
delete(endpoint, body) {
|
|
1206
|
+
return this.makeRequest("DELETE", endpoint, body);
|
|
747
1207
|
}
|
|
748
1208
|
async put(endpoint, body) {
|
|
749
1209
|
return this.makeRequest("PUT", endpoint, body);
|
|
750
1210
|
}
|
|
751
1211
|
};
|
|
752
1212
|
|
|
753
|
-
// src/utils/Collection.ts
|
|
754
|
-
var Collection = class _Collection extends Map {
|
|
755
|
-
limit;
|
|
756
|
-
constructor(limit = Infinity) {
|
|
757
|
-
super();
|
|
758
|
-
this.limit = limit;
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Overrides the default set method to enforce the maximum cache size.
|
|
762
|
-
*/
|
|
763
|
-
set(key, value) {
|
|
764
|
-
if (this.limit === 0) return this;
|
|
765
|
-
if (this.size >= this.limit && !this.has(key)) {
|
|
766
|
-
const oldestKey = this.keys().next().value;
|
|
767
|
-
if (oldestKey !== void 0) {
|
|
768
|
-
this.delete(oldestKey);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
return super.set(key, value);
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Finds the first item where the given function returns true.
|
|
775
|
-
*/
|
|
776
|
-
find(fn) {
|
|
777
|
-
for (const [key, val] of this) {
|
|
778
|
-
if (fn(val, key, this)) return val;
|
|
779
|
-
}
|
|
780
|
-
return void 0;
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Returns a new Collection containing only the items where the function returns true.
|
|
784
|
-
*/
|
|
785
|
-
filter(fn) {
|
|
786
|
-
const results = new _Collection();
|
|
787
|
-
for (const [key, val] of this) {
|
|
788
|
-
if (fn(val, key, this)) results.set(key, val);
|
|
789
|
-
}
|
|
790
|
-
return results;
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* Maps each item to a new array of values.
|
|
794
|
-
*/
|
|
795
|
-
map(fn) {
|
|
796
|
-
const results = [];
|
|
797
|
-
for (const [key, val] of this) {
|
|
798
|
-
results.push(fn(val, key, this));
|
|
799
|
-
}
|
|
800
|
-
return results;
|
|
801
|
-
}
|
|
802
|
-
/**
|
|
803
|
-
* Gets the very first value in the Collection (based on insertion order).
|
|
804
|
-
*/
|
|
805
|
-
first() {
|
|
806
|
-
return this.values().next().value;
|
|
807
|
-
}
|
|
808
|
-
/**
|
|
809
|
-
* Gets the very last value in the Collection.
|
|
810
|
-
*/
|
|
811
|
-
last() {
|
|
812
|
-
const arr = Array.from(this.values());
|
|
813
|
-
return arr[arr.length - 1];
|
|
814
|
-
}
|
|
815
|
-
/**
|
|
816
|
-
* Checks if at least one item matches the condition.
|
|
817
|
-
*/
|
|
818
|
-
some(fn) {
|
|
819
|
-
for (const [key, val] of this) {
|
|
820
|
-
if (fn(val, key, this)) return true;
|
|
821
|
-
}
|
|
822
|
-
return false;
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
|
|
826
1213
|
// src/managers/MessageManager.ts
|
|
827
|
-
import * as
|
|
1214
|
+
import * as util3 from "util";
|
|
828
1215
|
|
|
829
1216
|
// src/managers/BaseManager.ts
|
|
830
1217
|
var BaseManager = class {
|
|
@@ -851,6 +1238,42 @@ var BaseManager = class {
|
|
|
851
1238
|
}
|
|
852
1239
|
};
|
|
853
1240
|
|
|
1241
|
+
// src/builders/AttachmentBuilder.ts
|
|
1242
|
+
var AttachmentBuilder = class {
|
|
1243
|
+
// Filename for CDN to use, optional but recommended
|
|
1244
|
+
filename = void 0;
|
|
1245
|
+
file;
|
|
1246
|
+
/**
|
|
1247
|
+
* Creates a new AttachmentBuilder with the given file and optional filename.
|
|
1248
|
+
* @param file The file data as a Buffer or Blob.
|
|
1249
|
+
* @param filename An optional filename to use for the uploaded file. If not provided, the CDN will assign a default name.
|
|
1250
|
+
* Providing a filename can help with organization and debugging, but is not strictly required.
|
|
1251
|
+
* @example
|
|
1252
|
+
* // Create an attachment from a Buffer with a custom filename
|
|
1253
|
+
* const buffer = Buffer.from("Hello, world!");
|
|
1254
|
+
* const attachment = new AttachmentBuilder(buffer, "greeting.txt");
|
|
1255
|
+
*/
|
|
1256
|
+
constructor(file, filename) {
|
|
1257
|
+
this.filename = filename;
|
|
1258
|
+
this.file = file;
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* Uploads this attachment to the Stoat CDN and returns the resulting file ID.
|
|
1262
|
+
* @internal — use `resolveAttachment()` instead of calling this directly.
|
|
1263
|
+
*/
|
|
1264
|
+
async upload(rest, tag) {
|
|
1265
|
+
return rest.uploadFile(tag, this.file, this.filename);
|
|
1266
|
+
}
|
|
1267
|
+
};
|
|
1268
|
+
|
|
1269
|
+
// src/utils/resolveAttachment.ts
|
|
1270
|
+
async function resolveAttachment(rest, value, tag) {
|
|
1271
|
+
if (value instanceof AttachmentBuilder) {
|
|
1272
|
+
return value.upload(rest, tag);
|
|
1273
|
+
}
|
|
1274
|
+
return value;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
854
1277
|
// src/managers/MessageManager.ts
|
|
855
1278
|
var MessageManager = class extends BaseManager {
|
|
856
1279
|
constructor(client, channel, limit = Infinity) {
|
|
@@ -926,6 +1349,13 @@ var MessageManager = class extends BaseManager {
|
|
|
926
1349
|
(embed) => typeof embed.toJSON === "function" ? embed.toJSON() : embed
|
|
927
1350
|
);
|
|
928
1351
|
}
|
|
1352
|
+
if (payload.attachments) {
|
|
1353
|
+
payload.attachments = await Promise.all(
|
|
1354
|
+
payload.attachments.map(
|
|
1355
|
+
(attachment) => resolveAttachment(this.client.rest, attachment, "attachments")
|
|
1356
|
+
)
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
929
1359
|
const data = await this.client.rest.post(`/channels/${this.channel.id}/messages`, payload);
|
|
930
1360
|
return new Message(this.client, data);
|
|
931
1361
|
}
|
|
@@ -980,11 +1410,105 @@ var MessageManager = class extends BaseManager {
|
|
|
980
1410
|
const existing = this.cache.get(id);
|
|
981
1411
|
if (existing) existing.pinned = false;
|
|
982
1412
|
}
|
|
983
|
-
|
|
1413
|
+
/**
|
|
1414
|
+
* React to a message
|
|
1415
|
+
* @param message The MessageResolvable to react to.
|
|
1416
|
+
* @param reaction The emoji to react with. Can be a Unicode emoji or a custom emoji ID.
|
|
1417
|
+
* @throws {Error} If the API request fails.
|
|
1418
|
+
* @example
|
|
1419
|
+
* await channel.messages.react(messageId, "👍");
|
|
1420
|
+
* await channel.messages.react(messageId, "customEmojiId");
|
|
1421
|
+
*/
|
|
1422
|
+
async react(message, reaction) {
|
|
1423
|
+
const id = this.resolveId(message);
|
|
1424
|
+
await this.client.rest.put(`/channels/${this.channel.id}/messages/${id}/reactions/${encodeURIComponent(reaction)}`);
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Remove a reaction(s) from a message
|
|
1428
|
+
* Requires ManageMessages if changing others' reactions.
|
|
1429
|
+
* @param reaction The emoji to remove. Can be a unicode emoji or a custom emoji ID.
|
|
1430
|
+
* @param message The MessageResolvable to remove the reaction from.
|
|
1431
|
+
* @param userId The ID of the user whose reaction to remove. If not provided, removes the current user's reaction.
|
|
1432
|
+
* @param removeAll Remove all reactions of this type.
|
|
1433
|
+
* @throws {Error} If both userId and removeAll are provided, or if the API request fails.
|
|
1434
|
+
* @example
|
|
1435
|
+
* // Remove the current user's reaction
|
|
1436
|
+
* await channel.messages.removeReaction(messageId, "👍");
|
|
1437
|
+
* // Remove a specific user's reaction
|
|
1438
|
+
* await channel.messages.removeReaction(messageId, "👍", userId);
|
|
1439
|
+
* // Remove all reactions of this type
|
|
1440
|
+
* await channel.messages.removeReaction(messageId, "👍", undefined, true);
|
|
1441
|
+
*/
|
|
1442
|
+
async removeReaction(message, reaction, userId, removeAll) {
|
|
1443
|
+
const id = this.resolveId(message);
|
|
1444
|
+
const targetUser = userId ? this.client.users.resolveId(userId) : void 0;
|
|
1445
|
+
const params = new URLSearchParams();
|
|
1446
|
+
if (targetUser) params.append("user_id", targetUser);
|
|
1447
|
+
if (removeAll) params.append("remove_all", "true");
|
|
1448
|
+
const queryString = params.toString();
|
|
1449
|
+
const endpoint = `/channels/${this.channel.id}/messages/${id}/reactions/${encodeURIComponent(reaction)}${queryString ? `?${queryString}` : ""}`;
|
|
1450
|
+
await this.client.rest.delete(endpoint);
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Remove all reactions from a message
|
|
1454
|
+
* Requires ManageMessages permission.
|
|
1455
|
+
* @param message The MessageResolvable to clear reactions from.
|
|
1456
|
+
* @throws {Error} If the API request fails.
|
|
1457
|
+
* @example
|
|
1458
|
+
* await channel.messages.clearReactions(messageId);
|
|
1459
|
+
*/
|
|
1460
|
+
async clearReactions(message) {
|
|
1461
|
+
const id = this.resolveId(message);
|
|
1462
|
+
await this.client.rest.delete(`/channels/${this.channel.id}/messages/${id}/reactions`);
|
|
1463
|
+
}
|
|
1464
|
+
[util3.inspect.custom]() {
|
|
984
1465
|
return this.cache;
|
|
985
1466
|
}
|
|
986
1467
|
};
|
|
987
1468
|
|
|
1469
|
+
// src/utils/MessageCollector.ts
|
|
1470
|
+
var MessageCollector = class extends Collector {
|
|
1471
|
+
constructor(channel, options = {}) {
|
|
1472
|
+
super(channel.client, options);
|
|
1473
|
+
this.channel = channel;
|
|
1474
|
+
this.channelId = channel.id;
|
|
1475
|
+
const boundHandleCollect = this.handleCollect.bind(this);
|
|
1476
|
+
const boundHandleDispose = this.handleDispose.bind(this);
|
|
1477
|
+
this.client.on("messageCreate", boundHandleCollect);
|
|
1478
|
+
this.client.on("messageDelete", boundHandleDispose);
|
|
1479
|
+
this.once("end", () => {
|
|
1480
|
+
this.client.removeListener("messageCreate", boundHandleCollect);
|
|
1481
|
+
this.client.removeListener("messageDelete", boundHandleDispose);
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
channelId;
|
|
1485
|
+
total = 0;
|
|
1486
|
+
processed = 0;
|
|
1487
|
+
collect(message) {
|
|
1488
|
+
if (message.channelId !== this.channelId) return null;
|
|
1489
|
+
return message.id;
|
|
1490
|
+
}
|
|
1491
|
+
dispose(message) {
|
|
1492
|
+
if (message.channelId !== this.channelId) return null;
|
|
1493
|
+
return message.id;
|
|
1494
|
+
}
|
|
1495
|
+
handleCollect(message) {
|
|
1496
|
+
if (message.channelId !== this.channelId) return;
|
|
1497
|
+
this.processed++;
|
|
1498
|
+
super.handleCollect(message);
|
|
1499
|
+
if (!this.ended && this.collected.has(message.id)) {
|
|
1500
|
+
this.total++;
|
|
1501
|
+
this.checkEnd();
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
endReason() {
|
|
1505
|
+
const options = this.options;
|
|
1506
|
+
if (options.max && this.total >= options.max) return "limit";
|
|
1507
|
+
if (options.maxProcessed && this.processed >= options.maxProcessed) return "processedLimit";
|
|
1508
|
+
return null;
|
|
1509
|
+
}
|
|
1510
|
+
};
|
|
1511
|
+
|
|
988
1512
|
// src/structures/BaseChannel.ts
|
|
989
1513
|
var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
|
|
990
1514
|
ChannelType2["TEXT"] = "TextChannel";
|
|
@@ -1011,12 +1535,36 @@ var BaseChannel = class extends Base {
|
|
|
1011
1535
|
async send(contentOrOptions) {
|
|
1012
1536
|
return this.messages.send(contentOrOptions);
|
|
1013
1537
|
}
|
|
1014
|
-
|
|
1538
|
+
/**
|
|
1539
|
+
* Fetch this channel
|
|
1540
|
+
* @param force Whether to skip the cache check and force a direct API request. Defaults to false
|
|
1541
|
+
* @throws {Error} If the API request fails
|
|
1542
|
+
* @returns {BaseChannel}
|
|
1543
|
+
* @example
|
|
1544
|
+
* // Force fetch channel to update its data
|
|
1545
|
+
* await channel.fetch(true);
|
|
1546
|
+
*/
|
|
1547
|
+
async fetch(force = false) {
|
|
1015
1548
|
return await this.client.channels.fetch(this.id, force);
|
|
1016
1549
|
}
|
|
1017
1550
|
/**
|
|
1018
1551
|
* Fetches multiple messages from this channel.
|
|
1019
1552
|
* @param options The query parameters to filter the messages.
|
|
1553
|
+
* @throws {Error} If the API request fails
|
|
1554
|
+
* @returns A Collection of Messages, keyed by their ID.
|
|
1555
|
+
* @example
|
|
1556
|
+
* // Fetch the last 50 messages in the channel
|
|
1557
|
+
* const messages = await channel.fetchMessages({ limit: 50 });
|
|
1558
|
+
* console.log(`Fetched ${messages.size} messages`);
|
|
1559
|
+
* // Fetch messages before a specific message ID
|
|
1560
|
+
* const messages = await channel.fetchMessages({ before: "MESSAGE_ID" });
|
|
1561
|
+
* console.log(`Fetched ${messages.size} messages sent before the specified message`);
|
|
1562
|
+
* // Fetch messages after a specific message ID
|
|
1563
|
+
* const messages = await channel.fetchMessages({ after: "MESSAGE_ID" });
|
|
1564
|
+
* console.log(`Fetched ${messages.size} messages sent after the specified message`);
|
|
1565
|
+
* // Fetch messages around a specific message ID
|
|
1566
|
+
* const messages = await channel.fetchMessages({ around: "MESSAGE_ID", limit: 10 });
|
|
1567
|
+
* console.log(`Fetched ${messages.size} messages sent around the specified message`);
|
|
1020
1568
|
*/
|
|
1021
1569
|
async fetchMessages(options) {
|
|
1022
1570
|
return this.messages.fetchMany(options);
|
|
@@ -1024,16 +1572,72 @@ var BaseChannel = class extends Base {
|
|
|
1024
1572
|
/**
|
|
1025
1573
|
* Edits this channel.
|
|
1026
1574
|
* @param options The fields to update
|
|
1575
|
+
* @throws {Error} If the API request fails
|
|
1576
|
+
* @returns BaseChannel
|
|
1577
|
+
* @example
|
|
1578
|
+
* // Edit the channel's name
|
|
1579
|
+
* await channel.edit({name: "New Cool Name"});
|
|
1027
1580
|
*/
|
|
1028
1581
|
async edit(options) {
|
|
1029
1582
|
return await this.client.channels.edit(this.id, options);
|
|
1030
1583
|
}
|
|
1031
1584
|
/**
|
|
1032
1585
|
* Deletes this channel.
|
|
1586
|
+
* @throws {Error} If the API request fails
|
|
1587
|
+
* @example
|
|
1588
|
+
* // Delete the channel
|
|
1589
|
+
* await channel.delete();
|
|
1033
1590
|
*/
|
|
1034
1591
|
async delete() {
|
|
1035
1592
|
await this.client.channels.delete(this.id);
|
|
1036
1593
|
}
|
|
1594
|
+
/**
|
|
1595
|
+
* Bulk delete messages from this channel
|
|
1596
|
+
* @param messages MessageResolvable to delete
|
|
1597
|
+
* @throws {Error} If the API request fails
|
|
1598
|
+
* @example
|
|
1599
|
+
* // Delete messages by their ID's
|
|
1600
|
+
* await channel.bulkDelete(["MESSAGE_ID_1", "MESSAGE_ID_2", "MESSAGE_ID_3"]);
|
|
1601
|
+
* // Delete messages by their Message objects
|
|
1602
|
+
* await channel.bulkDelete([message1, message2, message3]);
|
|
1603
|
+
*/
|
|
1604
|
+
async bulkDelete(messages) {
|
|
1605
|
+
await this.client.channels.bulkDelete(this.id, messages);
|
|
1606
|
+
}
|
|
1607
|
+
/**
|
|
1608
|
+
* Creates a MessageCollector to collect messages in this channel.
|
|
1609
|
+
* @param options The options for the collector.
|
|
1610
|
+
* @returns The instantiated MessageCollector
|
|
1611
|
+
* @example
|
|
1612
|
+
* const collector = channel.createMessageCollector({ filter: m => m.authorId === '123', time: 15000 });
|
|
1613
|
+
* collector.on('collect', m => console.log(`Collected ${m.content}`));
|
|
1614
|
+
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
|
1615
|
+
*/
|
|
1616
|
+
createMessageCollector(options) {
|
|
1617
|
+
return new MessageCollector(this, options);
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Awaits messages in this channel that meet certain criteria.
|
|
1621
|
+
* @param options The options for the collector.
|
|
1622
|
+
* @returns A promise that resolves to a collection of messages.
|
|
1623
|
+
* @example
|
|
1624
|
+
* // Await !vote messages
|
|
1625
|
+
* const filter = m => m.content.startsWith('!vote');
|
|
1626
|
+
* channel.awaitMessages({ filter, max: 4, time: 60000 })
|
|
1627
|
+
* .then(collected => console.log(collected.size))
|
|
1628
|
+
* .catch(console.error);
|
|
1629
|
+
*/
|
|
1630
|
+
awaitMessages(options = {}) {
|
|
1631
|
+
return new Promise((resolve, reject) => {
|
|
1632
|
+
const collector = this.createMessageCollector(options);
|
|
1633
|
+
collector.once("end", (collected, reason) => {
|
|
1634
|
+
if (options.max && reason !== "limit" && reason !== "time") {
|
|
1635
|
+
return reject(new Error(`Collector ended with reason: ${reason}`));
|
|
1636
|
+
}
|
|
1637
|
+
resolve(collected);
|
|
1638
|
+
});
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1037
1641
|
isText() {
|
|
1038
1642
|
return this.type === "TextChannel" /* TEXT */;
|
|
1039
1643
|
}
|
|
@@ -1077,36 +1681,175 @@ var TextChannel = class extends BaseChannel {
|
|
|
1077
1681
|
case "Description":
|
|
1078
1682
|
this.description = null;
|
|
1079
1683
|
break;
|
|
1684
|
+
case "Icon":
|
|
1685
|
+
this.icon = null;
|
|
1686
|
+
break;
|
|
1687
|
+
case "DefaultPermissions":
|
|
1688
|
+
this.defaultPermissions = data.default_permissions;
|
|
1689
|
+
break;
|
|
1690
|
+
case "Voice":
|
|
1691
|
+
this.voice = data.voice;
|
|
1692
|
+
break;
|
|
1080
1693
|
}
|
|
1081
1694
|
}
|
|
1082
1695
|
}
|
|
1083
1696
|
}
|
|
1084
1697
|
/**
|
|
1085
|
-
* Updates the permission overrides for the channel.
|
|
1086
|
-
* @param roleId The raw string ID of the role to update.
|
|
1087
|
-
* @param options The allow and deny permissions to set.
|
|
1088
|
-
* @returns A promise that resolves to the updated BaseChannel.
|
|
1089
|
-
* @throws {TypeError} If the channel is not a Server Channel, or options are invalid.
|
|
1090
|
-
* @throws {Error} If the API request fails.
|
|
1698
|
+
* Updates the permission overrides for the channel.
|
|
1699
|
+
* @param roleId The raw string ID of the role to update.
|
|
1700
|
+
* @param options The allow and deny permissions to set.
|
|
1701
|
+
* @returns A promise that resolves to the updated BaseChannel.
|
|
1702
|
+
* @throws {TypeError} If the channel is not a Server Channel, or options are invalid.
|
|
1703
|
+
* @throws {Error} If the API request fails.
|
|
1704
|
+
* @example
|
|
1705
|
+
* // Deny a role the ability to send messages in this channel
|
|
1706
|
+
* await channel.setRolePermissions("ROLE_ID", { deny: ["SendMessage"] });
|
|
1707
|
+
*/
|
|
1708
|
+
async setRolePermissions(roleId, options) {
|
|
1709
|
+
return await this.client.channels.setRolePermissions(this.id, roleId, options);
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Updates the default (everyone) permissions for this channel.
|
|
1713
|
+
* @param permissions The default permissions to grant globally in this channel.
|
|
1714
|
+
* @returns A promise that resolves to the updated BaseChannel.
|
|
1715
|
+
* @throws {TypeError} If invalid permissions are provided.
|
|
1716
|
+
* @throws {Error} If the API request fails.
|
|
1717
|
+
* @example
|
|
1718
|
+
* // Set the default permission to allow everyone to view the channel
|
|
1719
|
+
* await channel.setDefaultPermissions(["ViewChannel", "ReadMessageHistory"]);
|
|
1720
|
+
*/
|
|
1721
|
+
async setDefaultPermissions(permissions) {
|
|
1722
|
+
return await this.client.channels.setDefaultPermissions(this.id, permissions);
|
|
1723
|
+
}
|
|
1724
|
+
/**
|
|
1725
|
+
* Edits the category of this channel. Only applicable to server channels.
|
|
1726
|
+
* @param category The ID of the category to move this channel into, or "default" to remove from any category.
|
|
1727
|
+
* @returns The updated TextChannel with the new category.
|
|
1728
|
+
* @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.
|
|
1729
|
+
* @example
|
|
1730
|
+
* // Move this channel into a category
|
|
1731
|
+
* await channel.setCategory("CATEGORY_ID");
|
|
1732
|
+
* // Remove this channel from its category
|
|
1733
|
+
* await channel.setCategory("default");
|
|
1734
|
+
*/
|
|
1735
|
+
async setCategory(category) {
|
|
1736
|
+
const serverId = this.serverId;
|
|
1737
|
+
const server = await this.client.servers.fetch(serverId);
|
|
1738
|
+
const categories = server.categories.map((c) => ({
|
|
1739
|
+
id: c.id,
|
|
1740
|
+
title: c.title,
|
|
1741
|
+
channels: [...c.channels]
|
|
1742
|
+
}));
|
|
1743
|
+
for (const cat of categories) {
|
|
1744
|
+
cat.channels = cat.channels.filter((id) => id !== this.id);
|
|
1745
|
+
}
|
|
1746
|
+
if (category !== "default") {
|
|
1747
|
+
const targetCategory = categories.find((c) => c.id === category);
|
|
1748
|
+
if (!targetCategory) {
|
|
1749
|
+
throw new Error(`Category ${category} not found in server.`);
|
|
1750
|
+
}
|
|
1751
|
+
targetCategory.channels.push(this.id);
|
|
1752
|
+
}
|
|
1753
|
+
await this.client.servers.edit(serverId, { categories });
|
|
1754
|
+
return this;
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* Sets the position of this channel within its current category.
|
|
1758
|
+
* @param position The new index position for the channel within its category.
|
|
1759
|
+
* @returns The updated TextChannel.
|
|
1760
|
+
* @throws {Error} If the channel is not in a category, or if the API request fails.
|
|
1761
|
+
* @example
|
|
1762
|
+
* // Move channel to the top of its category
|
|
1763
|
+
* await channel.setPosition(0);
|
|
1764
|
+
*/
|
|
1765
|
+
async setPosition(position) {
|
|
1766
|
+
const serverId = this.serverId;
|
|
1767
|
+
const server = await this.client.servers.fetch(serverId);
|
|
1768
|
+
const categories = server.categories.map((c) => ({
|
|
1769
|
+
id: c.id,
|
|
1770
|
+
title: c.title,
|
|
1771
|
+
channels: [...c.channels]
|
|
1772
|
+
}));
|
|
1773
|
+
const currentCategory = categories.find((c) => c.channels.includes(this.id));
|
|
1774
|
+
if (!currentCategory) {
|
|
1775
|
+
throw new Error("This channel is not currently inside any category.");
|
|
1776
|
+
}
|
|
1777
|
+
currentCategory.channels = currentCategory.channels.filter((id) => id !== this.id);
|
|
1778
|
+
const safePosition = Math.max(0, Math.min(position, currentCategory.channels.length));
|
|
1779
|
+
currentCategory.channels.splice(safePosition, 0, this.id);
|
|
1780
|
+
await this.client.servers.edit(serverId, { categories });
|
|
1781
|
+
return this;
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Edit the description of this channel
|
|
1785
|
+
* @param description
|
|
1786
|
+
* @throws {Error} If the API request fails
|
|
1787
|
+
* @returns The updated TextChannel
|
|
1091
1788
|
* @example
|
|
1092
|
-
* //
|
|
1093
|
-
* await channel.
|
|
1789
|
+
* // Set the channel description
|
|
1790
|
+
* await channel.setDescription("This is a channel about cats!");
|
|
1791
|
+
* // Remove the channel description
|
|
1792
|
+
* await channel.setDescription(null);
|
|
1094
1793
|
*/
|
|
1095
|
-
async
|
|
1096
|
-
|
|
1794
|
+
async setDescription(description) {
|
|
1795
|
+
await this.edit({ description });
|
|
1796
|
+
return this;
|
|
1097
1797
|
}
|
|
1098
1798
|
/**
|
|
1099
|
-
*
|
|
1100
|
-
* @param
|
|
1101
|
-
* @
|
|
1102
|
-
* @
|
|
1103
|
-
* @throws {Error} If the API request fails.
|
|
1799
|
+
* Edit the name of this channel
|
|
1800
|
+
* @param name
|
|
1801
|
+
* @throws {Error} If the API request fails
|
|
1802
|
+
* @returns The updated TextChannel
|
|
1104
1803
|
* @example
|
|
1105
|
-
*
|
|
1106
|
-
* await channel.setDefaultPermissions(["ViewChannel", "ReadMessageHistory"]);
|
|
1804
|
+
* await channel.setName("New Name");
|
|
1107
1805
|
*/
|
|
1108
|
-
async
|
|
1109
|
-
|
|
1806
|
+
async setName(name) {
|
|
1807
|
+
await this.edit({ name });
|
|
1808
|
+
return this;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Set whether this channel is NSFW
|
|
1812
|
+
* @param nsfw
|
|
1813
|
+
* @throws {Error} If the API request fails
|
|
1814
|
+
* @returns The updated TextChannel
|
|
1815
|
+
* @example
|
|
1816
|
+
* // Mark the channel as NSFW
|
|
1817
|
+
* await channel.setNSFW(true);
|
|
1818
|
+
* // Mark the channel as SFW
|
|
1819
|
+
* await channel.setNSFW(false);
|
|
1820
|
+
*/
|
|
1821
|
+
async setNSFW(nsfw) {
|
|
1822
|
+
await this.edit({ nsfw });
|
|
1823
|
+
return this;
|
|
1824
|
+
}
|
|
1825
|
+
/**
|
|
1826
|
+
* Set the channel slowmode in seconds
|
|
1827
|
+
* @param slowmode
|
|
1828
|
+
* @throws {Error} If the API request fails
|
|
1829
|
+
* @returns The updated TextChannel
|
|
1830
|
+
* @example
|
|
1831
|
+
* // Set the slowmode to 5 seconds
|
|
1832
|
+
* await channel.setSlowmode(5);
|
|
1833
|
+
* // Remove slowmode
|
|
1834
|
+
* await channel.setSlowmode(0);
|
|
1835
|
+
*/
|
|
1836
|
+
async setSlowmode(slowmode) {
|
|
1837
|
+
await this.edit({ slowmode });
|
|
1838
|
+
return this;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Set the channel Icon
|
|
1842
|
+
* @param id Autumn ID to use
|
|
1843
|
+
* @throws {Error} If the API request fails
|
|
1844
|
+
* @returns The updated TextChannel
|
|
1845
|
+
* @example
|
|
1846
|
+
* await channel.setIcon("123");
|
|
1847
|
+
* // Remove the channel icon
|
|
1848
|
+
* await channel.setIcon(null);
|
|
1849
|
+
*/
|
|
1850
|
+
async setIcon(id) {
|
|
1851
|
+
await this.edit({ icon: id });
|
|
1852
|
+
return this;
|
|
1110
1853
|
}
|
|
1111
1854
|
};
|
|
1112
1855
|
|
|
@@ -1133,7 +1876,7 @@ var DMChannel = class extends BaseChannel {
|
|
|
1133
1876
|
};
|
|
1134
1877
|
|
|
1135
1878
|
// src/structures/GroupChannel.ts
|
|
1136
|
-
import * as
|
|
1879
|
+
import * as util4 from "util";
|
|
1137
1880
|
var GroupChannel = class extends BaseChannel {
|
|
1138
1881
|
name;
|
|
1139
1882
|
ownerId;
|
|
@@ -1193,9 +1936,9 @@ var GroupChannel = class extends BaseChannel {
|
|
|
1193
1936
|
async setDefaultPermissions(permissions) {
|
|
1194
1937
|
return await this.client.channels.setDefaultPermissions(this.id, permissions);
|
|
1195
1938
|
}
|
|
1196
|
-
[
|
|
1939
|
+
[util4.inspect.custom](_depth, options, inspect12) {
|
|
1197
1940
|
const { client, ...props } = this;
|
|
1198
|
-
return `${this.constructor.name} ${
|
|
1941
|
+
return `${this.constructor.name} ${inspect12(
|
|
1199
1942
|
{
|
|
1200
1943
|
...props,
|
|
1201
1944
|
owner: this.owner,
|
|
@@ -1221,6 +1964,233 @@ function createChannel(client, data) {
|
|
|
1221
1964
|
}
|
|
1222
1965
|
}
|
|
1223
1966
|
|
|
1967
|
+
// src/utils/BitField.ts
|
|
1968
|
+
var BitField = class _BitField {
|
|
1969
|
+
static Flags = {};
|
|
1970
|
+
static DefaultBit = 0;
|
|
1971
|
+
bitfield;
|
|
1972
|
+
constructor(bits) {
|
|
1973
|
+
this.bitfield = this.constructor.resolve(
|
|
1974
|
+
bits ?? this.constructor.DefaultBit
|
|
1975
|
+
);
|
|
1976
|
+
}
|
|
1977
|
+
/**
|
|
1978
|
+
* Checks whether this bitfield has any of the given bits set.
|
|
1979
|
+
*
|
|
1980
|
+
* @param bit The bit(s) to test against.
|
|
1981
|
+
* @returns `true` if at least one of the provided bits is set.
|
|
1982
|
+
*
|
|
1983
|
+
* @example
|
|
1984
|
+
* perms.any(['SendMessage', 'ManageChannel']); // true if either is set
|
|
1985
|
+
*/
|
|
1986
|
+
any(bit) {
|
|
1987
|
+
const resolved = this.constructor.resolve(bit);
|
|
1988
|
+
if (typeof this.bitfield === "bigint" && typeof resolved === "bigint") {
|
|
1989
|
+
return (this.bitfield & resolved) !== BigInt(0);
|
|
1990
|
+
}
|
|
1991
|
+
return (Number(this.bitfield) & Number(resolved)) !== 0;
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* Checks whether this bitfield is exactly equal to the given bit value.
|
|
1995
|
+
*
|
|
1996
|
+
* @param bit The bit(s) to compare against.
|
|
1997
|
+
* @returns `true` if the resolved bit value is identical to this bitfield.
|
|
1998
|
+
*
|
|
1999
|
+
* @example
|
|
2000
|
+
* new Permissions(0n).equals(0n); // true
|
|
2001
|
+
*/
|
|
2002
|
+
equals(bit) {
|
|
2003
|
+
return this.bitfield === this.constructor.resolve(bit);
|
|
2004
|
+
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Checks whether this bitfield has *all* of the given bits set.
|
|
2007
|
+
*
|
|
2008
|
+
* @param bit The bit(s) to check for.
|
|
2009
|
+
* @returns `true` if every provided bit is set in this bitfield.
|
|
2010
|
+
*
|
|
2011
|
+
* @example
|
|
2012
|
+
* perms.has('SendMessage');
|
|
2013
|
+
* perms.has(['SendMessage', 'ViewChannel']); // true only if both are set
|
|
2014
|
+
*/
|
|
2015
|
+
has(bit, ..._hasParams) {
|
|
2016
|
+
const resolvedBit = this.constructor.resolve(bit);
|
|
2017
|
+
if (typeof this.bitfield === "bigint" && typeof resolvedBit === "bigint") {
|
|
2018
|
+
return (this.bitfield & resolvedBit) === resolvedBit;
|
|
2019
|
+
}
|
|
2020
|
+
return (Number(this.bitfield) & Number(resolvedBit)) === Number(resolvedBit);
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Returns the flag names present in `bits` that are *missing* from this bitfield.
|
|
2024
|
+
*
|
|
2025
|
+
* @param bits The bits to check against.
|
|
2026
|
+
* @returns An array of flag name strings that are in `bits` but not in this bitfield.
|
|
2027
|
+
*
|
|
2028
|
+
* @example
|
|
2029
|
+
* // If perms only has SendMessage:
|
|
2030
|
+
* perms.missing(['SendMessage', 'ManageChannel']); // ['ManageChannel']
|
|
2031
|
+
*/
|
|
2032
|
+
missing(bits, ...hasParams) {
|
|
2033
|
+
return new this.constructor(bits).remove(this).toArray(...hasParams);
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Freezes this BitField instance, making it immutable.
|
|
2037
|
+
* Subsequent calls to `add()` or `remove()` will return a new instance instead of mutating this one.
|
|
2038
|
+
*
|
|
2039
|
+
* @returns This instance, frozen.
|
|
2040
|
+
*/
|
|
2041
|
+
freeze() {
|
|
2042
|
+
return Object.freeze(this);
|
|
2043
|
+
}
|
|
2044
|
+
/**
|
|
2045
|
+
* Adds one or more bits to this bitfield.
|
|
2046
|
+
* If the instance is frozen, returns a new BitField with the bits added.
|
|
2047
|
+
*
|
|
2048
|
+
* @param bits The bit(s) to add.
|
|
2049
|
+
* @returns This instance (or a new one if frozen), with the bits added.
|
|
2050
|
+
*
|
|
2051
|
+
* @example
|
|
2052
|
+
* perms.add('SendMessage', 'ViewChannel');
|
|
2053
|
+
*/
|
|
2054
|
+
add(...bits) {
|
|
2055
|
+
let total = this.constructor.DefaultBit;
|
|
2056
|
+
for (const bit of bits) {
|
|
2057
|
+
const resolved = this.constructor.resolve(bit);
|
|
2058
|
+
if (typeof total === "bigint" && typeof resolved === "bigint") {
|
|
2059
|
+
total |= resolved;
|
|
2060
|
+
} else {
|
|
2061
|
+
total = Number(total) | Number(resolved);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
if (typeof this.bitfield === "bigint" && typeof total === "bigint") {
|
|
2065
|
+
if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
|
|
2066
|
+
this.bitfield |= total;
|
|
2067
|
+
} else {
|
|
2068
|
+
if (Object.isFrozen(this))
|
|
2069
|
+
return new this.constructor(Number(this.bitfield) | Number(total));
|
|
2070
|
+
this.bitfield = Number(this.bitfield) | Number(total);
|
|
2071
|
+
}
|
|
2072
|
+
return this;
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Removes one or more bits from this bitfield.
|
|
2076
|
+
* If the instance is frozen, returns a new BitField with the bits removed.
|
|
2077
|
+
*
|
|
2078
|
+
* @param bits The bit(s) to remove.
|
|
2079
|
+
* @returns This instance (or a new one if frozen), with the bits cleared.
|
|
2080
|
+
*
|
|
2081
|
+
* @example
|
|
2082
|
+
* perms.remove('ManageChannel');
|
|
2083
|
+
*/
|
|
2084
|
+
remove(...bits) {
|
|
2085
|
+
let total = this.constructor.DefaultBit;
|
|
2086
|
+
for (const bit of bits) {
|
|
2087
|
+
const resolved = this.constructor.resolve(bit);
|
|
2088
|
+
if (typeof total === "bigint" && typeof resolved === "bigint") {
|
|
2089
|
+
total |= resolved;
|
|
2090
|
+
} else {
|
|
2091
|
+
total = Number(total) | Number(resolved);
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
if (typeof this.bitfield === "bigint" && typeof total === "bigint") {
|
|
2095
|
+
if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
|
|
2096
|
+
this.bitfield &= ~total;
|
|
2097
|
+
} else {
|
|
2098
|
+
if (Object.isFrozen(this))
|
|
2099
|
+
return new this.constructor(Number(this.bitfield) & ~Number(total));
|
|
2100
|
+
this.bitfield = Number(this.bitfield) & ~Number(total);
|
|
2101
|
+
}
|
|
2102
|
+
return this;
|
|
2103
|
+
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Serializes this bitfield to a plain object mapping each flag name to a boolean
|
|
2106
|
+
* indicating whether that flag is set.
|
|
2107
|
+
*
|
|
2108
|
+
* @returns A record of `{ [flagName]: boolean }` for all defined flags.
|
|
2109
|
+
*
|
|
2110
|
+
* @example
|
|
2111
|
+
* perms.serialize();
|
|
2112
|
+
* // { SendMessage: true, ManageChannel: false, ... }
|
|
2113
|
+
*/
|
|
2114
|
+
serialize(...hasParams) {
|
|
2115
|
+
const serialized = {};
|
|
2116
|
+
for (const [flag, bit] of Object.entries(this.constructor.Flags)) {
|
|
2117
|
+
if (isNaN(Number(flag))) serialized[flag] = this.has(bit, ...hasParams);
|
|
2118
|
+
}
|
|
2119
|
+
return serialized;
|
|
2120
|
+
}
|
|
2121
|
+
/**
|
|
2122
|
+
* Returns an array of flag names that are set in this bitfield.
|
|
2123
|
+
*
|
|
2124
|
+
* @returns An array of string flag names.
|
|
2125
|
+
*
|
|
2126
|
+
* @example
|
|
2127
|
+
* perms.toArray(); // ['SendMessage', 'ViewChannel']
|
|
2128
|
+
*/
|
|
2129
|
+
toArray(...hasParams) {
|
|
2130
|
+
return [...this[Symbol.iterator](...hasParams)];
|
|
2131
|
+
}
|
|
2132
|
+
/**
|
|
2133
|
+
* Returns the bitfield value as a JSON-safe primitive.
|
|
2134
|
+
* Numbers are returned as-is; bigints are converted to their string representation
|
|
2135
|
+
* to avoid JSON serialization errors.
|
|
2136
|
+
*/
|
|
2137
|
+
toJSON() {
|
|
2138
|
+
return typeof this.bitfield === "number" ? this.bitfield : this.bitfield.toString();
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Returns the underlying numeric value of this bitfield.
|
|
2142
|
+
* Allows BitField instances to be used directly in arithmetic expressions.
|
|
2143
|
+
*/
|
|
2144
|
+
valueOf() {
|
|
2145
|
+
return this.bitfield;
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Iterates over the names of all flags that are set in this bitfield.
|
|
2149
|
+
*
|
|
2150
|
+
* @example
|
|
2151
|
+
* for (const flag of perms) {
|
|
2152
|
+
* console.log(flag); // 'SendMessage', 'ViewChannel', etc.
|
|
2153
|
+
* }
|
|
2154
|
+
*/
|
|
2155
|
+
*[Symbol.iterator](...hasParams) {
|
|
2156
|
+
for (const bitName of Object.keys(this.constructor.Flags)) {
|
|
2157
|
+
if (isNaN(Number(bitName)) && this.has(bitName, ...hasParams)) yield bitName;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Resolves a {@link BitFieldResolvable} into a raw `number | bigint`.
|
|
2162
|
+
*
|
|
2163
|
+
* Resolution rules (in order):
|
|
2164
|
+
* - `undefined` → `DefaultBit`
|
|
2165
|
+
* - A number or bigint matching `DefaultBit`'s type and >= 0 → returned as-is
|
|
2166
|
+
* - A `BitField` instance → its `.bitfield` value
|
|
2167
|
+
* - An array → each element resolved and OR'd together
|
|
2168
|
+
* - A numeric string → parsed as `BigInt` or `Number` depending on `DefaultBit`'s type
|
|
2169
|
+
* - A named string flag → looked up in `Flags`
|
|
2170
|
+
* - Anything else → throws `RangeError`
|
|
2171
|
+
*
|
|
2172
|
+
* @param bit The value to resolve.
|
|
2173
|
+
* @throws {RangeError} If the value cannot be resolved to a valid bit.
|
|
2174
|
+
*/
|
|
2175
|
+
static resolve(bit) {
|
|
2176
|
+
const { DefaultBit } = this;
|
|
2177
|
+
if (bit === void 0) return DefaultBit;
|
|
2178
|
+
if (typeof DefaultBit === typeof bit && bit >= DefaultBit) return bit;
|
|
2179
|
+
if (bit instanceof _BitField) return bit.bitfield;
|
|
2180
|
+
if (Array.isArray(bit)) {
|
|
2181
|
+
return bit.map((b) => this.resolve(b)).reduce((prev, b) => {
|
|
2182
|
+
if (typeof prev === "bigint" && typeof b === "bigint") return prev | b;
|
|
2183
|
+
return Number(prev) | Number(b);
|
|
2184
|
+
}, DefaultBit);
|
|
2185
|
+
}
|
|
2186
|
+
if (typeof bit === "string") {
|
|
2187
|
+
if (!isNaN(Number(bit))) return typeof DefaultBit === "bigint" ? BigInt(bit) : Number(bit);
|
|
2188
|
+
if (this.Flags[bit] !== void 0) return this.Flags[bit];
|
|
2189
|
+
}
|
|
2190
|
+
throw new RangeError(`Invalid bitfield flag or number: ${String(bit)}`);
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
2193
|
+
|
|
1224
2194
|
// src/utils/permissions.ts
|
|
1225
2195
|
var PermissionFlags = {
|
|
1226
2196
|
// Server permissions
|
|
@@ -1264,26 +2234,26 @@ var PermissionFlags = {
|
|
|
1264
2234
|
// Grant all
|
|
1265
2235
|
GrantAllSafe: 0x000fffffffffffffn
|
|
1266
2236
|
};
|
|
1267
|
-
var Permissions = class {
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
if (typeof permission === "bigint") return permission;
|
|
1273
|
-
if (typeof permission === "string") {
|
|
1274
|
-
return PermissionFlags[permission] ?? 0n;
|
|
1275
|
-
}
|
|
1276
|
-
if (Array.isArray(permission)) {
|
|
1277
|
-
return permission.reduce((acc, p) => acc | this.resolve(p), 0n);
|
|
1278
|
-
}
|
|
1279
|
-
return 0n;
|
|
2237
|
+
var Permissions = class extends BitField {
|
|
2238
|
+
static Flags = PermissionFlags;
|
|
2239
|
+
static DefaultBit = 0n;
|
|
2240
|
+
static resolve(bit) {
|
|
2241
|
+
return super.resolve(bit);
|
|
1280
2242
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
2243
|
+
has(bit) {
|
|
2244
|
+
return super.has(bit);
|
|
2245
|
+
}
|
|
2246
|
+
any(bit) {
|
|
2247
|
+
return super.any(bit);
|
|
2248
|
+
}
|
|
2249
|
+
missing(bits) {
|
|
2250
|
+
return super.missing(bits);
|
|
2251
|
+
}
|
|
2252
|
+
add(...bits) {
|
|
2253
|
+
return super.add(...bits);
|
|
2254
|
+
}
|
|
2255
|
+
remove(...bits) {
|
|
2256
|
+
return super.remove(...bits);
|
|
1287
2257
|
}
|
|
1288
2258
|
};
|
|
1289
2259
|
|
|
@@ -1346,7 +2316,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1346
2316
|
/**
|
|
1347
2317
|
* Fetches a Channel from the API or resolves it from the local cache.
|
|
1348
2318
|
* @param channel The ID, mention, or Channel object to fetch.
|
|
1349
|
-
* @param force Whether to skip the cache check and force a direct API request. Defaults to
|
|
2319
|
+
* @param force Whether to skip the cache check and force a direct API request. Defaults to false.
|
|
1350
2320
|
* @returns A promise that resolves to the fetched BaseChannel object.
|
|
1351
2321
|
* @throws {TypeError} If an invalid ChannelResolvable is provided.
|
|
1352
2322
|
* @throws {Error} If the API request fails.
|
|
@@ -1354,7 +2324,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1354
2324
|
* // Fetch a channel, bypassing cache
|
|
1355
2325
|
* const channel = await client.channels.fetch("01H...");
|
|
1356
2326
|
*/
|
|
1357
|
-
async fetch(channel, force =
|
|
2327
|
+
async fetch(channel, force = false) {
|
|
1358
2328
|
if (!force) {
|
|
1359
2329
|
const cached = this.resolve(channel);
|
|
1360
2330
|
if (cached) return cached;
|
|
@@ -1392,7 +2362,7 @@ var ChannelManager = class extends BaseManager {
|
|
|
1392
2362
|
}
|
|
1393
2363
|
if (options.icon !== void 0) {
|
|
1394
2364
|
if (options.icon === null) remove.push("Icon");
|
|
1395
|
-
else payload.icon = options.icon;
|
|
2365
|
+
else payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
|
|
1396
2366
|
}
|
|
1397
2367
|
if (remove.length > 0) payload.remove = remove;
|
|
1398
2368
|
if (Object.keys(payload).length === 0) return this.fetch(channel);
|
|
@@ -1468,10 +2438,51 @@ var ChannelManager = class extends BaseManager {
|
|
|
1468
2438
|
await this.client.rest.delete(`/channels/${id}`);
|
|
1469
2439
|
this.cache.delete(id);
|
|
1470
2440
|
}
|
|
2441
|
+
/**
|
|
2442
|
+
* Pin a message
|
|
2443
|
+
* @param id Channel ID
|
|
2444
|
+
* @param messageId Message ID
|
|
2445
|
+
* @throws {Error} If the API request fails.
|
|
2446
|
+
* @example
|
|
2447
|
+
* await client.channels.pin("CHANNEL_ID", "MESSAGE_ID");
|
|
2448
|
+
*/
|
|
2449
|
+
async pin(id, messageId) {
|
|
2450
|
+
await this.client.rest.post(`/channels/${id}/pins/${messageId}`);
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* Unpin a message
|
|
2454
|
+
* @param id Channel ID
|
|
2455
|
+
* @param messageId Message ID
|
|
2456
|
+
* @throws {Error} If the API request fails
|
|
2457
|
+
* @example
|
|
2458
|
+
* await client.channels.unpin("CHANNEL_ID", "MESSAGE_ID");
|
|
2459
|
+
*/
|
|
2460
|
+
async unpin(id, messageId) {
|
|
2461
|
+
await this.client.rest.delete(`/channels/${id}/pins/${messageId}`);
|
|
2462
|
+
}
|
|
2463
|
+
/**
|
|
2464
|
+
* Bulk delete up to 100 messages
|
|
2465
|
+
* @param id Channel ID
|
|
2466
|
+
* @param messages An array of MessageResolvable
|
|
2467
|
+
* @throws {Error} If the API request fails
|
|
2468
|
+
* @example
|
|
2469
|
+
* await client.channels.bulkDelete("CHANNEL_ID", ["MESSAGE_ID_1", "MESSAGE_ID_2", "MESSAGE_ID_3"]);
|
|
2470
|
+
*/
|
|
2471
|
+
async bulkDelete(id, messages) {
|
|
2472
|
+
if (!Array.isArray(messages) || messages.length === 0 || messages.length > 100) {
|
|
2473
|
+
throw new TypeError("Messages must be an array of 1-100 MessageResolvable items.");
|
|
2474
|
+
}
|
|
2475
|
+
const messageIds = messages.map((msg) => {
|
|
2476
|
+
if (typeof msg === "string") return msg.replace(/[<#>]/g, "");
|
|
2477
|
+
if ("id" in msg) return msg.id;
|
|
2478
|
+
throw new TypeError("Invalid MessageResolvable provided. Expected a Message object or a string ID/Mention.");
|
|
2479
|
+
});
|
|
2480
|
+
await this.client.rest.delete(`/channels/${id}/messages/bulk`, { messages: messageIds });
|
|
2481
|
+
}
|
|
1471
2482
|
};
|
|
1472
2483
|
|
|
1473
2484
|
// src/structures/Member.ts
|
|
1474
|
-
import * as
|
|
2485
|
+
import * as util5 from "util";
|
|
1475
2486
|
|
|
1476
2487
|
// src/managers/MemberRoleManager.ts
|
|
1477
2488
|
var MemberRoleManager = class {
|
|
@@ -1597,15 +2608,15 @@ var Member = class extends Base {
|
|
|
1597
2608
|
/** Calculates the member's total permissions using BigInt */
|
|
1598
2609
|
get permissions() {
|
|
1599
2610
|
const server = this.server;
|
|
1600
|
-
if (!server) return 0n;
|
|
2611
|
+
if (!server) return new Permissions(0n);
|
|
2612
|
+
if (server.ownerId === this.id) {
|
|
2613
|
+
return new Permissions(PermissionFlags.GrantAllSafe);
|
|
2614
|
+
}
|
|
1601
2615
|
let totalPerms = server.defaultPermissions ?? 0n;
|
|
1602
2616
|
for (const role of this.roles.cache.values()) {
|
|
1603
|
-
totalPerms |= BigInt(role.permissions);
|
|
1604
|
-
}
|
|
1605
|
-
if (server.ownerId === this.id) {
|
|
1606
|
-
return PermissionFlags.GrantAllSafe;
|
|
2617
|
+
totalPerms |= BigInt(role.permissions.bitfield);
|
|
1607
2618
|
}
|
|
1608
|
-
return totalPerms;
|
|
2619
|
+
return new Permissions(totalPerms);
|
|
1609
2620
|
}
|
|
1610
2621
|
/** Get avatar URL for this member, or null if they don't have one.
|
|
1611
2622
|
* @example
|
|
@@ -1650,13 +2661,24 @@ var Member = class extends Base {
|
|
|
1650
2661
|
* await member.setTimeout(600000);
|
|
1651
2662
|
*/
|
|
1652
2663
|
async setTimeout(duration) {
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
2664
|
+
await this.edit({ timeout: new Date(Date.now() + duration).toISOString() });
|
|
2665
|
+
}
|
|
2666
|
+
/**
|
|
2667
|
+
* Send a message to this member.
|
|
2668
|
+
* @param options The content or options for the message to send.
|
|
2669
|
+
* @returns A promise that resolves to the sent Message object.
|
|
2670
|
+
* @throws {Error} If the API request fails.
|
|
2671
|
+
* @example
|
|
2672
|
+
* // Send a message to this member
|
|
2673
|
+
* const message = await member.send("Hello!");
|
|
2674
|
+
* console.log(`Sent message ID: ${message.id}`);
|
|
2675
|
+
*/
|
|
2676
|
+
async send(options) {
|
|
2677
|
+
let dmChannel = await this.client.users.createDM(this.id);
|
|
2678
|
+
return dmChannel.messages.send(options);
|
|
1656
2679
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
return Permissions.has(this.permissions, permission);
|
|
2680
|
+
async setNickname(nickname) {
|
|
2681
|
+
return this.edit({ nickname });
|
|
1660
2682
|
}
|
|
1661
2683
|
/**
|
|
1662
2684
|
* Edit this member.
|
|
@@ -1668,6 +2690,16 @@ var Member = class extends Base {
|
|
|
1668
2690
|
if (!server) server = await this.client.servers.fetch(this.serverId);
|
|
1669
2691
|
return await server.members.edit(this.id, options);
|
|
1670
2692
|
}
|
|
2693
|
+
/**
|
|
2694
|
+
* When concatenated with a string, this automatically returns the user's mention instead of the GuildMember object.
|
|
2695
|
+
* @returns {string}
|
|
2696
|
+
* @example
|
|
2697
|
+
* // Logs: Hello from <@01JE2MM759J5D7CHJF084R7MJ2>!
|
|
2698
|
+
* console.log(`Hello from ${member}!`);
|
|
2699
|
+
*/
|
|
2700
|
+
toString() {
|
|
2701
|
+
return `<@${this.id}>`;
|
|
2702
|
+
}
|
|
1671
2703
|
/**
|
|
1672
2704
|
* Kick this member from the server.
|
|
1673
2705
|
*/
|
|
@@ -1677,9 +2709,9 @@ var Member = class extends Base {
|
|
|
1677
2709
|
await server.members.kick(this.id);
|
|
1678
2710
|
}
|
|
1679
2711
|
/** @internal */
|
|
1680
|
-
[
|
|
2712
|
+
[util5.inspect.custom](depth, options, inspect12) {
|
|
1681
2713
|
const { client, serverId, ...props } = this;
|
|
1682
|
-
return `${this.constructor.name} ${
|
|
2714
|
+
return `${this.constructor.name} ${inspect12(
|
|
1683
2715
|
{
|
|
1684
2716
|
...props,
|
|
1685
2717
|
user: this.user,
|
|
@@ -1691,7 +2723,7 @@ var Member = class extends Base {
|
|
|
1691
2723
|
};
|
|
1692
2724
|
|
|
1693
2725
|
// src/managers/MemberManager.ts
|
|
1694
|
-
import * as
|
|
2726
|
+
import * as util6 from "util";
|
|
1695
2727
|
var MemberManager = class extends BaseManager {
|
|
1696
2728
|
constructor(client, server, limit = Infinity) {
|
|
1697
2729
|
super(client, limit);
|
|
@@ -1865,25 +2897,13 @@ var MemberManager = class extends BaseManager {
|
|
|
1865
2897
|
const id = this.resolveId(member);
|
|
1866
2898
|
await this.client.rest.delete(`/servers/${this.server.id}/bans/${id}`);
|
|
1867
2899
|
}
|
|
1868
|
-
|
|
1869
|
-
* Timeouts a member in the server for a specified duration.
|
|
1870
|
-
* @param member The MemberResolvable to timeout
|
|
1871
|
-
* @param duration The duration of the timeout in milliseconds
|
|
1872
|
-
* @example
|
|
1873
|
-
* // Timeout a member for 10 minutes
|
|
1874
|
-
* await server.members.setTimeout("1234567890", 10 * 60 * 1000);
|
|
1875
|
-
*/
|
|
1876
|
-
async setTimeout(member, duration) {
|
|
1877
|
-
const id = this.resolveId(member);
|
|
1878
|
-
await this.edit(id, { timeout: new Date(Date.now() + duration).toISOString() });
|
|
1879
|
-
}
|
|
1880
|
-
[util5.inspect.custom]() {
|
|
2900
|
+
[util6.inspect.custom]() {
|
|
1881
2901
|
return this.cache;
|
|
1882
2902
|
}
|
|
1883
2903
|
};
|
|
1884
2904
|
|
|
1885
2905
|
// src/managers/ServerChannelManager.ts
|
|
1886
|
-
import * as
|
|
2906
|
+
import * as util7 from "util";
|
|
1887
2907
|
var ServerChannelManager = class {
|
|
1888
2908
|
client;
|
|
1889
2909
|
server;
|
|
@@ -1913,20 +2933,21 @@ var ServerChannelManager = class {
|
|
|
1913
2933
|
const data = await this.client.rest.post(`/servers/${this.server.id}/channels`, payload);
|
|
1914
2934
|
return this.client.channels._add(data);
|
|
1915
2935
|
}
|
|
1916
|
-
[
|
|
2936
|
+
[util7.inspect.custom]() {
|
|
1917
2937
|
return this.cache;
|
|
1918
2938
|
}
|
|
1919
2939
|
};
|
|
1920
2940
|
|
|
1921
2941
|
// src/structures/Role.ts
|
|
1922
|
-
import * as
|
|
2942
|
+
import * as util8 from "util";
|
|
1923
2943
|
var Role = class extends Base {
|
|
1924
2944
|
serverId;
|
|
1925
2945
|
name;
|
|
1926
2946
|
color = null;
|
|
1927
2947
|
hoist = false;
|
|
1928
2948
|
rank = 0;
|
|
1929
|
-
|
|
2949
|
+
icon = null;
|
|
2950
|
+
_permissions = 0n;
|
|
1930
2951
|
constructor(client, data, serverId) {
|
|
1931
2952
|
super(client, data);
|
|
1932
2953
|
this.serverId = serverId;
|
|
@@ -1941,16 +2962,17 @@ var Role = class extends Base {
|
|
|
1941
2962
|
if (data.color !== void 0) this.color = data.color;
|
|
1942
2963
|
if (data.hoist !== void 0) this.hoist = data.hoist;
|
|
1943
2964
|
if (data.rank !== void 0) this.rank = data.rank;
|
|
2965
|
+
if (data.icon !== void 0) this.icon = new Attachment(this.client, data.icon);
|
|
1944
2966
|
if (data.permissions !== void 0) {
|
|
1945
2967
|
try {
|
|
1946
2968
|
if (typeof data.permissions === "object" && data.permissions !== null) {
|
|
1947
2969
|
const allowPerms = data.permissions.a ?? data.permissions[0] ?? 0;
|
|
1948
|
-
this.
|
|
2970
|
+
this._permissions = BigInt(allowPerms);
|
|
1949
2971
|
} else {
|
|
1950
|
-
this.
|
|
2972
|
+
this._permissions = BigInt(data.permissions);
|
|
1951
2973
|
}
|
|
1952
2974
|
} catch {
|
|
1953
|
-
this.
|
|
2975
|
+
this._permissions = 0n;
|
|
1954
2976
|
}
|
|
1955
2977
|
}
|
|
1956
2978
|
}
|
|
@@ -1962,12 +2984,10 @@ var Role = class extends Base {
|
|
|
1962
2984
|
return this.client.servers.cache.get(this.serverId);
|
|
1963
2985
|
}
|
|
1964
2986
|
/**
|
|
1965
|
-
*
|
|
1966
|
-
* @param permission The permission to check for.
|
|
1967
|
-
* @returns True if the role has the permission.
|
|
2987
|
+
* Permissions for this role
|
|
1968
2988
|
*/
|
|
1969
|
-
|
|
1970
|
-
return Permissions
|
|
2989
|
+
get permissions() {
|
|
2990
|
+
return new Permissions(this._permissions);
|
|
1971
2991
|
}
|
|
1972
2992
|
/**
|
|
1973
2993
|
* Fetches this role directly from the API to ensure data is up to date.
|
|
@@ -1995,10 +3015,10 @@ var Role = class extends Base {
|
|
|
1995
3015
|
* @throws {Error} If the API request fails (e.g., lack of permissions).
|
|
1996
3016
|
* @example
|
|
1997
3017
|
* // Change the role's name and color
|
|
1998
|
-
* await role.edit({ name: "Senior Admin",
|
|
3018
|
+
* await role.edit({ name: "Senior Admin", color: "#FFD700" });
|
|
1999
3019
|
*
|
|
2000
3020
|
* // Remove the custom color from the role
|
|
2001
|
-
* await role.edit({
|
|
3021
|
+
* await role.edit({ color: null });
|
|
2002
3022
|
*/
|
|
2003
3023
|
async edit(options) {
|
|
2004
3024
|
let server = this.server;
|
|
@@ -2057,19 +3077,86 @@ var Role = class extends Base {
|
|
|
2057
3077
|
await server.roles.setRanks(filteredRoles);
|
|
2058
3078
|
return this;
|
|
2059
3079
|
}
|
|
3080
|
+
/**
|
|
3081
|
+
* Change the name for this role
|
|
3082
|
+
* @param name The new name for the role
|
|
3083
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3084
|
+
* @throws {Error} If API request fails.
|
|
3085
|
+
* @example
|
|
3086
|
+
* // Change the role's name
|
|
3087
|
+
* await role.setName("New Role Name");
|
|
3088
|
+
* console.log(`Role's new name: ${role.name}`);
|
|
3089
|
+
*/
|
|
3090
|
+
async setName(name) {
|
|
3091
|
+
return await this.edit({ name });
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Change the color for this role, it can be a HEX or CSS colours
|
|
3095
|
+
* @param {[string]} color The new color for the role
|
|
3096
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3097
|
+
* @throws {Error} If API request fails
|
|
3098
|
+
* @example
|
|
3099
|
+
* // Change the role's color
|
|
3100
|
+
* await role.setColour("#FF0000");
|
|
3101
|
+
* console.log(`Role's new color: ${role.color}`);
|
|
3102
|
+
*
|
|
3103
|
+
* // Use CSS color linear-graident
|
|
3104
|
+
* await role.setColour("linear-gradient(90deg, #FF0000, #0000FF)");
|
|
3105
|
+
* console.log(`Role's new color: ${role.color}`);
|
|
3106
|
+
*
|
|
3107
|
+
* // Remove the custom color from the role
|
|
3108
|
+
* await role.setColour(null);
|
|
3109
|
+
* console.log(`Role's color removed, current color: ${role.color}`);
|
|
3110
|
+
*/
|
|
3111
|
+
async setColor(color) {
|
|
3112
|
+
return await this.edit({ color });
|
|
3113
|
+
}
|
|
3114
|
+
/**
|
|
3115
|
+
* Edit the icon of this role
|
|
3116
|
+
* @param icon Autumn ID for the new icon, or null to remove the custom icon
|
|
3117
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3118
|
+
* @throws {Error} If API request fails
|
|
3119
|
+
* @example
|
|
3120
|
+
* // Set a new icon for the role
|
|
3121
|
+
* await role.setIcon("AUTUMN_ID_FOR_ICON");
|
|
3122
|
+
* console.log(`Role's new icon: ${role.icon}`);
|
|
3123
|
+
*
|
|
3124
|
+
* // Use AttachmentBuilder to upload a new icon file
|
|
3125
|
+
* import { readFile } from "node:fs/promises";
|
|
3126
|
+
* const iconFile = await readFile("./a.jpg");
|
|
3127
|
+
* const attachment = new AttachmentBuilder(iconFile, "a.jpg");
|
|
3128
|
+
* await role.setIcon(attachment);
|
|
3129
|
+
* console.log(`Role's new icon: ${role.icon}`);
|
|
3130
|
+
*/
|
|
3131
|
+
async setIcon(icon) {
|
|
3132
|
+
return await this.edit({ icon });
|
|
3133
|
+
}
|
|
3134
|
+
/**
|
|
3135
|
+
* Change the hoist status for this role
|
|
3136
|
+
* @param hoist The new hoist status for the role
|
|
3137
|
+
* @returns A promise that resolves to this updated Role object.
|
|
3138
|
+
* @throws {Error} If API request fails
|
|
3139
|
+
* @example
|
|
3140
|
+
* // Enable hoisting for the role
|
|
3141
|
+
* await role.setHoist(true);
|
|
3142
|
+
* console.log(`Role is now hoisted: ${role.hoist}`);
|
|
3143
|
+
*/
|
|
3144
|
+
async setHoist(hoist) {
|
|
3145
|
+
return await this.edit({ hoist });
|
|
3146
|
+
}
|
|
2060
3147
|
/**
|
|
2061
3148
|
* Customizer for Node.js `console.log` and `util.inspect`.
|
|
2062
3149
|
* Hides the cyclic client reference and raw serverId for a cleaner output.
|
|
2063
3150
|
* @internal
|
|
2064
3151
|
*/
|
|
2065
|
-
[
|
|
3152
|
+
[util8.inspect.custom]() {
|
|
2066
3153
|
const { client, serverId, ...props } = this;
|
|
2067
|
-
return `${this.constructor.name} ${
|
|
3154
|
+
return `${this.constructor.name} ${util8.inspect(props)}`;
|
|
2068
3155
|
}
|
|
2069
3156
|
};
|
|
2070
3157
|
|
|
2071
3158
|
// src/managers/RoleManager.ts
|
|
2072
|
-
import * as
|
|
3159
|
+
import * as util9 from "util";
|
|
2073
3160
|
var RoleManager = class extends BaseManager {
|
|
2074
3161
|
/**
|
|
2075
3162
|
* Manages API methods and caching for server roles.
|
|
@@ -2108,7 +3195,7 @@ var RoleManager = class extends BaseManager {
|
|
|
2108
3195
|
this.cache.set(role.id, role);
|
|
2109
3196
|
return role;
|
|
2110
3197
|
}
|
|
2111
|
-
[
|
|
3198
|
+
[util9.inspect.custom]() {
|
|
2112
3199
|
return this.cache;
|
|
2113
3200
|
}
|
|
2114
3201
|
/**
|
|
@@ -2194,7 +3281,7 @@ var RoleManager = class extends BaseManager {
|
|
|
2194
3281
|
}
|
|
2195
3282
|
/**
|
|
2196
3283
|
* Edits an existing role in the server.
|
|
2197
|
-
* @param role The RoleResolvable to edit.
|
|
3284
|
+
* @param role The {@link RoleResolvable} to edit.
|
|
2198
3285
|
* @param options The fields to update.
|
|
2199
3286
|
* @returns A promise that resolves to the updated Role.
|
|
2200
3287
|
* @throws {TypeError} If invalid options or RoleResolvable are provided.
|
|
@@ -2215,11 +3302,18 @@ var RoleManager = class extends BaseManager {
|
|
|
2215
3302
|
const remove = [];
|
|
2216
3303
|
if (options.name !== void 0) payload.name = options.name;
|
|
2217
3304
|
if (options.hoist !== void 0) payload.hoist = options.hoist;
|
|
2218
|
-
if (options.
|
|
2219
|
-
if (options.
|
|
3305
|
+
if (options.color !== void 0) {
|
|
3306
|
+
if (options.color === null) {
|
|
2220
3307
|
remove.push("Colour");
|
|
2221
3308
|
} else {
|
|
2222
|
-
payload.colour = options.
|
|
3309
|
+
payload.colour = options.color;
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
if (options.icon !== void 0) {
|
|
3313
|
+
if (options.icon === null) {
|
|
3314
|
+
remove.push("Icon");
|
|
3315
|
+
} else {
|
|
3316
|
+
payload.icon = await resolveAttachment(this.client.rest, options.icon, "icons");
|
|
2223
3317
|
}
|
|
2224
3318
|
}
|
|
2225
3319
|
if (remove.length > 0) {
|
|
@@ -2409,6 +3503,54 @@ var ServerBanManager = class extends BaseManager {
|
|
|
2409
3503
|
}
|
|
2410
3504
|
};
|
|
2411
3505
|
|
|
3506
|
+
// src/structures/Emoji.ts
|
|
3507
|
+
var Emoji = class extends Base {
|
|
3508
|
+
creatorId;
|
|
3509
|
+
name;
|
|
3510
|
+
parent;
|
|
3511
|
+
animated = false;
|
|
3512
|
+
nsfw = false;
|
|
3513
|
+
constructor(client, data) {
|
|
3514
|
+
super(client, data);
|
|
3515
|
+
this._patch(data);
|
|
3516
|
+
}
|
|
3517
|
+
_patch(data) {
|
|
3518
|
+
if (data.creator_id !== void 0) this.creatorId = data.creator_id;
|
|
3519
|
+
if (data.name !== void 0) this.name = data.name;
|
|
3520
|
+
if (data.parent !== void 0) this.parent = data.parent;
|
|
3521
|
+
if (data.animated !== void 0) this.animated = data.animated;
|
|
3522
|
+
if (data.nsfw !== void 0) this.nsfw = data.nsfw;
|
|
3523
|
+
}
|
|
3524
|
+
};
|
|
3525
|
+
|
|
3526
|
+
// src/managers/EmojiManager.ts
|
|
3527
|
+
import * as util10 from "util";
|
|
3528
|
+
var EmojiManager = class extends BaseManager {
|
|
3529
|
+
constructor(client, server, limit = Infinity) {
|
|
3530
|
+
super(client, limit);
|
|
3531
|
+
this.server = server;
|
|
3532
|
+
}
|
|
3533
|
+
/**
|
|
3534
|
+
* Tell BaseManager how to find the ID for Emojis
|
|
3535
|
+
*/
|
|
3536
|
+
extractId(data) {
|
|
3537
|
+
return data._id ?? data.id;
|
|
3538
|
+
}
|
|
3539
|
+
/**
|
|
3540
|
+
* Tell BaseManager how to build an Emoji
|
|
3541
|
+
*/
|
|
3542
|
+
construct(data) {
|
|
3543
|
+
return new Emoji(this.client, data);
|
|
3544
|
+
}
|
|
3545
|
+
async fetch(id) {
|
|
3546
|
+
const data = await this.client.rest.get(`/custom/emoji/${id}`);
|
|
3547
|
+
return this._add(data);
|
|
3548
|
+
}
|
|
3549
|
+
[util10.inspect.custom]() {
|
|
3550
|
+
return this.cache;
|
|
3551
|
+
}
|
|
3552
|
+
};
|
|
3553
|
+
|
|
2412
3554
|
// src/structures/Server.ts
|
|
2413
3555
|
var Server = class extends Base {
|
|
2414
3556
|
channelIds = [];
|
|
@@ -2428,6 +3570,7 @@ var Server = class extends Base {
|
|
|
2428
3570
|
roles;
|
|
2429
3571
|
bans;
|
|
2430
3572
|
invites;
|
|
3573
|
+
emojis;
|
|
2431
3574
|
constructor(client, data) {
|
|
2432
3575
|
super(client, data);
|
|
2433
3576
|
this.channels = new ServerChannelManager(client, this);
|
|
@@ -2435,6 +3578,7 @@ var Server = class extends Base {
|
|
|
2435
3578
|
this.roles = new RoleManager(client, this);
|
|
2436
3579
|
this.bans = new ServerBanManager(this.client, this);
|
|
2437
3580
|
this.invites = new ServerInviteManager(this.client, this);
|
|
3581
|
+
this.emojis = new EmojiManager(this.client, this);
|
|
2438
3582
|
this._patch(data);
|
|
2439
3583
|
}
|
|
2440
3584
|
/**
|
|
@@ -2468,6 +3612,13 @@ var Server = class extends Base {
|
|
|
2468
3612
|
this.roles._add({ id, ...roleData });
|
|
2469
3613
|
}
|
|
2470
3614
|
}
|
|
3615
|
+
if (data.emojis !== void 0) {
|
|
3616
|
+
if (Array.isArray(data.emojis)) {
|
|
3617
|
+
for (const emoji of data.emojis) {
|
|
3618
|
+
this.emojis._add(emoji);
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
2471
3622
|
if (clear && Array.isArray(clear)) {
|
|
2472
3623
|
for (const field of clear) {
|
|
2473
3624
|
switch (field) {
|
|
@@ -2506,7 +3657,7 @@ var Server = class extends Base {
|
|
|
2506
3657
|
};
|
|
2507
3658
|
|
|
2508
3659
|
// src/managers/ServerManager.ts
|
|
2509
|
-
import * as
|
|
3660
|
+
import * as util11 from "util";
|
|
2510
3661
|
var ServerManager = class extends BaseManager {
|
|
2511
3662
|
constructor(client, limit = Infinity) {
|
|
2512
3663
|
super(client, limit);
|
|
@@ -2579,7 +3730,7 @@ var ServerManager = class extends BaseManager {
|
|
|
2579
3730
|
const data = await this.client.rest.patch(`/servers/${serverId}`, payload);
|
|
2580
3731
|
return this._add(data);
|
|
2581
3732
|
}
|
|
2582
|
-
[
|
|
3733
|
+
[util11.inspect.custom]() {
|
|
2583
3734
|
return this.cache;
|
|
2584
3735
|
}
|
|
2585
3736
|
};
|
|
@@ -2808,7 +3959,7 @@ var SweeperManager = class {
|
|
|
2808
3959
|
};
|
|
2809
3960
|
|
|
2810
3961
|
// src/client/Client.ts
|
|
2811
|
-
var Client = class extends
|
|
3962
|
+
var Client = class extends EventEmitter2 {
|
|
2812
3963
|
constructor(options = {}) {
|
|
2813
3964
|
super({ captureRejections: true });
|
|
2814
3965
|
this.options = options;
|
|
@@ -2817,6 +3968,7 @@ var Client = class extends EventEmitter {
|
|
|
2817
3968
|
this.channels = new ChannelManager(this, options.cacheLimits?.channels);
|
|
2818
3969
|
this.servers = new ServerManager(this, options.cacheLimits?.servers);
|
|
2819
3970
|
this.users = new UserManager(this, options.cacheLimits?.users);
|
|
3971
|
+
this.emojis = new EmojiManager(this, void 0, options.cacheLimits?.emojis);
|
|
2820
3972
|
this.sweepers = new SweeperManager(this, options.sweepers ?? {});
|
|
2821
3973
|
}
|
|
2822
3974
|
rest;
|
|
@@ -2825,6 +3977,7 @@ var Client = class extends EventEmitter {
|
|
|
2825
3977
|
servers;
|
|
2826
3978
|
users;
|
|
2827
3979
|
sweepers;
|
|
3980
|
+
emojis;
|
|
2828
3981
|
user = null;
|
|
2829
3982
|
/**
|
|
2830
3983
|
* Connects the bot to the Stoat Gateway
|
|
@@ -2888,23 +4041,31 @@ var EmbedBuilder = class {
|
|
|
2888
4041
|
};
|
|
2889
4042
|
export {
|
|
2890
4043
|
Attachment,
|
|
4044
|
+
AttachmentBuilder,
|
|
2891
4045
|
Base,
|
|
2892
4046
|
BaseChannel,
|
|
4047
|
+
BitField,
|
|
2893
4048
|
ChannelManager,
|
|
2894
4049
|
ChannelType,
|
|
2895
4050
|
Client,
|
|
2896
4051
|
ClientUser,
|
|
2897
4052
|
Collection,
|
|
4053
|
+
Collector,
|
|
2898
4054
|
DMChannel,
|
|
2899
4055
|
EmbedBuilder,
|
|
4056
|
+
Emoji,
|
|
4057
|
+
EmojiManager,
|
|
2900
4058
|
GatewayManager,
|
|
2901
4059
|
Member,
|
|
2902
4060
|
MemberManager,
|
|
2903
4061
|
Message,
|
|
4062
|
+
MessageCollector,
|
|
2904
4063
|
MessageManager,
|
|
4064
|
+
MessageReaction,
|
|
2905
4065
|
PermissionFlags,
|
|
2906
4066
|
Permissions,
|
|
2907
4067
|
RESTManager,
|
|
4068
|
+
ReactionCollector,
|
|
2908
4069
|
Role,
|
|
2909
4070
|
RoleManager,
|
|
2910
4071
|
Server,
|