@fluxerjs/core 1.0.8 → 1.1.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/{Channel-TWPDKW2P.mjs → Channel-WJZZSNML.mjs} +3 -1
- package/dist/{ClientUser-2K2BACK7.mjs → ClientUser-DJO2FS7P.mjs} +1 -1
- package/dist/Guild-2P77HBQM.mjs +11 -0
- package/dist/GuildBan-7CXLTPKY.mjs +7 -0
- package/dist/GuildMember-43B5E5CH.mjs +9 -0
- package/dist/{Message-G2QIKZQK.mjs → Invite-UM5BU5A6.mjs} +3 -3
- package/dist/Message-OFIVTTAZ.mjs +9 -0
- package/dist/{MessageReaction-XRPYZDSC.mjs → MessageReaction-V4UZ7OXE.mjs} +1 -1
- package/dist/{Role-SVLWIAMN.mjs → Role-5MWSGL66.mjs} +1 -1
- package/dist/Webhook-RWDDYW2Q.mjs +10 -0
- package/dist/chunk-4XJIM6SC.mjs +315 -0
- package/dist/chunk-AH7KYH2Z.mjs +50 -0
- package/dist/{chunk-HBF5QEDH.mjs → chunk-CEABHTAF.mjs} +1 -0
- package/dist/chunk-CJVQNARM.mjs +145 -0
- package/dist/chunk-DQ4TNBPG.mjs +63 -0
- package/dist/chunk-DUQAD7F6.mjs +173 -0
- package/dist/{chunk-4GCZFOS5.mjs → chunk-JHNKZIHY.mjs} +54 -3
- package/dist/chunk-LU2SNC5G.mjs +392 -0
- package/dist/chunk-PM2IUGNR.mjs +29 -0
- package/dist/chunk-QEXIYXXU.mjs +62 -0
- package/dist/chunk-UXIF75BV.mjs +36 -0
- package/dist/chunk-V7LPVPGH.mjs +305 -0
- package/dist/chunk-X6K3ZD62.mjs +53 -0
- package/dist/index.d.mts +802 -160
- package/dist/index.d.ts +802 -160
- package/dist/index.js +1467 -262
- package/dist/index.mjs +292 -119
- package/package.json +7 -7
- package/dist/Guild-CMZGA6DW.mjs +0 -10
- package/dist/GuildMember-DW2N6ITI.mjs +0 -7
- package/dist/Webhook-2MQESB7Z.mjs +0 -7
- package/dist/chunk-CO5EL5LH.mjs +0 -168
- package/dist/chunk-CZIO2D7F.mjs +0 -207
- package/dist/chunk-JVEOQFUX.mjs +0 -52
- package/dist/chunk-SQVCCSNN.mjs +0 -41
- package/dist/chunk-TJVZEILY.mjs +0 -120
- package/dist/chunk-ZGMM6IPQ.mjs +0 -79
package/dist/index.js
CHANGED
|
@@ -20,6 +20,72 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
20
20
|
};
|
|
21
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
22
|
|
|
23
|
+
// src/errors/FluxerError.ts
|
|
24
|
+
var FluxerError;
|
|
25
|
+
var init_FluxerError = __esm({
|
|
26
|
+
"src/errors/FluxerError.ts"() {
|
|
27
|
+
"use strict";
|
|
28
|
+
FluxerError = class _FluxerError extends Error {
|
|
29
|
+
code;
|
|
30
|
+
constructor(message, options) {
|
|
31
|
+
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
32
|
+
this.name = "FluxerError";
|
|
33
|
+
this.code = options?.code;
|
|
34
|
+
Object.setPrototypeOf(this, _FluxerError.prototype);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// src/errors/ErrorCodes.ts
|
|
41
|
+
var ErrorCodes;
|
|
42
|
+
var init_ErrorCodes = __esm({
|
|
43
|
+
"src/errors/ErrorCodes.ts"() {
|
|
44
|
+
"use strict";
|
|
45
|
+
ErrorCodes = {
|
|
46
|
+
ClientNotReady: "CLIENT_NOT_READY",
|
|
47
|
+
InvalidToken: "INVALID_TOKEN",
|
|
48
|
+
AlreadyLoggedIn: "ALREADY_LOGGED_IN",
|
|
49
|
+
ChannelNotFound: "CHANNEL_NOT_FOUND",
|
|
50
|
+
MessageNotFound: "MESSAGE_NOT_FOUND",
|
|
51
|
+
GuildNotFound: "GUILD_NOT_FOUND",
|
|
52
|
+
MemberNotFound: "MEMBER_NOT_FOUND"
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// src/util/messageUtils.ts
|
|
58
|
+
function buildSendBody(options) {
|
|
59
|
+
const body = typeof options === "string" ? { content: options } : options;
|
|
60
|
+
const result = {};
|
|
61
|
+
if (body.content !== void 0) result.content = body.content;
|
|
62
|
+
if (body.embeds?.length) {
|
|
63
|
+
result.embeds = body.embeds.map((e) => e instanceof import_builders.EmbedBuilder ? e.toJSON() : e);
|
|
64
|
+
}
|
|
65
|
+
if (body.files?.length && body.attachments) {
|
|
66
|
+
result.attachments = body.attachments.map((a) => ({
|
|
67
|
+
id: a.id,
|
|
68
|
+
filename: a.filename,
|
|
69
|
+
...a.title != null && { title: a.title },
|
|
70
|
+
...a.description != null && { description: a.description },
|
|
71
|
+
...a.flags != null && { flags: a.flags }
|
|
72
|
+
}));
|
|
73
|
+
} else if (body.files?.length) {
|
|
74
|
+
result.attachments = body.files.map((f, i) => ({
|
|
75
|
+
id: i,
|
|
76
|
+
filename: f.filename ?? f.name
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
var import_builders;
|
|
82
|
+
var init_messageUtils = __esm({
|
|
83
|
+
"src/util/messageUtils.ts"() {
|
|
84
|
+
"use strict";
|
|
85
|
+
import_builders = require("@fluxerjs/builders");
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
23
89
|
// src/client/MessageManager.ts
|
|
24
90
|
var MessageManager;
|
|
25
91
|
var init_MessageManager = __esm({
|
|
@@ -33,7 +99,8 @@ var init_MessageManager = __esm({
|
|
|
33
99
|
/**
|
|
34
100
|
* Fetch a message by ID from this channel.
|
|
35
101
|
* @param messageId - Snowflake of the message
|
|
36
|
-
* @returns The message
|
|
102
|
+
* @returns The message
|
|
103
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
37
104
|
*/
|
|
38
105
|
async fetch(messageId) {
|
|
39
106
|
return this.client.channels.fetchMessage(this.channelId, messageId);
|
|
@@ -42,6 +109,118 @@ var init_MessageManager = __esm({
|
|
|
42
109
|
}
|
|
43
110
|
});
|
|
44
111
|
|
|
112
|
+
// src/util/Events.ts
|
|
113
|
+
var Events;
|
|
114
|
+
var init_Events = __esm({
|
|
115
|
+
"src/util/Events.ts"() {
|
|
116
|
+
"use strict";
|
|
117
|
+
Events = {
|
|
118
|
+
Ready: "ready",
|
|
119
|
+
MessageCreate: "messageCreate",
|
|
120
|
+
MessageUpdate: "messageUpdate",
|
|
121
|
+
MessageDelete: "messageDelete",
|
|
122
|
+
MessageDeleteBulk: "messageDeleteBulk",
|
|
123
|
+
MessageReactionAdd: "messageReactionAdd",
|
|
124
|
+
MessageReactionRemove: "messageReactionRemove",
|
|
125
|
+
MessageReactionRemoveAll: "messageReactionRemoveAll",
|
|
126
|
+
MessageReactionRemoveEmoji: "messageReactionRemoveEmoji",
|
|
127
|
+
InteractionCreate: "interactionCreate",
|
|
128
|
+
GuildCreate: "guildCreate",
|
|
129
|
+
GuildUpdate: "guildUpdate",
|
|
130
|
+
GuildDelete: "guildDelete",
|
|
131
|
+
GuildBanAdd: "guildBanAdd",
|
|
132
|
+
GuildBanRemove: "guildBanRemove",
|
|
133
|
+
GuildEmojisUpdate: "guildEmojisUpdate",
|
|
134
|
+
GuildStickersUpdate: "guildStickersUpdate",
|
|
135
|
+
GuildIntegrationsUpdate: "guildIntegrationsUpdate",
|
|
136
|
+
GuildMemberAdd: "guildMemberAdd",
|
|
137
|
+
GuildMemberUpdate: "guildMemberUpdate",
|
|
138
|
+
GuildMemberRemove: "guildMemberRemove",
|
|
139
|
+
GuildRoleCreate: "guildRoleCreate",
|
|
140
|
+
GuildRoleUpdate: "guildRoleUpdate",
|
|
141
|
+
GuildRoleDelete: "guildRoleDelete",
|
|
142
|
+
GuildScheduledEventCreate: "guildScheduledEventCreate",
|
|
143
|
+
GuildScheduledEventUpdate: "guildScheduledEventUpdate",
|
|
144
|
+
GuildScheduledEventDelete: "guildScheduledEventDelete",
|
|
145
|
+
ChannelCreate: "channelCreate",
|
|
146
|
+
ChannelUpdate: "channelUpdate",
|
|
147
|
+
ChannelDelete: "channelDelete",
|
|
148
|
+
ChannelPinsUpdate: "channelPinsUpdate",
|
|
149
|
+
InviteCreate: "inviteCreate",
|
|
150
|
+
InviteDelete: "inviteDelete",
|
|
151
|
+
TypingStart: "typingStart",
|
|
152
|
+
UserUpdate: "userUpdate",
|
|
153
|
+
PresenceUpdate: "presenceUpdate",
|
|
154
|
+
VoiceStateUpdate: "voiceStateUpdate",
|
|
155
|
+
VoiceServerUpdate: "voiceServerUpdate",
|
|
156
|
+
VoiceStatesSync: "voiceStatesSync",
|
|
157
|
+
WebhooksUpdate: "webhooksUpdate",
|
|
158
|
+
Resumed: "resumed",
|
|
159
|
+
Error: "error",
|
|
160
|
+
Debug: "debug"
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// src/util/MessageCollector.ts
|
|
166
|
+
var import_events, import_collection, MessageCollector;
|
|
167
|
+
var init_MessageCollector = __esm({
|
|
168
|
+
"src/util/MessageCollector.ts"() {
|
|
169
|
+
"use strict";
|
|
170
|
+
import_events = require("events");
|
|
171
|
+
import_collection = require("@fluxerjs/collection");
|
|
172
|
+
init_Events();
|
|
173
|
+
MessageCollector = class extends import_events.EventEmitter {
|
|
174
|
+
client;
|
|
175
|
+
channelId;
|
|
176
|
+
options;
|
|
177
|
+
collected = new import_collection.Collection();
|
|
178
|
+
_timeout = null;
|
|
179
|
+
_ended = false;
|
|
180
|
+
_listener;
|
|
181
|
+
constructor(client, channelId, options = {}) {
|
|
182
|
+
super();
|
|
183
|
+
this.client = client;
|
|
184
|
+
this.channelId = channelId;
|
|
185
|
+
this.options = {
|
|
186
|
+
filter: options.filter ?? (() => true),
|
|
187
|
+
time: options.time ?? 0,
|
|
188
|
+
max: options.max ?? 0
|
|
189
|
+
};
|
|
190
|
+
this._listener = (message) => {
|
|
191
|
+
if (this._ended || message.channelId !== this.channelId) return;
|
|
192
|
+
if (!this.options.filter(message)) return;
|
|
193
|
+
this.collected.set(message.id, message);
|
|
194
|
+
this.emit("collect", message);
|
|
195
|
+
if (this.options.max > 0 && this.collected.size >= this.options.max) {
|
|
196
|
+
this.stop("limit");
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
this.client.on(Events.MessageCreate, this._listener);
|
|
200
|
+
if (this.options.time > 0) {
|
|
201
|
+
this._timeout = setTimeout(() => this.stop("time"), this.options.time);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
stop(reason = "user") {
|
|
205
|
+
if (this._ended) return;
|
|
206
|
+
this._ended = true;
|
|
207
|
+
this.client.off(Events.MessageCreate, this._listener);
|
|
208
|
+
if (this._timeout) {
|
|
209
|
+
clearTimeout(this._timeout);
|
|
210
|
+
this._timeout = null;
|
|
211
|
+
}
|
|
212
|
+
this.emit("end", this.collected, reason);
|
|
213
|
+
}
|
|
214
|
+
on(event, listener) {
|
|
215
|
+
return super.on(event, listener);
|
|
216
|
+
}
|
|
217
|
+
emit(event, ...args) {
|
|
218
|
+
return super.emit(event, ...args);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
45
224
|
// src/structures/Base.ts
|
|
46
225
|
var Base;
|
|
47
226
|
var init_Base = __esm({
|
|
@@ -52,84 +231,119 @@ var init_Base = __esm({
|
|
|
52
231
|
}
|
|
53
232
|
});
|
|
54
233
|
|
|
55
|
-
// src/
|
|
56
|
-
var
|
|
57
|
-
|
|
58
|
-
|
|
234
|
+
// src/util/Constants.ts
|
|
235
|
+
var CDN_URL;
|
|
236
|
+
var init_Constants = __esm({
|
|
237
|
+
"src/util/Constants.ts"() {
|
|
238
|
+
"use strict";
|
|
239
|
+
CDN_URL = "https://fluxerusercontent.com";
|
|
240
|
+
}
|
|
59
241
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
242
|
+
|
|
243
|
+
// src/util/cdn.ts
|
|
244
|
+
function getExtension(hash, options) {
|
|
245
|
+
const ext = options?.extension ?? "png";
|
|
246
|
+
if (hash?.startsWith("a_")) return "gif";
|
|
247
|
+
return ext;
|
|
248
|
+
}
|
|
249
|
+
function appendSize(options) {
|
|
250
|
+
return options?.size ? `?size=${options.size}` : "";
|
|
251
|
+
}
|
|
252
|
+
function cdnAvatarURL(userId, avatarHash, options) {
|
|
253
|
+
if (!avatarHash) return null;
|
|
254
|
+
const ext = getExtension(avatarHash, options);
|
|
255
|
+
const size = appendSize(options);
|
|
256
|
+
return `${CDN_URL}/avatars/${userId}/${avatarHash}.${ext}${size}`;
|
|
257
|
+
}
|
|
258
|
+
function cdnDisplayAvatarURL(userId, avatarHash, options) {
|
|
259
|
+
return cdnAvatarURL(userId, avatarHash, options) ?? `${CDN_URL}/avatars/0/0.png`;
|
|
260
|
+
}
|
|
261
|
+
function cdnBannerURL(resourceId, bannerHash, options) {
|
|
262
|
+
if (!bannerHash) return null;
|
|
263
|
+
const ext = getExtension(bannerHash, options);
|
|
264
|
+
const size = appendSize(options);
|
|
265
|
+
return `${CDN_URL}/banners/${resourceId}/${bannerHash}.${ext}${size}`;
|
|
266
|
+
}
|
|
267
|
+
function cdnMemberAvatarURL(guildId, userId, avatarHash, options) {
|
|
268
|
+
if (!avatarHash) return null;
|
|
269
|
+
const ext = getExtension(avatarHash, options);
|
|
270
|
+
const size = appendSize(options);
|
|
271
|
+
return `${CDN_URL}/guilds/${guildId}/users/${userId}/avatars/${avatarHash}.${ext}${size}`;
|
|
272
|
+
}
|
|
273
|
+
function cdnMemberBannerURL(guildId, userId, bannerHash, options) {
|
|
274
|
+
if (!bannerHash) return null;
|
|
275
|
+
const ext = getExtension(bannerHash, options);
|
|
276
|
+
const size = appendSize(options);
|
|
277
|
+
return `${CDN_URL}/guilds/${guildId}/users/${userId}/banners/${bannerHash}.${ext}${size}`;
|
|
278
|
+
}
|
|
279
|
+
function cdnDefaultAvatarURL(discriminatorIndex) {
|
|
280
|
+
const index = discriminatorIndex != null ? discriminatorIndex % 5 : 0;
|
|
281
|
+
return `${CDN_URL}/avatars/0/${index}.png`;
|
|
282
|
+
}
|
|
283
|
+
var init_cdn = __esm({
|
|
284
|
+
"src/util/cdn.ts"() {
|
|
63
285
|
"use strict";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
286
|
+
init_Constants();
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// src/util/ReactionCollector.ts
|
|
291
|
+
var import_events2, import_collection2, ReactionCollector;
|
|
292
|
+
var init_ReactionCollector = __esm({
|
|
293
|
+
"src/util/ReactionCollector.ts"() {
|
|
294
|
+
"use strict";
|
|
295
|
+
import_events2 = require("events");
|
|
296
|
+
import_collection2 = require("@fluxerjs/collection");
|
|
297
|
+
init_Events();
|
|
298
|
+
ReactionCollector = class extends import_events2.EventEmitter {
|
|
67
299
|
client;
|
|
68
|
-
|
|
69
|
-
guildId;
|
|
300
|
+
messageId;
|
|
70
301
|
channelId;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
constructor(client,
|
|
302
|
+
options;
|
|
303
|
+
collected = new import_collection2.Collection();
|
|
304
|
+
_timeout = null;
|
|
305
|
+
_ended = false;
|
|
306
|
+
_listener;
|
|
307
|
+
constructor(client, messageId, channelId, options = {}) {
|
|
77
308
|
super();
|
|
78
309
|
this.client = client;
|
|
79
|
-
this.
|
|
80
|
-
this.
|
|
81
|
-
this.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
310
|
+
this.messageId = messageId;
|
|
311
|
+
this.channelId = channelId;
|
|
312
|
+
this.options = {
|
|
313
|
+
filter: options.filter ?? (() => true),
|
|
314
|
+
time: options.time ?? 0,
|
|
315
|
+
max: options.max ?? 0
|
|
316
|
+
};
|
|
317
|
+
this._listener = (reaction, user, _msgId, chId, _emoji, userId) => {
|
|
318
|
+
if (this._ended || reaction.messageId !== this.messageId || chId !== this.channelId) return;
|
|
319
|
+
if (!this.options.filter(reaction, user)) return;
|
|
320
|
+
const key = `${userId}:${reaction.emoji.id ?? reaction.emoji.name}`;
|
|
321
|
+
this.collected.set(key, { reaction, user });
|
|
322
|
+
this.emit("collect", reaction, user);
|
|
323
|
+
if (this.options.max > 0 && this.collected.size >= this.options.max) {
|
|
324
|
+
this.stop("limit");
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
this.client.on(Events.MessageReactionAdd, this._listener);
|
|
328
|
+
if (this.options.time > 0) {
|
|
329
|
+
this._timeout = setTimeout(() => this.stop("time"), this.options.time);
|
|
330
|
+
}
|
|
89
331
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
"Webhook token is required to send. The token is only returned when creating a webhook; fetched webhooks cannot send."
|
|
98
|
-
);
|
|
332
|
+
stop(reason = "user") {
|
|
333
|
+
if (this._ended) return;
|
|
334
|
+
this._ended = true;
|
|
335
|
+
this.client.off(Events.MessageReactionAdd, this._listener);
|
|
336
|
+
if (this._timeout) {
|
|
337
|
+
clearTimeout(this._timeout);
|
|
338
|
+
this._timeout = null;
|
|
99
339
|
}
|
|
100
|
-
|
|
101
|
-
await this.client.rest.post(import_types.Routes.webhookExecute(this.id, this.token), {
|
|
102
|
-
body,
|
|
103
|
-
auth: false
|
|
104
|
-
});
|
|
340
|
+
this.emit("end", this.collected, reason);
|
|
105
341
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
* @param client - The client instance
|
|
109
|
-
* @param webhookId - The webhook ID
|
|
110
|
-
* @returns Webhook without token (cannot send)
|
|
111
|
-
*/
|
|
112
|
-
static async fetch(client, webhookId) {
|
|
113
|
-
const data = await client.rest.get(import_types.Routes.webhook(webhookId));
|
|
114
|
-
return new _Webhook(client, data);
|
|
342
|
+
on(event, listener) {
|
|
343
|
+
return super.on(event, listener);
|
|
115
344
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
* @param client - The client instance
|
|
119
|
-
* @param webhookId - The webhook ID
|
|
120
|
-
* @param token - The webhook token (from createWebhook or stored)
|
|
121
|
-
* @param options - Optional channelId, guildId, name for display
|
|
122
|
-
*/
|
|
123
|
-
static fromToken(client, webhookId, token, options) {
|
|
124
|
-
return new _Webhook(client, {
|
|
125
|
-
id: webhookId,
|
|
126
|
-
guild_id: options?.guildId ?? "",
|
|
127
|
-
channel_id: options?.channelId ?? "",
|
|
128
|
-
name: options?.name ?? "Webhook",
|
|
129
|
-
avatar: null,
|
|
130
|
-
token,
|
|
131
|
-
user: { id: "", username: "webhook", discriminator: "0" }
|
|
132
|
-
});
|
|
345
|
+
emit(event, ...args) {
|
|
346
|
+
return super.emit(event, ...args);
|
|
133
347
|
}
|
|
134
348
|
};
|
|
135
349
|
}
|
|
@@ -140,14 +354,16 @@ var Message_exports = {};
|
|
|
140
354
|
__export(Message_exports, {
|
|
141
355
|
Message: () => Message
|
|
142
356
|
});
|
|
143
|
-
var
|
|
357
|
+
var import_collection3, import_types, import_builders2, Message;
|
|
144
358
|
var init_Message = __esm({
|
|
145
359
|
"src/structures/Message.ts"() {
|
|
146
360
|
"use strict";
|
|
147
361
|
init_Base();
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
362
|
+
import_collection3 = require("@fluxerjs/collection");
|
|
363
|
+
import_types = require("@fluxerjs/types");
|
|
364
|
+
import_builders2 = require("@fluxerjs/builders");
|
|
365
|
+
init_messageUtils();
|
|
366
|
+
init_ReactionCollector();
|
|
151
367
|
Message = class _Message extends Base {
|
|
152
368
|
client;
|
|
153
369
|
id;
|
|
@@ -159,6 +375,25 @@ var init_Message = __esm({
|
|
|
159
375
|
editedAt;
|
|
160
376
|
pinned;
|
|
161
377
|
attachments;
|
|
378
|
+
type;
|
|
379
|
+
flags;
|
|
380
|
+
mentionEveryone;
|
|
381
|
+
tts;
|
|
382
|
+
embeds;
|
|
383
|
+
stickers;
|
|
384
|
+
reactions;
|
|
385
|
+
messageReference;
|
|
386
|
+
messageSnapshots;
|
|
387
|
+
call;
|
|
388
|
+
referencedMessage;
|
|
389
|
+
/** Webhook ID if this message was sent via webhook. Null otherwise. */
|
|
390
|
+
webhookId;
|
|
391
|
+
/** Users mentioned in this message. */
|
|
392
|
+
mentions;
|
|
393
|
+
/** Role IDs mentioned in this message. */
|
|
394
|
+
mentionRoles;
|
|
395
|
+
/** Client-side nonce for acknowledgment. Null if not provided. */
|
|
396
|
+
nonce;
|
|
162
397
|
/** Channel where this message was sent. Resolved from cache; null if not cached (e.g. DM channel not in cache). */
|
|
163
398
|
get channel() {
|
|
164
399
|
return this.client.channels.get(this.channelId) ?? null;
|
|
@@ -179,19 +414,37 @@ var init_Message = __esm({
|
|
|
179
414
|
this.createdAt = new Date(data.timestamp);
|
|
180
415
|
this.editedAt = data.edited_timestamp ? new Date(data.edited_timestamp) : null;
|
|
181
416
|
this.pinned = data.pinned;
|
|
182
|
-
this.attachments = new
|
|
417
|
+
this.attachments = new import_collection3.Collection();
|
|
183
418
|
for (const a of data.attachments ?? []) this.attachments.set(a.id, a);
|
|
419
|
+
this.type = data.type ?? import_types.MessageType.Default;
|
|
420
|
+
this.flags = data.flags ?? 0;
|
|
421
|
+
this.mentionEveryone = data.mention_everyone ?? false;
|
|
422
|
+
this.tts = data.tts ?? false;
|
|
423
|
+
this.embeds = data.embeds ?? [];
|
|
424
|
+
this.stickers = data.stickers ?? [];
|
|
425
|
+
this.reactions = data.reactions ?? [];
|
|
426
|
+
this.messageReference = data.message_reference ?? null;
|
|
427
|
+
this.messageSnapshots = data.message_snapshots ?? [];
|
|
428
|
+
this.call = data.call ?? null;
|
|
429
|
+
this.referencedMessage = data.referenced_message ? new _Message(client, data.referenced_message) : null;
|
|
430
|
+
this.webhookId = data.webhook_id ?? null;
|
|
431
|
+
this.mentions = (data.mentions ?? []).map((u) => client.getOrCreateUser(u));
|
|
432
|
+
this.mentionRoles = data.mention_roles ?? [];
|
|
433
|
+
this.nonce = data.nonce ?? null;
|
|
184
434
|
}
|
|
185
435
|
/**
|
|
186
436
|
* Send a message to this channel without replying. Use when you want a standalone message.
|
|
187
|
-
* @param options - Text content or object with content and/or
|
|
437
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
188
438
|
* @example
|
|
189
439
|
* await message.send('Pong!');
|
|
190
440
|
* await message.send({ embeds: [embed.toJSON()] });
|
|
441
|
+
* await message.send({ content: 'File', files: [{ name: 'data.txt', data }] });
|
|
191
442
|
*/
|
|
192
443
|
async send(options) {
|
|
193
|
-
const
|
|
194
|
-
const
|
|
444
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
445
|
+
const body = buildSendBody(options);
|
|
446
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
447
|
+
const data = await this.client.rest.post(import_types.Routes.channelMessages(this.channelId), postOptions);
|
|
195
448
|
return new _Message(this.client, data);
|
|
196
449
|
}
|
|
197
450
|
/**
|
|
@@ -207,25 +460,21 @@ var init_Message = __esm({
|
|
|
207
460
|
}
|
|
208
461
|
/**
|
|
209
462
|
* Reply to this message.
|
|
210
|
-
* @param options - Text content or object with content and/or
|
|
463
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
211
464
|
*/
|
|
212
465
|
async reply(options) {
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
message_id: this.id,
|
|
218
|
-
guild_id: this.guildId ?? void 0
|
|
219
|
-
}
|
|
220
|
-
} : {
|
|
221
|
-
...options,
|
|
466
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
467
|
+
const base = buildSendBody(options);
|
|
468
|
+
const body = {
|
|
469
|
+
...base,
|
|
222
470
|
message_reference: {
|
|
223
471
|
channel_id: this.channelId,
|
|
224
472
|
message_id: this.id,
|
|
225
473
|
guild_id: this.guildId ?? void 0
|
|
226
474
|
}
|
|
227
475
|
};
|
|
228
|
-
const
|
|
476
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
477
|
+
const data = await this.client.rest.post(import_types.Routes.channelMessages(this.channelId), postOptions);
|
|
229
478
|
return new _Message(this.client, data);
|
|
230
479
|
}
|
|
231
480
|
/**
|
|
@@ -236,27 +485,50 @@ var init_Message = __esm({
|
|
|
236
485
|
const body = {};
|
|
237
486
|
if (options.content !== void 0) body.content = options.content;
|
|
238
487
|
if (options.embeds?.length) {
|
|
239
|
-
body.embeds = options.embeds.map((e) => e instanceof
|
|
488
|
+
body.embeds = options.embeds.map((e) => e instanceof import_builders2.EmbedBuilder ? e.toJSON() : e);
|
|
240
489
|
}
|
|
241
|
-
const data = await this.client.rest.patch(
|
|
490
|
+
const data = await this.client.rest.patch(import_types.Routes.channelMessage(this.channelId, this.id), {
|
|
242
491
|
body
|
|
243
492
|
});
|
|
244
493
|
return new _Message(this.client, data);
|
|
245
494
|
}
|
|
495
|
+
/**
|
|
496
|
+
* Create a reaction collector for this message.
|
|
497
|
+
* Collects reactions matching the filter until time expires or max is reached.
|
|
498
|
+
* @param options - Filter, time (ms), and max count
|
|
499
|
+
* @example
|
|
500
|
+
* const collector = message.createReactionCollector({ filter: (r, u) => u.id === userId, time: 10000 });
|
|
501
|
+
* collector.on('collect', (reaction, user) => console.log(user.username, 'reacted with', reaction.emoji.name));
|
|
502
|
+
* collector.on('end', (collected, reason) => { ... });
|
|
503
|
+
*/
|
|
504
|
+
createReactionCollector(options) {
|
|
505
|
+
return new ReactionCollector(this.client, this.id, this.channelId, options);
|
|
506
|
+
}
|
|
246
507
|
/**
|
|
247
508
|
* Re-fetch this message from the API to get the latest content, embeds, reactions, etc.
|
|
248
509
|
* Use when you have a stale Message (e.g. from an old event or cache) and need fresh data.
|
|
249
|
-
* @returns The updated message
|
|
510
|
+
* @returns The updated message
|
|
511
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message was deleted or does not exist
|
|
250
512
|
* @example
|
|
251
513
|
* const updated = await message.fetch();
|
|
252
|
-
*
|
|
514
|
+
* console.log('Latest content:', updated.content);
|
|
253
515
|
*/
|
|
254
516
|
async fetch() {
|
|
255
517
|
return this.client.channels.fetchMessage(this.channelId, this.id);
|
|
256
518
|
}
|
|
257
519
|
/** Delete this message. */
|
|
258
520
|
async delete() {
|
|
259
|
-
await this.client.rest.delete(
|
|
521
|
+
await this.client.rest.delete(import_types.Routes.channelMessage(this.channelId, this.id));
|
|
522
|
+
}
|
|
523
|
+
/** Pin this message to the channel. Requires Manage Messages permission. */
|
|
524
|
+
async pin() {
|
|
525
|
+
await this.client.rest.put(import_types.Routes.channelPinMessage(this.channelId, this.id));
|
|
526
|
+
this.pinned = true;
|
|
527
|
+
}
|
|
528
|
+
/** Unpin this message from the channel. Requires Manage Messages permission. */
|
|
529
|
+
async unpin() {
|
|
530
|
+
await this.client.rest.delete(import_types.Routes.channelPinMessage(this.channelId, this.id));
|
|
531
|
+
this.pinned = false;
|
|
260
532
|
}
|
|
261
533
|
/**
|
|
262
534
|
* Format emoji for reaction API: unicode string or "name:id" for custom.
|
|
@@ -275,7 +547,7 @@ var init_Message = __esm({
|
|
|
275
547
|
*/
|
|
276
548
|
async react(emoji) {
|
|
277
549
|
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
278
|
-
const route = `${
|
|
550
|
+
const route = `${import_types.Routes.channelMessageReaction(this.channelId, this.id, emojiStr)}/@me`;
|
|
279
551
|
await this.client.rest.put(route);
|
|
280
552
|
}
|
|
281
553
|
/**
|
|
@@ -285,7 +557,7 @@ var init_Message = __esm({
|
|
|
285
557
|
*/
|
|
286
558
|
async removeReaction(emoji, userId) {
|
|
287
559
|
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
288
|
-
const route = `${
|
|
560
|
+
const route = `${import_types.Routes.channelMessageReaction(this.channelId, this.id, emojiStr)}/${userId ?? "@me"}`;
|
|
289
561
|
await this.client.rest.delete(route);
|
|
290
562
|
}
|
|
291
563
|
/**
|
|
@@ -293,7 +565,7 @@ var init_Message = __esm({
|
|
|
293
565
|
* Requires moderator permissions.
|
|
294
566
|
*/
|
|
295
567
|
async removeAllReactions() {
|
|
296
|
-
await this.client.rest.delete(
|
|
568
|
+
await this.client.rest.delete(import_types.Routes.channelMessageReactions(this.channelId, this.id));
|
|
297
569
|
}
|
|
298
570
|
/**
|
|
299
571
|
* Remove all reactions of a specific emoji from this message.
|
|
@@ -301,7 +573,235 @@ var init_Message = __esm({
|
|
|
301
573
|
*/
|
|
302
574
|
async removeReactionEmoji(emoji) {
|
|
303
575
|
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
304
|
-
await this.client.rest.delete(
|
|
576
|
+
await this.client.rest.delete(import_types.Routes.channelMessageReaction(this.channelId, this.id, emojiStr));
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Fetch users who reacted with the given emoji.
|
|
580
|
+
* @param emoji - Unicode emoji or custom `{ name, id }`
|
|
581
|
+
* @param options - limit (1–100), after (user ID for pagination)
|
|
582
|
+
* @returns Array of User objects
|
|
583
|
+
*/
|
|
584
|
+
async fetchReactionUsers(emoji, options) {
|
|
585
|
+
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
586
|
+
const params = new URLSearchParams();
|
|
587
|
+
if (options?.limit != null) params.set("limit", String(options.limit));
|
|
588
|
+
if (options?.after) params.set("after", options.after);
|
|
589
|
+
const qs = params.toString();
|
|
590
|
+
const route = import_types.Routes.channelMessageReaction(this.channelId, this.id, emojiStr) + (qs ? `?${qs}` : "");
|
|
591
|
+
const data = await this.client.rest.get(route);
|
|
592
|
+
const list = Array.isArray(data) ? data : data?.users ?? [];
|
|
593
|
+
return list.map((u) => this.client.getOrCreateUser(u));
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// src/structures/Webhook.ts
|
|
600
|
+
var Webhook_exports = {};
|
|
601
|
+
__export(Webhook_exports, {
|
|
602
|
+
Webhook: () => Webhook
|
|
603
|
+
});
|
|
604
|
+
var import_types2, Webhook;
|
|
605
|
+
var init_Webhook = __esm({
|
|
606
|
+
"src/structures/Webhook.ts"() {
|
|
607
|
+
"use strict";
|
|
608
|
+
init_Base();
|
|
609
|
+
import_types2 = require("@fluxerjs/types");
|
|
610
|
+
init_messageUtils();
|
|
611
|
+
init_cdn();
|
|
612
|
+
Webhook = class _Webhook extends Base {
|
|
613
|
+
client;
|
|
614
|
+
id;
|
|
615
|
+
guildId;
|
|
616
|
+
channelId;
|
|
617
|
+
name;
|
|
618
|
+
avatar;
|
|
619
|
+
/** Present only when webhook was created via createWebhook(); not returned when fetching. */
|
|
620
|
+
token;
|
|
621
|
+
/** User who created the webhook. */
|
|
622
|
+
user;
|
|
623
|
+
/** @param data - API webhook from POST /channels/{id}/webhooks (has token) or GET /webhooks/{id} (no token) */
|
|
624
|
+
constructor(client, data) {
|
|
625
|
+
super();
|
|
626
|
+
this.client = client;
|
|
627
|
+
this.id = data.id;
|
|
628
|
+
this.guildId = data.guild_id;
|
|
629
|
+
this.channelId = data.channel_id;
|
|
630
|
+
this.name = data.name ?? "Unknown";
|
|
631
|
+
this.avatar = data.avatar ?? null;
|
|
632
|
+
this.token = data.token ?? null;
|
|
633
|
+
this.user = client.getOrCreateUser(data.user);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Get the URL for this webhook's avatar.
|
|
637
|
+
* Returns null if the webhook has no custom avatar.
|
|
638
|
+
*/
|
|
639
|
+
avatarURL(options) {
|
|
640
|
+
return cdnAvatarURL(this.id, this.avatar, options);
|
|
641
|
+
}
|
|
642
|
+
/** Delete this webhook. Requires bot token with Manage Webhooks permission. */
|
|
643
|
+
async delete() {
|
|
644
|
+
await this.client.rest.delete(import_types2.Routes.webhook(this.id), { auth: true });
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Edit this webhook. With token: name and avatar only. Without token (bot auth): name, avatar, and channel_id.
|
|
648
|
+
* @param options - Fields to update (name, avatar, channel_id when using bot auth)
|
|
649
|
+
* @returns This webhook instance with updated fields
|
|
650
|
+
*/
|
|
651
|
+
async edit(options) {
|
|
652
|
+
const body = {};
|
|
653
|
+
if (options.name !== void 0) body.name = options.name;
|
|
654
|
+
if (options.avatar !== void 0) body.avatar = options.avatar;
|
|
655
|
+
if ("channel_id" in options && options.channel_id !== void 0 && !this.token) {
|
|
656
|
+
body.channel_id = options.channel_id;
|
|
657
|
+
}
|
|
658
|
+
if (this.token) {
|
|
659
|
+
const data2 = await this.client.rest.patch(import_types2.Routes.webhookExecute(this.id, this.token), {
|
|
660
|
+
body,
|
|
661
|
+
auth: false
|
|
662
|
+
});
|
|
663
|
+
const w2 = data2;
|
|
664
|
+
this.name = w2.name ?? this.name;
|
|
665
|
+
this.avatar = w2.avatar ?? null;
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
668
|
+
const data = await this.client.rest.patch(import_types2.Routes.webhook(this.id), {
|
|
669
|
+
body,
|
|
670
|
+
auth: true
|
|
671
|
+
});
|
|
672
|
+
const w = data;
|
|
673
|
+
this.name = w.name ?? this.name;
|
|
674
|
+
this.avatar = w.avatar ?? null;
|
|
675
|
+
this.channelId = w.channel_id ?? this.channelId;
|
|
676
|
+
return this;
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Send a message via this webhook. Requires the webhook token (only present when created, not when fetched).
|
|
680
|
+
* @param options - Text content or object with content, embeds, username, avatar_url, tts, files, attachments
|
|
681
|
+
* @param wait - If true, waits for the API and returns the created Message; otherwise returns void (204)
|
|
682
|
+
* @throws Error if token is not available
|
|
683
|
+
* @example
|
|
684
|
+
* await webhook.send('Hello!');
|
|
685
|
+
* await webhook.send({ embeds: [embed.toJSON()] });
|
|
686
|
+
* await webhook.send({ content: 'File attached', files: [{ name: 'data.txt', data: buffer }] });
|
|
687
|
+
* const msg = await webhook.send({ content: 'Hi' }, true);
|
|
688
|
+
*/
|
|
689
|
+
async send(options, wait) {
|
|
690
|
+
if (!this.token) {
|
|
691
|
+
throw new Error(
|
|
692
|
+
"Webhook token is required to send. The token is only returned when creating a webhook; fetched webhooks cannot send."
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
696
|
+
const body = buildSendBody(options);
|
|
697
|
+
if (opts.username !== void 0) body.username = opts.username;
|
|
698
|
+
if (opts.avatar_url !== void 0) body.avatar_url = opts.avatar_url;
|
|
699
|
+
if (opts.tts !== void 0) body.tts = opts.tts;
|
|
700
|
+
const route = import_types2.Routes.webhookExecute(this.id, this.token) + (wait ? "?wait=true" : "");
|
|
701
|
+
const postOptions = opts.files?.length ? { body, files: opts.files, auth: false } : { body, auth: false };
|
|
702
|
+
const data = await this.client.rest.post(
|
|
703
|
+
route,
|
|
704
|
+
postOptions
|
|
705
|
+
);
|
|
706
|
+
if (wait && data) {
|
|
707
|
+
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
708
|
+
return new Message2(this.client, data);
|
|
709
|
+
}
|
|
710
|
+
return void 0;
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Fetch a webhook by ID using bot auth.
|
|
714
|
+
* @param client - The client instance
|
|
715
|
+
* @param webhookId - The webhook ID
|
|
716
|
+
* @returns Webhook without token (cannot send)
|
|
717
|
+
*/
|
|
718
|
+
static async fetch(client, webhookId) {
|
|
719
|
+
const data = await client.rest.get(import_types2.Routes.webhook(webhookId));
|
|
720
|
+
return new _Webhook(client, data);
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Create a Webhook instance from an ID and token (e.g. from a stored webhook URL).
|
|
724
|
+
* @param client - The client instance
|
|
725
|
+
* @param webhookId - The webhook ID
|
|
726
|
+
* @param token - The webhook token (from createWebhook or stored)
|
|
727
|
+
* @param options - Optional channelId, guildId, name for display
|
|
728
|
+
*/
|
|
729
|
+
static fromToken(client, webhookId, token, options) {
|
|
730
|
+
return new _Webhook(client, {
|
|
731
|
+
id: webhookId,
|
|
732
|
+
guild_id: options?.guildId ?? "",
|
|
733
|
+
channel_id: options?.channelId ?? "",
|
|
734
|
+
name: options?.name ?? "Webhook",
|
|
735
|
+
avatar: null,
|
|
736
|
+
token,
|
|
737
|
+
user: { id: "", username: "webhook", discriminator: "0" }
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
// src/structures/Invite.ts
|
|
745
|
+
var Invite_exports = {};
|
|
746
|
+
__export(Invite_exports, {
|
|
747
|
+
Invite: () => Invite
|
|
748
|
+
});
|
|
749
|
+
var import_types3, Invite;
|
|
750
|
+
var init_Invite = __esm({
|
|
751
|
+
"src/structures/Invite.ts"() {
|
|
752
|
+
"use strict";
|
|
753
|
+
init_Base();
|
|
754
|
+
import_types3 = require("@fluxerjs/types");
|
|
755
|
+
Invite = class extends Base {
|
|
756
|
+
client;
|
|
757
|
+
code;
|
|
758
|
+
type;
|
|
759
|
+
guild;
|
|
760
|
+
channel;
|
|
761
|
+
inviter;
|
|
762
|
+
memberCount;
|
|
763
|
+
presenceCount;
|
|
764
|
+
expiresAt;
|
|
765
|
+
temporary;
|
|
766
|
+
createdAt;
|
|
767
|
+
uses;
|
|
768
|
+
maxUses;
|
|
769
|
+
maxAge;
|
|
770
|
+
/** @param data - API invite from GET /invites/{code}, channel/guild invite list, or gateway INVITE_CREATE */
|
|
771
|
+
constructor(client, data) {
|
|
772
|
+
super();
|
|
773
|
+
this.client = client;
|
|
774
|
+
this.code = data.code;
|
|
775
|
+
this.type = data.type;
|
|
776
|
+
this.guild = data.guild;
|
|
777
|
+
this.channel = data.channel;
|
|
778
|
+
this.inviter = data.inviter ? client.getOrCreateUser(data.inviter) : null;
|
|
779
|
+
this.memberCount = data.member_count ?? null;
|
|
780
|
+
this.presenceCount = data.presence_count ?? null;
|
|
781
|
+
this.expiresAt = data.expires_at ?? null;
|
|
782
|
+
this.temporary = data.temporary ?? null;
|
|
783
|
+
this.createdAt = data.created_at ?? null;
|
|
784
|
+
this.uses = data.uses ?? null;
|
|
785
|
+
this.maxUses = data.max_uses ?? null;
|
|
786
|
+
this.maxAge = data.max_age ?? null;
|
|
787
|
+
}
|
|
788
|
+
/** Full invite URL (https://fluxer.gg/{code} or instance-specific). */
|
|
789
|
+
get url() {
|
|
790
|
+
return `https://fluxer.gg/${this.code}`;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Resolve the guild from cache if available.
|
|
794
|
+
* @returns The guild, or null if not cached
|
|
795
|
+
*/
|
|
796
|
+
getGuild() {
|
|
797
|
+
return this.guild?.id ? this.client.guilds.get(this.guild.id) ?? null : null;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Delete this invite.
|
|
801
|
+
* Requires Manage Guild or Create Instant Invite permission.
|
|
802
|
+
*/
|
|
803
|
+
async delete() {
|
|
804
|
+
await this.client.rest.delete(import_types3.Routes.invite(this.code), { auth: true });
|
|
305
805
|
}
|
|
306
806
|
};
|
|
307
807
|
}
|
|
@@ -318,13 +818,16 @@ __export(Channel_exports, {
|
|
|
318
818
|
TextChannel: () => TextChannel,
|
|
319
819
|
VoiceChannel: () => VoiceChannel
|
|
320
820
|
});
|
|
321
|
-
var
|
|
821
|
+
var import_types4, import_util, Channel, GuildChannel, TextChannel, CategoryChannel, VoiceChannel, LinkChannel, DMChannel;
|
|
322
822
|
var init_Channel = __esm({
|
|
323
823
|
"src/structures/Channel.ts"() {
|
|
324
824
|
"use strict";
|
|
325
825
|
init_MessageManager();
|
|
826
|
+
init_MessageCollector();
|
|
326
827
|
init_Base();
|
|
327
|
-
|
|
828
|
+
init_messageUtils();
|
|
829
|
+
import_types4 = require("@fluxerjs/types");
|
|
830
|
+
import_util = require("@fluxerjs/util");
|
|
328
831
|
Channel = class _Channel extends Base {
|
|
329
832
|
/** Whether this channel has a send method (TextChannel, DMChannel). */
|
|
330
833
|
isSendable() {
|
|
@@ -332,7 +835,7 @@ var init_Channel = __esm({
|
|
|
332
835
|
}
|
|
333
836
|
/** Whether this channel is a DM or Group DM. */
|
|
334
837
|
isDM() {
|
|
335
|
-
return this.type ===
|
|
838
|
+
return this.type === import_types4.ChannelType.DM || this.type === import_types4.ChannelType.GroupDM;
|
|
336
839
|
}
|
|
337
840
|
/** Whether this channel is voice-based (VoiceChannel). */
|
|
338
841
|
isVoice() {
|
|
@@ -345,12 +848,21 @@ var init_Channel = __esm({
|
|
|
345
848
|
client;
|
|
346
849
|
id;
|
|
347
850
|
type;
|
|
851
|
+
/** Channel name. Guild channels and Group DMs have names; 1:1 DMs are typically null. */
|
|
852
|
+
name;
|
|
853
|
+
/** Channel icon hash (Group DMs). Null if none. */
|
|
854
|
+
icon;
|
|
855
|
+
/** ISO timestamp when the last message was pinned. Null if never pinned. */
|
|
856
|
+
lastPinTimestamp;
|
|
348
857
|
/** @param data - API channel from GET /channels/{id} or GET /guilds/{id}/channels */
|
|
349
858
|
constructor(client, data) {
|
|
350
859
|
super();
|
|
351
860
|
this.client = client;
|
|
352
861
|
this.id = data.id;
|
|
353
862
|
this.type = data.type;
|
|
863
|
+
this.name = data.name ?? null;
|
|
864
|
+
this.icon = data.icon ?? null;
|
|
865
|
+
this.lastPinTimestamp = data.last_pin_timestamp ?? null;
|
|
354
866
|
}
|
|
355
867
|
/**
|
|
356
868
|
* Create the appropriate channel subclass from API data.
|
|
@@ -359,10 +871,10 @@ var init_Channel = __esm({
|
|
|
359
871
|
*/
|
|
360
872
|
static from(client, data) {
|
|
361
873
|
const type = data.type ?? 0;
|
|
362
|
-
if (type ===
|
|
363
|
-
if (type ===
|
|
364
|
-
if (type ===
|
|
365
|
-
if (type ===
|
|
874
|
+
if (type === import_types4.ChannelType.GuildText) return new TextChannel(client, data);
|
|
875
|
+
if (type === import_types4.ChannelType.GuildCategory) return new CategoryChannel(client, data);
|
|
876
|
+
if (type === import_types4.ChannelType.GuildVoice) return new VoiceChannel(client, data);
|
|
877
|
+
if (type === import_types4.ChannelType.GuildLink || type === import_types4.ChannelType.GuildLinkExtended)
|
|
366
878
|
return new LinkChannel(client, data);
|
|
367
879
|
return new GuildChannel(client, data);
|
|
368
880
|
}
|
|
@@ -372,22 +884,41 @@ var init_Channel = __esm({
|
|
|
372
884
|
*/
|
|
373
885
|
static fromOrCreate(client, data) {
|
|
374
886
|
const type = data.type ?? 0;
|
|
375
|
-
if (type ===
|
|
887
|
+
if (type === import_types4.ChannelType.DM || type === import_types4.ChannelType.GroupDM)
|
|
376
888
|
return _Channel.createDM(client, data);
|
|
377
889
|
return _Channel.from(client, data);
|
|
378
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Bulk delete messages. Requires Manage Messages permission.
|
|
893
|
+
* @param messageIds - Array of message IDs to delete (2–100)
|
|
894
|
+
*/
|
|
895
|
+
async bulkDeleteMessages(messageIds) {
|
|
896
|
+
await this.client.rest.post(import_types4.Routes.channelBulkDelete(this.id), {
|
|
897
|
+
body: { message_ids: messageIds },
|
|
898
|
+
auth: true
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Send a typing indicator to the channel. Lasts ~10 seconds.
|
|
903
|
+
*/
|
|
904
|
+
async sendTyping() {
|
|
905
|
+
await this.client.rest.post(import_types4.Routes.channelTyping(this.id), { auth: true });
|
|
906
|
+
}
|
|
379
907
|
};
|
|
380
908
|
GuildChannel = class extends Channel {
|
|
381
909
|
guildId;
|
|
382
910
|
name;
|
|
383
911
|
position;
|
|
384
912
|
parentId;
|
|
913
|
+
/** Permission overwrites for roles and members. */
|
|
914
|
+
permissionOverwrites;
|
|
385
915
|
constructor(client, data) {
|
|
386
916
|
super(client, data);
|
|
387
917
|
this.guildId = data.guild_id ?? "";
|
|
388
918
|
this.name = data.name ?? null;
|
|
389
919
|
this.position = data.position;
|
|
390
920
|
this.parentId = data.parent_id ?? null;
|
|
921
|
+
this.permissionOverwrites = data.permission_overwrites ?? [];
|
|
391
922
|
}
|
|
392
923
|
/**
|
|
393
924
|
* Create a webhook in this channel.
|
|
@@ -396,7 +927,7 @@ var init_Channel = __esm({
|
|
|
396
927
|
*/
|
|
397
928
|
async createWebhook(options) {
|
|
398
929
|
const { Webhook: Webhook2 } = await Promise.resolve().then(() => (init_Webhook(), Webhook_exports));
|
|
399
|
-
const data = await this.client.rest.post(
|
|
930
|
+
const data = await this.client.rest.post(import_types4.Routes.channelWebhooks(this.id), {
|
|
400
931
|
body: options,
|
|
401
932
|
auth: true
|
|
402
933
|
});
|
|
@@ -408,10 +939,38 @@ var init_Channel = __esm({
|
|
|
408
939
|
*/
|
|
409
940
|
async fetchWebhooks() {
|
|
410
941
|
const { Webhook: Webhook2 } = await Promise.resolve().then(() => (init_Webhook(), Webhook_exports));
|
|
411
|
-
const data = await this.client.rest.get(
|
|
942
|
+
const data = await this.client.rest.get(import_types4.Routes.channelWebhooks(this.id));
|
|
412
943
|
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
413
944
|
return list.map((w) => new Webhook2(this.client, w));
|
|
414
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* Create an invite for this channel.
|
|
948
|
+
* @param options - max_uses (0–100), max_age (0–604800 seconds), unique, temporary
|
|
949
|
+
* Requires Create Instant Invite permission.
|
|
950
|
+
*/
|
|
951
|
+
async createInvite(options) {
|
|
952
|
+
const { Invite: Invite2 } = await Promise.resolve().then(() => (init_Invite(), Invite_exports));
|
|
953
|
+
const body = {};
|
|
954
|
+
if (options?.max_uses != null) body.max_uses = options.max_uses;
|
|
955
|
+
if (options?.max_age != null) body.max_age = options.max_age;
|
|
956
|
+
if (options?.unique != null) body.unique = options.unique;
|
|
957
|
+
if (options?.temporary != null) body.temporary = options.temporary;
|
|
958
|
+
const data = await this.client.rest.post(import_types4.Routes.channelInvites(this.id), {
|
|
959
|
+
body: Object.keys(body).length ? body : void 0,
|
|
960
|
+
auth: true
|
|
961
|
+
});
|
|
962
|
+
return new Invite2(this.client, data);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Fetch invites for this channel.
|
|
966
|
+
* Requires Manage Channel permission.
|
|
967
|
+
*/
|
|
968
|
+
async fetchInvites() {
|
|
969
|
+
const { Invite: Invite2 } = await Promise.resolve().then(() => (init_Invite(), Invite_exports));
|
|
970
|
+
const data = await this.client.rest.get(import_types4.Routes.channelInvites(this.id));
|
|
971
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
972
|
+
return list.map((i) => new Invite2(this.client, i));
|
|
973
|
+
}
|
|
415
974
|
};
|
|
416
975
|
TextChannel = class extends GuildChannel {
|
|
417
976
|
topic;
|
|
@@ -427,18 +986,45 @@ var init_Channel = __esm({
|
|
|
427
986
|
}
|
|
428
987
|
/**
|
|
429
988
|
* Send a message to this channel.
|
|
430
|
-
* @param options - Text content or object with
|
|
989
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
431
990
|
*/
|
|
432
991
|
async send(options) {
|
|
433
|
-
const
|
|
992
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
993
|
+
const body = buildSendBody(options);
|
|
434
994
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
435
|
-
const
|
|
995
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
996
|
+
const data = await this.client.rest.post(import_types4.Routes.channelMessages(this.id), postOptions);
|
|
436
997
|
return new Message2(this.client, data);
|
|
437
998
|
}
|
|
438
999
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
439
1000
|
get messages() {
|
|
440
1001
|
return new MessageManager(this.client, this.id);
|
|
441
1002
|
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Create a message collector for this channel.
|
|
1005
|
+
* Collects messages matching the filter until time expires or max is reached.
|
|
1006
|
+
* @param options - Filter, time (ms), and max count
|
|
1007
|
+
* @example
|
|
1008
|
+
* const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
|
|
1009
|
+
* collector.on('collect', m => console.log(m.content));
|
|
1010
|
+
* collector.on('end', (collected, reason) => { ... });
|
|
1011
|
+
*/
|
|
1012
|
+
createMessageCollector(options) {
|
|
1013
|
+
return new MessageCollector(this.client, this.id, options);
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Fetch pinned messages in this channel.
|
|
1017
|
+
* @returns Pinned messages
|
|
1018
|
+
*/
|
|
1019
|
+
async fetchPinnedMessages() {
|
|
1020
|
+
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
1021
|
+
const data = await this.client.rest.get(import_types4.Routes.channelPins(this.id));
|
|
1022
|
+
const list = Array.isArray(data) ? data : data?.items ?? [];
|
|
1023
|
+
return list.map((item) => {
|
|
1024
|
+
const msg = typeof item === "object" && item && "message" in item ? item.message : item;
|
|
1025
|
+
return new Message2(this.client, msg);
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
442
1028
|
/**
|
|
443
1029
|
* Fetch a message by ID from this channel.
|
|
444
1030
|
* @param messageId - Snowflake of the message
|
|
@@ -446,6 +1032,10 @@ var init_Channel = __esm({
|
|
|
446
1032
|
* @deprecated Use channel.messages.fetch(messageId) instead.
|
|
447
1033
|
*/
|
|
448
1034
|
async fetchMessage(messageId) {
|
|
1035
|
+
(0, import_util.emitDeprecationWarning)(
|
|
1036
|
+
"Channel.fetchMessage()",
|
|
1037
|
+
"Use channel.messages.fetch(messageId) instead."
|
|
1038
|
+
);
|
|
449
1039
|
return this.client.channels.fetchMessage(this.id, messageId);
|
|
450
1040
|
}
|
|
451
1041
|
};
|
|
@@ -471,24 +1061,57 @@ var init_Channel = __esm({
|
|
|
471
1061
|
};
|
|
472
1062
|
DMChannel = class extends Channel {
|
|
473
1063
|
lastMessageId;
|
|
1064
|
+
/** Group DM creator ID. Null for 1:1 DMs. */
|
|
1065
|
+
ownerId;
|
|
1066
|
+
/** Group DM recipients as User objects. Empty for 1:1 DMs. */
|
|
1067
|
+
recipients;
|
|
1068
|
+
/** Group DM member display names (userId -> nickname). */
|
|
1069
|
+
nicks;
|
|
474
1070
|
constructor(client, data) {
|
|
475
1071
|
super(client, data);
|
|
476
1072
|
this.lastMessageId = data.last_message_id ?? null;
|
|
1073
|
+
this.ownerId = data.owner_id ?? null;
|
|
1074
|
+
this.recipients = (data.recipients ?? []).map(
|
|
1075
|
+
(u) => client.getOrCreateUser(u)
|
|
1076
|
+
);
|
|
1077
|
+
this.nicks = data.nicks ?? {};
|
|
477
1078
|
}
|
|
478
1079
|
/**
|
|
479
1080
|
* Send a message to this DM channel.
|
|
480
|
-
* @param options - Text content or object with
|
|
1081
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
481
1082
|
*/
|
|
482
1083
|
async send(options) {
|
|
483
|
-
const
|
|
1084
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
1085
|
+
const body = buildSendBody(options);
|
|
484
1086
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
485
|
-
const
|
|
1087
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
1088
|
+
const data = await this.client.rest.post(import_types4.Routes.channelMessages(this.id), postOptions);
|
|
486
1089
|
return new Message2(this.client, data);
|
|
487
1090
|
}
|
|
488
1091
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
489
1092
|
get messages() {
|
|
490
1093
|
return new MessageManager(this.client, this.id);
|
|
491
1094
|
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Create a message collector for this DM channel.
|
|
1097
|
+
* @param options - Filter, time (ms), and max count
|
|
1098
|
+
*/
|
|
1099
|
+
createMessageCollector(options) {
|
|
1100
|
+
return new MessageCollector(this.client, this.id, options);
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Fetch pinned messages in this DM channel.
|
|
1104
|
+
* @returns Pinned messages
|
|
1105
|
+
*/
|
|
1106
|
+
async fetchPinnedMessages() {
|
|
1107
|
+
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
1108
|
+
const data = await this.client.rest.get(import_types4.Routes.channelPins(this.id));
|
|
1109
|
+
const list = Array.isArray(data) ? data : data?.items ?? [];
|
|
1110
|
+
return list.map((item) => {
|
|
1111
|
+
const msg = typeof item === "object" && item && "message" in item ? item.message : item;
|
|
1112
|
+
return new Message2(this.client, msg);
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
492
1115
|
/**
|
|
493
1116
|
* Fetch a message by ID from this DM channel.
|
|
494
1117
|
* @param messageId - Snowflake of the message
|
|
@@ -496,23 +1119,57 @@ var init_Channel = __esm({
|
|
|
496
1119
|
* @deprecated Use channel.messages.fetch(messageId) instead.
|
|
497
1120
|
*/
|
|
498
1121
|
async fetchMessage(messageId) {
|
|
1122
|
+
(0, import_util.emitDeprecationWarning)(
|
|
1123
|
+
"Channel.fetchMessage()",
|
|
1124
|
+
"Use channel.messages.fetch(messageId) instead."
|
|
1125
|
+
);
|
|
499
1126
|
return this.client.channels.fetchMessage(this.id, messageId);
|
|
500
1127
|
}
|
|
501
1128
|
};
|
|
502
1129
|
}
|
|
503
1130
|
});
|
|
504
1131
|
|
|
1132
|
+
// src/util/permissions.ts
|
|
1133
|
+
function computePermissions(basePermissions, overwrites, memberRoles, memberId, isOwner) {
|
|
1134
|
+
if (isOwner) return import_util3.ALL_PERMISSIONS_BIGINT;
|
|
1135
|
+
let perms = basePermissions;
|
|
1136
|
+
for (const overwrite of overwrites ?? []) {
|
|
1137
|
+
const applies = overwrite.type === import_types6.OverwriteType.Role && memberRoles.includes(overwrite.id) || overwrite.type === import_types6.OverwriteType.Member && overwrite.id === memberId;
|
|
1138
|
+
if (!applies) continue;
|
|
1139
|
+
const allow = BigInt(overwrite.allow || "0");
|
|
1140
|
+
const deny = BigInt(overwrite.deny || "0");
|
|
1141
|
+
perms = perms & ~deny | allow;
|
|
1142
|
+
}
|
|
1143
|
+
return perms;
|
|
1144
|
+
}
|
|
1145
|
+
function hasPermission(bitfield, permission) {
|
|
1146
|
+
const Administrator = 1n << 3n;
|
|
1147
|
+
if ((bitfield & Administrator) !== 0n) return true;
|
|
1148
|
+
return (bitfield & permission) === permission;
|
|
1149
|
+
}
|
|
1150
|
+
var import_types6, import_util3;
|
|
1151
|
+
var init_permissions = __esm({
|
|
1152
|
+
"src/util/permissions.ts"() {
|
|
1153
|
+
"use strict";
|
|
1154
|
+
import_types6 = require("@fluxerjs/types");
|
|
1155
|
+
import_util3 = require("@fluxerjs/util");
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
|
|
505
1159
|
// src/structures/GuildMember.ts
|
|
506
1160
|
var GuildMember_exports = {};
|
|
507
1161
|
__export(GuildMember_exports, {
|
|
508
1162
|
GuildMember: () => GuildMember
|
|
509
1163
|
});
|
|
510
|
-
var
|
|
1164
|
+
var import_util4, import_types7, GuildMember;
|
|
511
1165
|
var init_GuildMember = __esm({
|
|
512
1166
|
"src/structures/GuildMember.ts"() {
|
|
513
1167
|
"use strict";
|
|
514
1168
|
init_Base();
|
|
515
|
-
|
|
1169
|
+
import_util4 = require("@fluxerjs/util");
|
|
1170
|
+
import_types7 = require("@fluxerjs/types");
|
|
1171
|
+
init_cdn();
|
|
1172
|
+
init_permissions();
|
|
516
1173
|
GuildMember = class extends Base {
|
|
517
1174
|
client;
|
|
518
1175
|
id;
|
|
@@ -522,6 +1179,12 @@ var init_GuildMember = __esm({
|
|
|
522
1179
|
roles;
|
|
523
1180
|
joinedAt;
|
|
524
1181
|
communicationDisabledUntil;
|
|
1182
|
+
mute;
|
|
1183
|
+
deaf;
|
|
1184
|
+
avatar;
|
|
1185
|
+
banner;
|
|
1186
|
+
accentColor;
|
|
1187
|
+
profileFlags;
|
|
525
1188
|
/** @param data - API guild member from GET /guilds/{id}/members or GET /guilds/{id}/members/{user_id} */
|
|
526
1189
|
constructor(client, data, guild) {
|
|
527
1190
|
super();
|
|
@@ -533,18 +1196,45 @@ var init_GuildMember = __esm({
|
|
|
533
1196
|
this.roles = data.roles ?? [];
|
|
534
1197
|
this.joinedAt = new Date(data.joined_at);
|
|
535
1198
|
this.communicationDisabledUntil = data.communication_disabled_until ? new Date(data.communication_disabled_until) : null;
|
|
1199
|
+
this.mute = data.mute ?? false;
|
|
1200
|
+
this.deaf = data.deaf ?? false;
|
|
1201
|
+
this.avatar = data.avatar ?? null;
|
|
1202
|
+
this.banner = data.banner ?? null;
|
|
1203
|
+
this.accentColor = data.accent_color ?? null;
|
|
1204
|
+
this.profileFlags = data.profile_flags ?? null;
|
|
536
1205
|
}
|
|
537
1206
|
/** Nickname, or global name, or username. */
|
|
538
1207
|
get displayName() {
|
|
539
1208
|
return this.nick ?? this.user.globalName ?? this.user.username;
|
|
540
1209
|
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Get the guild-specific avatar URL for this member.
|
|
1212
|
+
* Returns null if the member has no guild avatar (use displayAvatarURL for fallback).
|
|
1213
|
+
*/
|
|
1214
|
+
avatarURL(options) {
|
|
1215
|
+
return cdnMemberAvatarURL(this.guild.id, this.id, this.avatar, options);
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Get the avatar URL to display for this member.
|
|
1219
|
+
* Uses guild-specific avatar if set, otherwise falls back to the user's avatar.
|
|
1220
|
+
*/
|
|
1221
|
+
displayAvatarURL(options) {
|
|
1222
|
+
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Get the guild-specific banner URL for this member.
|
|
1226
|
+
* Returns null if the member has no guild banner.
|
|
1227
|
+
*/
|
|
1228
|
+
bannerURL(options) {
|
|
1229
|
+
return cdnMemberBannerURL(this.guild.id, this.id, this.banner, options);
|
|
1230
|
+
}
|
|
541
1231
|
/**
|
|
542
1232
|
* Add a role to this member.
|
|
543
1233
|
* @param roleId - The role ID to add
|
|
544
1234
|
* Requires Manage Roles permission.
|
|
545
1235
|
*/
|
|
546
1236
|
async addRole(roleId) {
|
|
547
|
-
await this.client.rest.put(
|
|
1237
|
+
await this.client.rest.put(import_types7.Routes.guildMemberRole(this.guild.id, this.id, roleId));
|
|
548
1238
|
}
|
|
549
1239
|
/**
|
|
550
1240
|
* Remove a role from this member.
|
|
@@ -552,7 +1242,67 @@ var init_GuildMember = __esm({
|
|
|
552
1242
|
* Requires Manage Roles permission.
|
|
553
1243
|
*/
|
|
554
1244
|
async removeRole(roleId) {
|
|
555
|
-
await this.client.rest.delete(
|
|
1245
|
+
await this.client.rest.delete(import_types7.Routes.guildMemberRole(this.guild.id, this.id, roleId));
|
|
1246
|
+
}
|
|
1247
|
+
/**
|
|
1248
|
+
* Get the member's guild-level permissions (from roles only, no channel overwrites).
|
|
1249
|
+
* Use this for server-wide permission checks (e.g. ban, kick, manage roles).
|
|
1250
|
+
* @returns Object with has(permission) to check specific permissions
|
|
1251
|
+
* @example
|
|
1252
|
+
* const perms = member.permissions;
|
|
1253
|
+
* if (perms.has(PermissionFlags.BanMembers)) { ... }
|
|
1254
|
+
*/
|
|
1255
|
+
get permissions() {
|
|
1256
|
+
const base = this._computeBasePermissions();
|
|
1257
|
+
const ownerId = this.guild.ownerId;
|
|
1258
|
+
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
1259
|
+
const perms = computePermissions(base, [], [], this.id, isOwner);
|
|
1260
|
+
return {
|
|
1261
|
+
has(permission) {
|
|
1262
|
+
const perm = typeof permission === "number" ? permission : import_util4.PermissionFlagsMap[String(permission)];
|
|
1263
|
+
if (perm === void 0) return false;
|
|
1264
|
+
return hasPermission(perms, BigInt(perm));
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Compute the member's effective permissions in a guild channel.
|
|
1270
|
+
* Applies role permissions and channel overwrites.
|
|
1271
|
+
* @param channel - The guild channel to check permissions for
|
|
1272
|
+
* @returns Object with has(permission) to check specific permissions
|
|
1273
|
+
* @example
|
|
1274
|
+
* const perms = member.permissionsIn(channel);
|
|
1275
|
+
* if (perms.has(PermissionFlags.SendMessages)) { ... }
|
|
1276
|
+
*/
|
|
1277
|
+
permissionsIn(channel) {
|
|
1278
|
+
const base = this._computeBasePermissions();
|
|
1279
|
+
const ownerId = this.guild.ownerId;
|
|
1280
|
+
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
1281
|
+
const perms = computePermissions(
|
|
1282
|
+
base,
|
|
1283
|
+
channel.permissionOverwrites,
|
|
1284
|
+
this.roles,
|
|
1285
|
+
this.id,
|
|
1286
|
+
isOwner
|
|
1287
|
+
);
|
|
1288
|
+
return {
|
|
1289
|
+
has(permission) {
|
|
1290
|
+
const perm = typeof permission === "number" ? permission : import_util4.PermissionFlagsMap[String(permission)];
|
|
1291
|
+
if (perm === void 0) return false;
|
|
1292
|
+
return hasPermission(perms, BigInt(perm));
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
_computeBasePermissions() {
|
|
1297
|
+
let base = 0n;
|
|
1298
|
+
const everyone = this.guild.roles.get(this.guild.id);
|
|
1299
|
+
if (everyone) base |= BigInt(everyone.permissions);
|
|
1300
|
+
for (const roleId of this.roles) {
|
|
1301
|
+
if (roleId === this.guild.id) continue;
|
|
1302
|
+
const role = this.guild.roles.get(roleId);
|
|
1303
|
+
if (role) base |= BigInt(role.permissions);
|
|
1304
|
+
}
|
|
1305
|
+
return base;
|
|
556
1306
|
}
|
|
557
1307
|
};
|
|
558
1308
|
}
|
|
@@ -563,11 +1313,12 @@ var Role_exports = {};
|
|
|
563
1313
|
__export(Role_exports, {
|
|
564
1314
|
Role: () => Role
|
|
565
1315
|
});
|
|
566
|
-
var Role;
|
|
1316
|
+
var import_util5, Role;
|
|
567
1317
|
var init_Role = __esm({
|
|
568
1318
|
"src/structures/Role.ts"() {
|
|
569
1319
|
"use strict";
|
|
570
1320
|
init_Base();
|
|
1321
|
+
import_util5 = require("@fluxerjs/util");
|
|
571
1322
|
Role = class extends Base {
|
|
572
1323
|
client;
|
|
573
1324
|
id;
|
|
@@ -579,6 +1330,8 @@ var init_Role = __esm({
|
|
|
579
1330
|
hoist;
|
|
580
1331
|
mentionable;
|
|
581
1332
|
unicodeEmoji;
|
|
1333
|
+
/** Separately sorted position for hoisted roles. Null if not set. */
|
|
1334
|
+
hoistPosition;
|
|
582
1335
|
/** @param client - The client instance */
|
|
583
1336
|
/** @param data - API role from GET /guilds/{id}/roles or gateway role events */
|
|
584
1337
|
/** @param guildId - The guild this role belongs to */
|
|
@@ -594,21 +1347,71 @@ var init_Role = __esm({
|
|
|
594
1347
|
this.hoist = !!data.hoist;
|
|
595
1348
|
this.mentionable = !!data.mentionable;
|
|
596
1349
|
this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
1350
|
+
this.hoistPosition = data.hoist_position ?? null;
|
|
597
1351
|
}
|
|
598
1352
|
/** Returns a mention string (e.g. `<@&123456>`). */
|
|
599
1353
|
toString() {
|
|
600
1354
|
return `<@&${this.id}>`;
|
|
601
1355
|
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Check if this role has a permission. Administrator grants all permissions.
|
|
1358
|
+
* @param permission - Permission flag, name, or resolvable
|
|
1359
|
+
* @returns true if the role has the permission
|
|
1360
|
+
* @example
|
|
1361
|
+
* if (role.has(PermissionFlags.BanMembers)) { ... }
|
|
1362
|
+
* if (role.has('ManageChannels')) { ... }
|
|
1363
|
+
*/
|
|
1364
|
+
has(permission) {
|
|
1365
|
+
const perm = typeof permission === "number" ? permission : import_util5.PermissionFlags[permission];
|
|
1366
|
+
if (perm === void 0) return false;
|
|
1367
|
+
const permNum = Number(perm);
|
|
1368
|
+
const rolePerms = BigInt(this.permissions);
|
|
1369
|
+
const permBig = BigInt(permNum);
|
|
1370
|
+
if (permBig < 0) return false;
|
|
1371
|
+
if ((rolePerms & BigInt(import_util5.PermissionFlags.Administrator)) !== 0n) return true;
|
|
1372
|
+
return (rolePerms & permBig) === permBig;
|
|
1373
|
+
}
|
|
602
1374
|
};
|
|
603
1375
|
}
|
|
604
1376
|
});
|
|
605
1377
|
|
|
606
|
-
// src/
|
|
607
|
-
var
|
|
608
|
-
|
|
609
|
-
|
|
1378
|
+
// src/structures/GuildBan.ts
|
|
1379
|
+
var GuildBan_exports = {};
|
|
1380
|
+
__export(GuildBan_exports, {
|
|
1381
|
+
GuildBan: () => GuildBan
|
|
1382
|
+
});
|
|
1383
|
+
var import_types8, GuildBan;
|
|
1384
|
+
var init_GuildBan = __esm({
|
|
1385
|
+
"src/structures/GuildBan.ts"() {
|
|
610
1386
|
"use strict";
|
|
611
|
-
|
|
1387
|
+
init_Base();
|
|
1388
|
+
import_types8 = require("@fluxerjs/types");
|
|
1389
|
+
GuildBan = class extends Base {
|
|
1390
|
+
client;
|
|
1391
|
+
guildId;
|
|
1392
|
+
user;
|
|
1393
|
+
reason;
|
|
1394
|
+
/** ISO timestamp when a temporary ban expires. Null for permanent bans. */
|
|
1395
|
+
expiresAt;
|
|
1396
|
+
/** @param data - API ban from GET /guilds/{id}/bans or gateway GUILD_BAN_ADD */
|
|
1397
|
+
constructor(client, data, guildId) {
|
|
1398
|
+
super();
|
|
1399
|
+
this.client = client;
|
|
1400
|
+
this.guildId = data.guild_id ?? guildId;
|
|
1401
|
+
this.user = client.getOrCreateUser(data.user);
|
|
1402
|
+
this.reason = data.reason ?? null;
|
|
1403
|
+
this.expiresAt = data.expires_at ?? null;
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Remove this ban (unban the user).
|
|
1407
|
+
* Requires Ban Members permission.
|
|
1408
|
+
*/
|
|
1409
|
+
async unban() {
|
|
1410
|
+
await this.client.rest.delete(import_types8.Routes.guildBan(this.guildId, this.user.id), {
|
|
1411
|
+
auth: true
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
612
1415
|
}
|
|
613
1416
|
});
|
|
614
1417
|
|
|
@@ -617,17 +1420,20 @@ var Guild_exports = {};
|
|
|
617
1420
|
__export(Guild_exports, {
|
|
618
1421
|
Guild: () => Guild
|
|
619
1422
|
});
|
|
620
|
-
var
|
|
1423
|
+
var import_util6, import_rest2, import_collection5, import_types9, Guild;
|
|
621
1424
|
var init_Guild = __esm({
|
|
622
1425
|
"src/structures/Guild.ts"() {
|
|
623
1426
|
"use strict";
|
|
624
|
-
|
|
1427
|
+
import_util6 = require("@fluxerjs/util");
|
|
1428
|
+
import_rest2 = require("@fluxerjs/rest");
|
|
625
1429
|
init_Base();
|
|
626
|
-
|
|
1430
|
+
init_FluxerError();
|
|
1431
|
+
init_ErrorCodes();
|
|
1432
|
+
import_collection5 = require("@fluxerjs/collection");
|
|
627
1433
|
init_GuildMember();
|
|
628
1434
|
init_Role();
|
|
629
1435
|
init_Constants();
|
|
630
|
-
|
|
1436
|
+
import_types9 = require("@fluxerjs/types");
|
|
631
1437
|
Guild = class extends Base {
|
|
632
1438
|
client;
|
|
633
1439
|
id;
|
|
@@ -635,9 +1441,36 @@ var init_Guild = __esm({
|
|
|
635
1441
|
icon;
|
|
636
1442
|
banner;
|
|
637
1443
|
ownerId;
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
1444
|
+
/** Invite splash image hash. Null if none. */
|
|
1445
|
+
splash;
|
|
1446
|
+
/** Custom vanity URL code (e.g. fluxer.gg/code). Null if none. */
|
|
1447
|
+
vanityURLCode;
|
|
1448
|
+
/** Enabled guild features. */
|
|
1449
|
+
features;
|
|
1450
|
+
verificationLevel;
|
|
1451
|
+
defaultMessageNotifications;
|
|
1452
|
+
explicitContentFilter;
|
|
1453
|
+
/** AFK voice channel ID. Null if none. */
|
|
1454
|
+
afkChannelId;
|
|
1455
|
+
/** AFK timeout in seconds. */
|
|
1456
|
+
afkTimeout;
|
|
1457
|
+
/** System messages channel ID. Null if none. */
|
|
1458
|
+
systemChannelId;
|
|
1459
|
+
/** Rules/guidelines channel ID. Null if none. */
|
|
1460
|
+
rulesChannelId;
|
|
1461
|
+
nsfwLevel;
|
|
1462
|
+
mfaLevel;
|
|
1463
|
+
/** Banner image width. Optional. */
|
|
1464
|
+
bannerWidth;
|
|
1465
|
+
/** Banner image height. Optional. */
|
|
1466
|
+
bannerHeight;
|
|
1467
|
+
/** Splash image width. Optional. */
|
|
1468
|
+
splashWidth;
|
|
1469
|
+
/** Splash image height. Optional. */
|
|
1470
|
+
splashHeight;
|
|
1471
|
+
members = new import_collection5.Collection();
|
|
1472
|
+
channels = new import_collection5.Collection();
|
|
1473
|
+
roles = new import_collection5.Collection();
|
|
641
1474
|
/** @param data - API guild from GET /guilds/{id} or gateway GUILD_CREATE */
|
|
642
1475
|
constructor(client, data) {
|
|
643
1476
|
super();
|
|
@@ -646,7 +1479,23 @@ var init_Guild = __esm({
|
|
|
646
1479
|
this.name = data.name;
|
|
647
1480
|
this.icon = data.icon ?? null;
|
|
648
1481
|
this.banner = data.banner ?? null;
|
|
649
|
-
this.ownerId = data.owner_id;
|
|
1482
|
+
this.ownerId = data.owner_id ?? data.ownerId ?? "";
|
|
1483
|
+
this.splash = data.splash ?? null;
|
|
1484
|
+
this.vanityURLCode = data.vanity_url_code ?? null;
|
|
1485
|
+
this.features = data.features ?? [];
|
|
1486
|
+
this.verificationLevel = data.verification_level ?? 0;
|
|
1487
|
+
this.defaultMessageNotifications = data.default_message_notifications ?? 0;
|
|
1488
|
+
this.explicitContentFilter = data.explicit_content_filter ?? 0;
|
|
1489
|
+
this.afkChannelId = data.afk_channel_id ?? null;
|
|
1490
|
+
this.afkTimeout = data.afk_timeout ?? 0;
|
|
1491
|
+
this.systemChannelId = data.system_channel_id ?? null;
|
|
1492
|
+
this.rulesChannelId = data.rules_channel_id ?? null;
|
|
1493
|
+
this.nsfwLevel = data.nsfw_level ?? 0;
|
|
1494
|
+
this.mfaLevel = data.mfa_level ?? 0;
|
|
1495
|
+
this.bannerWidth = data.banner_width ?? null;
|
|
1496
|
+
this.bannerHeight = data.banner_height ?? null;
|
|
1497
|
+
this.splashWidth = data.splash_width ?? null;
|
|
1498
|
+
this.splashHeight = data.splash_height ?? null;
|
|
650
1499
|
for (const r of data.roles ?? []) {
|
|
651
1500
|
this.roles.set(r.id, new Role(client, r, this.id));
|
|
652
1501
|
}
|
|
@@ -663,6 +1512,12 @@ var init_Guild = __esm({
|
|
|
663
1512
|
const size = options?.size ? `?size=${options.size}` : "";
|
|
664
1513
|
return `${CDN_URL}/banners/${this.id}/${this.banner}.png${size}`;
|
|
665
1514
|
}
|
|
1515
|
+
/** Get the guild splash (invite background) URL, or null if no splash. */
|
|
1516
|
+
splashURL(options) {
|
|
1517
|
+
if (!this.splash) return null;
|
|
1518
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
1519
|
+
return `${CDN_URL}/splashes/${this.id}/${this.splash}.png${size}`;
|
|
1520
|
+
}
|
|
666
1521
|
/**
|
|
667
1522
|
* Add a role to a member by user ID. Does not require fetching the member first.
|
|
668
1523
|
* @param userId - The user ID of the member
|
|
@@ -670,7 +1525,7 @@ var init_Guild = __esm({
|
|
|
670
1525
|
* Requires Manage Roles permission.
|
|
671
1526
|
*/
|
|
672
1527
|
async addRoleToMember(userId, roleId) {
|
|
673
|
-
await this.client.rest.put(
|
|
1528
|
+
await this.client.rest.put(import_types9.Routes.guildMemberRole(this.id, userId, roleId));
|
|
674
1529
|
}
|
|
675
1530
|
/**
|
|
676
1531
|
* Remove a role from a member by user ID. Does not require fetching the member first.
|
|
@@ -679,7 +1534,7 @@ var init_Guild = __esm({
|
|
|
679
1534
|
* Requires Manage Roles permission.
|
|
680
1535
|
*/
|
|
681
1536
|
async removeRoleFromMember(userId, roleId) {
|
|
682
|
-
await this.client.rest.delete(
|
|
1537
|
+
await this.client.rest.delete(import_types9.Routes.guildMemberRole(this.id, userId, roleId));
|
|
683
1538
|
}
|
|
684
1539
|
/**
|
|
685
1540
|
* Resolve a role ID from an argument (role mention, raw ID, or name).
|
|
@@ -688,14 +1543,14 @@ var init_Guild = __esm({
|
|
|
688
1543
|
* @returns The role ID, or null if not found
|
|
689
1544
|
*/
|
|
690
1545
|
async resolveRoleId(arg) {
|
|
691
|
-
const parsed = (0,
|
|
1546
|
+
const parsed = (0, import_util6.parseRoleMention)(arg);
|
|
692
1547
|
if (parsed) return parsed;
|
|
693
1548
|
if (/^\d{17,19}$/.test(arg.trim())) return arg.trim();
|
|
694
1549
|
const cached = this.roles.find(
|
|
695
1550
|
(r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase())
|
|
696
1551
|
);
|
|
697
1552
|
if (cached) return cached.id;
|
|
698
|
-
const roles = await this.client.rest.get(
|
|
1553
|
+
const roles = await this.client.rest.get(import_types9.Routes.guildRoles(this.id));
|
|
699
1554
|
const list = Array.isArray(roles) ? roles : Object.values(roles ?? {});
|
|
700
1555
|
const role = list.find((r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase()));
|
|
701
1556
|
if (role) {
|
|
@@ -704,39 +1559,158 @@ var init_Guild = __esm({
|
|
|
704
1559
|
}
|
|
705
1560
|
return null;
|
|
706
1561
|
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Ban a user from this guild.
|
|
1564
|
+
* @param userId - The user ID to ban
|
|
1565
|
+
* @param options - Optional reason, delete_message_days (0–7), and ban_duration_seconds (temporary ban).
|
|
1566
|
+
* ban_duration_seconds: 0 = permanent, or use 3600, 43200, 86400, 259200, 432000, 604800, 1209600, 2592000.
|
|
1567
|
+
* Requires Ban Members permission.
|
|
1568
|
+
*/
|
|
1569
|
+
async ban(userId, options) {
|
|
1570
|
+
const body = {};
|
|
1571
|
+
if (options?.reason) body.reason = options.reason;
|
|
1572
|
+
if (options?.delete_message_days != null)
|
|
1573
|
+
body.delete_message_days = options.delete_message_days;
|
|
1574
|
+
if (options?.ban_duration_seconds != null)
|
|
1575
|
+
body.ban_duration_seconds = options.ban_duration_seconds;
|
|
1576
|
+
await this.client.rest.put(import_types9.Routes.guildBan(this.id, userId), {
|
|
1577
|
+
body: Object.keys(body).length ? body : void 0,
|
|
1578
|
+
auth: true
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Fetch guild bans. Requires Ban Members permission.
|
|
1583
|
+
* @returns List of GuildBan objects
|
|
1584
|
+
*/
|
|
1585
|
+
async fetchBans() {
|
|
1586
|
+
const { GuildBan: GuildBan2 } = await Promise.resolve().then(() => (init_GuildBan(), GuildBan_exports));
|
|
1587
|
+
const data = await this.client.rest.get(import_types9.Routes.guildBans(this.id));
|
|
1588
|
+
const list = Array.isArray(data) ? data : data?.bans ?? [];
|
|
1589
|
+
return list.map((b) => new GuildBan2(this.client, { ...b, guild_id: this.id }, this.id));
|
|
1590
|
+
}
|
|
1591
|
+
/**
|
|
1592
|
+
* Remove a ban (unban a user).
|
|
1593
|
+
* @param userId - The user ID to unban
|
|
1594
|
+
* Requires Ban Members permission.
|
|
1595
|
+
*/
|
|
1596
|
+
async unban(userId) {
|
|
1597
|
+
await this.client.rest.delete(import_types9.Routes.guildBan(this.id, userId), { auth: true });
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Kick a member from this guild.
|
|
1601
|
+
* @param userId - The user ID to kick
|
|
1602
|
+
* Requires Kick Members permission.
|
|
1603
|
+
*/
|
|
1604
|
+
async kick(userId) {
|
|
1605
|
+
await this.client.rest.delete(import_types9.Routes.guildMember(this.id, userId), { auth: true });
|
|
1606
|
+
}
|
|
707
1607
|
/**
|
|
708
1608
|
* Fetch a guild member by user ID.
|
|
709
1609
|
* @param userId - The user ID of the member to fetch
|
|
710
|
-
* @returns The guild member
|
|
1610
|
+
* @returns The guild member
|
|
1611
|
+
* @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
|
|
1612
|
+
* @throws FluxerError with cause for permission denied (403) or other REST errors
|
|
711
1613
|
*/
|
|
712
1614
|
async fetchMember(userId) {
|
|
713
1615
|
try {
|
|
714
1616
|
const data = await this.client.rest.get(
|
|
715
|
-
|
|
1617
|
+
import_types9.Routes.guildMember(this.id, userId)
|
|
716
1618
|
);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
return
|
|
1619
|
+
const member = new GuildMember(this.client, { ...data, guild_id: this.id }, this);
|
|
1620
|
+
this.members.set(member.id, member);
|
|
1621
|
+
return member;
|
|
1622
|
+
} catch (err) {
|
|
1623
|
+
const statusCode = err instanceof import_rest2.FluxerAPIError ? err.statusCode : err?.statusCode;
|
|
1624
|
+
if (statusCode === 404) {
|
|
1625
|
+
throw new FluxerError(`Member ${userId} not found in guild`, {
|
|
1626
|
+
code: ErrorCodes.MemberNotFound,
|
|
1627
|
+
cause: err
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
throw err instanceof FluxerError ? err : new FluxerError("Failed to fetch guild member", { cause: err });
|
|
720
1631
|
}
|
|
721
1632
|
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Fetch guild audit logs. Requires View Audit Log permission.
|
|
1635
|
+
* @param options - Optional limit, before, after, user_id, action_type for filtering
|
|
1636
|
+
*/
|
|
1637
|
+
async fetchAuditLogs(options) {
|
|
1638
|
+
const params = new URLSearchParams();
|
|
1639
|
+
if (options?.limit != null) params.set("limit", String(options.limit));
|
|
1640
|
+
if (options?.before) params.set("before", options.before);
|
|
1641
|
+
if (options?.after) params.set("after", options.after);
|
|
1642
|
+
if (options?.userId) params.set("user_id", options.userId);
|
|
1643
|
+
if (options?.actionType != null) params.set("action_type", String(options.actionType));
|
|
1644
|
+
const qs = params.toString();
|
|
1645
|
+
const url = import_types9.Routes.guildAuditLogs(this.id) + (qs ? `?${qs}` : "");
|
|
1646
|
+
return this.client.rest.get(url);
|
|
1647
|
+
}
|
|
722
1648
|
/** Fetch all webhooks in this guild. Returned webhooks do not include the token (cannot send). */
|
|
723
1649
|
async fetchWebhooks() {
|
|
724
1650
|
const { Webhook: Webhook2 } = await Promise.resolve().then(() => (init_Webhook(), Webhook_exports));
|
|
725
|
-
const data = await this.client.rest.get(
|
|
1651
|
+
const data = await this.client.rest.get(import_types9.Routes.guildWebhooks(this.id));
|
|
726
1652
|
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
727
1653
|
return list.map((w) => new Webhook2(this.client, w));
|
|
728
1654
|
}
|
|
1655
|
+
/**
|
|
1656
|
+
* Create a channel in this guild.
|
|
1657
|
+
* @param data - Channel data: type (0=text, 2=voice, 4=category, 5=link), name, and optional parent_id, topic, bitrate, user_limit, nsfw, permission_overwrites
|
|
1658
|
+
* Requires Manage Channels permission.
|
|
1659
|
+
*/
|
|
1660
|
+
async createChannel(data) {
|
|
1661
|
+
const { Channel: Channel2 } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
1662
|
+
const created = await this.client.rest.post(import_types9.Routes.guildChannels(this.id), {
|
|
1663
|
+
body: data,
|
|
1664
|
+
auth: true
|
|
1665
|
+
});
|
|
1666
|
+
const channel = Channel2.from(this.client, created);
|
|
1667
|
+
if (channel) {
|
|
1668
|
+
this.client.channels.set(channel.id, channel);
|
|
1669
|
+
this.channels.set(channel.id, channel);
|
|
1670
|
+
}
|
|
1671
|
+
return channel;
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* Fetch all channels in this guild.
|
|
1675
|
+
* @returns Array of GuildChannel objects (cached in guild.channels and client.channels)
|
|
1676
|
+
*/
|
|
1677
|
+
async fetchChannels() {
|
|
1678
|
+
const { Channel: Channel2 } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
1679
|
+
const data = await this.client.rest.get(import_types9.Routes.guildChannels(this.id));
|
|
1680
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
1681
|
+
const channels = [];
|
|
1682
|
+
for (const ch of list) {
|
|
1683
|
+
const channel = Channel2.from(this.client, ch);
|
|
1684
|
+
if (channel) {
|
|
1685
|
+
this.client.channels.set(channel.id, channel);
|
|
1686
|
+
this.channels.set(channel.id, channel);
|
|
1687
|
+
channels.push(channel);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
return channels;
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Update channel positions.
|
|
1694
|
+
* @param updates - Array of { id, position?, parent_id?, lock_permissions? }
|
|
1695
|
+
* Requires Manage Channels permission.
|
|
1696
|
+
*/
|
|
1697
|
+
async setChannelPositions(updates) {
|
|
1698
|
+
await this.client.rest.patch(import_types9.Routes.guildChannels(this.id), {
|
|
1699
|
+
body: updates,
|
|
1700
|
+
auth: true
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
729
1703
|
};
|
|
730
1704
|
}
|
|
731
1705
|
});
|
|
732
1706
|
|
|
733
1707
|
// src/structures/User.ts
|
|
734
|
-
var
|
|
1708
|
+
var import_types11, User;
|
|
735
1709
|
var init_User = __esm({
|
|
736
1710
|
"src/structures/User.ts"() {
|
|
737
1711
|
"use strict";
|
|
738
1712
|
init_Base();
|
|
739
|
-
|
|
1713
|
+
import_types11 = require("@fluxerjs/types");
|
|
740
1714
|
init_Constants();
|
|
741
1715
|
User = class extends Base {
|
|
742
1716
|
client;
|
|
@@ -746,6 +1720,14 @@ var init_User = __esm({
|
|
|
746
1720
|
globalName;
|
|
747
1721
|
avatar;
|
|
748
1722
|
bot;
|
|
1723
|
+
/** RGB avatar color (e.g. 7577782). Null if not set. */
|
|
1724
|
+
avatarColor;
|
|
1725
|
+
/** Public flags bitfield. Null if not set. */
|
|
1726
|
+
flags;
|
|
1727
|
+
/** Whether this is an official system user. */
|
|
1728
|
+
system;
|
|
1729
|
+
/** Banner hash (from profile, member, or invite context). Null when not available. */
|
|
1730
|
+
banner;
|
|
749
1731
|
/** @param data - API user from message author, GET /users/{id}, or GET /users/@me */
|
|
750
1732
|
constructor(client, data) {
|
|
751
1733
|
super();
|
|
@@ -756,6 +1738,10 @@ var init_User = __esm({
|
|
|
756
1738
|
this.globalName = data.global_name ?? null;
|
|
757
1739
|
this.avatar = data.avatar ?? null;
|
|
758
1740
|
this.bot = !!data.bot;
|
|
1741
|
+
this.avatarColor = data.avatar_color ?? null;
|
|
1742
|
+
this.flags = data.flags ?? data.public_flags ?? null;
|
|
1743
|
+
this.system = !!data.system;
|
|
1744
|
+
this.banner = data.banner ?? null;
|
|
759
1745
|
}
|
|
760
1746
|
/** Update mutable fields from fresh API data. Used by getOrCreateUser cache. */
|
|
761
1747
|
_patch(data) {
|
|
@@ -763,14 +1749,18 @@ var init_User = __esm({
|
|
|
763
1749
|
this.discriminator = data.discriminator;
|
|
764
1750
|
this.globalName = data.global_name ?? null;
|
|
765
1751
|
this.avatar = data.avatar ?? null;
|
|
1752
|
+
if (data.avatar_color !== void 0) this.avatarColor = data.avatar_color;
|
|
1753
|
+
if (data.flags !== void 0) this.flags = data.flags;
|
|
1754
|
+
if (data.banner !== void 0) this.banner = data.banner;
|
|
766
1755
|
}
|
|
767
1756
|
/**
|
|
768
1757
|
* Get the URL for this user's avatar.
|
|
769
|
-
*
|
|
1758
|
+
* Auto-detects animated avatars (hash starting with `a_`) and uses gif extension.
|
|
1759
|
+
* @param options - Optional `size` and `extension` (default: png, or gif for animated)
|
|
770
1760
|
*/
|
|
771
1761
|
avatarURL(options) {
|
|
772
1762
|
if (!this.avatar) return null;
|
|
773
|
-
const ext = options?.extension ?? "png";
|
|
1763
|
+
const ext = this.avatar.startsWith("a_") ? "gif" : options?.extension ?? "png";
|
|
774
1764
|
const size = options?.size ? `?size=${options.size}` : "";
|
|
775
1765
|
return `${CDN_URL}/avatars/${this.id}/${this.avatar}.${ext}${size}`;
|
|
776
1766
|
}
|
|
@@ -778,6 +1768,16 @@ var init_User = __esm({
|
|
|
778
1768
|
displayAvatarURL(options) {
|
|
779
1769
|
return this.avatarURL(options) ?? `${CDN_URL}/avatars/0/0.png`;
|
|
780
1770
|
}
|
|
1771
|
+
/**
|
|
1772
|
+
* Get the URL for this user's banner.
|
|
1773
|
+
* Returns null if the user has no banner (only available when fetched from profile/member context).
|
|
1774
|
+
*/
|
|
1775
|
+
bannerURL(options) {
|
|
1776
|
+
if (!this.banner) return null;
|
|
1777
|
+
const ext = this.banner.startsWith("a_") ? "gif" : options?.extension ?? "png";
|
|
1778
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
1779
|
+
return `${CDN_URL}/banners/${this.id}/${this.banner}.${ext}${size}`;
|
|
1780
|
+
}
|
|
781
1781
|
/** Returns a mention string (e.g. `<@123456>`). */
|
|
782
1782
|
toString() {
|
|
783
1783
|
return `<@${this.id}>`;
|
|
@@ -788,7 +1788,7 @@ var init_User = __esm({
|
|
|
788
1788
|
*/
|
|
789
1789
|
async createDM() {
|
|
790
1790
|
const { DMChannel: DMChannelClass } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
791
|
-
const data = await this.client.rest.post(
|
|
1791
|
+
const data = await this.client.rest.post(import_types11.Routes.userMeChannels(), {
|
|
792
1792
|
body: { recipient_id: this.id },
|
|
793
1793
|
auth: true
|
|
794
1794
|
});
|
|
@@ -844,6 +1844,7 @@ var init_MessageReaction = __esm({
|
|
|
844
1844
|
/**
|
|
845
1845
|
* Fetch the message this reaction belongs to.
|
|
846
1846
|
* Use when you need to edit, delete, or otherwise interact with the message.
|
|
1847
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
847
1848
|
*/
|
|
848
1849
|
async fetchMessage() {
|
|
849
1850
|
return this.client.channels.fetchMessage(this.channelId, this.messageId);
|
|
@@ -857,15 +1858,40 @@ var ClientUser_exports = {};
|
|
|
857
1858
|
__export(ClientUser_exports, {
|
|
858
1859
|
ClientUser: () => ClientUser
|
|
859
1860
|
});
|
|
860
|
-
var ClientUser;
|
|
1861
|
+
var import_types12, ClientUser;
|
|
861
1862
|
var init_ClientUser = __esm({
|
|
862
1863
|
"src/client/ClientUser.ts"() {
|
|
863
1864
|
"use strict";
|
|
864
1865
|
init_User();
|
|
1866
|
+
import_types12 = require("@fluxerjs/types");
|
|
865
1867
|
ClientUser = class extends User {
|
|
866
1868
|
constructor(client, data) {
|
|
867
1869
|
super(client, { ...data });
|
|
868
1870
|
}
|
|
1871
|
+
/**
|
|
1872
|
+
* Fetch guilds the bot is a member of.
|
|
1873
|
+
* @returns Array of Guild objects (cached in client.guilds)
|
|
1874
|
+
*/
|
|
1875
|
+
async fetchGuilds() {
|
|
1876
|
+
const { Guild: Guild2 } = await Promise.resolve().then(() => (init_Guild(), Guild_exports));
|
|
1877
|
+
const data = await this.client.rest.get(import_types12.Routes.currentUserGuilds());
|
|
1878
|
+
const list = Array.isArray(data) ? data : data?.guilds ?? [];
|
|
1879
|
+
const guilds = [];
|
|
1880
|
+
for (const g of list) {
|
|
1881
|
+
const guild = new Guild2(this.client, g);
|
|
1882
|
+
this.client.guilds.set(guild.id, guild);
|
|
1883
|
+
guilds.push(guild);
|
|
1884
|
+
}
|
|
1885
|
+
return guilds;
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Leave a guild. Requires the bot to be a member.
|
|
1889
|
+
* @param guildId - The guild ID to leave
|
|
1890
|
+
*/
|
|
1891
|
+
async leaveGuild(guildId) {
|
|
1892
|
+
await this.client.rest.delete(import_types12.Routes.leaveGuild(guildId), { auth: true });
|
|
1893
|
+
this.client.guilds.delete(guildId);
|
|
1894
|
+
}
|
|
869
1895
|
};
|
|
870
1896
|
}
|
|
871
1897
|
});
|
|
@@ -873,7 +1899,7 @@ var init_ClientUser = __esm({
|
|
|
873
1899
|
// src/index.ts
|
|
874
1900
|
var index_exports = {};
|
|
875
1901
|
__export(index_exports, {
|
|
876
|
-
AttachmentBuilder: () =>
|
|
1902
|
+
AttachmentBuilder: () => import_builders3.AttachmentBuilder,
|
|
877
1903
|
Base: () => Base,
|
|
878
1904
|
CategoryChannel: () => CategoryChannel,
|
|
879
1905
|
Channel: () => Channel,
|
|
@@ -881,39 +1907,60 @@ __export(index_exports, {
|
|
|
881
1907
|
Client: () => Client,
|
|
882
1908
|
ClientUser: () => ClientUser,
|
|
883
1909
|
DMChannel: () => DMChannel,
|
|
884
|
-
EmbedBuilder: () =>
|
|
1910
|
+
EmbedBuilder: () => import_builders3.EmbedBuilder,
|
|
885
1911
|
ErrorCodes: () => ErrorCodes,
|
|
886
1912
|
Events: () => Events,
|
|
887
1913
|
FluxerError: () => FluxerError,
|
|
888
|
-
GatewayOpcodes: () =>
|
|
1914
|
+
GatewayOpcodes: () => import_types16.GatewayOpcodes,
|
|
889
1915
|
Guild: () => Guild,
|
|
1916
|
+
GuildBan: () => GuildBan,
|
|
890
1917
|
GuildChannel: () => GuildChannel,
|
|
1918
|
+
GuildEmoji: () => GuildEmoji,
|
|
891
1919
|
GuildMember: () => GuildMember,
|
|
1920
|
+
GuildSticker: () => GuildSticker,
|
|
1921
|
+
Invite: () => Invite,
|
|
892
1922
|
LinkChannel: () => LinkChannel,
|
|
893
1923
|
Message: () => Message,
|
|
1924
|
+
MessageAttachmentFlags: () => import_types16.MessageAttachmentFlags,
|
|
1925
|
+
MessageCollector: () => MessageCollector,
|
|
894
1926
|
MessageManager: () => MessageManager,
|
|
895
|
-
MessagePayload: () =>
|
|
1927
|
+
MessagePayload: () => import_builders3.MessagePayload,
|
|
896
1928
|
MessageReaction: () => MessageReaction,
|
|
1929
|
+
PermissionFlags: () => import_util9.PermissionFlags,
|
|
1930
|
+
PermissionsBitField: () => import_util9.PermissionsBitField,
|
|
1931
|
+
ReactionCollector: () => ReactionCollector,
|
|
897
1932
|
Role: () => Role,
|
|
898
|
-
Routes: () =>
|
|
1933
|
+
Routes: () => import_types16.Routes,
|
|
899
1934
|
TextChannel: () => TextChannel,
|
|
900
1935
|
User: () => User,
|
|
901
1936
|
VoiceChannel: () => VoiceChannel,
|
|
902
|
-
Webhook: () => Webhook
|
|
1937
|
+
Webhook: () => Webhook,
|
|
1938
|
+
cdnAvatarURL: () => cdnAvatarURL,
|
|
1939
|
+
cdnBannerURL: () => cdnBannerURL,
|
|
1940
|
+
cdnDefaultAvatarURL: () => cdnDefaultAvatarURL,
|
|
1941
|
+
cdnDisplayAvatarURL: () => cdnDisplayAvatarURL,
|
|
1942
|
+
cdnMemberAvatarURL: () => cdnMemberAvatarURL,
|
|
1943
|
+
cdnMemberBannerURL: () => cdnMemberBannerURL,
|
|
1944
|
+
resolveTenorToImageUrl: () => import_util8.resolveTenorToImageUrl
|
|
903
1945
|
});
|
|
904
1946
|
module.exports = __toCommonJS(index_exports);
|
|
905
1947
|
|
|
906
1948
|
// src/client/Client.ts
|
|
907
|
-
var
|
|
908
|
-
var
|
|
1949
|
+
var import_events3 = require("events");
|
|
1950
|
+
var import_rest3 = require("@fluxerjs/rest");
|
|
909
1951
|
var import_ws = require("@fluxerjs/ws");
|
|
910
|
-
var
|
|
911
|
-
var
|
|
1952
|
+
var import_types13 = require("@fluxerjs/types");
|
|
1953
|
+
var import_collection7 = require("@fluxerjs/collection");
|
|
912
1954
|
|
|
913
1955
|
// src/client/ChannelManager.ts
|
|
914
|
-
var
|
|
915
|
-
var
|
|
916
|
-
var
|
|
1956
|
+
var import_collection4 = require("@fluxerjs/collection");
|
|
1957
|
+
var import_types5 = require("@fluxerjs/types");
|
|
1958
|
+
var import_util2 = require("@fluxerjs/util");
|
|
1959
|
+
var import_rest = require("@fluxerjs/rest");
|
|
1960
|
+
init_FluxerError();
|
|
1961
|
+
init_ErrorCodes();
|
|
1962
|
+
init_messageUtils();
|
|
1963
|
+
var ChannelManager = class extends import_collection4.Collection {
|
|
917
1964
|
constructor(client) {
|
|
918
1965
|
super();
|
|
919
1966
|
this.client = client;
|
|
@@ -921,7 +1968,8 @@ var ChannelManager = class extends import_collection2.Collection {
|
|
|
921
1968
|
/**
|
|
922
1969
|
* Fetch a channel by ID from the API (or return from cache if present).
|
|
923
1970
|
* @param channelId - Snowflake of the channel
|
|
924
|
-
* @returns The channel
|
|
1971
|
+
* @returns The channel
|
|
1972
|
+
* @throws FluxerError with CHANNEL_NOT_FOUND if the channel does not exist
|
|
925
1973
|
* @example
|
|
926
1974
|
* const channel = await client.channels.fetch(channelId);
|
|
927
1975
|
* if (channel?.isSendable()) await channel.send('Hello!');
|
|
@@ -932,58 +1980,85 @@ var ChannelManager = class extends import_collection2.Collection {
|
|
|
932
1980
|
try {
|
|
933
1981
|
const { Channel: Channel2 } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
934
1982
|
const data = await this.client.rest.get(
|
|
935
|
-
|
|
1983
|
+
import_types5.Routes.channel(channelId)
|
|
936
1984
|
);
|
|
937
1985
|
const channel = Channel2.fromOrCreate(this.client, data);
|
|
938
|
-
if (channel)
|
|
1986
|
+
if (!channel) {
|
|
1987
|
+
throw new FluxerError("Channel data invalid or unsupported type", {
|
|
1988
|
+
code: ErrorCodes.ChannelNotFound
|
|
1989
|
+
});
|
|
1990
|
+
}
|
|
1991
|
+
this.set(channel.id, channel);
|
|
939
1992
|
return channel;
|
|
940
|
-
} catch {
|
|
941
|
-
|
|
1993
|
+
} catch (err) {
|
|
1994
|
+
if (err instanceof import_rest.RateLimitError) throw err;
|
|
1995
|
+
if (err instanceof import_rest.FluxerAPIError && err.statusCode === 404) {
|
|
1996
|
+
throw new FluxerError(`Channel ${channelId} not found`, {
|
|
1997
|
+
code: ErrorCodes.ChannelNotFound,
|
|
1998
|
+
cause: err
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
throw err instanceof FluxerError ? err : new FluxerError(String(err), { cause: err });
|
|
942
2002
|
}
|
|
943
2003
|
}
|
|
944
2004
|
/**
|
|
945
2005
|
* Fetch a message by ID from the API.
|
|
946
2006
|
* @param channelId - Snowflake of the channel
|
|
947
2007
|
* @param messageId - Snowflake of the message
|
|
948
|
-
* @returns The message
|
|
2008
|
+
* @returns The message
|
|
2009
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
949
2010
|
* @deprecated Use channel.messages.fetch(messageId). Prefer (await client.channels.fetch(channelId))?.messages?.fetch(messageId).
|
|
950
2011
|
* @example
|
|
951
2012
|
* const channel = await client.channels.fetch(channelId);
|
|
952
2013
|
* const message = await channel?.messages?.fetch(messageId);
|
|
953
2014
|
*/
|
|
954
2015
|
async fetchMessage(channelId, messageId) {
|
|
2016
|
+
(0, import_util2.emitDeprecationWarning)(
|
|
2017
|
+
"ChannelManager.fetchMessage()",
|
|
2018
|
+
"Use channel.messages.fetch(messageId). Prefer (await client.channels.fetch(channelId))?.messages?.fetch(messageId)."
|
|
2019
|
+
);
|
|
955
2020
|
try {
|
|
956
2021
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
957
2022
|
const data = await this.client.rest.get(
|
|
958
|
-
|
|
2023
|
+
import_types5.Routes.channelMessage(channelId, messageId)
|
|
959
2024
|
);
|
|
960
2025
|
return new Message2(this.client, data);
|
|
961
|
-
} catch {
|
|
962
|
-
|
|
2026
|
+
} catch (err) {
|
|
2027
|
+
if (err instanceof import_rest.RateLimitError) throw err;
|
|
2028
|
+
if (err instanceof import_rest.FluxerAPIError && err.statusCode === 404) {
|
|
2029
|
+
throw new FluxerError(`Message ${messageId} not found in channel ${channelId}`, {
|
|
2030
|
+
code: ErrorCodes.MessageNotFound,
|
|
2031
|
+
cause: err
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
throw err instanceof FluxerError ? err : new FluxerError(String(err), { cause: err });
|
|
963
2035
|
}
|
|
964
2036
|
}
|
|
965
2037
|
/**
|
|
966
2038
|
* Send a message to a channel by ID. Works even when the channel is not cached.
|
|
967
2039
|
* Skips the fetch when you only need to send.
|
|
968
2040
|
* @param channelId - Snowflake of the channel (text channel or DM)
|
|
969
|
-
* @param payload - Text content or object with content and/or
|
|
2041
|
+
* @param payload - Text content or object with content, embeds, and/or files
|
|
970
2042
|
* @returns The created message
|
|
971
2043
|
* @example
|
|
972
2044
|
* await client.channels.send(logChannelId, 'User joined!');
|
|
973
2045
|
* await client.channels.send(channelId, { embeds: [embed.toJSON()] });
|
|
2046
|
+
* await client.channels.send(channelId, { content: 'Report', files: [{ name: 'log.txt', data }] });
|
|
974
2047
|
*/
|
|
975
2048
|
async send(channelId, payload) {
|
|
976
|
-
const
|
|
2049
|
+
const opts = typeof payload === "string" ? { content: payload } : payload;
|
|
2050
|
+
const body = buildSendBody(payload);
|
|
977
2051
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
978
|
-
const
|
|
2052
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
2053
|
+
const data = await this.client.rest.post(import_types5.Routes.channelMessages(channelId), postOptions);
|
|
979
2054
|
return new Message2(this.client, data);
|
|
980
2055
|
}
|
|
981
2056
|
};
|
|
982
2057
|
|
|
983
2058
|
// src/client/GuildManager.ts
|
|
984
|
-
var
|
|
985
|
-
var
|
|
986
|
-
var GuildManager = class extends
|
|
2059
|
+
var import_collection6 = require("@fluxerjs/collection");
|
|
2060
|
+
var import_types10 = require("@fluxerjs/types");
|
|
2061
|
+
var GuildManager = class extends import_collection6.Collection {
|
|
987
2062
|
constructor(client) {
|
|
988
2063
|
super();
|
|
989
2064
|
this.client = client;
|
|
@@ -1002,7 +2077,7 @@ var GuildManager = class extends import_collection4.Collection {
|
|
|
1002
2077
|
try {
|
|
1003
2078
|
const { Guild: Guild2 } = await Promise.resolve().then(() => (init_Guild(), Guild_exports));
|
|
1004
2079
|
const data = await this.client.rest.get(
|
|
1005
|
-
|
|
2080
|
+
import_types10.Routes.guild(guildId)
|
|
1006
2081
|
);
|
|
1007
2082
|
const guild = new Guild2(this.client, data);
|
|
1008
2083
|
this.set(guild.id, guild);
|
|
@@ -1013,71 +2088,29 @@ var GuildManager = class extends import_collection4.Collection {
|
|
|
1013
2088
|
}
|
|
1014
2089
|
};
|
|
1015
2090
|
|
|
1016
|
-
// src/errors/FluxerError.ts
|
|
1017
|
-
var FluxerError = class _FluxerError extends Error {
|
|
1018
|
-
constructor(message) {
|
|
1019
|
-
super(message);
|
|
1020
|
-
this.name = "FluxerError";
|
|
1021
|
-
Object.setPrototypeOf(this, _FluxerError.prototype);
|
|
1022
|
-
}
|
|
1023
|
-
};
|
|
1024
|
-
|
|
1025
|
-
// src/util/Events.ts
|
|
1026
|
-
var Events = {
|
|
1027
|
-
Ready: "ready",
|
|
1028
|
-
MessageCreate: "messageCreate",
|
|
1029
|
-
MessageUpdate: "messageUpdate",
|
|
1030
|
-
MessageDelete: "messageDelete",
|
|
1031
|
-
MessageDeleteBulk: "messageDeleteBulk",
|
|
1032
|
-
MessageReactionAdd: "messageReactionAdd",
|
|
1033
|
-
MessageReactionRemove: "messageReactionRemove",
|
|
1034
|
-
MessageReactionRemoveAll: "messageReactionRemoveAll",
|
|
1035
|
-
MessageReactionRemoveEmoji: "messageReactionRemoveEmoji",
|
|
1036
|
-
InteractionCreate: "interactionCreate",
|
|
1037
|
-
GuildCreate: "guildCreate",
|
|
1038
|
-
GuildUpdate: "guildUpdate",
|
|
1039
|
-
GuildDelete: "guildDelete",
|
|
1040
|
-
GuildBanAdd: "guildBanAdd",
|
|
1041
|
-
GuildBanRemove: "guildBanRemove",
|
|
1042
|
-
GuildEmojisUpdate: "guildEmojisUpdate",
|
|
1043
|
-
GuildStickersUpdate: "guildStickersUpdate",
|
|
1044
|
-
GuildIntegrationsUpdate: "guildIntegrationsUpdate",
|
|
1045
|
-
GuildMemberAdd: "guildMemberAdd",
|
|
1046
|
-
GuildMemberUpdate: "guildMemberUpdate",
|
|
1047
|
-
GuildMemberRemove: "guildMemberRemove",
|
|
1048
|
-
GuildRoleCreate: "guildRoleCreate",
|
|
1049
|
-
GuildRoleUpdate: "guildRoleUpdate",
|
|
1050
|
-
GuildRoleDelete: "guildRoleDelete",
|
|
1051
|
-
GuildScheduledEventCreate: "guildScheduledEventCreate",
|
|
1052
|
-
GuildScheduledEventUpdate: "guildScheduledEventUpdate",
|
|
1053
|
-
GuildScheduledEventDelete: "guildScheduledEventDelete",
|
|
1054
|
-
ChannelCreate: "channelCreate",
|
|
1055
|
-
ChannelUpdate: "channelUpdate",
|
|
1056
|
-
ChannelDelete: "channelDelete",
|
|
1057
|
-
ChannelPinsUpdate: "channelPinsUpdate",
|
|
1058
|
-
InviteCreate: "inviteCreate",
|
|
1059
|
-
InviteDelete: "inviteDelete",
|
|
1060
|
-
TypingStart: "typingStart",
|
|
1061
|
-
UserUpdate: "userUpdate",
|
|
1062
|
-
PresenceUpdate: "presenceUpdate",
|
|
1063
|
-
VoiceStateUpdate: "voiceStateUpdate",
|
|
1064
|
-
VoiceServerUpdate: "voiceServerUpdate",
|
|
1065
|
-
VoiceStatesSync: "voiceStatesSync",
|
|
1066
|
-
WebhooksUpdate: "webhooksUpdate",
|
|
1067
|
-
Resumed: "resumed",
|
|
1068
|
-
Error: "error",
|
|
1069
|
-
Debug: "debug"
|
|
1070
|
-
};
|
|
1071
|
-
|
|
1072
2091
|
// src/client/Client.ts
|
|
1073
|
-
|
|
2092
|
+
init_FluxerError();
|
|
2093
|
+
init_ErrorCodes();
|
|
2094
|
+
init_Events();
|
|
2095
|
+
var import_util7 = require("@fluxerjs/util");
|
|
1074
2096
|
init_User();
|
|
1075
2097
|
|
|
1076
2098
|
// src/client/EventHandlerRegistry.ts
|
|
2099
|
+
init_Events();
|
|
1077
2100
|
var handlers = /* @__PURE__ */ new Map();
|
|
1078
2101
|
handlers.set("MESSAGE_CREATE", async (client, d) => {
|
|
1079
2102
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
1080
|
-
|
|
2103
|
+
const { GuildMember: GuildMember2 } = await Promise.resolve().then(() => (init_GuildMember(), GuildMember_exports));
|
|
2104
|
+
const data = d;
|
|
2105
|
+
if (data.guild_id && data.member && data.author) {
|
|
2106
|
+
const guild = client.guilds.get(data.guild_id);
|
|
2107
|
+
if (guild) {
|
|
2108
|
+
const memberData = { ...data.member, user: data.author, guild_id: data.guild_id };
|
|
2109
|
+
const member = new GuildMember2(client, memberData, guild);
|
|
2110
|
+
guild.members.set(member.id, member);
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
client.emit(Events.MessageCreate, new Message2(client, data));
|
|
1081
2114
|
});
|
|
1082
2115
|
handlers.set("MESSAGE_UPDATE", async (client, d) => {
|
|
1083
2116
|
const { Message: Message2 } = await Promise.resolve().then(() => (init_Message(), Message_exports));
|
|
@@ -1101,7 +2134,15 @@ handlers.set("MESSAGE_REACTION_ADD", async (client, d) => {
|
|
|
1101
2134
|
username: "Unknown",
|
|
1102
2135
|
discriminator: "0"
|
|
1103
2136
|
});
|
|
1104
|
-
client.emit(
|
|
2137
|
+
client.emit(
|
|
2138
|
+
Events.MessageReactionAdd,
|
|
2139
|
+
reaction,
|
|
2140
|
+
user,
|
|
2141
|
+
reaction.messageId,
|
|
2142
|
+
reaction.channelId,
|
|
2143
|
+
reaction.emoji,
|
|
2144
|
+
user.id
|
|
2145
|
+
);
|
|
1105
2146
|
});
|
|
1106
2147
|
handlers.set("MESSAGE_REACTION_REMOVE", async (client, d) => {
|
|
1107
2148
|
const data = d;
|
|
@@ -1112,7 +2153,15 @@ handlers.set("MESSAGE_REACTION_REMOVE", async (client, d) => {
|
|
|
1112
2153
|
username: "Unknown",
|
|
1113
2154
|
discriminator: "0"
|
|
1114
2155
|
});
|
|
1115
|
-
client.emit(
|
|
2156
|
+
client.emit(
|
|
2157
|
+
Events.MessageReactionRemove,
|
|
2158
|
+
reaction,
|
|
2159
|
+
user,
|
|
2160
|
+
reaction.messageId,
|
|
2161
|
+
reaction.channelId,
|
|
2162
|
+
reaction.emoji,
|
|
2163
|
+
user.id
|
|
2164
|
+
);
|
|
1116
2165
|
});
|
|
1117
2166
|
handlers.set("MESSAGE_REACTION_REMOVE_ALL", async (client, d) => {
|
|
1118
2167
|
client.emit(Events.MessageReactionRemoveAll, d);
|
|
@@ -1126,7 +2175,9 @@ handlers.set("MESSAGE_REACTION_REMOVE_EMOJI", async (client, d) => {
|
|
|
1126
2175
|
handlers.set("GUILD_CREATE", async (client, d) => {
|
|
1127
2176
|
const { Guild: Guild2 } = await Promise.resolve().then(() => (init_Guild(), Guild_exports));
|
|
1128
2177
|
const { Channel: Channel2 } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
1129
|
-
const
|
|
2178
|
+
const raw = d;
|
|
2179
|
+
const guildData = raw?.properties != null ? { ...raw.properties, roles: raw.roles } : raw;
|
|
2180
|
+
const guild = new Guild2(client, guildData);
|
|
1130
2181
|
client.guilds.set(guild.id, guild);
|
|
1131
2182
|
const g = d;
|
|
1132
2183
|
for (const ch of g.channels ?? []) {
|
|
@@ -1140,9 +2191,10 @@ handlers.set("GUILD_CREATE", async (client, d) => {
|
|
|
1140
2191
|
});
|
|
1141
2192
|
handlers.set("GUILD_UPDATE", async (client, d) => {
|
|
1142
2193
|
const { Guild: Guild2 } = await Promise.resolve().then(() => (init_Guild(), Guild_exports));
|
|
1143
|
-
const
|
|
1144
|
-
const
|
|
1145
|
-
const
|
|
2194
|
+
const raw = d;
|
|
2195
|
+
const guildData = raw?.properties != null ? { ...raw.properties, roles: raw.roles } : raw;
|
|
2196
|
+
const old = client.guilds.get(guildData.id);
|
|
2197
|
+
const updated = new Guild2(client, guildData);
|
|
1146
2198
|
client.guilds.set(updated.id, updated);
|
|
1147
2199
|
client.emit(Events.GuildUpdate, old ?? updated, updated);
|
|
1148
2200
|
});
|
|
@@ -1225,10 +2277,16 @@ handlers.set("MESSAGE_DELETE_BULK", async (client, d) => {
|
|
|
1225
2277
|
client.emit(Events.MessageDeleteBulk, d);
|
|
1226
2278
|
});
|
|
1227
2279
|
handlers.set("GUILD_BAN_ADD", async (client, d) => {
|
|
1228
|
-
|
|
2280
|
+
const data = d;
|
|
2281
|
+
const { GuildBan: GuildBan2 } = await Promise.resolve().then(() => (init_GuildBan(), GuildBan_exports));
|
|
2282
|
+
const ban = new GuildBan2(client, data, data.guild_id);
|
|
2283
|
+
client.emit(Events.GuildBanAdd, ban);
|
|
1229
2284
|
});
|
|
1230
2285
|
handlers.set("GUILD_BAN_REMOVE", async (client, d) => {
|
|
1231
|
-
|
|
2286
|
+
const data = d;
|
|
2287
|
+
const { GuildBan: GuildBan2 } = await Promise.resolve().then(() => (init_GuildBan(), GuildBan_exports));
|
|
2288
|
+
const ban = new GuildBan2(client, { ...data, reason: null }, data.guild_id);
|
|
2289
|
+
client.emit(Events.GuildBanRemove, ban);
|
|
1232
2290
|
});
|
|
1233
2291
|
handlers.set("GUILD_EMOJIS_UPDATE", async (client, d) => {
|
|
1234
2292
|
client.emit(Events.GuildEmojisUpdate, d);
|
|
@@ -1276,7 +2334,9 @@ handlers.set("CHANNEL_PINS_UPDATE", async (client, d) => {
|
|
|
1276
2334
|
client.emit(Events.ChannelPinsUpdate, d);
|
|
1277
2335
|
});
|
|
1278
2336
|
handlers.set("INVITE_CREATE", async (client, d) => {
|
|
1279
|
-
|
|
2337
|
+
const data = d;
|
|
2338
|
+
const { Invite: Invite2 } = await Promise.resolve().then(() => (init_Invite(), Invite_exports));
|
|
2339
|
+
client.emit(Events.InviteCreate, new Invite2(client, data));
|
|
1280
2340
|
});
|
|
1281
2341
|
handlers.set("INVITE_DELETE", async (client, d) => {
|
|
1282
2342
|
client.emit(Events.InviteDelete, d);
|
|
@@ -1303,11 +2363,23 @@ handlers.set("RESUMED", async (client) => {
|
|
|
1303
2363
|
var eventHandlers = handlers;
|
|
1304
2364
|
|
|
1305
2365
|
// src/client/Client.ts
|
|
1306
|
-
|
|
2366
|
+
function createEventMethods(client) {
|
|
2367
|
+
const result = {};
|
|
2368
|
+
for (const key of Object.keys(Events)) {
|
|
2369
|
+
const eventName = Events[key];
|
|
2370
|
+
result[key] = (cb) => {
|
|
2371
|
+
client.on(eventName, cb);
|
|
2372
|
+
return client;
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
return result;
|
|
2376
|
+
}
|
|
2377
|
+
var Client = class extends import_events3.EventEmitter {
|
|
1307
2378
|
/** @param options - Token, REST config, WebSocket, presence, etc. */
|
|
1308
2379
|
constructor(options = {}) {
|
|
1309
2380
|
super();
|
|
1310
2381
|
this.options = options;
|
|
2382
|
+
this.events = createEventMethods(this);
|
|
1311
2383
|
Object.defineProperty(this.channels, "cache", {
|
|
1312
2384
|
get: () => this.channels,
|
|
1313
2385
|
configurable: true
|
|
@@ -1316,7 +2388,7 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1316
2388
|
get: () => this.guilds,
|
|
1317
2389
|
configurable: true
|
|
1318
2390
|
});
|
|
1319
|
-
this.rest = new
|
|
2391
|
+
this.rest = new import_rest3.REST({
|
|
1320
2392
|
api: options.rest?.api ?? "https://api.fluxer.app",
|
|
1321
2393
|
version: options.rest?.version ?? "1",
|
|
1322
2394
|
...options.rest
|
|
@@ -1325,8 +2397,12 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1325
2397
|
rest;
|
|
1326
2398
|
guilds = new GuildManager(this);
|
|
1327
2399
|
channels = new ChannelManager(this);
|
|
1328
|
-
users = new
|
|
2400
|
+
users = new import_collection7.Collection();
|
|
2401
|
+
/** Typed event handlers. Use client.events.MessageReactionAdd((reaction, user, messageId, channelId, emoji, userId) => {...}) or client.on(Events.MessageReactionAdd, ...). */
|
|
2402
|
+
events;
|
|
2403
|
+
/** The authenticated bot user. Null until READY is received. */
|
|
1329
2404
|
user = null;
|
|
2405
|
+
/** Timestamp when the client became ready. Null until READY is received. */
|
|
1330
2406
|
readyAt = null;
|
|
1331
2407
|
_ws = null;
|
|
1332
2408
|
/**
|
|
@@ -1339,16 +2415,16 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1339
2415
|
*/
|
|
1340
2416
|
async resolveEmoji(emoji, guildId) {
|
|
1341
2417
|
if (typeof emoji === "object" && emoji.id) {
|
|
1342
|
-
return (0,
|
|
2418
|
+
return (0, import_util7.formatEmoji)({ name: emoji.name, id: emoji.id, animated: emoji.animated });
|
|
1343
2419
|
}
|
|
1344
|
-
const parsed = (0,
|
|
2420
|
+
const parsed = (0, import_util7.parseEmoji)(typeof emoji === "string" ? emoji : `:${emoji.name}:`);
|
|
1345
2421
|
if (!parsed) throw new Error("Invalid emoji");
|
|
1346
|
-
if (parsed.id) return (0,
|
|
2422
|
+
if (parsed.id) return (0, import_util7.formatEmoji)(parsed);
|
|
1347
2423
|
if (guildId) {
|
|
1348
|
-
const emojis = await this.rest.get(
|
|
2424
|
+
const emojis = await this.rest.get(import_types13.Routes.guildEmojis(guildId));
|
|
1349
2425
|
const list = Array.isArray(emojis) ? emojis : Object.values(emojis ?? {});
|
|
1350
2426
|
const found = list.find((e) => e.name && e.name.toLowerCase() === parsed.name.toLowerCase());
|
|
1351
|
-
if (found) return (0,
|
|
2427
|
+
if (found) return (0, import_util7.formatEmoji)({ ...parsed, id: found.id, animated: found.animated });
|
|
1352
2428
|
throw new Error(
|
|
1353
2429
|
`Custom emoji ":${parsed.name}:" not found in guild. Use name:id or <:name:id> format.`
|
|
1354
2430
|
);
|
|
@@ -1364,13 +2440,18 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1364
2440
|
* Fetch a message by channel and message ID. Use when you have IDs (e.g. from a DB).
|
|
1365
2441
|
* @param channelId - Snowflake of the channel
|
|
1366
2442
|
* @param messageId - Snowflake of the message
|
|
1367
|
-
* @returns The message
|
|
2443
|
+
* @returns The message
|
|
2444
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
1368
2445
|
* @deprecated Use channel.messages.fetch(messageId). For IDs-only: (await client.channels.fetch(channelId))?.messages?.fetch(messageId)
|
|
1369
2446
|
* @example
|
|
1370
2447
|
* const channel = await client.channels.fetch(channelId);
|
|
1371
2448
|
* const message = await channel?.messages?.fetch(messageId);
|
|
1372
2449
|
*/
|
|
1373
2450
|
async fetchMessage(channelId, messageId) {
|
|
2451
|
+
(0, import_util7.emitDeprecationWarning)(
|
|
2452
|
+
"Client.fetchMessage()",
|
|
2453
|
+
"Use channel.messages.fetch(messageId). For IDs-only: (await client.channels.fetch(channelId))?.messages?.fetch(messageId)"
|
|
2454
|
+
);
|
|
1374
2455
|
return this.channels.fetchMessage(channelId, messageId);
|
|
1375
2456
|
}
|
|
1376
2457
|
/**
|
|
@@ -1423,7 +2504,9 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1423
2504
|
*/
|
|
1424
2505
|
async login(token) {
|
|
1425
2506
|
if (this._ws) {
|
|
1426
|
-
throw new FluxerError("Client is already logged in. Call destroy() first."
|
|
2507
|
+
throw new FluxerError("Client is already logged in. Call destroy() first.", {
|
|
2508
|
+
code: ErrorCodes.AlreadyLoggedIn
|
|
2509
|
+
});
|
|
1427
2510
|
}
|
|
1428
2511
|
this.rest.setToken(token);
|
|
1429
2512
|
let intents = this.options.intents ?? 0;
|
|
@@ -1460,7 +2543,11 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1460
2543
|
const { Channel: Channel2 } = await Promise.resolve().then(() => (init_Channel(), Channel_exports));
|
|
1461
2544
|
this.user = new ClientUser2(this, data.user);
|
|
1462
2545
|
for (const g of data.guilds ?? []) {
|
|
1463
|
-
const
|
|
2546
|
+
const guildData = g && typeof g === "object" && "properties" in g && g.properties ? {
|
|
2547
|
+
...g.properties,
|
|
2548
|
+
roles: g.roles
|
|
2549
|
+
} : g;
|
|
2550
|
+
const guild = new Guild2(this, guildData);
|
|
1464
2551
|
this.guilds.set(guild.id, guild);
|
|
1465
2552
|
const withCh = g;
|
|
1466
2553
|
for (const ch of withCh.channels ?? []) {
|
|
@@ -1501,7 +2588,7 @@ var Client = class extends import_events.EventEmitter {
|
|
|
1501
2588
|
return this.readyAt !== null && this.user !== null;
|
|
1502
2589
|
}
|
|
1503
2590
|
static get Routes() {
|
|
1504
|
-
return
|
|
2591
|
+
return import_types13.Routes;
|
|
1505
2592
|
}
|
|
1506
2593
|
};
|
|
1507
2594
|
|
|
@@ -1517,16 +2604,118 @@ init_MessageReaction();
|
|
|
1517
2604
|
init_Webhook();
|
|
1518
2605
|
init_GuildMember();
|
|
1519
2606
|
init_Role();
|
|
2607
|
+
init_Invite();
|
|
2608
|
+
init_GuildBan();
|
|
1520
2609
|
|
|
1521
|
-
// src/
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
2610
|
+
// src/structures/GuildEmoji.ts
|
|
2611
|
+
init_Base();
|
|
2612
|
+
var import_types14 = require("@fluxerjs/types");
|
|
2613
|
+
init_Constants();
|
|
2614
|
+
var GuildEmoji = class extends Base {
|
|
2615
|
+
client;
|
|
2616
|
+
id;
|
|
2617
|
+
guildId;
|
|
2618
|
+
name;
|
|
2619
|
+
animated;
|
|
2620
|
+
/** @param data - API emoji from GET /guilds/{id}/emojis or guild emoji events */
|
|
2621
|
+
constructor(client, data, guildId) {
|
|
2622
|
+
super();
|
|
2623
|
+
this.client = client;
|
|
2624
|
+
this.id = data.id;
|
|
2625
|
+
this.guildId = data.guild_id ?? guildId;
|
|
2626
|
+
this.name = data.name;
|
|
2627
|
+
this.animated = data.animated ?? false;
|
|
2628
|
+
}
|
|
2629
|
+
/** CDN URL for this emoji image. */
|
|
2630
|
+
get url() {
|
|
2631
|
+
const ext = this.animated ? "gif" : "png";
|
|
2632
|
+
return `${CDN_URL}/emojis/${this.id}.${ext}`;
|
|
2633
|
+
}
|
|
2634
|
+
/** Emoji identifier for use in reactions: `name:id` */
|
|
2635
|
+
get identifier() {
|
|
2636
|
+
return `${this.name}:${this.id}`;
|
|
2637
|
+
}
|
|
2638
|
+
/** Delete this emoji. Requires Manage Emojis and Stickers permission. */
|
|
2639
|
+
async delete() {
|
|
2640
|
+
await this.client.rest.delete(import_types14.Routes.guildEmoji(this.guildId, this.id), {
|
|
2641
|
+
auth: true
|
|
2642
|
+
});
|
|
2643
|
+
}
|
|
2644
|
+
/**
|
|
2645
|
+
* Edit this emoji's name.
|
|
2646
|
+
* Requires Manage Emojis and Stickers permission.
|
|
2647
|
+
*/
|
|
2648
|
+
async edit(options) {
|
|
2649
|
+
const data = await this.client.rest.patch(import_types14.Routes.guildEmoji(this.guildId, this.id), {
|
|
2650
|
+
body: options,
|
|
2651
|
+
auth: true
|
|
2652
|
+
});
|
|
2653
|
+
this.name = data.name;
|
|
2654
|
+
return this;
|
|
2655
|
+
}
|
|
2656
|
+
};
|
|
2657
|
+
|
|
2658
|
+
// src/structures/GuildSticker.ts
|
|
2659
|
+
init_Base();
|
|
2660
|
+
var import_types15 = require("@fluxerjs/types");
|
|
2661
|
+
init_Constants();
|
|
2662
|
+
var GuildSticker = class extends Base {
|
|
2663
|
+
client;
|
|
2664
|
+
id;
|
|
2665
|
+
guildId;
|
|
2666
|
+
name;
|
|
2667
|
+
description;
|
|
2668
|
+
tags;
|
|
2669
|
+
animated;
|
|
2670
|
+
/** @param data - API sticker from GET /guilds/{id}/stickers or guild sticker events */
|
|
2671
|
+
constructor(client, data, guildId) {
|
|
2672
|
+
super();
|
|
2673
|
+
this.client = client;
|
|
2674
|
+
this.id = data.id;
|
|
2675
|
+
this.guildId = data.guild_id ?? guildId;
|
|
2676
|
+
this.name = data.name;
|
|
2677
|
+
this.description = data.description ?? "";
|
|
2678
|
+
this.tags = data.tags ?? [];
|
|
2679
|
+
this.animated = data.animated ?? false;
|
|
2680
|
+
}
|
|
2681
|
+
/** CDN URL for this sticker image. */
|
|
2682
|
+
get url() {
|
|
2683
|
+
const ext = this.animated ? "gif" : "png";
|
|
2684
|
+
return `${CDN_URL}/stickers/${this.id}.${ext}`;
|
|
2685
|
+
}
|
|
2686
|
+
/** Delete this sticker. Requires Manage Emojis and Stickers permission. */
|
|
2687
|
+
async delete() {
|
|
2688
|
+
await this.client.rest.delete(import_types15.Routes.guildSticker(this.guildId, this.id), {
|
|
2689
|
+
auth: true
|
|
2690
|
+
});
|
|
2691
|
+
}
|
|
2692
|
+
/**
|
|
2693
|
+
* Edit this sticker's name and/or description.
|
|
2694
|
+
* Requires Manage Emojis and Stickers permission.
|
|
2695
|
+
*/
|
|
2696
|
+
async edit(options) {
|
|
2697
|
+
const data = await this.client.rest.patch(import_types15.Routes.guildSticker(this.guildId, this.id), {
|
|
2698
|
+
body: options,
|
|
2699
|
+
auth: true
|
|
2700
|
+
});
|
|
2701
|
+
const s = data;
|
|
2702
|
+
this.name = s.name;
|
|
2703
|
+
this.description = s.description ?? "";
|
|
2704
|
+
return this;
|
|
2705
|
+
}
|
|
1525
2706
|
};
|
|
1526
2707
|
|
|
1527
2708
|
// src/index.ts
|
|
1528
|
-
|
|
1529
|
-
|
|
2709
|
+
init_Events();
|
|
2710
|
+
init_MessageCollector();
|
|
2711
|
+
init_ReactionCollector();
|
|
2712
|
+
init_FluxerError();
|
|
2713
|
+
init_ErrorCodes();
|
|
2714
|
+
var import_builders3 = require("@fluxerjs/builders");
|
|
2715
|
+
var import_types16 = require("@fluxerjs/types");
|
|
2716
|
+
var import_util8 = require("@fluxerjs/util");
|
|
2717
|
+
var import_util9 = require("@fluxerjs/util");
|
|
2718
|
+
init_cdn();
|
|
1530
2719
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1531
2720
|
0 && (module.exports = {
|
|
1532
2721
|
AttachmentBuilder,
|
|
@@ -1543,17 +2732,33 @@ var import_types10 = require("@fluxerjs/types");
|
|
|
1543
2732
|
FluxerError,
|
|
1544
2733
|
GatewayOpcodes,
|
|
1545
2734
|
Guild,
|
|
2735
|
+
GuildBan,
|
|
1546
2736
|
GuildChannel,
|
|
2737
|
+
GuildEmoji,
|
|
1547
2738
|
GuildMember,
|
|
2739
|
+
GuildSticker,
|
|
2740
|
+
Invite,
|
|
1548
2741
|
LinkChannel,
|
|
1549
2742
|
Message,
|
|
2743
|
+
MessageAttachmentFlags,
|
|
2744
|
+
MessageCollector,
|
|
1550
2745
|
MessageManager,
|
|
1551
2746
|
MessagePayload,
|
|
1552
2747
|
MessageReaction,
|
|
2748
|
+
PermissionFlags,
|
|
2749
|
+
PermissionsBitField,
|
|
2750
|
+
ReactionCollector,
|
|
1553
2751
|
Role,
|
|
1554
2752
|
Routes,
|
|
1555
2753
|
TextChannel,
|
|
1556
2754
|
User,
|
|
1557
2755
|
VoiceChannel,
|
|
1558
|
-
Webhook
|
|
2756
|
+
Webhook,
|
|
2757
|
+
cdnAvatarURL,
|
|
2758
|
+
cdnBannerURL,
|
|
2759
|
+
cdnDefaultAvatarURL,
|
|
2760
|
+
cdnDisplayAvatarURL,
|
|
2761
|
+
cdnMemberAvatarURL,
|
|
2762
|
+
cdnMemberBannerURL,
|
|
2763
|
+
resolveTenorToImageUrl
|
|
1559
2764
|
});
|