@fluxerjs/core 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +76 -29
- package/dist/index.d.ts +76 -29
- package/dist/index.js +156 -56
- package/dist/index.mjs +167 -65
- package/package.json +8 -8
package/dist/index.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ export { GatewayOpcodes, MessageAttachmentFlags, Routes } from '@fluxerjs/types'
|
|
|
6
6
|
import { Collection } from '@fluxerjs/collection';
|
|
7
7
|
import { EmbedBuilder } from '@fluxerjs/builders';
|
|
8
8
|
export { AttachmentBuilder, EmbedBuilder, MessagePayload } from '@fluxerjs/builders';
|
|
9
|
-
import { PermissionResolvable } from '@fluxerjs/util';
|
|
9
|
+
import { PermissionsBitField, PermissionResolvable, BitField } from '@fluxerjs/util';
|
|
10
10
|
export { PermissionFlags, PermissionResolvable, PermissionString, PermissionsBitField, UserFlagsBitField, UserFlagsBits, UserFlagsResolvable, UserFlagsString, parsePrefixCommand, parseUserMention, resolvePermissionsToBitfield, resolveTenorToImageUrl } from '@fluxerjs/util';
|
|
11
11
|
|
|
12
12
|
/** Resolved file data (after URL fetch). Used internally by REST layer. */
|
|
@@ -45,8 +45,10 @@ type MessageSendOptions = {
|
|
|
45
45
|
files?: MessageFileData[];
|
|
46
46
|
/** Attachment metadata for files (id = index). Use when files are provided. */
|
|
47
47
|
attachments?: MessageAttachmentMeta[];
|
|
48
|
+
/** Message flags (e.g. MessageFlags.SuppressNotifications for reply without ping). */
|
|
49
|
+
flags?: number;
|
|
48
50
|
};
|
|
49
|
-
/** API-ready body from MessageSendOptions (serializes EmbedBuilder, includes attachments when files present). */
|
|
51
|
+
/** API-ready body from MessageSendOptions or text content (serializes EmbedBuilder, includes attachments when files present). */
|
|
50
52
|
interface SendBodyResult {
|
|
51
53
|
content?: string;
|
|
52
54
|
embeds?: APIEmbed[];
|
|
@@ -57,6 +59,8 @@ interface SendBodyResult {
|
|
|
57
59
|
description?: string | null;
|
|
58
60
|
flags?: number;
|
|
59
61
|
}>;
|
|
62
|
+
/** Message flags (e.g. SuppressNotifications for reply without ping). */
|
|
63
|
+
flags?: number;
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/** Base class for all Fluxer structures. Provides the client reference. */
|
|
@@ -130,7 +134,7 @@ declare class Role extends Base {
|
|
|
130
134
|
name: string;
|
|
131
135
|
color: number;
|
|
132
136
|
position: number;
|
|
133
|
-
|
|
137
|
+
_permissions: string;
|
|
134
138
|
hoist: boolean;
|
|
135
139
|
mentionable: boolean;
|
|
136
140
|
unicodeEmoji: string | null;
|
|
@@ -140,19 +144,11 @@ declare class Role extends Base {
|
|
|
140
144
|
/** @param data - API role from GET /guilds/{id}/roles or gateway role events */
|
|
141
145
|
/** @param guildId - The guild this role belongs to */
|
|
142
146
|
constructor(client: Client, data: APIRole, guildId: string);
|
|
147
|
+
get permissions(): PermissionsBitField;
|
|
143
148
|
/** Update mutable fields from fresh API data. Used by edit and gateway events. */
|
|
144
149
|
_patch(data: Partial<APIRole>): void;
|
|
145
150
|
/** Returns a mention string (e.g. `<@&123456>`). */
|
|
146
151
|
toString(): string;
|
|
147
|
-
/**
|
|
148
|
-
* Check if this role has a permission. Administrator grants all permissions.
|
|
149
|
-
* @param permission - Permission flag, name, or resolvable
|
|
150
|
-
* @returns true if the role has the permission
|
|
151
|
-
* @example
|
|
152
|
-
* if (role.has(PermissionFlags.BanMembers)) { ... }
|
|
153
|
-
* if (role.has('ManageChannels')) { ... }
|
|
154
|
-
*/
|
|
155
|
-
has(permission: PermissionResolvable): boolean;
|
|
156
152
|
/**
|
|
157
153
|
* Edit this role.
|
|
158
154
|
* Requires Manage Roles permission.
|
|
@@ -332,9 +328,7 @@ declare class GuildMember extends Base {
|
|
|
332
328
|
* const perms = member.permissions;
|
|
333
329
|
* if (perms.has(PermissionFlags.BanMembers)) { ... }
|
|
334
330
|
*/
|
|
335
|
-
get permissions():
|
|
336
|
-
has(permission: PermissionResolvable): boolean;
|
|
337
|
-
};
|
|
331
|
+
get permissions(): BitField<"CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTtsMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVad" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageExpressions" | "UseExternalStickers" | "ModerateMembers" | "CreateExpressions" | "PinMessages" | "BypassSlowmode" | "UpdateRtcRegion">;
|
|
338
332
|
/**
|
|
339
333
|
* Compute the member's effective permissions in a guild channel.
|
|
340
334
|
* Applies role permissions and channel overwrites.
|
|
@@ -344,9 +338,21 @@ declare class GuildMember extends Base {
|
|
|
344
338
|
* const perms = member.permissionsIn(channel);
|
|
345
339
|
* if (perms.has(PermissionFlags.SendMessages)) { ... }
|
|
346
340
|
*/
|
|
347
|
-
permissionsIn(channel: GuildChannel):
|
|
348
|
-
|
|
349
|
-
|
|
341
|
+
permissionsIn(channel: GuildChannel): BitField<"CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTtsMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVad" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageExpressions" | "UseExternalStickers" | "ModerateMembers" | "CreateExpressions" | "PinMessages" | "BypassSlowmode" | "UpdateRtcRegion">;
|
|
342
|
+
/**
|
|
343
|
+
* Move this member to a different voice channel or disconnect them from voice.
|
|
344
|
+
* Requires Move Members permission.
|
|
345
|
+
* @param channelId - The voice channel ID to move the member to, or null to disconnect
|
|
346
|
+
* @param connectionId - Optional connection ID for the specific voice session (usually not needed)
|
|
347
|
+
* @returns Promise that resolves when the member has been moved
|
|
348
|
+
* @example
|
|
349
|
+
* // Move member to a different voice channel
|
|
350
|
+
* await member.move('123456789012345678');
|
|
351
|
+
*
|
|
352
|
+
* // Disconnect member from voice
|
|
353
|
+
* await member.move(null);
|
|
354
|
+
*/
|
|
355
|
+
move(channelId: string | null, connectionId?: string | null): Promise<void>;
|
|
350
356
|
private _computeBasePermissions;
|
|
351
357
|
}
|
|
352
358
|
|
|
@@ -929,9 +935,20 @@ interface MessageEditOptions {
|
|
|
929
935
|
type MessagePayload = {
|
|
930
936
|
files?: ResolvedMessageFile[];
|
|
931
937
|
body: SendBodyResult & {
|
|
932
|
-
|
|
938
|
+
message_reference?: APIMessageReference;
|
|
939
|
+
flags?: number;
|
|
933
940
|
};
|
|
934
941
|
};
|
|
942
|
+
/** Options for message.reply() — ping toggle and reply-to-different-message. */
|
|
943
|
+
interface ReplyOptions {
|
|
944
|
+
/** Whether to ping the replied-to user (default true). Use false to suppress the mention notification. */
|
|
945
|
+
ping?: boolean;
|
|
946
|
+
/** Reply to a different message instead of this one. Default: this message. */
|
|
947
|
+
replyTo?: Message | {
|
|
948
|
+
channelId: string;
|
|
949
|
+
messageId: string;
|
|
950
|
+
};
|
|
951
|
+
}
|
|
935
952
|
|
|
936
953
|
/** Represents a message in a channel. */
|
|
937
954
|
declare class Message extends Base {
|
|
@@ -1004,18 +1021,20 @@ declare class Message extends Base {
|
|
|
1004
1021
|
sendTo(channelId: string, options: MessageSendOptions): Promise<Message>;
|
|
1005
1022
|
/**
|
|
1006
1023
|
* Reply to this message (shows as a reply in the client).
|
|
1007
|
-
* @param options - Text content or object with content, embeds, and/or
|
|
1024
|
+
* @param options - Text content or object with content, embeds, and/or reply options (ping, replyTo)
|
|
1008
1025
|
* @example
|
|
1009
1026
|
* await message.reply('Pong!');
|
|
1010
1027
|
* await message.reply({ embeds: [embed] });
|
|
1028
|
+
* await message.reply('No ping!', { ping: false });
|
|
1029
|
+
* await message.reply({ content: 'Reply to other', replyTo: otherMessage });
|
|
1011
1030
|
*/
|
|
1012
|
-
reply(options: string | MessageSendOptions): Promise<Message>;
|
|
1031
|
+
reply(options: string | (MessageSendOptions & ReplyOptions), replyOptions?: ReplyOptions): Promise<Message>;
|
|
1013
1032
|
/** Exposed for testing purposes, use Message.reply() or send() for normal use */
|
|
1014
1033
|
static _createMessageBody(content: string | MessageSendOptions, referenced_message?: {
|
|
1015
1034
|
channel_id: string;
|
|
1016
1035
|
message_id: string;
|
|
1017
1036
|
guild_id?: string;
|
|
1018
|
-
}): Promise<MessagePayload>;
|
|
1037
|
+
}, ping?: boolean): Promise<MessagePayload>;
|
|
1019
1038
|
_send(payload: MessagePayload): Promise<Message>;
|
|
1020
1039
|
/**
|
|
1021
1040
|
* Edit this message. Only the author (or admins) can edit.
|
|
@@ -1111,15 +1130,23 @@ declare class Message extends Base {
|
|
|
1111
1130
|
/**
|
|
1112
1131
|
* Manages messages for a channel. Access via channel.messages.
|
|
1113
1132
|
* @example
|
|
1114
|
-
* const message =
|
|
1133
|
+
* const message = channel.messages.get(messageId); // from cache (if enabled)
|
|
1134
|
+
* const message = await channel.messages.fetch(messageId); // from API
|
|
1115
1135
|
* if (message) await message.edit({ content: 'Updated!' });
|
|
1116
1136
|
*/
|
|
1117
1137
|
declare class MessageManager {
|
|
1118
1138
|
private readonly client;
|
|
1119
1139
|
private readonly channelId;
|
|
1120
1140
|
constructor(client: Client, channelId: string);
|
|
1141
|
+
/**
|
|
1142
|
+
* Get a message from cache. Returns undefined if not cached or caching is disabled.
|
|
1143
|
+
* Requires options.cache.messages > 0.
|
|
1144
|
+
* @param messageId - Snowflake of the message
|
|
1145
|
+
*/
|
|
1146
|
+
get(messageId: string): Message | undefined;
|
|
1121
1147
|
/**
|
|
1122
1148
|
* Fetch a message by ID from this channel.
|
|
1149
|
+
* When message caching is enabled, the fetched message is added to the cache.
|
|
1123
1150
|
* @param messageId - Snowflake of the message
|
|
1124
1151
|
* @returns The message
|
|
1125
1152
|
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
@@ -1483,7 +1510,7 @@ declare class ChannelManager extends Collection<string, Channel | GuildChannel>
|
|
|
1483
1510
|
* await client.channels.send(channelId, { embeds: [embed] });
|
|
1484
1511
|
* await client.channels.send(channelId, { content: 'Report', files: [{ name: 'log.txt', data }] });
|
|
1485
1512
|
*/
|
|
1486
|
-
send(channelId: string, payload: MessageSendOptions): Promise<Message>;
|
|
1513
|
+
send(channelId: string, payload: string | MessageSendOptions): Promise<Message>;
|
|
1487
1514
|
}
|
|
1488
1515
|
|
|
1489
1516
|
/**
|
|
@@ -1531,6 +1558,8 @@ interface CacheSizeLimits {
|
|
|
1531
1558
|
channels?: number;
|
|
1532
1559
|
guilds?: number;
|
|
1533
1560
|
users?: number;
|
|
1561
|
+
/** Max messages per channel to cache. Enables channel.messages.get() and oldMessage in messageUpdate. 0 = disabled. */
|
|
1562
|
+
messages?: number;
|
|
1534
1563
|
}
|
|
1535
1564
|
interface ClientOptions {
|
|
1536
1565
|
rest?: Partial<ConstructorParameters<typeof REST>[0]>;
|
|
@@ -1776,6 +1805,10 @@ declare class Client extends EventEmitter {
|
|
|
1776
1805
|
private _ws;
|
|
1777
1806
|
/** When waitForGuilds, set of guild IDs we're waiting for GUILD_CREATE on. Null when not waiting. */
|
|
1778
1807
|
_pendingGuildIds: Set<string> | null;
|
|
1808
|
+
/** Timeout for guild stream when READY has no guilds (gateway sends only GUILD_CREATE). Cleared in finally. */
|
|
1809
|
+
private _guildStreamSettleTimeout;
|
|
1810
|
+
/** Per-channel message cache (channelId -> messageId -> APIMessage). Used when options.cache.messages > 0. */
|
|
1811
|
+
private _messageCaches;
|
|
1779
1812
|
/** @param options - Token, REST config, WebSocket, presence, etc. */
|
|
1780
1813
|
constructor(options?: ClientOptions);
|
|
1781
1814
|
/**
|
|
@@ -1818,11 +1851,25 @@ declare class Client extends EventEmitter {
|
|
|
1818
1851
|
/**
|
|
1819
1852
|
* Send a message to any channel by ID. Shorthand for client.channels.send().
|
|
1820
1853
|
* Works even when the channel is not cached.
|
|
1854
|
+
* @deprecated Use client.channels.send(channelId, payload).
|
|
1855
|
+
*/
|
|
1856
|
+
sendToChannel(channelId: string, payload: string | MessageSendOptions): Promise<Message>;
|
|
1857
|
+
/**
|
|
1858
|
+
* Get the message cache for a channel. Returns null if message caching is disabled.
|
|
1859
|
+
* Used by MessageManager.get() and event handlers.
|
|
1860
|
+
* @internal
|
|
1861
|
+
*/
|
|
1862
|
+
_getMessageCache(channelId: string): Map<string, APIMessage> | null;
|
|
1863
|
+
/**
|
|
1864
|
+
* Add a message to the channel cache. Evicts oldest (FIFO) when over limit.
|
|
1865
|
+
* @internal
|
|
1866
|
+
*/
|
|
1867
|
+
_addMessageToCache(channelId: string, data: APIMessage): void;
|
|
1868
|
+
/**
|
|
1869
|
+
* Remove a message from the channel cache.
|
|
1870
|
+
* @internal
|
|
1821
1871
|
*/
|
|
1822
|
-
|
|
1823
|
-
content?: string;
|
|
1824
|
-
embeds?: APIEmbed[];
|
|
1825
|
-
}): Promise<Message>;
|
|
1872
|
+
_removeMessageFromCache(channelId: string, messageId: string): void;
|
|
1826
1873
|
/**
|
|
1827
1874
|
* Get or create a User from API data. Caches in client.users.
|
|
1828
1875
|
* Updates existing user's username, avatar, etc. when fresh data is provided.
|
|
@@ -1957,4 +2004,4 @@ declare function cdnMemberBannerURL(guildId: string, userId: string, bannerHash:
|
|
|
1957
2004
|
*/
|
|
1958
2005
|
declare function cdnDefaultAvatarURL(userIdOrIndex: string | number): string;
|
|
1959
2006
|
|
|
1960
|
-
export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildMemberRoleManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, Role, type RoleResolvable, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };
|
|
2007
|
+
export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildMemberRoleManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, type ReplyOptions, Role, type RoleResolvable, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { GatewayOpcodes, MessageAttachmentFlags, Routes } from '@fluxerjs/types'
|
|
|
6
6
|
import { Collection } from '@fluxerjs/collection';
|
|
7
7
|
import { EmbedBuilder } from '@fluxerjs/builders';
|
|
8
8
|
export { AttachmentBuilder, EmbedBuilder, MessagePayload } from '@fluxerjs/builders';
|
|
9
|
-
import { PermissionResolvable } from '@fluxerjs/util';
|
|
9
|
+
import { PermissionsBitField, PermissionResolvable, BitField } from '@fluxerjs/util';
|
|
10
10
|
export { PermissionFlags, PermissionResolvable, PermissionString, PermissionsBitField, UserFlagsBitField, UserFlagsBits, UserFlagsResolvable, UserFlagsString, parsePrefixCommand, parseUserMention, resolvePermissionsToBitfield, resolveTenorToImageUrl } from '@fluxerjs/util';
|
|
11
11
|
|
|
12
12
|
/** Resolved file data (after URL fetch). Used internally by REST layer. */
|
|
@@ -45,8 +45,10 @@ type MessageSendOptions = {
|
|
|
45
45
|
files?: MessageFileData[];
|
|
46
46
|
/** Attachment metadata for files (id = index). Use when files are provided. */
|
|
47
47
|
attachments?: MessageAttachmentMeta[];
|
|
48
|
+
/** Message flags (e.g. MessageFlags.SuppressNotifications for reply without ping). */
|
|
49
|
+
flags?: number;
|
|
48
50
|
};
|
|
49
|
-
/** API-ready body from MessageSendOptions (serializes EmbedBuilder, includes attachments when files present). */
|
|
51
|
+
/** API-ready body from MessageSendOptions or text content (serializes EmbedBuilder, includes attachments when files present). */
|
|
50
52
|
interface SendBodyResult {
|
|
51
53
|
content?: string;
|
|
52
54
|
embeds?: APIEmbed[];
|
|
@@ -57,6 +59,8 @@ interface SendBodyResult {
|
|
|
57
59
|
description?: string | null;
|
|
58
60
|
flags?: number;
|
|
59
61
|
}>;
|
|
62
|
+
/** Message flags (e.g. SuppressNotifications for reply without ping). */
|
|
63
|
+
flags?: number;
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
/** Base class for all Fluxer structures. Provides the client reference. */
|
|
@@ -130,7 +134,7 @@ declare class Role extends Base {
|
|
|
130
134
|
name: string;
|
|
131
135
|
color: number;
|
|
132
136
|
position: number;
|
|
133
|
-
|
|
137
|
+
_permissions: string;
|
|
134
138
|
hoist: boolean;
|
|
135
139
|
mentionable: boolean;
|
|
136
140
|
unicodeEmoji: string | null;
|
|
@@ -140,19 +144,11 @@ declare class Role extends Base {
|
|
|
140
144
|
/** @param data - API role from GET /guilds/{id}/roles or gateway role events */
|
|
141
145
|
/** @param guildId - The guild this role belongs to */
|
|
142
146
|
constructor(client: Client, data: APIRole, guildId: string);
|
|
147
|
+
get permissions(): PermissionsBitField;
|
|
143
148
|
/** Update mutable fields from fresh API data. Used by edit and gateway events. */
|
|
144
149
|
_patch(data: Partial<APIRole>): void;
|
|
145
150
|
/** Returns a mention string (e.g. `<@&123456>`). */
|
|
146
151
|
toString(): string;
|
|
147
|
-
/**
|
|
148
|
-
* Check if this role has a permission. Administrator grants all permissions.
|
|
149
|
-
* @param permission - Permission flag, name, or resolvable
|
|
150
|
-
* @returns true if the role has the permission
|
|
151
|
-
* @example
|
|
152
|
-
* if (role.has(PermissionFlags.BanMembers)) { ... }
|
|
153
|
-
* if (role.has('ManageChannels')) { ... }
|
|
154
|
-
*/
|
|
155
|
-
has(permission: PermissionResolvable): boolean;
|
|
156
152
|
/**
|
|
157
153
|
* Edit this role.
|
|
158
154
|
* Requires Manage Roles permission.
|
|
@@ -332,9 +328,7 @@ declare class GuildMember extends Base {
|
|
|
332
328
|
* const perms = member.permissions;
|
|
333
329
|
* if (perms.has(PermissionFlags.BanMembers)) { ... }
|
|
334
330
|
*/
|
|
335
|
-
get permissions():
|
|
336
|
-
has(permission: PermissionResolvable): boolean;
|
|
337
|
-
};
|
|
331
|
+
get permissions(): BitField<"CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTtsMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVad" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageExpressions" | "UseExternalStickers" | "ModerateMembers" | "CreateExpressions" | "PinMessages" | "BypassSlowmode" | "UpdateRtcRegion">;
|
|
338
332
|
/**
|
|
339
333
|
* Compute the member's effective permissions in a guild channel.
|
|
340
334
|
* Applies role permissions and channel overwrites.
|
|
@@ -344,9 +338,21 @@ declare class GuildMember extends Base {
|
|
|
344
338
|
* const perms = member.permissionsIn(channel);
|
|
345
339
|
* if (perms.has(PermissionFlags.SendMessages)) { ... }
|
|
346
340
|
*/
|
|
347
|
-
permissionsIn(channel: GuildChannel):
|
|
348
|
-
|
|
349
|
-
|
|
341
|
+
permissionsIn(channel: GuildChannel): BitField<"CreateInstantInvite" | "KickMembers" | "BanMembers" | "Administrator" | "ManageChannels" | "ManageGuild" | "AddReactions" | "ViewAuditLog" | "PrioritySpeaker" | "Stream" | "ViewChannel" | "SendMessages" | "SendTtsMessages" | "ManageMessages" | "EmbedLinks" | "AttachFiles" | "ReadMessageHistory" | "MentionEveryone" | "UseExternalEmojis" | "Connect" | "Speak" | "MuteMembers" | "DeafenMembers" | "MoveMembers" | "UseVad" | "ChangeNickname" | "ManageNicknames" | "ManageRoles" | "ManageWebhooks" | "ManageEmojisAndStickers" | "ManageExpressions" | "UseExternalStickers" | "ModerateMembers" | "CreateExpressions" | "PinMessages" | "BypassSlowmode" | "UpdateRtcRegion">;
|
|
342
|
+
/**
|
|
343
|
+
* Move this member to a different voice channel or disconnect them from voice.
|
|
344
|
+
* Requires Move Members permission.
|
|
345
|
+
* @param channelId - The voice channel ID to move the member to, or null to disconnect
|
|
346
|
+
* @param connectionId - Optional connection ID for the specific voice session (usually not needed)
|
|
347
|
+
* @returns Promise that resolves when the member has been moved
|
|
348
|
+
* @example
|
|
349
|
+
* // Move member to a different voice channel
|
|
350
|
+
* await member.move('123456789012345678');
|
|
351
|
+
*
|
|
352
|
+
* // Disconnect member from voice
|
|
353
|
+
* await member.move(null);
|
|
354
|
+
*/
|
|
355
|
+
move(channelId: string | null, connectionId?: string | null): Promise<void>;
|
|
350
356
|
private _computeBasePermissions;
|
|
351
357
|
}
|
|
352
358
|
|
|
@@ -929,9 +935,20 @@ interface MessageEditOptions {
|
|
|
929
935
|
type MessagePayload = {
|
|
930
936
|
files?: ResolvedMessageFile[];
|
|
931
937
|
body: SendBodyResult & {
|
|
932
|
-
|
|
938
|
+
message_reference?: APIMessageReference;
|
|
939
|
+
flags?: number;
|
|
933
940
|
};
|
|
934
941
|
};
|
|
942
|
+
/** Options for message.reply() — ping toggle and reply-to-different-message. */
|
|
943
|
+
interface ReplyOptions {
|
|
944
|
+
/** Whether to ping the replied-to user (default true). Use false to suppress the mention notification. */
|
|
945
|
+
ping?: boolean;
|
|
946
|
+
/** Reply to a different message instead of this one. Default: this message. */
|
|
947
|
+
replyTo?: Message | {
|
|
948
|
+
channelId: string;
|
|
949
|
+
messageId: string;
|
|
950
|
+
};
|
|
951
|
+
}
|
|
935
952
|
|
|
936
953
|
/** Represents a message in a channel. */
|
|
937
954
|
declare class Message extends Base {
|
|
@@ -1004,18 +1021,20 @@ declare class Message extends Base {
|
|
|
1004
1021
|
sendTo(channelId: string, options: MessageSendOptions): Promise<Message>;
|
|
1005
1022
|
/**
|
|
1006
1023
|
* Reply to this message (shows as a reply in the client).
|
|
1007
|
-
* @param options - Text content or object with content, embeds, and/or
|
|
1024
|
+
* @param options - Text content or object with content, embeds, and/or reply options (ping, replyTo)
|
|
1008
1025
|
* @example
|
|
1009
1026
|
* await message.reply('Pong!');
|
|
1010
1027
|
* await message.reply({ embeds: [embed] });
|
|
1028
|
+
* await message.reply('No ping!', { ping: false });
|
|
1029
|
+
* await message.reply({ content: 'Reply to other', replyTo: otherMessage });
|
|
1011
1030
|
*/
|
|
1012
|
-
reply(options: string | MessageSendOptions): Promise<Message>;
|
|
1031
|
+
reply(options: string | (MessageSendOptions & ReplyOptions), replyOptions?: ReplyOptions): Promise<Message>;
|
|
1013
1032
|
/** Exposed for testing purposes, use Message.reply() or send() for normal use */
|
|
1014
1033
|
static _createMessageBody(content: string | MessageSendOptions, referenced_message?: {
|
|
1015
1034
|
channel_id: string;
|
|
1016
1035
|
message_id: string;
|
|
1017
1036
|
guild_id?: string;
|
|
1018
|
-
}): Promise<MessagePayload>;
|
|
1037
|
+
}, ping?: boolean): Promise<MessagePayload>;
|
|
1019
1038
|
_send(payload: MessagePayload): Promise<Message>;
|
|
1020
1039
|
/**
|
|
1021
1040
|
* Edit this message. Only the author (or admins) can edit.
|
|
@@ -1111,15 +1130,23 @@ declare class Message extends Base {
|
|
|
1111
1130
|
/**
|
|
1112
1131
|
* Manages messages for a channel. Access via channel.messages.
|
|
1113
1132
|
* @example
|
|
1114
|
-
* const message =
|
|
1133
|
+
* const message = channel.messages.get(messageId); // from cache (if enabled)
|
|
1134
|
+
* const message = await channel.messages.fetch(messageId); // from API
|
|
1115
1135
|
* if (message) await message.edit({ content: 'Updated!' });
|
|
1116
1136
|
*/
|
|
1117
1137
|
declare class MessageManager {
|
|
1118
1138
|
private readonly client;
|
|
1119
1139
|
private readonly channelId;
|
|
1120
1140
|
constructor(client: Client, channelId: string);
|
|
1141
|
+
/**
|
|
1142
|
+
* Get a message from cache. Returns undefined if not cached or caching is disabled.
|
|
1143
|
+
* Requires options.cache.messages > 0.
|
|
1144
|
+
* @param messageId - Snowflake of the message
|
|
1145
|
+
*/
|
|
1146
|
+
get(messageId: string): Message | undefined;
|
|
1121
1147
|
/**
|
|
1122
1148
|
* Fetch a message by ID from this channel.
|
|
1149
|
+
* When message caching is enabled, the fetched message is added to the cache.
|
|
1123
1150
|
* @param messageId - Snowflake of the message
|
|
1124
1151
|
* @returns The message
|
|
1125
1152
|
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
@@ -1483,7 +1510,7 @@ declare class ChannelManager extends Collection<string, Channel | GuildChannel>
|
|
|
1483
1510
|
* await client.channels.send(channelId, { embeds: [embed] });
|
|
1484
1511
|
* await client.channels.send(channelId, { content: 'Report', files: [{ name: 'log.txt', data }] });
|
|
1485
1512
|
*/
|
|
1486
|
-
send(channelId: string, payload: MessageSendOptions): Promise<Message>;
|
|
1513
|
+
send(channelId: string, payload: string | MessageSendOptions): Promise<Message>;
|
|
1487
1514
|
}
|
|
1488
1515
|
|
|
1489
1516
|
/**
|
|
@@ -1531,6 +1558,8 @@ interface CacheSizeLimits {
|
|
|
1531
1558
|
channels?: number;
|
|
1532
1559
|
guilds?: number;
|
|
1533
1560
|
users?: number;
|
|
1561
|
+
/** Max messages per channel to cache. Enables channel.messages.get() and oldMessage in messageUpdate. 0 = disabled. */
|
|
1562
|
+
messages?: number;
|
|
1534
1563
|
}
|
|
1535
1564
|
interface ClientOptions {
|
|
1536
1565
|
rest?: Partial<ConstructorParameters<typeof REST>[0]>;
|
|
@@ -1776,6 +1805,10 @@ declare class Client extends EventEmitter {
|
|
|
1776
1805
|
private _ws;
|
|
1777
1806
|
/** When waitForGuilds, set of guild IDs we're waiting for GUILD_CREATE on. Null when not waiting. */
|
|
1778
1807
|
_pendingGuildIds: Set<string> | null;
|
|
1808
|
+
/** Timeout for guild stream when READY has no guilds (gateway sends only GUILD_CREATE). Cleared in finally. */
|
|
1809
|
+
private _guildStreamSettleTimeout;
|
|
1810
|
+
/** Per-channel message cache (channelId -> messageId -> APIMessage). Used when options.cache.messages > 0. */
|
|
1811
|
+
private _messageCaches;
|
|
1779
1812
|
/** @param options - Token, REST config, WebSocket, presence, etc. */
|
|
1780
1813
|
constructor(options?: ClientOptions);
|
|
1781
1814
|
/**
|
|
@@ -1818,11 +1851,25 @@ declare class Client extends EventEmitter {
|
|
|
1818
1851
|
/**
|
|
1819
1852
|
* Send a message to any channel by ID. Shorthand for client.channels.send().
|
|
1820
1853
|
* Works even when the channel is not cached.
|
|
1854
|
+
* @deprecated Use client.channels.send(channelId, payload).
|
|
1855
|
+
*/
|
|
1856
|
+
sendToChannel(channelId: string, payload: string | MessageSendOptions): Promise<Message>;
|
|
1857
|
+
/**
|
|
1858
|
+
* Get the message cache for a channel. Returns null if message caching is disabled.
|
|
1859
|
+
* Used by MessageManager.get() and event handlers.
|
|
1860
|
+
* @internal
|
|
1861
|
+
*/
|
|
1862
|
+
_getMessageCache(channelId: string): Map<string, APIMessage> | null;
|
|
1863
|
+
/**
|
|
1864
|
+
* Add a message to the channel cache. Evicts oldest (FIFO) when over limit.
|
|
1865
|
+
* @internal
|
|
1866
|
+
*/
|
|
1867
|
+
_addMessageToCache(channelId: string, data: APIMessage): void;
|
|
1868
|
+
/**
|
|
1869
|
+
* Remove a message from the channel cache.
|
|
1870
|
+
* @internal
|
|
1821
1871
|
*/
|
|
1822
|
-
|
|
1823
|
-
content?: string;
|
|
1824
|
-
embeds?: APIEmbed[];
|
|
1825
|
-
}): Promise<Message>;
|
|
1872
|
+
_removeMessageFromCache(channelId: string, messageId: string): void;
|
|
1826
1873
|
/**
|
|
1827
1874
|
* Get or create a User from API data. Caches in client.users.
|
|
1828
1875
|
* Updates existing user's username, avatar, etc. when fresh data is provided.
|
|
@@ -1957,4 +2004,4 @@ declare function cdnMemberBannerURL(guildId: string, userId: string, bannerHash:
|
|
|
1957
2004
|
*/
|
|
1958
2005
|
declare function cdnDefaultAvatarURL(userIdOrIndex: string | number): string;
|
|
1959
2006
|
|
|
1960
|
-
export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildMemberRoleManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, Role, type RoleResolvable, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };
|
|
2007
|
+
export { Base, CDN_URL, CategoryChannel, type CdnUrlOptions, Channel, ChannelManager, Client, type ClientEventMethods, type ClientEvents, ClientUser, type CollectedReaction, DMChannel, ErrorCodes, Events, type FetchedUserWithProfile, FluxerError, type FluxerErrorOptions, Guild, GuildBan, GuildChannel, GuildEmoji, GuildMember, GuildMemberManager, GuildMemberRoleManager, GuildSticker, Invite, LinkChannel, Message, MessageCollector, type MessageCollectorEndReason, type MessageCollectorOptions, type MessageEditOptions, MessageManager, MessageReaction, type MessageSendOptions, type PartialMessage, ReactionCollector, type ReactionCollectorEndReason, type ReactionCollectorOptions, type ReplyOptions, Role, type RoleResolvable, STATIC_CDN_URL, TextChannel, User, UsersManager, VoiceChannel, Webhook, type WebhookSendOptions, cdnAvatarURL, cdnBannerURL, cdnDefaultAvatarURL, cdnDisplayAvatarURL, cdnMemberAvatarURL, cdnMemberBannerURL };
|
package/dist/index.js
CHANGED
|
@@ -162,6 +162,7 @@ function buildSendBody(options) {
|
|
|
162
162
|
filename: f.filename ?? f.name
|
|
163
163
|
}));
|
|
164
164
|
}
|
|
165
|
+
if (body.flags !== void 0) result.flags = body.flags;
|
|
165
166
|
return result;
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -394,21 +395,31 @@ var Message = class _Message extends Base {
|
|
|
394
395
|
}
|
|
395
396
|
/**
|
|
396
397
|
* Reply to this message (shows as a reply in the client).
|
|
397
|
-
* @param options - Text content or object with content, embeds, and/or
|
|
398
|
+
* @param options - Text content or object with content, embeds, and/or reply options (ping, replyTo)
|
|
398
399
|
* @example
|
|
399
400
|
* await message.reply('Pong!');
|
|
400
401
|
* await message.reply({ embeds: [embed] });
|
|
402
|
+
* await message.reply('No ping!', { ping: false });
|
|
403
|
+
* await message.reply({ content: 'Reply to other', replyTo: otherMessage });
|
|
401
404
|
*/
|
|
402
|
-
async reply(options) {
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
405
|
+
async reply(options, replyOptions) {
|
|
406
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
407
|
+
const mergedReply = replyOptions ?? (opts.ping !== void 0 || opts.replyTo !== void 0) ? { ping: opts.ping, replyTo: opts.replyTo } : void 0;
|
|
408
|
+
const refMessage = mergedReply?.replyTo ?? this;
|
|
409
|
+
const ref = refMessage instanceof _Message ? {
|
|
410
|
+
channel_id: refMessage.channelId,
|
|
411
|
+
message_id: refMessage.id,
|
|
412
|
+
guild_id: refMessage.guildId ?? void 0
|
|
413
|
+
} : {
|
|
414
|
+
channel_id: refMessage.channelId,
|
|
415
|
+
message_id: refMessage.messageId,
|
|
416
|
+
guild_id: void 0
|
|
417
|
+
};
|
|
418
|
+
const payload = await _Message._createMessageBody(opts, ref, mergedReply?.ping !== false);
|
|
408
419
|
return this._send(payload);
|
|
409
420
|
}
|
|
410
421
|
/** Exposed for testing purposes, use Message.reply() or send() for normal use */
|
|
411
|
-
static async _createMessageBody(content, referenced_message) {
|
|
422
|
+
static async _createMessageBody(content, referenced_message, ping) {
|
|
412
423
|
if (typeof content === "string") {
|
|
413
424
|
if (content.length === 0) {
|
|
414
425
|
throw new RangeError("Cannot send an empty message");
|
|
@@ -417,13 +428,21 @@ var Message = class _Message extends Base {
|
|
|
417
428
|
}
|
|
418
429
|
const base = buildSendBody(content);
|
|
419
430
|
const files = content.files?.length ? await resolveMessageFiles(content.files) : void 0;
|
|
420
|
-
|
|
431
|
+
const body = { ...base };
|
|
432
|
+
if (referenced_message) {
|
|
433
|
+
body.message_reference = referenced_message;
|
|
434
|
+
if (ping === false) {
|
|
435
|
+
body.flags = (body.flags ?? 0) | import_types.MessageFlags.SuppressNotifications;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return { files, body };
|
|
421
439
|
}
|
|
422
440
|
async _send(payload) {
|
|
423
441
|
const data = await this.client.rest.post(
|
|
424
442
|
import_types.Routes.channelMessages(this.channelId),
|
|
425
443
|
payload
|
|
426
444
|
);
|
|
445
|
+
this.client._addMessageToCache(this.channelId, data);
|
|
427
446
|
return new _Message(this.client, data);
|
|
428
447
|
}
|
|
429
448
|
/**
|
|
@@ -560,8 +579,18 @@ var MessageManager = class {
|
|
|
560
579
|
this.client = client;
|
|
561
580
|
this.channelId = channelId;
|
|
562
581
|
}
|
|
582
|
+
/**
|
|
583
|
+
* Get a message from cache. Returns undefined if not cached or caching is disabled.
|
|
584
|
+
* Requires options.cache.messages > 0.
|
|
585
|
+
* @param messageId - Snowflake of the message
|
|
586
|
+
*/
|
|
587
|
+
get(messageId) {
|
|
588
|
+
const data = this.client._getMessageCache(this.channelId)?.get(messageId);
|
|
589
|
+
return data ? new Message(this.client, data) : void 0;
|
|
590
|
+
}
|
|
563
591
|
/**
|
|
564
592
|
* Fetch a message by ID from this channel.
|
|
593
|
+
* When message caching is enabled, the fetched message is added to the cache.
|
|
565
594
|
* @param messageId - Snowflake of the message
|
|
566
595
|
* @returns The message
|
|
567
596
|
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
@@ -571,6 +600,7 @@ var MessageManager = class {
|
|
|
571
600
|
const data = await this.client.rest.get(
|
|
572
601
|
import_types2.Routes.channelMessage(this.channelId, messageId)
|
|
573
602
|
);
|
|
603
|
+
this.client._addMessageToCache(this.channelId, data);
|
|
574
604
|
return new Message(this.client, data);
|
|
575
605
|
} catch (err) {
|
|
576
606
|
if (err instanceof import_rest.RateLimitError) throw err;
|
|
@@ -1068,6 +1098,7 @@ var GuildChannel = class extends Channel {
|
|
|
1068
1098
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1069
1099
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1070
1100
|
const data = await this.client.rest.post(import_types5.Routes.channelMessages(this.id), postOptions);
|
|
1101
|
+
this.client._addMessageToCache(this.id, data);
|
|
1071
1102
|
return new Message(this.client, data);
|
|
1072
1103
|
}
|
|
1073
1104
|
/**
|
|
@@ -1133,6 +1164,7 @@ var TextChannel = class extends GuildChannel {
|
|
|
1133
1164
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1134
1165
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1135
1166
|
const data = await this.client.rest.post(import_types5.Routes.channelMessages(this.id), postOptions);
|
|
1167
|
+
this.client._addMessageToCache(this.id, data);
|
|
1136
1168
|
return new Message(this.client, data);
|
|
1137
1169
|
}
|
|
1138
1170
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
@@ -1224,6 +1256,7 @@ var DMChannel = class extends Channel {
|
|
|
1224
1256
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1225
1257
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1226
1258
|
const data = await this.client.rest.post(import_types5.Routes.channelMessages(this.id), postOptions);
|
|
1259
|
+
this.client._addMessageToCache(this.id, data);
|
|
1227
1260
|
return new Message(this.client, data);
|
|
1228
1261
|
}
|
|
1229
1262
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
@@ -1398,6 +1431,7 @@ var ChannelManager = class extends import_collection4.Collection {
|
|
|
1398
1431
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1399
1432
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1400
1433
|
const data = await this.client.rest.post(import_types6.Routes.channelMessages(channelId), postOptions);
|
|
1434
|
+
this.client._addMessageToCache(channelId, data);
|
|
1401
1435
|
return new Message(this.client, data);
|
|
1402
1436
|
}
|
|
1403
1437
|
};
|
|
@@ -1432,12 +1466,7 @@ function computePermissions(basePermissions, overwrites, memberRoles, memberId,
|
|
|
1432
1466
|
const deny = BigInt(overwrite.deny || "0");
|
|
1433
1467
|
perms = perms & ~deny | allow;
|
|
1434
1468
|
}
|
|
1435
|
-
return perms;
|
|
1436
|
-
}
|
|
1437
|
-
function hasPermission(bitfield, permission) {
|
|
1438
|
-
const Administrator = 1n << 3n;
|
|
1439
|
-
if ((bitfield & Administrator) !== 0n) return true;
|
|
1440
|
-
return (bitfield & permission) === permission;
|
|
1469
|
+
return (perms & import_util4.PermissionFlags.Administrator) !== 0n ? import_util4.ALL_PERMISSIONS_BIGINT : perms;
|
|
1441
1470
|
}
|
|
1442
1471
|
|
|
1443
1472
|
// src/structures/GuildMemberRoleManager.ts
|
|
@@ -1639,13 +1668,7 @@ var GuildMember = class extends Base {
|
|
|
1639
1668
|
const ownerId = this.guild.ownerId;
|
|
1640
1669
|
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
1641
1670
|
const perms = computePermissions(base, [], [], this.id, isOwner);
|
|
1642
|
-
return
|
|
1643
|
-
has(permission) {
|
|
1644
|
-
const perm = typeof permission === "number" ? permission : import_util5.PermissionFlagsMap[String(permission)];
|
|
1645
|
-
if (perm === void 0) return false;
|
|
1646
|
-
return hasPermission(perms, BigInt(perm));
|
|
1647
|
-
}
|
|
1648
|
-
};
|
|
1671
|
+
return new import_util5.BitField(perms);
|
|
1649
1672
|
}
|
|
1650
1673
|
/**
|
|
1651
1674
|
* Compute the member's effective permissions in a guild channel.
|
|
@@ -1667,22 +1690,35 @@ var GuildMember = class extends Base {
|
|
|
1667
1690
|
this.id,
|
|
1668
1691
|
isOwner
|
|
1669
1692
|
);
|
|
1670
|
-
return
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1693
|
+
return new import_util5.BitField(perms);
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Move this member to a different voice channel or disconnect them from voice.
|
|
1697
|
+
* Requires Move Members permission.
|
|
1698
|
+
* @param channelId - The voice channel ID to move the member to, or null to disconnect
|
|
1699
|
+
* @param connectionId - Optional connection ID for the specific voice session (usually not needed)
|
|
1700
|
+
* @returns Promise that resolves when the member has been moved
|
|
1701
|
+
* @example
|
|
1702
|
+
* // Move member to a different voice channel
|
|
1703
|
+
* await member.move('123456789012345678');
|
|
1704
|
+
*
|
|
1705
|
+
* // Disconnect member from voice
|
|
1706
|
+
* await member.move(null);
|
|
1707
|
+
*/
|
|
1708
|
+
async move(channelId, connectionId) {
|
|
1709
|
+
await this.edit({
|
|
1710
|
+
channel_id: channelId,
|
|
1711
|
+
connection_id: connectionId
|
|
1712
|
+
});
|
|
1677
1713
|
}
|
|
1678
1714
|
_computeBasePermissions() {
|
|
1679
1715
|
let base = 0n;
|
|
1680
1716
|
const everyone = this.guild.roles.get(this.guild.id);
|
|
1681
|
-
if (everyone) base |=
|
|
1717
|
+
if (everyone) base |= everyone.permissions.bitfield;
|
|
1682
1718
|
for (const roleId of this.roles.roleIds) {
|
|
1683
1719
|
if (roleId === this.guild.id) continue;
|
|
1684
1720
|
const role = this.guild.roles.get(roleId);
|
|
1685
|
-
if (role) base |=
|
|
1721
|
+
if (role) base |= role.permissions.bitfield;
|
|
1686
1722
|
}
|
|
1687
1723
|
return base;
|
|
1688
1724
|
}
|
|
@@ -1774,7 +1810,7 @@ var Role = class extends Base {
|
|
|
1774
1810
|
name;
|
|
1775
1811
|
color;
|
|
1776
1812
|
position;
|
|
1777
|
-
|
|
1813
|
+
_permissions;
|
|
1778
1814
|
hoist;
|
|
1779
1815
|
mentionable;
|
|
1780
1816
|
unicodeEmoji;
|
|
@@ -1791,18 +1827,24 @@ var Role = class extends Base {
|
|
|
1791
1827
|
this.name = data.name;
|
|
1792
1828
|
this.color = data.color;
|
|
1793
1829
|
this.position = data.position;
|
|
1794
|
-
this.
|
|
1830
|
+
this._permissions = data.permissions;
|
|
1795
1831
|
this.hoist = !!data.hoist;
|
|
1796
1832
|
this.mentionable = !!data.mentionable;
|
|
1797
1833
|
this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
1798
1834
|
this.hoistPosition = data.hoist_position ?? null;
|
|
1799
1835
|
}
|
|
1836
|
+
get permissions() {
|
|
1837
|
+
const bits = BigInt(this._permissions);
|
|
1838
|
+
return new import_util6.PermissionsBitField(
|
|
1839
|
+
(bits & import_util6.PermissionFlags.Administrator) !== 0n ? import_util6.ALL_PERMISSIONS_BIGINT : bits
|
|
1840
|
+
);
|
|
1841
|
+
}
|
|
1800
1842
|
/** Update mutable fields from fresh API data. Used by edit and gateway events. */
|
|
1801
1843
|
_patch(data) {
|
|
1802
1844
|
if (data.name !== void 0) this.name = data.name;
|
|
1803
1845
|
if (data.color !== void 0) this.color = data.color;
|
|
1804
1846
|
if (data.position !== void 0) this.position = data.position;
|
|
1805
|
-
if (data.permissions !== void 0) this.
|
|
1847
|
+
if (data.permissions !== void 0) this._permissions = data.permissions;
|
|
1806
1848
|
if (data.hoist !== void 0) this.hoist = !!data.hoist;
|
|
1807
1849
|
if (data.mentionable !== void 0) this.mentionable = !!data.mentionable;
|
|
1808
1850
|
if (data.unicode_emoji !== void 0) this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
@@ -1812,24 +1854,6 @@ var Role = class extends Base {
|
|
|
1812
1854
|
toString() {
|
|
1813
1855
|
return `<@&${this.id}>`;
|
|
1814
1856
|
}
|
|
1815
|
-
/**
|
|
1816
|
-
* Check if this role has a permission. Administrator grants all permissions.
|
|
1817
|
-
* @param permission - Permission flag, name, or resolvable
|
|
1818
|
-
* @returns true if the role has the permission
|
|
1819
|
-
* @example
|
|
1820
|
-
* if (role.has(PermissionFlags.BanMembers)) { ... }
|
|
1821
|
-
* if (role.has('ManageChannels')) { ... }
|
|
1822
|
-
*/
|
|
1823
|
-
has(permission) {
|
|
1824
|
-
const perm = typeof permission === "number" ? permission : import_util6.PermissionFlags[permission];
|
|
1825
|
-
if (perm === void 0) return false;
|
|
1826
|
-
const permNum = Number(perm);
|
|
1827
|
-
const rolePerms = BigInt(this.permissions);
|
|
1828
|
-
const permBig = BigInt(permNum);
|
|
1829
|
-
if (permBig < 0) return false;
|
|
1830
|
-
if ((rolePerms & BigInt(import_util6.PermissionFlags.Administrator)) !== 0n) return true;
|
|
1831
|
-
return (rolePerms & permBig) === permBig;
|
|
1832
|
-
}
|
|
1833
1857
|
/**
|
|
1834
1858
|
* Edit this role.
|
|
1835
1859
|
* Requires Manage Roles permission.
|
|
@@ -2869,13 +2893,28 @@ handlers.set("MESSAGE_CREATE", async (client, d) => {
|
|
|
2869
2893
|
guild.members.set(member.id, member);
|
|
2870
2894
|
}
|
|
2871
2895
|
}
|
|
2896
|
+
client._addMessageToCache(data.channel_id, data);
|
|
2872
2897
|
client.emit(Events.MessageCreate, new Message(client, data));
|
|
2873
2898
|
});
|
|
2874
2899
|
handlers.set("MESSAGE_UPDATE", async (client, d) => {
|
|
2875
|
-
|
|
2900
|
+
const partial = d;
|
|
2901
|
+
const cache = client._getMessageCache(partial.channel_id);
|
|
2902
|
+
let oldMessage = null;
|
|
2903
|
+
let mergedData = partial;
|
|
2904
|
+
if (cache) {
|
|
2905
|
+
const oldData = cache.get(partial.id);
|
|
2906
|
+
if (oldData) {
|
|
2907
|
+
oldMessage = new Message(client, oldData);
|
|
2908
|
+
mergedData = { ...oldData, ...partial };
|
|
2909
|
+
}
|
|
2910
|
+
cache.set(partial.id, mergedData);
|
|
2911
|
+
}
|
|
2912
|
+
const newMessage = new Message(client, mergedData);
|
|
2913
|
+
client.emit(Events.MessageUpdate, oldMessage, newMessage);
|
|
2876
2914
|
});
|
|
2877
2915
|
handlers.set("MESSAGE_DELETE", async (client, d) => {
|
|
2878
2916
|
const data = d;
|
|
2917
|
+
client._removeMessageFromCache(data.channel_id, data.id);
|
|
2879
2918
|
const channel = client.channels.get(data.channel_id) ?? null;
|
|
2880
2919
|
client.emit(Events.MessageDelete, {
|
|
2881
2920
|
id: data.id,
|
|
@@ -3045,7 +3084,11 @@ handlers.set("VOICE_SERVER_UPDATE", async (client, d) => {
|
|
|
3045
3084
|
client.emit(Events.VoiceServerUpdate, d);
|
|
3046
3085
|
});
|
|
3047
3086
|
handlers.set("MESSAGE_DELETE_BULK", async (client, d) => {
|
|
3048
|
-
|
|
3087
|
+
const data = d;
|
|
3088
|
+
for (const id of data.ids ?? []) {
|
|
3089
|
+
client._removeMessageFromCache(data.channel_id, id);
|
|
3090
|
+
}
|
|
3091
|
+
client.emit(Events.MessageDeleteBulk, data);
|
|
3049
3092
|
});
|
|
3050
3093
|
handlers.set("GUILD_BAN_ADD", async (client, d) => {
|
|
3051
3094
|
const data = d;
|
|
@@ -3203,6 +3246,10 @@ var Client = class extends import_events3.EventEmitter {
|
|
|
3203
3246
|
_ws = null;
|
|
3204
3247
|
/** When waitForGuilds, set of guild IDs we're waiting for GUILD_CREATE on. Null when not waiting. */
|
|
3205
3248
|
_pendingGuildIds = null;
|
|
3249
|
+
/** Timeout for guild stream when READY has no guilds (gateway sends only GUILD_CREATE). Cleared in finally. */
|
|
3250
|
+
_guildStreamSettleTimeout = null;
|
|
3251
|
+
/** Per-channel message cache (channelId -> messageId -> APIMessage). Used when options.cache.messages > 0. */
|
|
3252
|
+
_messageCaches = null;
|
|
3206
3253
|
/**
|
|
3207
3254
|
* Resolve an emoji argument to the API format (unicode or "name:id").
|
|
3208
3255
|
* Supports: <:name:id>, :name:, name:id, { name, id }, unicode.
|
|
@@ -3291,11 +3338,52 @@ var Client = class extends import_events3.EventEmitter {
|
|
|
3291
3338
|
/**
|
|
3292
3339
|
* Send a message to any channel by ID. Shorthand for client.channels.send().
|
|
3293
3340
|
* Works even when the channel is not cached.
|
|
3341
|
+
* @deprecated Use client.channels.send(channelId, payload).
|
|
3294
3342
|
*/
|
|
3295
|
-
async sendToChannel(channelId,
|
|
3296
|
-
|
|
3343
|
+
async sendToChannel(channelId, payload) {
|
|
3344
|
+
(0, import_util8.emitDeprecationWarning)(
|
|
3345
|
+
"Client.sendToChannel()",
|
|
3346
|
+
"Use client.channels.send(channelId, payload)."
|
|
3347
|
+
);
|
|
3297
3348
|
return this.channels.send(channelId, payload);
|
|
3298
3349
|
}
|
|
3350
|
+
/**
|
|
3351
|
+
* Get the message cache for a channel. Returns null if message caching is disabled.
|
|
3352
|
+
* Used by MessageManager.get() and event handlers.
|
|
3353
|
+
* @internal
|
|
3354
|
+
*/
|
|
3355
|
+
_getMessageCache(channelId) {
|
|
3356
|
+
const limit = this.options.cache?.messages ?? 0;
|
|
3357
|
+
if (limit <= 0) return null;
|
|
3358
|
+
if (!this._messageCaches) this._messageCaches = /* @__PURE__ */ new Map();
|
|
3359
|
+
let cache = this._messageCaches.get(channelId);
|
|
3360
|
+
if (!cache) {
|
|
3361
|
+
cache = /* @__PURE__ */ new Map();
|
|
3362
|
+
this._messageCaches.set(channelId, cache);
|
|
3363
|
+
}
|
|
3364
|
+
return cache;
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Add a message to the channel cache. Evicts oldest (FIFO) when over limit.
|
|
3368
|
+
* @internal
|
|
3369
|
+
*/
|
|
3370
|
+
_addMessageToCache(channelId, data) {
|
|
3371
|
+
const cache = this._getMessageCache(channelId);
|
|
3372
|
+
if (!cache) return;
|
|
3373
|
+
const limit = this.options.cache?.messages ?? 0;
|
|
3374
|
+
if (limit > 0 && cache.size >= limit && !cache.has(data.id)) {
|
|
3375
|
+
const firstKey = cache.keys().next().value;
|
|
3376
|
+
if (firstKey !== void 0) cache.delete(firstKey);
|
|
3377
|
+
}
|
|
3378
|
+
cache.set(data.id, { ...data });
|
|
3379
|
+
}
|
|
3380
|
+
/**
|
|
3381
|
+
* Remove a message from the channel cache.
|
|
3382
|
+
* @internal
|
|
3383
|
+
*/
|
|
3384
|
+
_removeMessageFromCache(channelId, messageId) {
|
|
3385
|
+
this._messageCaches?.get(channelId)?.delete(messageId);
|
|
3386
|
+
}
|
|
3299
3387
|
/**
|
|
3300
3388
|
* Get or create a User from API data. Caches in client.users.
|
|
3301
3389
|
* Updates existing user's username, avatar, etc. when fresh data is provided.
|
|
@@ -3406,6 +3494,14 @@ var Client = class extends import_events3.EventEmitter {
|
|
|
3406
3494
|
this._pendingGuildIds = pending;
|
|
3407
3495
|
return;
|
|
3408
3496
|
}
|
|
3497
|
+
if (waitForGuilds && (data.guilds ?? []).length === 0) {
|
|
3498
|
+
const GUILD_STREAM_SETTLE_MS = 500;
|
|
3499
|
+
this._guildStreamSettleTimeout = setTimeout(() => {
|
|
3500
|
+
this._guildStreamSettleTimeout = null;
|
|
3501
|
+
this._finalizeReady();
|
|
3502
|
+
}, GUILD_STREAM_SETTLE_MS);
|
|
3503
|
+
return;
|
|
3504
|
+
}
|
|
3409
3505
|
this._finalizeReady();
|
|
3410
3506
|
}
|
|
3411
3507
|
);
|
|
@@ -3435,6 +3531,10 @@ var Client = class extends import_events3.EventEmitter {
|
|
|
3435
3531
|
}
|
|
3436
3532
|
/** Disconnect from the gateway and clear cached data. */
|
|
3437
3533
|
async destroy() {
|
|
3534
|
+
if (this._guildStreamSettleTimeout !== null) {
|
|
3535
|
+
clearTimeout(this._guildStreamSettleTimeout);
|
|
3536
|
+
this._guildStreamSettleTimeout = null;
|
|
3537
|
+
}
|
|
3438
3538
|
if (this._ws) {
|
|
3439
3539
|
this._ws.destroy();
|
|
3440
3540
|
this._ws = null;
|
package/dist/index.mjs
CHANGED
|
@@ -86,6 +86,7 @@ function buildSendBody(options) {
|
|
|
86
86
|
filename: f.filename ?? f.name
|
|
87
87
|
}));
|
|
88
88
|
}
|
|
89
|
+
if (body.flags !== void 0) result.flags = body.flags;
|
|
89
90
|
return result;
|
|
90
91
|
}
|
|
91
92
|
|
|
@@ -99,7 +100,7 @@ var Base = class {
|
|
|
99
100
|
|
|
100
101
|
// src/structures/Message.ts
|
|
101
102
|
import { Collection as Collection2 } from "@fluxerjs/collection";
|
|
102
|
-
import { MessageType, Routes } from "@fluxerjs/types";
|
|
103
|
+
import { MessageType, MessageFlags, Routes } from "@fluxerjs/types";
|
|
103
104
|
import { EmbedBuilder as EmbedBuilder2 } from "@fluxerjs/builders";
|
|
104
105
|
|
|
105
106
|
// src/util/ReactionCollector.ts
|
|
@@ -318,21 +319,31 @@ var Message = class _Message extends Base {
|
|
|
318
319
|
}
|
|
319
320
|
/**
|
|
320
321
|
* Reply to this message (shows as a reply in the client).
|
|
321
|
-
* @param options - Text content or object with content, embeds, and/or
|
|
322
|
+
* @param options - Text content or object with content, embeds, and/or reply options (ping, replyTo)
|
|
322
323
|
* @example
|
|
323
324
|
* await message.reply('Pong!');
|
|
324
325
|
* await message.reply({ embeds: [embed] });
|
|
326
|
+
* await message.reply('No ping!', { ping: false });
|
|
327
|
+
* await message.reply({ content: 'Reply to other', replyTo: otherMessage });
|
|
325
328
|
*/
|
|
326
|
-
async reply(options) {
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
329
|
+
async reply(options, replyOptions) {
|
|
330
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
331
|
+
const mergedReply = replyOptions ?? (opts.ping !== void 0 || opts.replyTo !== void 0) ? { ping: opts.ping, replyTo: opts.replyTo } : void 0;
|
|
332
|
+
const refMessage = mergedReply?.replyTo ?? this;
|
|
333
|
+
const ref = refMessage instanceof _Message ? {
|
|
334
|
+
channel_id: refMessage.channelId,
|
|
335
|
+
message_id: refMessage.id,
|
|
336
|
+
guild_id: refMessage.guildId ?? void 0
|
|
337
|
+
} : {
|
|
338
|
+
channel_id: refMessage.channelId,
|
|
339
|
+
message_id: refMessage.messageId,
|
|
340
|
+
guild_id: void 0
|
|
341
|
+
};
|
|
342
|
+
const payload = await _Message._createMessageBody(opts, ref, mergedReply?.ping !== false);
|
|
332
343
|
return this._send(payload);
|
|
333
344
|
}
|
|
334
345
|
/** Exposed for testing purposes, use Message.reply() or send() for normal use */
|
|
335
|
-
static async _createMessageBody(content, referenced_message) {
|
|
346
|
+
static async _createMessageBody(content, referenced_message, ping) {
|
|
336
347
|
if (typeof content === "string") {
|
|
337
348
|
if (content.length === 0) {
|
|
338
349
|
throw new RangeError("Cannot send an empty message");
|
|
@@ -341,13 +352,21 @@ var Message = class _Message extends Base {
|
|
|
341
352
|
}
|
|
342
353
|
const base = buildSendBody(content);
|
|
343
354
|
const files = content.files?.length ? await resolveMessageFiles(content.files) : void 0;
|
|
344
|
-
|
|
355
|
+
const body = { ...base };
|
|
356
|
+
if (referenced_message) {
|
|
357
|
+
body.message_reference = referenced_message;
|
|
358
|
+
if (ping === false) {
|
|
359
|
+
body.flags = (body.flags ?? 0) | MessageFlags.SuppressNotifications;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return { files, body };
|
|
345
363
|
}
|
|
346
364
|
async _send(payload) {
|
|
347
365
|
const data = await this.client.rest.post(
|
|
348
366
|
Routes.channelMessages(this.channelId),
|
|
349
367
|
payload
|
|
350
368
|
);
|
|
369
|
+
this.client._addMessageToCache(this.channelId, data);
|
|
351
370
|
return new _Message(this.client, data);
|
|
352
371
|
}
|
|
353
372
|
/**
|
|
@@ -484,8 +503,18 @@ var MessageManager = class {
|
|
|
484
503
|
this.client = client;
|
|
485
504
|
this.channelId = channelId;
|
|
486
505
|
}
|
|
506
|
+
/**
|
|
507
|
+
* Get a message from cache. Returns undefined if not cached or caching is disabled.
|
|
508
|
+
* Requires options.cache.messages > 0.
|
|
509
|
+
* @param messageId - Snowflake of the message
|
|
510
|
+
*/
|
|
511
|
+
get(messageId) {
|
|
512
|
+
const data = this.client._getMessageCache(this.channelId)?.get(messageId);
|
|
513
|
+
return data ? new Message(this.client, data) : void 0;
|
|
514
|
+
}
|
|
487
515
|
/**
|
|
488
516
|
* Fetch a message by ID from this channel.
|
|
517
|
+
* When message caching is enabled, the fetched message is added to the cache.
|
|
489
518
|
* @param messageId - Snowflake of the message
|
|
490
519
|
* @returns The message
|
|
491
520
|
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
@@ -495,6 +524,7 @@ var MessageManager = class {
|
|
|
495
524
|
const data = await this.client.rest.get(
|
|
496
525
|
Routes2.channelMessage(this.channelId, messageId)
|
|
497
526
|
);
|
|
527
|
+
this.client._addMessageToCache(this.channelId, data);
|
|
498
528
|
return new Message(this.client, data);
|
|
499
529
|
} catch (err) {
|
|
500
530
|
if (err instanceof RateLimitError) throw err;
|
|
@@ -992,6 +1022,7 @@ var GuildChannel = class extends Channel {
|
|
|
992
1022
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
993
1023
|
const postOptions = files?.length ? { body, files } : { body };
|
|
994
1024
|
const data = await this.client.rest.post(Routes5.channelMessages(this.id), postOptions);
|
|
1025
|
+
this.client._addMessageToCache(this.id, data);
|
|
995
1026
|
return new Message(this.client, data);
|
|
996
1027
|
}
|
|
997
1028
|
/**
|
|
@@ -1057,6 +1088,7 @@ var TextChannel = class extends GuildChannel {
|
|
|
1057
1088
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1058
1089
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1059
1090
|
const data = await this.client.rest.post(Routes5.channelMessages(this.id), postOptions);
|
|
1091
|
+
this.client._addMessageToCache(this.id, data);
|
|
1060
1092
|
return new Message(this.client, data);
|
|
1061
1093
|
}
|
|
1062
1094
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
@@ -1148,6 +1180,7 @@ var DMChannel = class extends Channel {
|
|
|
1148
1180
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1149
1181
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1150
1182
|
const data = await this.client.rest.post(Routes5.channelMessages(this.id), postOptions);
|
|
1183
|
+
this.client._addMessageToCache(this.id, data);
|
|
1151
1184
|
return new Message(this.client, data);
|
|
1152
1185
|
}
|
|
1153
1186
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
@@ -1322,6 +1355,7 @@ var ChannelManager = class extends Collection4 {
|
|
|
1322
1355
|
const files = opts.files?.length ? await resolveMessageFiles(opts.files) : void 0;
|
|
1323
1356
|
const postOptions = files?.length ? { body, files } : { body };
|
|
1324
1357
|
const data = await this.client.rest.post(Routes6.channelMessages(channelId), postOptions);
|
|
1358
|
+
this.client._addMessageToCache(channelId, data);
|
|
1325
1359
|
return new Message(this.client, data);
|
|
1326
1360
|
}
|
|
1327
1361
|
};
|
|
@@ -1343,12 +1377,12 @@ import { Collection as Collection6 } from "@fluxerjs/collection";
|
|
|
1343
1377
|
import { Routes as Routes9 } from "@fluxerjs/types";
|
|
1344
1378
|
|
|
1345
1379
|
// src/structures/GuildMember.ts
|
|
1346
|
-
import {
|
|
1380
|
+
import { BitField } from "@fluxerjs/util";
|
|
1347
1381
|
import { Routes as Routes8 } from "@fluxerjs/types";
|
|
1348
1382
|
|
|
1349
1383
|
// src/util/permissions.ts
|
|
1350
1384
|
import { OverwriteType } from "@fluxerjs/types";
|
|
1351
|
-
import { ALL_PERMISSIONS_BIGINT } from "@fluxerjs/util";
|
|
1385
|
+
import { ALL_PERMISSIONS_BIGINT, PermissionFlags as PermissionFlags2 } from "@fluxerjs/util";
|
|
1352
1386
|
function computePermissions(basePermissions, overwrites, memberRoles, memberId, isOwner) {
|
|
1353
1387
|
if (isOwner) return ALL_PERMISSIONS_BIGINT;
|
|
1354
1388
|
let perms = basePermissions;
|
|
@@ -1359,12 +1393,7 @@ function computePermissions(basePermissions, overwrites, memberRoles, memberId,
|
|
|
1359
1393
|
const deny = BigInt(overwrite.deny || "0");
|
|
1360
1394
|
perms = perms & ~deny | allow;
|
|
1361
1395
|
}
|
|
1362
|
-
return perms;
|
|
1363
|
-
}
|
|
1364
|
-
function hasPermission(bitfield, permission) {
|
|
1365
|
-
const Administrator = 1n << 3n;
|
|
1366
|
-
if ((bitfield & Administrator) !== 0n) return true;
|
|
1367
|
-
return (bitfield & permission) === permission;
|
|
1396
|
+
return (perms & PermissionFlags2.Administrator) !== 0n ? ALL_PERMISSIONS_BIGINT : perms;
|
|
1368
1397
|
}
|
|
1369
1398
|
|
|
1370
1399
|
// src/structures/GuildMemberRoleManager.ts
|
|
@@ -1566,13 +1595,7 @@ var GuildMember = class extends Base {
|
|
|
1566
1595
|
const ownerId = this.guild.ownerId;
|
|
1567
1596
|
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
1568
1597
|
const perms = computePermissions(base, [], [], this.id, isOwner);
|
|
1569
|
-
return
|
|
1570
|
-
has(permission) {
|
|
1571
|
-
const perm = typeof permission === "number" ? permission : PermissionFlagsMap[String(permission)];
|
|
1572
|
-
if (perm === void 0) return false;
|
|
1573
|
-
return hasPermission(perms, BigInt(perm));
|
|
1574
|
-
}
|
|
1575
|
-
};
|
|
1598
|
+
return new BitField(perms);
|
|
1576
1599
|
}
|
|
1577
1600
|
/**
|
|
1578
1601
|
* Compute the member's effective permissions in a guild channel.
|
|
@@ -1594,22 +1617,35 @@ var GuildMember = class extends Base {
|
|
|
1594
1617
|
this.id,
|
|
1595
1618
|
isOwner
|
|
1596
1619
|
);
|
|
1597
|
-
return
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1620
|
+
return new BitField(perms);
|
|
1621
|
+
}
|
|
1622
|
+
/**
|
|
1623
|
+
* Move this member to a different voice channel or disconnect them from voice.
|
|
1624
|
+
* Requires Move Members permission.
|
|
1625
|
+
* @param channelId - The voice channel ID to move the member to, or null to disconnect
|
|
1626
|
+
* @param connectionId - Optional connection ID for the specific voice session (usually not needed)
|
|
1627
|
+
* @returns Promise that resolves when the member has been moved
|
|
1628
|
+
* @example
|
|
1629
|
+
* // Move member to a different voice channel
|
|
1630
|
+
* await member.move('123456789012345678');
|
|
1631
|
+
*
|
|
1632
|
+
* // Disconnect member from voice
|
|
1633
|
+
* await member.move(null);
|
|
1634
|
+
*/
|
|
1635
|
+
async move(channelId, connectionId) {
|
|
1636
|
+
await this.edit({
|
|
1637
|
+
channel_id: channelId,
|
|
1638
|
+
connection_id: connectionId
|
|
1639
|
+
});
|
|
1604
1640
|
}
|
|
1605
1641
|
_computeBasePermissions() {
|
|
1606
1642
|
let base = 0n;
|
|
1607
1643
|
const everyone = this.guild.roles.get(this.guild.id);
|
|
1608
|
-
if (everyone) base |=
|
|
1644
|
+
if (everyone) base |= everyone.permissions.bitfield;
|
|
1609
1645
|
for (const roleId of this.roles.roleIds) {
|
|
1610
1646
|
if (roleId === this.guild.id) continue;
|
|
1611
1647
|
const role = this.guild.roles.get(roleId);
|
|
1612
|
-
if (role) base |=
|
|
1648
|
+
if (role) base |= role.permissions.bitfield;
|
|
1613
1649
|
}
|
|
1614
1650
|
return base;
|
|
1615
1651
|
}
|
|
@@ -1694,8 +1730,10 @@ var GuildMemberManager = class extends Collection6 {
|
|
|
1694
1730
|
// src/structures/Role.ts
|
|
1695
1731
|
import { Routes as Routes10 } from "@fluxerjs/types";
|
|
1696
1732
|
import {
|
|
1697
|
-
PermissionFlags as
|
|
1698
|
-
resolvePermissionsToBitfield
|
|
1733
|
+
PermissionFlags as PermissionFlags4,
|
|
1734
|
+
resolvePermissionsToBitfield,
|
|
1735
|
+
ALL_PERMISSIONS_BIGINT as ALL_PERMISSIONS_BIGINT2,
|
|
1736
|
+
PermissionsBitField
|
|
1699
1737
|
} from "@fluxerjs/util";
|
|
1700
1738
|
var Role = class extends Base {
|
|
1701
1739
|
client;
|
|
@@ -1704,7 +1742,7 @@ var Role = class extends Base {
|
|
|
1704
1742
|
name;
|
|
1705
1743
|
color;
|
|
1706
1744
|
position;
|
|
1707
|
-
|
|
1745
|
+
_permissions;
|
|
1708
1746
|
hoist;
|
|
1709
1747
|
mentionable;
|
|
1710
1748
|
unicodeEmoji;
|
|
@@ -1721,18 +1759,24 @@ var Role = class extends Base {
|
|
|
1721
1759
|
this.name = data.name;
|
|
1722
1760
|
this.color = data.color;
|
|
1723
1761
|
this.position = data.position;
|
|
1724
|
-
this.
|
|
1762
|
+
this._permissions = data.permissions;
|
|
1725
1763
|
this.hoist = !!data.hoist;
|
|
1726
1764
|
this.mentionable = !!data.mentionable;
|
|
1727
1765
|
this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
1728
1766
|
this.hoistPosition = data.hoist_position ?? null;
|
|
1729
1767
|
}
|
|
1768
|
+
get permissions() {
|
|
1769
|
+
const bits = BigInt(this._permissions);
|
|
1770
|
+
return new PermissionsBitField(
|
|
1771
|
+
(bits & PermissionFlags4.Administrator) !== 0n ? ALL_PERMISSIONS_BIGINT2 : bits
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1730
1774
|
/** Update mutable fields from fresh API data. Used by edit and gateway events. */
|
|
1731
1775
|
_patch(data) {
|
|
1732
1776
|
if (data.name !== void 0) this.name = data.name;
|
|
1733
1777
|
if (data.color !== void 0) this.color = data.color;
|
|
1734
1778
|
if (data.position !== void 0) this.position = data.position;
|
|
1735
|
-
if (data.permissions !== void 0) this.
|
|
1779
|
+
if (data.permissions !== void 0) this._permissions = data.permissions;
|
|
1736
1780
|
if (data.hoist !== void 0) this.hoist = !!data.hoist;
|
|
1737
1781
|
if (data.mentionable !== void 0) this.mentionable = !!data.mentionable;
|
|
1738
1782
|
if (data.unicode_emoji !== void 0) this.unicodeEmoji = data.unicode_emoji ?? null;
|
|
@@ -1742,24 +1786,6 @@ var Role = class extends Base {
|
|
|
1742
1786
|
toString() {
|
|
1743
1787
|
return `<@&${this.id}>`;
|
|
1744
1788
|
}
|
|
1745
|
-
/**
|
|
1746
|
-
* Check if this role has a permission. Administrator grants all permissions.
|
|
1747
|
-
* @param permission - Permission flag, name, or resolvable
|
|
1748
|
-
* @returns true if the role has the permission
|
|
1749
|
-
* @example
|
|
1750
|
-
* if (role.has(PermissionFlags.BanMembers)) { ... }
|
|
1751
|
-
* if (role.has('ManageChannels')) { ... }
|
|
1752
|
-
*/
|
|
1753
|
-
has(permission) {
|
|
1754
|
-
const perm = typeof permission === "number" ? permission : PermissionFlags2[permission];
|
|
1755
|
-
if (perm === void 0) return false;
|
|
1756
|
-
const permNum = Number(perm);
|
|
1757
|
-
const rolePerms = BigInt(this.permissions);
|
|
1758
|
-
const permBig = BigInt(permNum);
|
|
1759
|
-
if (permBig < 0) return false;
|
|
1760
|
-
if ((rolePerms & BigInt(PermissionFlags2.Administrator)) !== 0n) return true;
|
|
1761
|
-
return (rolePerms & permBig) === permBig;
|
|
1762
|
-
}
|
|
1763
1789
|
/**
|
|
1764
1790
|
* Edit this role.
|
|
1765
1791
|
* Requires Manage Roles permission.
|
|
@@ -2804,13 +2830,28 @@ handlers.set("MESSAGE_CREATE", async (client, d) => {
|
|
|
2804
2830
|
guild.members.set(member.id, member);
|
|
2805
2831
|
}
|
|
2806
2832
|
}
|
|
2833
|
+
client._addMessageToCache(data.channel_id, data);
|
|
2807
2834
|
client.emit(Events.MessageCreate, new Message(client, data));
|
|
2808
2835
|
});
|
|
2809
2836
|
handlers.set("MESSAGE_UPDATE", async (client, d) => {
|
|
2810
|
-
|
|
2837
|
+
const partial = d;
|
|
2838
|
+
const cache = client._getMessageCache(partial.channel_id);
|
|
2839
|
+
let oldMessage = null;
|
|
2840
|
+
let mergedData = partial;
|
|
2841
|
+
if (cache) {
|
|
2842
|
+
const oldData = cache.get(partial.id);
|
|
2843
|
+
if (oldData) {
|
|
2844
|
+
oldMessage = new Message(client, oldData);
|
|
2845
|
+
mergedData = { ...oldData, ...partial };
|
|
2846
|
+
}
|
|
2847
|
+
cache.set(partial.id, mergedData);
|
|
2848
|
+
}
|
|
2849
|
+
const newMessage = new Message(client, mergedData);
|
|
2850
|
+
client.emit(Events.MessageUpdate, oldMessage, newMessage);
|
|
2811
2851
|
});
|
|
2812
2852
|
handlers.set("MESSAGE_DELETE", async (client, d) => {
|
|
2813
2853
|
const data = d;
|
|
2854
|
+
client._removeMessageFromCache(data.channel_id, data.id);
|
|
2814
2855
|
const channel = client.channels.get(data.channel_id) ?? null;
|
|
2815
2856
|
client.emit(Events.MessageDelete, {
|
|
2816
2857
|
id: data.id,
|
|
@@ -2980,7 +3021,11 @@ handlers.set("VOICE_SERVER_UPDATE", async (client, d) => {
|
|
|
2980
3021
|
client.emit(Events.VoiceServerUpdate, d);
|
|
2981
3022
|
});
|
|
2982
3023
|
handlers.set("MESSAGE_DELETE_BULK", async (client, d) => {
|
|
2983
|
-
|
|
3024
|
+
const data = d;
|
|
3025
|
+
for (const id of data.ids ?? []) {
|
|
3026
|
+
client._removeMessageFromCache(data.channel_id, id);
|
|
3027
|
+
}
|
|
3028
|
+
client.emit(Events.MessageDeleteBulk, data);
|
|
2984
3029
|
});
|
|
2985
3030
|
handlers.set("GUILD_BAN_ADD", async (client, d) => {
|
|
2986
3031
|
const data = d;
|
|
@@ -3138,6 +3183,10 @@ var Client = class extends EventEmitter3 {
|
|
|
3138
3183
|
_ws = null;
|
|
3139
3184
|
/** When waitForGuilds, set of guild IDs we're waiting for GUILD_CREATE on. Null when not waiting. */
|
|
3140
3185
|
_pendingGuildIds = null;
|
|
3186
|
+
/** Timeout for guild stream when READY has no guilds (gateway sends only GUILD_CREATE). Cleared in finally. */
|
|
3187
|
+
_guildStreamSettleTimeout = null;
|
|
3188
|
+
/** Per-channel message cache (channelId -> messageId -> APIMessage). Used when options.cache.messages > 0. */
|
|
3189
|
+
_messageCaches = null;
|
|
3141
3190
|
/**
|
|
3142
3191
|
* Resolve an emoji argument to the API format (unicode or "name:id").
|
|
3143
3192
|
* Supports: <:name:id>, :name:, name:id, { name, id }, unicode.
|
|
@@ -3226,11 +3275,52 @@ var Client = class extends EventEmitter3 {
|
|
|
3226
3275
|
/**
|
|
3227
3276
|
* Send a message to any channel by ID. Shorthand for client.channels.send().
|
|
3228
3277
|
* Works even when the channel is not cached.
|
|
3278
|
+
* @deprecated Use client.channels.send(channelId, payload).
|
|
3229
3279
|
*/
|
|
3230
|
-
async sendToChannel(channelId,
|
|
3231
|
-
|
|
3280
|
+
async sendToChannel(channelId, payload) {
|
|
3281
|
+
emitDeprecationWarning3(
|
|
3282
|
+
"Client.sendToChannel()",
|
|
3283
|
+
"Use client.channels.send(channelId, payload)."
|
|
3284
|
+
);
|
|
3232
3285
|
return this.channels.send(channelId, payload);
|
|
3233
3286
|
}
|
|
3287
|
+
/**
|
|
3288
|
+
* Get the message cache for a channel. Returns null if message caching is disabled.
|
|
3289
|
+
* Used by MessageManager.get() and event handlers.
|
|
3290
|
+
* @internal
|
|
3291
|
+
*/
|
|
3292
|
+
_getMessageCache(channelId) {
|
|
3293
|
+
const limit = this.options.cache?.messages ?? 0;
|
|
3294
|
+
if (limit <= 0) return null;
|
|
3295
|
+
if (!this._messageCaches) this._messageCaches = /* @__PURE__ */ new Map();
|
|
3296
|
+
let cache = this._messageCaches.get(channelId);
|
|
3297
|
+
if (!cache) {
|
|
3298
|
+
cache = /* @__PURE__ */ new Map();
|
|
3299
|
+
this._messageCaches.set(channelId, cache);
|
|
3300
|
+
}
|
|
3301
|
+
return cache;
|
|
3302
|
+
}
|
|
3303
|
+
/**
|
|
3304
|
+
* Add a message to the channel cache. Evicts oldest (FIFO) when over limit.
|
|
3305
|
+
* @internal
|
|
3306
|
+
*/
|
|
3307
|
+
_addMessageToCache(channelId, data) {
|
|
3308
|
+
const cache = this._getMessageCache(channelId);
|
|
3309
|
+
if (!cache) return;
|
|
3310
|
+
const limit = this.options.cache?.messages ?? 0;
|
|
3311
|
+
if (limit > 0 && cache.size >= limit && !cache.has(data.id)) {
|
|
3312
|
+
const firstKey = cache.keys().next().value;
|
|
3313
|
+
if (firstKey !== void 0) cache.delete(firstKey);
|
|
3314
|
+
}
|
|
3315
|
+
cache.set(data.id, { ...data });
|
|
3316
|
+
}
|
|
3317
|
+
/**
|
|
3318
|
+
* Remove a message from the channel cache.
|
|
3319
|
+
* @internal
|
|
3320
|
+
*/
|
|
3321
|
+
_removeMessageFromCache(channelId, messageId) {
|
|
3322
|
+
this._messageCaches?.get(channelId)?.delete(messageId);
|
|
3323
|
+
}
|
|
3234
3324
|
/**
|
|
3235
3325
|
* Get or create a User from API data. Caches in client.users.
|
|
3236
3326
|
* Updates existing user's username, avatar, etc. when fresh data is provided.
|
|
@@ -3341,6 +3431,14 @@ var Client = class extends EventEmitter3 {
|
|
|
3341
3431
|
this._pendingGuildIds = pending;
|
|
3342
3432
|
return;
|
|
3343
3433
|
}
|
|
3434
|
+
if (waitForGuilds && (data.guilds ?? []).length === 0) {
|
|
3435
|
+
const GUILD_STREAM_SETTLE_MS = 500;
|
|
3436
|
+
this._guildStreamSettleTimeout = setTimeout(() => {
|
|
3437
|
+
this._guildStreamSettleTimeout = null;
|
|
3438
|
+
this._finalizeReady();
|
|
3439
|
+
}, GUILD_STREAM_SETTLE_MS);
|
|
3440
|
+
return;
|
|
3441
|
+
}
|
|
3344
3442
|
this._finalizeReady();
|
|
3345
3443
|
}
|
|
3346
3444
|
);
|
|
@@ -3370,6 +3468,10 @@ var Client = class extends EventEmitter3 {
|
|
|
3370
3468
|
}
|
|
3371
3469
|
/** Disconnect from the gateway and clear cached data. */
|
|
3372
3470
|
async destroy() {
|
|
3471
|
+
if (this._guildStreamSettleTimeout !== null) {
|
|
3472
|
+
clearTimeout(this._guildStreamSettleTimeout);
|
|
3473
|
+
this._guildStreamSettleTimeout = null;
|
|
3474
|
+
}
|
|
3373
3475
|
if (this._ws) {
|
|
3374
3476
|
this._ws.destroy();
|
|
3375
3477
|
this._ws = null;
|
|
@@ -3410,8 +3512,8 @@ import { EmbedBuilder as EmbedBuilder3, MessagePayload, AttachmentBuilder } from
|
|
|
3410
3512
|
import { Routes as Routes21, GatewayOpcodes, MessageAttachmentFlags } from "@fluxerjs/types";
|
|
3411
3513
|
import { resolveTenorToImageUrl, parseUserMention, parsePrefixCommand } from "@fluxerjs/util";
|
|
3412
3514
|
import {
|
|
3413
|
-
PermissionsBitField,
|
|
3414
|
-
PermissionFlags as
|
|
3515
|
+
PermissionsBitField as PermissionsBitField2,
|
|
3516
|
+
PermissionFlags as PermissionFlags5,
|
|
3415
3517
|
resolvePermissionsToBitfield as resolvePermissionsToBitfield3,
|
|
3416
3518
|
UserFlagsBitField,
|
|
3417
3519
|
UserFlagsBits
|
|
@@ -3447,8 +3549,8 @@ export {
|
|
|
3447
3549
|
MessageManager,
|
|
3448
3550
|
MessagePayload,
|
|
3449
3551
|
MessageReaction,
|
|
3450
|
-
|
|
3451
|
-
PermissionsBitField,
|
|
3552
|
+
PermissionFlags5 as PermissionFlags,
|
|
3553
|
+
PermissionsBitField2 as PermissionsBitField,
|
|
3452
3554
|
ReactionCollector,
|
|
3453
3555
|
Role,
|
|
3454
3556
|
Routes21 as Routes,
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.2.
|
|
6
|
+
"version": "1.2.4",
|
|
7
7
|
"description": "A fully-featured SDK for Fluxer bots",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"dist"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@fluxerjs/rest": "1.2.
|
|
38
|
-
"@fluxerjs/
|
|
39
|
-
"@fluxerjs/
|
|
40
|
-
"@fluxerjs/
|
|
41
|
-
"@fluxerjs/
|
|
42
|
-
"@fluxerjs/
|
|
37
|
+
"@fluxerjs/rest": "1.2.4",
|
|
38
|
+
"@fluxerjs/builders": "1.2.4",
|
|
39
|
+
"@fluxerjs/collection": "1.2.4",
|
|
40
|
+
"@fluxerjs/types": "1.2.4",
|
|
41
|
+
"@fluxerjs/util": "1.2.4",
|
|
42
|
+
"@fluxerjs/ws": "1.2.4"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^20.0.0",
|
|
@@ -55,6 +55,6 @@
|
|
|
55
55
|
"lint": "eslint src --max-warnings 0 --config ../../eslint.config.js",
|
|
56
56
|
"lint:fix": "eslint src --fix --config ../../eslint.config.js",
|
|
57
57
|
"test": "vitest run --passWithNoTests",
|
|
58
|
-
"test:coverage": "vitest run --coverage
|
|
58
|
+
"test:coverage": "vitest run --coverage"
|
|
59
59
|
}
|
|
60
60
|
}
|