@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.
Files changed (37) hide show
  1. package/dist/{Channel-TWPDKW2P.mjs → Channel-WJZZSNML.mjs} +3 -1
  2. package/dist/{ClientUser-2K2BACK7.mjs → ClientUser-DJO2FS7P.mjs} +1 -1
  3. package/dist/Guild-2P77HBQM.mjs +11 -0
  4. package/dist/GuildBan-7CXLTPKY.mjs +7 -0
  5. package/dist/GuildMember-43B5E5CH.mjs +9 -0
  6. package/dist/{Message-G2QIKZQK.mjs → Invite-UM5BU5A6.mjs} +3 -3
  7. package/dist/Message-OFIVTTAZ.mjs +9 -0
  8. package/dist/{MessageReaction-XRPYZDSC.mjs → MessageReaction-V4UZ7OXE.mjs} +1 -1
  9. package/dist/{Role-SVLWIAMN.mjs → Role-5MWSGL66.mjs} +1 -1
  10. package/dist/Webhook-RWDDYW2Q.mjs +10 -0
  11. package/dist/chunk-4XJIM6SC.mjs +315 -0
  12. package/dist/chunk-AH7KYH2Z.mjs +50 -0
  13. package/dist/{chunk-HBF5QEDH.mjs → chunk-CEABHTAF.mjs} +1 -0
  14. package/dist/chunk-CJVQNARM.mjs +145 -0
  15. package/dist/chunk-DQ4TNBPG.mjs +63 -0
  16. package/dist/chunk-DUQAD7F6.mjs +173 -0
  17. package/dist/{chunk-4GCZFOS5.mjs → chunk-JHNKZIHY.mjs} +54 -3
  18. package/dist/chunk-LU2SNC5G.mjs +392 -0
  19. package/dist/chunk-PM2IUGNR.mjs +29 -0
  20. package/dist/chunk-QEXIYXXU.mjs +62 -0
  21. package/dist/chunk-UXIF75BV.mjs +36 -0
  22. package/dist/chunk-V7LPVPGH.mjs +305 -0
  23. package/dist/chunk-X6K3ZD62.mjs +53 -0
  24. package/dist/index.d.mts +802 -160
  25. package/dist/index.d.ts +802 -160
  26. package/dist/index.js +1467 -262
  27. package/dist/index.mjs +292 -119
  28. package/package.json +7 -7
  29. package/dist/Guild-CMZGA6DW.mjs +0 -10
  30. package/dist/GuildMember-DW2N6ITI.mjs +0 -7
  31. package/dist/Webhook-2MQESB7Z.mjs +0 -7
  32. package/dist/chunk-CO5EL5LH.mjs +0 -168
  33. package/dist/chunk-CZIO2D7F.mjs +0 -207
  34. package/dist/chunk-JVEOQFUX.mjs +0 -52
  35. package/dist/chunk-SQVCCSNN.mjs +0 -41
  36. package/dist/chunk-TJVZEILY.mjs +0 -120
  37. package/dist/chunk-ZGMM6IPQ.mjs +0 -79
@@ -0,0 +1,62 @@
1
+ import {
2
+ Base
3
+ } from "./chunk-XNS4O6QJ.mjs";
4
+
5
+ // src/structures/Invite.ts
6
+ import { Routes } from "@fluxerjs/types";
7
+ var Invite = class extends Base {
8
+ client;
9
+ code;
10
+ type;
11
+ guild;
12
+ channel;
13
+ inviter;
14
+ memberCount;
15
+ presenceCount;
16
+ expiresAt;
17
+ temporary;
18
+ createdAt;
19
+ uses;
20
+ maxUses;
21
+ maxAge;
22
+ /** @param data - API invite from GET /invites/{code}, channel/guild invite list, or gateway INVITE_CREATE */
23
+ constructor(client, data) {
24
+ super();
25
+ this.client = client;
26
+ this.code = data.code;
27
+ this.type = data.type;
28
+ this.guild = data.guild;
29
+ this.channel = data.channel;
30
+ this.inviter = data.inviter ? client.getOrCreateUser(data.inviter) : null;
31
+ this.memberCount = data.member_count ?? null;
32
+ this.presenceCount = data.presence_count ?? null;
33
+ this.expiresAt = data.expires_at ?? null;
34
+ this.temporary = data.temporary ?? null;
35
+ this.createdAt = data.created_at ?? null;
36
+ this.uses = data.uses ?? null;
37
+ this.maxUses = data.max_uses ?? null;
38
+ this.maxAge = data.max_age ?? null;
39
+ }
40
+ /** Full invite URL (https://fluxer.gg/{code} or instance-specific). */
41
+ get url() {
42
+ return `https://fluxer.gg/${this.code}`;
43
+ }
44
+ /**
45
+ * Resolve the guild from cache if available.
46
+ * @returns The guild, or null if not cached
47
+ */
48
+ getGuild() {
49
+ return this.guild?.id ? this.client.guilds.get(this.guild.id) ?? null : null;
50
+ }
51
+ /**
52
+ * Delete this invite.
53
+ * Requires Manage Guild or Create Instant Invite permission.
54
+ */
55
+ async delete() {
56
+ await this.client.rest.delete(Routes.invite(this.code), { auth: true });
57
+ }
58
+ };
59
+
60
+ export {
61
+ Invite
62
+ };
@@ -0,0 +1,36 @@
1
+ import {
2
+ Base
3
+ } from "./chunk-XNS4O6QJ.mjs";
4
+
5
+ // src/structures/GuildBan.ts
6
+ import { Routes } from "@fluxerjs/types";
7
+ var GuildBan = class extends Base {
8
+ client;
9
+ guildId;
10
+ user;
11
+ reason;
12
+ /** ISO timestamp when a temporary ban expires. Null for permanent bans. */
13
+ expiresAt;
14
+ /** @param data - API ban from GET /guilds/{id}/bans or gateway GUILD_BAN_ADD */
15
+ constructor(client, data, guildId) {
16
+ super();
17
+ this.client = client;
18
+ this.guildId = data.guild_id ?? guildId;
19
+ this.user = client.getOrCreateUser(data.user);
20
+ this.reason = data.reason ?? null;
21
+ this.expiresAt = data.expires_at ?? null;
22
+ }
23
+ /**
24
+ * Remove this ban (unban the user).
25
+ * Requires Ban Members permission.
26
+ */
27
+ async unban() {
28
+ await this.client.rest.delete(Routes.guildBan(this.guildId, this.user.id), {
29
+ auth: true
30
+ });
31
+ }
32
+ };
33
+
34
+ export {
35
+ GuildBan
36
+ };
@@ -0,0 +1,305 @@
1
+ import {
2
+ Events
3
+ } from "./chunk-AH7KYH2Z.mjs";
4
+ import {
5
+ buildSendBody
6
+ } from "./chunk-PM2IUGNR.mjs";
7
+ import {
8
+ Base
9
+ } from "./chunk-XNS4O6QJ.mjs";
10
+
11
+ // src/structures/Message.ts
12
+ import { Collection as Collection2 } from "@fluxerjs/collection";
13
+ import { MessageType, Routes } from "@fluxerjs/types";
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
72
+ var Message = class _Message extends Base {
73
+ client;
74
+ id;
75
+ channelId;
76
+ guildId;
77
+ author;
78
+ content;
79
+ createdAt;
80
+ editedAt;
81
+ pinned;
82
+ attachments;
83
+ type;
84
+ flags;
85
+ mentionEveryone;
86
+ tts;
87
+ embeds;
88
+ stickers;
89
+ reactions;
90
+ messageReference;
91
+ messageSnapshots;
92
+ call;
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;
102
+ /** Channel where this message was sent. Resolved from cache; null if not cached (e.g. DM channel not in cache). */
103
+ get channel() {
104
+ return this.client.channels.get(this.channelId) ?? null;
105
+ }
106
+ /** Guild where this message was sent. Resolved from cache; null for DMs or if not cached. */
107
+ get guild() {
108
+ return this.guildId ? this.client.guilds.get(this.guildId) ?? null : null;
109
+ }
110
+ /** @param data - API message from POST/PATCH /channels/{id}/messages or gateway MESSAGE_CREATE */
111
+ constructor(client, data) {
112
+ super();
113
+ this.client = client;
114
+ this.id = data.id;
115
+ this.channelId = data.channel_id;
116
+ this.guildId = data.guild_id ?? null;
117
+ this.author = client.getOrCreateUser(data.author);
118
+ this.content = data.content;
119
+ this.createdAt = new Date(data.timestamp);
120
+ this.editedAt = data.edited_timestamp ? new Date(data.edited_timestamp) : null;
121
+ this.pinned = data.pinned;
122
+ this.attachments = new Collection2();
123
+ for (const a of data.attachments ?? []) this.attachments.set(a.id, a);
124
+ this.type = data.type ?? MessageType.Default;
125
+ this.flags = data.flags ?? 0;
126
+ this.mentionEveryone = data.mention_everyone ?? false;
127
+ this.tts = data.tts ?? false;
128
+ this.embeds = data.embeds ?? [];
129
+ this.stickers = data.stickers ?? [];
130
+ this.reactions = data.reactions ?? [];
131
+ this.messageReference = data.message_reference ?? null;
132
+ this.messageSnapshots = data.message_snapshots ?? [];
133
+ this.call = data.call ?? null;
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;
139
+ }
140
+ /**
141
+ * Send a message to this channel without replying. Use when you want a standalone message.
142
+ * @param options - Text content or object with content, embeds, and/or files
143
+ * @example
144
+ * await message.send('Pong!');
145
+ * await message.send({ embeds: [embed.toJSON()] });
146
+ * await message.send({ content: 'File', files: [{ name: 'data.txt', data }] });
147
+ */
148
+ async send(options) {
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);
153
+ return new _Message(this.client, data);
154
+ }
155
+ /**
156
+ * Send a message to a specific channel. Use for logging, forwarding, or sending to another channel in the guild.
157
+ * @param channelId - Snowflake of the target channel (e.g. log channel ID)
158
+ * @param options - Text content or object with content and/or embeds
159
+ * @example
160
+ * await message.sendTo(logChannelId, 'User ' + message.author.username + ' said: ' + message.content);
161
+ * await message.sendTo(announceChannelId, { embeds: [embed.toJSON()] });
162
+ */
163
+ async sendTo(channelId, options) {
164
+ return this.client.channels.send(channelId, options);
165
+ }
166
+ /**
167
+ * Reply to this message.
168
+ * @param options - Text content or object with content, embeds, and/or files
169
+ */
170
+ async reply(options) {
171
+ const opts = typeof options === "string" ? { content: options } : options;
172
+ const base = buildSendBody(options);
173
+ const body = {
174
+ ...base,
175
+ message_reference: {
176
+ channel_id: this.channelId,
177
+ message_id: this.id,
178
+ guild_id: this.guildId ?? void 0
179
+ }
180
+ };
181
+ const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
182
+ const data = await this.client.rest.post(Routes.channelMessages(this.channelId), postOptions);
183
+ return new _Message(this.client, data);
184
+ }
185
+ /**
186
+ * Edit this message. Only the author (or admins) can edit.
187
+ * @param options - New content and/or embeds
188
+ */
189
+ async edit(options) {
190
+ const body = {};
191
+ if (options.content !== void 0) body.content = options.content;
192
+ if (options.embeds?.length) {
193
+ body.embeds = options.embeds.map((e) => e instanceof EmbedBuilder ? e.toJSON() : e);
194
+ }
195
+ const data = await this.client.rest.patch(Routes.channelMessage(this.channelId, this.id), {
196
+ body
197
+ });
198
+ return new _Message(this.client, data);
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
+ }
212
+ /**
213
+ * Re-fetch this message from the API to get the latest content, embeds, reactions, etc.
214
+ * Use when you have a stale Message (e.g. from an old event or cache) and need fresh data.
215
+ * @returns The updated message
216
+ * @throws FluxerError with MESSAGE_NOT_FOUND if the message was deleted or does not exist
217
+ * @example
218
+ * const updated = await message.fetch();
219
+ * console.log('Latest content:', updated.content);
220
+ */
221
+ async fetch() {
222
+ return this.client.channels.fetchMessage(this.channelId, this.id);
223
+ }
224
+ /** Delete this message. */
225
+ async delete() {
226
+ await this.client.rest.delete(Routes.channelMessage(this.channelId, this.id));
227
+ }
228
+ /** Pin this message to the channel. Requires Manage Messages permission. */
229
+ async pin() {
230
+ await this.client.rest.put(Routes.channelPinMessage(this.channelId, this.id));
231
+ this.pinned = true;
232
+ }
233
+ /** Unpin this message from the channel. Requires Manage Messages permission. */
234
+ async unpin() {
235
+ await this.client.rest.delete(Routes.channelPinMessage(this.channelId, this.id));
236
+ this.pinned = false;
237
+ }
238
+ /**
239
+ * Format emoji for reaction API: unicode string or "name:id" for custom.
240
+ * For string resolution (e.g. :name:), use client.resolveEmoji; Message methods resolve automatically when guildId is available.
241
+ */
242
+ static formatEmoji(emoji) {
243
+ if (typeof emoji === "string") return emoji;
244
+ return `${emoji.name}:${emoji.id}`;
245
+ }
246
+ resolveEmojiForReaction(emoji) {
247
+ return this.client.resolveEmoji(emoji, this.guildId);
248
+ }
249
+ /**
250
+ * Add a reaction to this message (as the bot).
251
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
252
+ */
253
+ async react(emoji) {
254
+ const emojiStr = await this.resolveEmojiForReaction(emoji);
255
+ const route = `${Routes.channelMessageReaction(this.channelId, this.id, emojiStr)}/@me`;
256
+ await this.client.rest.put(route);
257
+ }
258
+ /**
259
+ * Remove the bot's reaction, or a specific user's reaction if userId is provided.
260
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`
261
+ * @param userId - If provided, removes that user's reaction (requires moderator permissions)
262
+ */
263
+ async removeReaction(emoji, userId) {
264
+ const emojiStr = await this.resolveEmojiForReaction(emoji);
265
+ const route = `${Routes.channelMessageReaction(this.channelId, this.id, emojiStr)}/${userId ?? "@me"}`;
266
+ await this.client.rest.delete(route);
267
+ }
268
+ /**
269
+ * Remove all reactions from this message.
270
+ * Requires moderator permissions.
271
+ */
272
+ async removeAllReactions() {
273
+ await this.client.rest.delete(Routes.channelMessageReactions(this.channelId, this.id));
274
+ }
275
+ /**
276
+ * Remove all reactions of a specific emoji from this message.
277
+ * @param emoji - Unicode emoji, custom `{ name, id }`, `:name:`, `name:id`, or `<:name:id>`. Requires moderator permissions.
278
+ */
279
+ async removeReactionEmoji(emoji) {
280
+ const emojiStr = await this.resolveEmojiForReaction(emoji);
281
+ await this.client.rest.delete(Routes.channelMessageReaction(this.channelId, this.id, emojiStr));
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
+ }
300
+ };
301
+
302
+ export {
303
+ ReactionCollector,
304
+ Message
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
+ };