@fluxerjs/core 1.0.9 → 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-ICWNKXBR.mjs → Channel-WJZZSNML.mjs} +3 -1
- package/dist/{ClientUser-WWXUMO5O.mjs → ClientUser-DJO2FS7P.mjs} +1 -1
- package/dist/Guild-2P77HBQM.mjs +11 -0
- package/dist/{GuildBan-M4PA3HAA.mjs → GuildBan-7CXLTPKY.mjs} +1 -1
- package/dist/GuildMember-43B5E5CH.mjs +9 -0
- 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-53Y37KRG.mjs → chunk-CJVQNARM.mjs} +44 -10
- package/dist/chunk-DQ4TNBPG.mjs +63 -0
- package/dist/chunk-DUQAD7F6.mjs +173 -0
- package/dist/{chunk-GCIJYVRC.mjs → chunk-JHNKZIHY.mjs} +54 -3
- package/dist/{chunk-FJS5FBXO.mjs → chunk-LU2SNC5G.mjs} +172 -13
- package/dist/chunk-PM2IUGNR.mjs +29 -0
- package/dist/{chunk-RCP27MRC.mjs → chunk-UXIF75BV.mjs} +3 -0
- package/dist/{chunk-DSPSRPHF.mjs → chunk-V7LPVPGH.mjs} +123 -18
- package/dist/chunk-X6K3ZD62.mjs +53 -0
- package/dist/index.d.mts +603 -113
- package/dist/index.d.ts +603 -113
- package/dist/index.js +1278 -410
- package/dist/index.mjs +183 -124
- package/package.json +7 -7
- package/dist/Guild-TM6YGJWB.mjs +0 -10
- package/dist/GuildMember-RZWZ3OCG.mjs +0 -7
- package/dist/Message-6IYEYSV6.mjs +0 -7
- package/dist/Webhook-32VJD4AL.mjs +0 -7
- package/dist/chunk-GFUJVQ7L.mjs +0 -64
- package/dist/chunk-SQVCCSNN.mjs +0 -41
- package/dist/chunk-X77DFNE3.mjs +0 -136
|
@@ -1,11 +1,74 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Events
|
|
3
|
+
} from "./chunk-AH7KYH2Z.mjs";
|
|
4
|
+
import {
|
|
5
|
+
buildSendBody
|
|
6
|
+
} from "./chunk-PM2IUGNR.mjs";
|
|
1
7
|
import {
|
|
2
8
|
Base
|
|
3
9
|
} from "./chunk-XNS4O6QJ.mjs";
|
|
4
10
|
|
|
5
11
|
// src/structures/Message.ts
|
|
6
|
-
import { Collection } from "@fluxerjs/collection";
|
|
12
|
+
import { Collection as Collection2 } from "@fluxerjs/collection";
|
|
7
13
|
import { MessageType, Routes } from "@fluxerjs/types";
|
|
8
14
|
import { EmbedBuilder } from "@fluxerjs/builders";
|
|
15
|
+
|
|
16
|
+
// src/util/ReactionCollector.ts
|
|
17
|
+
import { EventEmitter } from "events";
|
|
18
|
+
import { Collection } from "@fluxerjs/collection";
|
|
19
|
+
var ReactionCollector = class extends EventEmitter {
|
|
20
|
+
client;
|
|
21
|
+
messageId;
|
|
22
|
+
channelId;
|
|
23
|
+
options;
|
|
24
|
+
collected = new Collection();
|
|
25
|
+
_timeout = null;
|
|
26
|
+
_ended = false;
|
|
27
|
+
_listener;
|
|
28
|
+
constructor(client, messageId, channelId, options = {}) {
|
|
29
|
+
super();
|
|
30
|
+
this.client = client;
|
|
31
|
+
this.messageId = messageId;
|
|
32
|
+
this.channelId = channelId;
|
|
33
|
+
this.options = {
|
|
34
|
+
filter: options.filter ?? (() => true),
|
|
35
|
+
time: options.time ?? 0,
|
|
36
|
+
max: options.max ?? 0
|
|
37
|
+
};
|
|
38
|
+
this._listener = (reaction, user, _msgId, chId, _emoji, userId) => {
|
|
39
|
+
if (this._ended || reaction.messageId !== this.messageId || chId !== this.channelId) return;
|
|
40
|
+
if (!this.options.filter(reaction, user)) return;
|
|
41
|
+
const key = `${userId}:${reaction.emoji.id ?? reaction.emoji.name}`;
|
|
42
|
+
this.collected.set(key, { reaction, user });
|
|
43
|
+
this.emit("collect", reaction, user);
|
|
44
|
+
if (this.options.max > 0 && this.collected.size >= this.options.max) {
|
|
45
|
+
this.stop("limit");
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
this.client.on(Events.MessageReactionAdd, this._listener);
|
|
49
|
+
if (this.options.time > 0) {
|
|
50
|
+
this._timeout = setTimeout(() => this.stop("time"), this.options.time);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
stop(reason = "user") {
|
|
54
|
+
if (this._ended) return;
|
|
55
|
+
this._ended = true;
|
|
56
|
+
this.client.off(Events.MessageReactionAdd, this._listener);
|
|
57
|
+
if (this._timeout) {
|
|
58
|
+
clearTimeout(this._timeout);
|
|
59
|
+
this._timeout = null;
|
|
60
|
+
}
|
|
61
|
+
this.emit("end", this.collected, reason);
|
|
62
|
+
}
|
|
63
|
+
on(event, listener) {
|
|
64
|
+
return super.on(event, listener);
|
|
65
|
+
}
|
|
66
|
+
emit(event, ...args) {
|
|
67
|
+
return super.emit(event, ...args);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/structures/Message.ts
|
|
9
72
|
var Message = class _Message extends Base {
|
|
10
73
|
client;
|
|
11
74
|
id;
|
|
@@ -28,6 +91,14 @@ var Message = class _Message extends Base {
|
|
|
28
91
|
messageSnapshots;
|
|
29
92
|
call;
|
|
30
93
|
referencedMessage;
|
|
94
|
+
/** Webhook ID if this message was sent via webhook. Null otherwise. */
|
|
95
|
+
webhookId;
|
|
96
|
+
/** Users mentioned in this message. */
|
|
97
|
+
mentions;
|
|
98
|
+
/** Role IDs mentioned in this message. */
|
|
99
|
+
mentionRoles;
|
|
100
|
+
/** Client-side nonce for acknowledgment. Null if not provided. */
|
|
101
|
+
nonce;
|
|
31
102
|
/** Channel where this message was sent. Resolved from cache; null if not cached (e.g. DM channel not in cache). */
|
|
32
103
|
get channel() {
|
|
33
104
|
return this.client.channels.get(this.channelId) ?? null;
|
|
@@ -48,7 +119,7 @@ var Message = class _Message extends Base {
|
|
|
48
119
|
this.createdAt = new Date(data.timestamp);
|
|
49
120
|
this.editedAt = data.edited_timestamp ? new Date(data.edited_timestamp) : null;
|
|
50
121
|
this.pinned = data.pinned;
|
|
51
|
-
this.attachments = new
|
|
122
|
+
this.attachments = new Collection2();
|
|
52
123
|
for (const a of data.attachments ?? []) this.attachments.set(a.id, a);
|
|
53
124
|
this.type = data.type ?? MessageType.Default;
|
|
54
125
|
this.flags = data.flags ?? 0;
|
|
@@ -61,17 +132,24 @@ var Message = class _Message extends Base {
|
|
|
61
132
|
this.messageSnapshots = data.message_snapshots ?? [];
|
|
62
133
|
this.call = data.call ?? null;
|
|
63
134
|
this.referencedMessage = data.referenced_message ? new _Message(client, data.referenced_message) : null;
|
|
135
|
+
this.webhookId = data.webhook_id ?? null;
|
|
136
|
+
this.mentions = (data.mentions ?? []).map((u) => client.getOrCreateUser(u));
|
|
137
|
+
this.mentionRoles = data.mention_roles ?? [];
|
|
138
|
+
this.nonce = data.nonce ?? null;
|
|
64
139
|
}
|
|
65
140
|
/**
|
|
66
141
|
* Send a message to this channel without replying. Use when you want a standalone message.
|
|
67
|
-
* @param options - Text content or object with content and/or
|
|
142
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
68
143
|
* @example
|
|
69
144
|
* await message.send('Pong!');
|
|
70
145
|
* await message.send({ embeds: [embed.toJSON()] });
|
|
146
|
+
* await message.send({ content: 'File', files: [{ name: 'data.txt', data }] });
|
|
71
147
|
*/
|
|
72
148
|
async send(options) {
|
|
73
|
-
const
|
|
74
|
-
const
|
|
149
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
150
|
+
const body = buildSendBody(options);
|
|
151
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
152
|
+
const data = await this.client.rest.post(Routes.channelMessages(this.channelId), postOptions);
|
|
75
153
|
return new _Message(this.client, data);
|
|
76
154
|
}
|
|
77
155
|
/**
|
|
@@ -87,25 +165,21 @@ var Message = class _Message extends Base {
|
|
|
87
165
|
}
|
|
88
166
|
/**
|
|
89
167
|
* Reply to this message.
|
|
90
|
-
* @param options - Text content or object with content and/or
|
|
168
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
91
169
|
*/
|
|
92
170
|
async reply(options) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
message_id: this.id,
|
|
98
|
-
guild_id: this.guildId ?? void 0
|
|
99
|
-
}
|
|
100
|
-
} : {
|
|
101
|
-
...options,
|
|
171
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
172
|
+
const base = buildSendBody(options);
|
|
173
|
+
const body = {
|
|
174
|
+
...base,
|
|
102
175
|
message_reference: {
|
|
103
176
|
channel_id: this.channelId,
|
|
104
177
|
message_id: this.id,
|
|
105
178
|
guild_id: this.guildId ?? void 0
|
|
106
179
|
}
|
|
107
180
|
};
|
|
108
|
-
const
|
|
181
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
182
|
+
const data = await this.client.rest.post(Routes.channelMessages(this.channelId), postOptions);
|
|
109
183
|
return new _Message(this.client, data);
|
|
110
184
|
}
|
|
111
185
|
/**
|
|
@@ -123,13 +197,26 @@ var Message = class _Message extends Base {
|
|
|
123
197
|
});
|
|
124
198
|
return new _Message(this.client, data);
|
|
125
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Create a reaction collector for this message.
|
|
202
|
+
* Collects reactions matching the filter until time expires or max is reached.
|
|
203
|
+
* @param options - Filter, time (ms), and max count
|
|
204
|
+
* @example
|
|
205
|
+
* const collector = message.createReactionCollector({ filter: (r, u) => u.id === userId, time: 10000 });
|
|
206
|
+
* collector.on('collect', (reaction, user) => console.log(user.username, 'reacted with', reaction.emoji.name));
|
|
207
|
+
* collector.on('end', (collected, reason) => { ... });
|
|
208
|
+
*/
|
|
209
|
+
createReactionCollector(options) {
|
|
210
|
+
return new ReactionCollector(this.client, this.id, this.channelId, options);
|
|
211
|
+
}
|
|
126
212
|
/**
|
|
127
213
|
* Re-fetch this message from the API to get the latest content, embeds, reactions, etc.
|
|
128
214
|
* Use when you have a stale Message (e.g. from an old event or cache) and need fresh data.
|
|
129
|
-
* @returns The updated message
|
|
215
|
+
* @returns The updated message
|
|
216
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message was deleted or does not exist
|
|
130
217
|
* @example
|
|
131
218
|
* const updated = await message.fetch();
|
|
132
|
-
*
|
|
219
|
+
* console.log('Latest content:', updated.content);
|
|
133
220
|
*/
|
|
134
221
|
async fetch() {
|
|
135
222
|
return this.client.channels.fetchMessage(this.channelId, this.id);
|
|
@@ -193,8 +280,26 @@ var Message = class _Message extends Base {
|
|
|
193
280
|
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
194
281
|
await this.client.rest.delete(Routes.channelMessageReaction(this.channelId, this.id, emojiStr));
|
|
195
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Fetch users who reacted with the given emoji.
|
|
285
|
+
* @param emoji - Unicode emoji or custom `{ name, id }`
|
|
286
|
+
* @param options - limit (1–100), after (user ID for pagination)
|
|
287
|
+
* @returns Array of User objects
|
|
288
|
+
*/
|
|
289
|
+
async fetchReactionUsers(emoji, options) {
|
|
290
|
+
const emojiStr = await this.resolveEmojiForReaction(emoji);
|
|
291
|
+
const params = new URLSearchParams();
|
|
292
|
+
if (options?.limit != null) params.set("limit", String(options.limit));
|
|
293
|
+
if (options?.after) params.set("after", options.after);
|
|
294
|
+
const qs = params.toString();
|
|
295
|
+
const route = Routes.channelMessageReaction(this.channelId, this.id, emojiStr) + (qs ? `?${qs}` : "");
|
|
296
|
+
const data = await this.client.rest.get(route);
|
|
297
|
+
const list = Array.isArray(data) ? data : data?.users ?? [];
|
|
298
|
+
return list.map((u) => this.client.getOrCreateUser(u));
|
|
299
|
+
}
|
|
196
300
|
};
|
|
197
301
|
|
|
198
302
|
export {
|
|
303
|
+
ReactionCollector,
|
|
199
304
|
Message
|
|
200
305
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CDN_URL
|
|
3
|
+
} from "./chunk-HQMYRYMY.mjs";
|
|
4
|
+
|
|
5
|
+
// src/util/cdn.ts
|
|
6
|
+
function getExtension(hash, options) {
|
|
7
|
+
const ext = options?.extension ?? "png";
|
|
8
|
+
if (hash?.startsWith("a_")) return "gif";
|
|
9
|
+
return ext;
|
|
10
|
+
}
|
|
11
|
+
function appendSize(options) {
|
|
12
|
+
return options?.size ? `?size=${options.size}` : "";
|
|
13
|
+
}
|
|
14
|
+
function cdnAvatarURL(userId, avatarHash, options) {
|
|
15
|
+
if (!avatarHash) return null;
|
|
16
|
+
const ext = getExtension(avatarHash, options);
|
|
17
|
+
const size = appendSize(options);
|
|
18
|
+
return `${CDN_URL}/avatars/${userId}/${avatarHash}.${ext}${size}`;
|
|
19
|
+
}
|
|
20
|
+
function cdnDisplayAvatarURL(userId, avatarHash, options) {
|
|
21
|
+
return cdnAvatarURL(userId, avatarHash, options) ?? `${CDN_URL}/avatars/0/0.png`;
|
|
22
|
+
}
|
|
23
|
+
function cdnBannerURL(resourceId, bannerHash, options) {
|
|
24
|
+
if (!bannerHash) return null;
|
|
25
|
+
const ext = getExtension(bannerHash, options);
|
|
26
|
+
const size = appendSize(options);
|
|
27
|
+
return `${CDN_URL}/banners/${resourceId}/${bannerHash}.${ext}${size}`;
|
|
28
|
+
}
|
|
29
|
+
function cdnMemberAvatarURL(guildId, userId, avatarHash, options) {
|
|
30
|
+
if (!avatarHash) return null;
|
|
31
|
+
const ext = getExtension(avatarHash, options);
|
|
32
|
+
const size = appendSize(options);
|
|
33
|
+
return `${CDN_URL}/guilds/${guildId}/users/${userId}/avatars/${avatarHash}.${ext}${size}`;
|
|
34
|
+
}
|
|
35
|
+
function cdnMemberBannerURL(guildId, userId, bannerHash, options) {
|
|
36
|
+
if (!bannerHash) return null;
|
|
37
|
+
const ext = getExtension(bannerHash, options);
|
|
38
|
+
const size = appendSize(options);
|
|
39
|
+
return `${CDN_URL}/guilds/${guildId}/users/${userId}/banners/${bannerHash}.${ext}${size}`;
|
|
40
|
+
}
|
|
41
|
+
function cdnDefaultAvatarURL(discriminatorIndex) {
|
|
42
|
+
const index = discriminatorIndex != null ? discriminatorIndex % 5 : 0;
|
|
43
|
+
return `${CDN_URL}/avatars/0/${index}.png`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
cdnAvatarURL,
|
|
48
|
+
cdnDisplayAvatarURL,
|
|
49
|
+
cdnBannerURL,
|
|
50
|
+
cdnMemberAvatarURL,
|
|
51
|
+
cdnMemberBannerURL,
|
|
52
|
+
cdnDefaultAvatarURL
|
|
53
|
+
};
|