@fluxerjs/core 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Channel-ICWNKXBR.mjs → Channel-WJZZSNML.mjs} +3 -1
- package/dist/{ClientUser-WWXUMO5O.mjs → ClientUser-DJO2FS7P.mjs} +1 -1
- package/dist/Guild-2P77HBQM.mjs +11 -0
- package/dist/{GuildBan-M4PA3HAA.mjs → GuildBan-7CXLTPKY.mjs} +1 -1
- package/dist/GuildMember-43B5E5CH.mjs +9 -0
- package/dist/Message-OFIVTTAZ.mjs +9 -0
- package/dist/{MessageReaction-XRPYZDSC.mjs → MessageReaction-V4UZ7OXE.mjs} +1 -1
- package/dist/{Role-SVLWIAMN.mjs → Role-5MWSGL66.mjs} +1 -1
- package/dist/Webhook-RWDDYW2Q.mjs +10 -0
- package/dist/chunk-4XJIM6SC.mjs +315 -0
- package/dist/chunk-AH7KYH2Z.mjs +50 -0
- package/dist/{chunk-HBF5QEDH.mjs → chunk-CEABHTAF.mjs} +1 -0
- package/dist/{chunk-53Y37KRG.mjs → chunk-CJVQNARM.mjs} +44 -10
- package/dist/chunk-DQ4TNBPG.mjs +63 -0
- package/dist/chunk-DUQAD7F6.mjs +173 -0
- package/dist/{chunk-GCIJYVRC.mjs → chunk-JHNKZIHY.mjs} +54 -3
- package/dist/{chunk-FJS5FBXO.mjs → chunk-LU2SNC5G.mjs} +172 -13
- package/dist/chunk-PM2IUGNR.mjs +29 -0
- package/dist/{chunk-RCP27MRC.mjs → chunk-UXIF75BV.mjs} +3 -0
- package/dist/{chunk-DSPSRPHF.mjs → chunk-V7LPVPGH.mjs} +123 -18
- package/dist/chunk-X6K3ZD62.mjs +53 -0
- package/dist/index.d.mts +603 -113
- package/dist/index.d.ts +603 -113
- package/dist/index.js +1278 -410
- package/dist/index.mjs +183 -124
- package/package.json +7 -7
- package/dist/Guild-TM6YGJWB.mjs +0 -10
- package/dist/GuildMember-RZWZ3OCG.mjs +0 -7
- package/dist/Message-6IYEYSV6.mjs +0 -7
- package/dist/Webhook-32VJD4AL.mjs +0 -7
- package/dist/chunk-GFUJVQ7L.mjs +0 -64
- package/dist/chunk-SQVCCSNN.mjs +0 -41
- package/dist/chunk-X77DFNE3.mjs +0 -136
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cdnMemberAvatarURL,
|
|
3
|
+
cdnMemberBannerURL
|
|
4
|
+
} from "./chunk-X6K3ZD62.mjs";
|
|
5
|
+
import {
|
|
6
|
+
Base
|
|
7
|
+
} from "./chunk-XNS4O6QJ.mjs";
|
|
8
|
+
|
|
9
|
+
// src/structures/GuildMember.ts
|
|
10
|
+
import { PermissionFlagsMap } from "@fluxerjs/util";
|
|
11
|
+
import { Routes } from "@fluxerjs/types";
|
|
12
|
+
|
|
13
|
+
// src/util/permissions.ts
|
|
14
|
+
import { OverwriteType } from "@fluxerjs/types";
|
|
15
|
+
import { ALL_PERMISSIONS_BIGINT } from "@fluxerjs/util";
|
|
16
|
+
function computePermissions(basePermissions, overwrites, memberRoles, memberId, isOwner) {
|
|
17
|
+
if (isOwner) return ALL_PERMISSIONS_BIGINT;
|
|
18
|
+
let perms = basePermissions;
|
|
19
|
+
for (const overwrite of overwrites ?? []) {
|
|
20
|
+
const applies = overwrite.type === OverwriteType.Role && memberRoles.includes(overwrite.id) || overwrite.type === OverwriteType.Member && overwrite.id === memberId;
|
|
21
|
+
if (!applies) continue;
|
|
22
|
+
const allow = BigInt(overwrite.allow || "0");
|
|
23
|
+
const deny = BigInt(overwrite.deny || "0");
|
|
24
|
+
perms = perms & ~deny | allow;
|
|
25
|
+
}
|
|
26
|
+
return perms;
|
|
27
|
+
}
|
|
28
|
+
function hasPermission(bitfield, permission) {
|
|
29
|
+
const Administrator = 1n << 3n;
|
|
30
|
+
if ((bitfield & Administrator) !== 0n) return true;
|
|
31
|
+
return (bitfield & permission) === permission;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/structures/GuildMember.ts
|
|
35
|
+
var GuildMember = class extends Base {
|
|
36
|
+
client;
|
|
37
|
+
id;
|
|
38
|
+
user;
|
|
39
|
+
guild;
|
|
40
|
+
nick;
|
|
41
|
+
roles;
|
|
42
|
+
joinedAt;
|
|
43
|
+
communicationDisabledUntil;
|
|
44
|
+
mute;
|
|
45
|
+
deaf;
|
|
46
|
+
avatar;
|
|
47
|
+
banner;
|
|
48
|
+
accentColor;
|
|
49
|
+
profileFlags;
|
|
50
|
+
/** @param data - API guild member from GET /guilds/{id}/members or GET /guilds/{id}/members/{user_id} */
|
|
51
|
+
constructor(client, data, guild) {
|
|
52
|
+
super();
|
|
53
|
+
this.client = client;
|
|
54
|
+
this.user = client.getOrCreateUser(data.user);
|
|
55
|
+
this.id = data.user.id;
|
|
56
|
+
this.guild = guild;
|
|
57
|
+
this.nick = data.nick ?? null;
|
|
58
|
+
this.roles = data.roles ?? [];
|
|
59
|
+
this.joinedAt = new Date(data.joined_at);
|
|
60
|
+
this.communicationDisabledUntil = data.communication_disabled_until ? new Date(data.communication_disabled_until) : null;
|
|
61
|
+
this.mute = data.mute ?? false;
|
|
62
|
+
this.deaf = data.deaf ?? false;
|
|
63
|
+
this.avatar = data.avatar ?? null;
|
|
64
|
+
this.banner = data.banner ?? null;
|
|
65
|
+
this.accentColor = data.accent_color ?? null;
|
|
66
|
+
this.profileFlags = data.profile_flags ?? null;
|
|
67
|
+
}
|
|
68
|
+
/** Nickname, or global name, or username. */
|
|
69
|
+
get displayName() {
|
|
70
|
+
return this.nick ?? this.user.globalName ?? this.user.username;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the guild-specific avatar URL for this member.
|
|
74
|
+
* Returns null if the member has no guild avatar (use displayAvatarURL for fallback).
|
|
75
|
+
*/
|
|
76
|
+
avatarURL(options) {
|
|
77
|
+
return cdnMemberAvatarURL(this.guild.id, this.id, this.avatar, options);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the avatar URL to display for this member.
|
|
81
|
+
* Uses guild-specific avatar if set, otherwise falls back to the user's avatar.
|
|
82
|
+
*/
|
|
83
|
+
displayAvatarURL(options) {
|
|
84
|
+
return this.avatarURL(options) ?? this.user.displayAvatarURL(options);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the guild-specific banner URL for this member.
|
|
88
|
+
* Returns null if the member has no guild banner.
|
|
89
|
+
*/
|
|
90
|
+
bannerURL(options) {
|
|
91
|
+
return cdnMemberBannerURL(this.guild.id, this.id, this.banner, options);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Add a role to this member.
|
|
95
|
+
* @param roleId - The role ID to add
|
|
96
|
+
* Requires Manage Roles permission.
|
|
97
|
+
*/
|
|
98
|
+
async addRole(roleId) {
|
|
99
|
+
await this.client.rest.put(Routes.guildMemberRole(this.guild.id, this.id, roleId));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Remove a role from this member.
|
|
103
|
+
* @param roleId - The role ID to remove
|
|
104
|
+
* Requires Manage Roles permission.
|
|
105
|
+
*/
|
|
106
|
+
async removeRole(roleId) {
|
|
107
|
+
await this.client.rest.delete(Routes.guildMemberRole(this.guild.id, this.id, roleId));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get the member's guild-level permissions (from roles only, no channel overwrites).
|
|
111
|
+
* Use this for server-wide permission checks (e.g. ban, kick, manage roles).
|
|
112
|
+
* @returns Object with has(permission) to check specific permissions
|
|
113
|
+
* @example
|
|
114
|
+
* const perms = member.permissions;
|
|
115
|
+
* if (perms.has(PermissionFlags.BanMembers)) { ... }
|
|
116
|
+
*/
|
|
117
|
+
get permissions() {
|
|
118
|
+
const base = this._computeBasePermissions();
|
|
119
|
+
const ownerId = this.guild.ownerId;
|
|
120
|
+
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
121
|
+
const perms = computePermissions(base, [], [], this.id, isOwner);
|
|
122
|
+
return {
|
|
123
|
+
has(permission) {
|
|
124
|
+
const perm = typeof permission === "number" ? permission : PermissionFlagsMap[String(permission)];
|
|
125
|
+
if (perm === void 0) return false;
|
|
126
|
+
return hasPermission(perms, BigInt(perm));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Compute the member's effective permissions in a guild channel.
|
|
132
|
+
* Applies role permissions and channel overwrites.
|
|
133
|
+
* @param channel - The guild channel to check permissions for
|
|
134
|
+
* @returns Object with has(permission) to check specific permissions
|
|
135
|
+
* @example
|
|
136
|
+
* const perms = member.permissionsIn(channel);
|
|
137
|
+
* if (perms.has(PermissionFlags.SendMessages)) { ... }
|
|
138
|
+
*/
|
|
139
|
+
permissionsIn(channel) {
|
|
140
|
+
const base = this._computeBasePermissions();
|
|
141
|
+
const ownerId = this.guild.ownerId;
|
|
142
|
+
const isOwner = ownerId != null && ownerId !== "" && String(ownerId) === String(this.id);
|
|
143
|
+
const perms = computePermissions(
|
|
144
|
+
base,
|
|
145
|
+
channel.permissionOverwrites,
|
|
146
|
+
this.roles,
|
|
147
|
+
this.id,
|
|
148
|
+
isOwner
|
|
149
|
+
);
|
|
150
|
+
return {
|
|
151
|
+
has(permission) {
|
|
152
|
+
const perm = typeof permission === "number" ? permission : PermissionFlagsMap[String(permission)];
|
|
153
|
+
if (perm === void 0) return false;
|
|
154
|
+
return hasPermission(perms, BigInt(perm));
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
_computeBasePermissions() {
|
|
159
|
+
let base = 0n;
|
|
160
|
+
const everyone = this.guild.roles.get(this.guild.id);
|
|
161
|
+
if (everyone) base |= BigInt(everyone.permissions);
|
|
162
|
+
for (const roleId of this.roles) {
|
|
163
|
+
if (roleId === this.guild.id) continue;
|
|
164
|
+
const role = this.guild.roles.get(roleId);
|
|
165
|
+
if (role) base |= BigInt(role.permissions);
|
|
166
|
+
}
|
|
167
|
+
return base;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export {
|
|
172
|
+
GuildMember
|
|
173
|
+
};
|
|
@@ -15,6 +15,14 @@ var User = class extends Base {
|
|
|
15
15
|
globalName;
|
|
16
16
|
avatar;
|
|
17
17
|
bot;
|
|
18
|
+
/** RGB avatar color (e.g. 7577782). Null if not set. */
|
|
19
|
+
avatarColor;
|
|
20
|
+
/** Public flags bitfield. Null if not set. */
|
|
21
|
+
flags;
|
|
22
|
+
/** Whether this is an official system user. */
|
|
23
|
+
system;
|
|
24
|
+
/** Banner hash (from profile, member, or invite context). Null when not available. */
|
|
25
|
+
banner;
|
|
18
26
|
/** @param data - API user from message author, GET /users/{id}, or GET /users/@me */
|
|
19
27
|
constructor(client, data) {
|
|
20
28
|
super();
|
|
@@ -25,6 +33,10 @@ var User = class extends Base {
|
|
|
25
33
|
this.globalName = data.global_name ?? null;
|
|
26
34
|
this.avatar = data.avatar ?? null;
|
|
27
35
|
this.bot = !!data.bot;
|
|
36
|
+
this.avatarColor = data.avatar_color ?? null;
|
|
37
|
+
this.flags = data.flags ?? data.public_flags ?? null;
|
|
38
|
+
this.system = !!data.system;
|
|
39
|
+
this.banner = data.banner ?? null;
|
|
28
40
|
}
|
|
29
41
|
/** Update mutable fields from fresh API data. Used by getOrCreateUser cache. */
|
|
30
42
|
_patch(data) {
|
|
@@ -32,14 +44,18 @@ var User = class extends Base {
|
|
|
32
44
|
this.discriminator = data.discriminator;
|
|
33
45
|
this.globalName = data.global_name ?? null;
|
|
34
46
|
this.avatar = data.avatar ?? null;
|
|
47
|
+
if (data.avatar_color !== void 0) this.avatarColor = data.avatar_color;
|
|
48
|
+
if (data.flags !== void 0) this.flags = data.flags;
|
|
49
|
+
if (data.banner !== void 0) this.banner = data.banner;
|
|
35
50
|
}
|
|
36
51
|
/**
|
|
37
52
|
* Get the URL for this user's avatar.
|
|
38
|
-
*
|
|
53
|
+
* Auto-detects animated avatars (hash starting with `a_`) and uses gif extension.
|
|
54
|
+
* @param options - Optional `size` and `extension` (default: png, or gif for animated)
|
|
39
55
|
*/
|
|
40
56
|
avatarURL(options) {
|
|
41
57
|
if (!this.avatar) return null;
|
|
42
|
-
const ext = options?.extension ?? "png";
|
|
58
|
+
const ext = this.avatar.startsWith("a_") ? "gif" : options?.extension ?? "png";
|
|
43
59
|
const size = options?.size ? `?size=${options.size}` : "";
|
|
44
60
|
return `${CDN_URL}/avatars/${this.id}/${this.avatar}.${ext}${size}`;
|
|
45
61
|
}
|
|
@@ -47,6 +63,16 @@ var User = class extends Base {
|
|
|
47
63
|
displayAvatarURL(options) {
|
|
48
64
|
return this.avatarURL(options) ?? `${CDN_URL}/avatars/0/0.png`;
|
|
49
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Get the URL for this user's banner.
|
|
68
|
+
* Returns null if the user has no banner (only available when fetched from profile/member context).
|
|
69
|
+
*/
|
|
70
|
+
bannerURL(options) {
|
|
71
|
+
if (!this.banner) return null;
|
|
72
|
+
const ext = this.banner.startsWith("a_") ? "gif" : options?.extension ?? "png";
|
|
73
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
74
|
+
return `${CDN_URL}/banners/${this.id}/${this.banner}.${ext}${size}`;
|
|
75
|
+
}
|
|
50
76
|
/** Returns a mention string (e.g. `<@123456>`). */
|
|
51
77
|
toString() {
|
|
52
78
|
return `<@${this.id}>`;
|
|
@@ -56,7 +82,7 @@ var User = class extends Base {
|
|
|
56
82
|
* Returns the DM channel; use {@link DMChannel.send} to send messages.
|
|
57
83
|
*/
|
|
58
84
|
async createDM() {
|
|
59
|
-
const { DMChannel: DMChannelClass } = await import("./Channel-
|
|
85
|
+
const { DMChannel: DMChannelClass } = await import("./Channel-WJZZSNML.mjs");
|
|
60
86
|
const data = await this.client.rest.post(Routes.userMeChannels(), {
|
|
61
87
|
body: { recipient_id: this.id },
|
|
62
88
|
auth: true
|
|
@@ -74,10 +100,35 @@ var User = class extends Base {
|
|
|
74
100
|
};
|
|
75
101
|
|
|
76
102
|
// src/client/ClientUser.ts
|
|
103
|
+
import { Routes as Routes2 } from "@fluxerjs/types";
|
|
77
104
|
var ClientUser = class extends User {
|
|
78
105
|
constructor(client, data) {
|
|
79
106
|
super(client, { ...data });
|
|
80
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Fetch guilds the bot is a member of.
|
|
110
|
+
* @returns Array of Guild objects (cached in client.guilds)
|
|
111
|
+
*/
|
|
112
|
+
async fetchGuilds() {
|
|
113
|
+
const { Guild } = await import("./Guild-2P77HBQM.mjs");
|
|
114
|
+
const data = await this.client.rest.get(Routes2.currentUserGuilds());
|
|
115
|
+
const list = Array.isArray(data) ? data : data?.guilds ?? [];
|
|
116
|
+
const guilds = [];
|
|
117
|
+
for (const g of list) {
|
|
118
|
+
const guild = new Guild(this.client, g);
|
|
119
|
+
this.client.guilds.set(guild.id, guild);
|
|
120
|
+
guilds.push(guild);
|
|
121
|
+
}
|
|
122
|
+
return guilds;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Leave a guild. Requires the bot to be a member.
|
|
126
|
+
* @param guildId - The guild ID to leave
|
|
127
|
+
*/
|
|
128
|
+
async leaveGuild(guildId) {
|
|
129
|
+
await this.client.rest.delete(Routes2.leaveGuild(guildId), { auth: true });
|
|
130
|
+
this.client.guilds.delete(guildId);
|
|
131
|
+
}
|
|
81
132
|
};
|
|
82
133
|
|
|
83
134
|
export {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Events
|
|
3
|
+
} from "./chunk-AH7KYH2Z.mjs";
|
|
4
|
+
import {
|
|
5
|
+
buildSendBody
|
|
6
|
+
} from "./chunk-PM2IUGNR.mjs";
|
|
1
7
|
import {
|
|
2
8
|
Base
|
|
3
9
|
} from "./chunk-XNS4O6QJ.mjs";
|
|
@@ -11,15 +17,69 @@ var MessageManager = class {
|
|
|
11
17
|
/**
|
|
12
18
|
* Fetch a message by ID from this channel.
|
|
13
19
|
* @param messageId - Snowflake of the message
|
|
14
|
-
* @returns The message
|
|
20
|
+
* @returns The message
|
|
21
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
15
22
|
*/
|
|
16
23
|
async fetch(messageId) {
|
|
17
24
|
return this.client.channels.fetchMessage(this.channelId, messageId);
|
|
18
25
|
}
|
|
19
26
|
};
|
|
20
27
|
|
|
28
|
+
// src/util/MessageCollector.ts
|
|
29
|
+
import { EventEmitter } from "events";
|
|
30
|
+
import { Collection } from "@fluxerjs/collection";
|
|
31
|
+
var MessageCollector = class extends EventEmitter {
|
|
32
|
+
client;
|
|
33
|
+
channelId;
|
|
34
|
+
options;
|
|
35
|
+
collected = new Collection();
|
|
36
|
+
_timeout = null;
|
|
37
|
+
_ended = false;
|
|
38
|
+
_listener;
|
|
39
|
+
constructor(client, channelId, options = {}) {
|
|
40
|
+
super();
|
|
41
|
+
this.client = client;
|
|
42
|
+
this.channelId = channelId;
|
|
43
|
+
this.options = {
|
|
44
|
+
filter: options.filter ?? (() => true),
|
|
45
|
+
time: options.time ?? 0,
|
|
46
|
+
max: options.max ?? 0
|
|
47
|
+
};
|
|
48
|
+
this._listener = (message) => {
|
|
49
|
+
if (this._ended || message.channelId !== this.channelId) return;
|
|
50
|
+
if (!this.options.filter(message)) return;
|
|
51
|
+
this.collected.set(message.id, message);
|
|
52
|
+
this.emit("collect", message);
|
|
53
|
+
if (this.options.max > 0 && this.collected.size >= this.options.max) {
|
|
54
|
+
this.stop("limit");
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
this.client.on(Events.MessageCreate, this._listener);
|
|
58
|
+
if (this.options.time > 0) {
|
|
59
|
+
this._timeout = setTimeout(() => this.stop("time"), this.options.time);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
stop(reason = "user") {
|
|
63
|
+
if (this._ended) return;
|
|
64
|
+
this._ended = true;
|
|
65
|
+
this.client.off(Events.MessageCreate, this._listener);
|
|
66
|
+
if (this._timeout) {
|
|
67
|
+
clearTimeout(this._timeout);
|
|
68
|
+
this._timeout = null;
|
|
69
|
+
}
|
|
70
|
+
this.emit("end", this.collected, reason);
|
|
71
|
+
}
|
|
72
|
+
on(event, listener) {
|
|
73
|
+
return super.on(event, listener);
|
|
74
|
+
}
|
|
75
|
+
emit(event, ...args) {
|
|
76
|
+
return super.emit(event, ...args);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
21
80
|
// src/structures/Channel.ts
|
|
22
81
|
import { ChannelType, Routes } from "@fluxerjs/types";
|
|
82
|
+
import { emitDeprecationWarning } from "@fluxerjs/util";
|
|
23
83
|
var Channel = class _Channel extends Base {
|
|
24
84
|
/** Whether this channel has a send method (TextChannel, DMChannel). */
|
|
25
85
|
isSendable() {
|
|
@@ -40,12 +100,21 @@ var Channel = class _Channel extends Base {
|
|
|
40
100
|
client;
|
|
41
101
|
id;
|
|
42
102
|
type;
|
|
103
|
+
/** Channel name. Guild channels and Group DMs have names; 1:1 DMs are typically null. */
|
|
104
|
+
name;
|
|
105
|
+
/** Channel icon hash (Group DMs). Null if none. */
|
|
106
|
+
icon;
|
|
107
|
+
/** ISO timestamp when the last message was pinned. Null if never pinned. */
|
|
108
|
+
lastPinTimestamp;
|
|
43
109
|
/** @param data - API channel from GET /channels/{id} or GET /guilds/{id}/channels */
|
|
44
110
|
constructor(client, data) {
|
|
45
111
|
super();
|
|
46
112
|
this.client = client;
|
|
47
113
|
this.id = data.id;
|
|
48
114
|
this.type = data.type;
|
|
115
|
+
this.name = data.name ?? null;
|
|
116
|
+
this.icon = data.icon ?? null;
|
|
117
|
+
this.lastPinTimestamp = data.last_pin_timestamp ?? null;
|
|
49
118
|
}
|
|
50
119
|
/**
|
|
51
120
|
* Create the appropriate channel subclass from API data.
|
|
@@ -71,18 +140,37 @@ var Channel = class _Channel extends Base {
|
|
|
71
140
|
return _Channel.createDM(client, data);
|
|
72
141
|
return _Channel.from(client, data);
|
|
73
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Bulk delete messages. Requires Manage Messages permission.
|
|
145
|
+
* @param messageIds - Array of message IDs to delete (2–100)
|
|
146
|
+
*/
|
|
147
|
+
async bulkDeleteMessages(messageIds) {
|
|
148
|
+
await this.client.rest.post(Routes.channelBulkDelete(this.id), {
|
|
149
|
+
body: { message_ids: messageIds },
|
|
150
|
+
auth: true
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Send a typing indicator to the channel. Lasts ~10 seconds.
|
|
155
|
+
*/
|
|
156
|
+
async sendTyping() {
|
|
157
|
+
await this.client.rest.post(Routes.channelTyping(this.id), { auth: true });
|
|
158
|
+
}
|
|
74
159
|
};
|
|
75
160
|
var GuildChannel = class extends Channel {
|
|
76
161
|
guildId;
|
|
77
162
|
name;
|
|
78
163
|
position;
|
|
79
164
|
parentId;
|
|
165
|
+
/** Permission overwrites for roles and members. */
|
|
166
|
+
permissionOverwrites;
|
|
80
167
|
constructor(client, data) {
|
|
81
168
|
super(client, data);
|
|
82
169
|
this.guildId = data.guild_id ?? "";
|
|
83
170
|
this.name = data.name ?? null;
|
|
84
171
|
this.position = data.position;
|
|
85
172
|
this.parentId = data.parent_id ?? null;
|
|
173
|
+
this.permissionOverwrites = data.permission_overwrites ?? [];
|
|
86
174
|
}
|
|
87
175
|
/**
|
|
88
176
|
* Create a webhook in this channel.
|
|
@@ -90,7 +178,7 @@ var GuildChannel = class extends Channel {
|
|
|
90
178
|
* @returns The webhook with token (required for send()). Requires Manage Webhooks permission.
|
|
91
179
|
*/
|
|
92
180
|
async createWebhook(options) {
|
|
93
|
-
const { Webhook } = await import("./Webhook-
|
|
181
|
+
const { Webhook } = await import("./Webhook-RWDDYW2Q.mjs");
|
|
94
182
|
const data = await this.client.rest.post(Routes.channelWebhooks(this.id), {
|
|
95
183
|
body: options,
|
|
96
184
|
auth: true
|
|
@@ -102,11 +190,39 @@ var GuildChannel = class extends Channel {
|
|
|
102
190
|
* @returns Webhooks (includes token when listing from channel; can send via send())
|
|
103
191
|
*/
|
|
104
192
|
async fetchWebhooks() {
|
|
105
|
-
const { Webhook } = await import("./Webhook-
|
|
193
|
+
const { Webhook } = await import("./Webhook-RWDDYW2Q.mjs");
|
|
106
194
|
const data = await this.client.rest.get(Routes.channelWebhooks(this.id));
|
|
107
195
|
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
108
196
|
return list.map((w) => new Webhook(this.client, w));
|
|
109
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Create an invite for this channel.
|
|
200
|
+
* @param options - max_uses (0–100), max_age (0–604800 seconds), unique, temporary
|
|
201
|
+
* Requires Create Instant Invite permission.
|
|
202
|
+
*/
|
|
203
|
+
async createInvite(options) {
|
|
204
|
+
const { Invite } = await import("./Invite-UM5BU5A6.mjs");
|
|
205
|
+
const body = {};
|
|
206
|
+
if (options?.max_uses != null) body.max_uses = options.max_uses;
|
|
207
|
+
if (options?.max_age != null) body.max_age = options.max_age;
|
|
208
|
+
if (options?.unique != null) body.unique = options.unique;
|
|
209
|
+
if (options?.temporary != null) body.temporary = options.temporary;
|
|
210
|
+
const data = await this.client.rest.post(Routes.channelInvites(this.id), {
|
|
211
|
+
body: Object.keys(body).length ? body : void 0,
|
|
212
|
+
auth: true
|
|
213
|
+
});
|
|
214
|
+
return new Invite(this.client, data);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Fetch invites for this channel.
|
|
218
|
+
* Requires Manage Channel permission.
|
|
219
|
+
*/
|
|
220
|
+
async fetchInvites() {
|
|
221
|
+
const { Invite } = await import("./Invite-UM5BU5A6.mjs");
|
|
222
|
+
const data = await this.client.rest.get(Routes.channelInvites(this.id));
|
|
223
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
224
|
+
return list.map((i) => new Invite(this.client, i));
|
|
225
|
+
}
|
|
110
226
|
};
|
|
111
227
|
var TextChannel = class extends GuildChannel {
|
|
112
228
|
topic;
|
|
@@ -122,24 +238,38 @@ var TextChannel = class extends GuildChannel {
|
|
|
122
238
|
}
|
|
123
239
|
/**
|
|
124
240
|
* Send a message to this channel.
|
|
125
|
-
* @param options - Text content or object with
|
|
241
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
126
242
|
*/
|
|
127
243
|
async send(options) {
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
const
|
|
244
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
245
|
+
const body = buildSendBody(options);
|
|
246
|
+
const { Message } = await import("./Message-OFIVTTAZ.mjs");
|
|
247
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
248
|
+
const data = await this.client.rest.post(Routes.channelMessages(this.id), postOptions);
|
|
131
249
|
return new Message(this.client, data);
|
|
132
250
|
}
|
|
133
251
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
134
252
|
get messages() {
|
|
135
253
|
return new MessageManager(this.client, this.id);
|
|
136
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Create a message collector for this channel.
|
|
257
|
+
* Collects messages matching the filter until time expires or max is reached.
|
|
258
|
+
* @param options - Filter, time (ms), and max count
|
|
259
|
+
* @example
|
|
260
|
+
* const collector = channel.createMessageCollector({ filter: m => m.author.id === userId, time: 10000 });
|
|
261
|
+
* collector.on('collect', m => console.log(m.content));
|
|
262
|
+
* collector.on('end', (collected, reason) => { ... });
|
|
263
|
+
*/
|
|
264
|
+
createMessageCollector(options) {
|
|
265
|
+
return new MessageCollector(this.client, this.id, options);
|
|
266
|
+
}
|
|
137
267
|
/**
|
|
138
268
|
* Fetch pinned messages in this channel.
|
|
139
269
|
* @returns Pinned messages
|
|
140
270
|
*/
|
|
141
271
|
async fetchPinnedMessages() {
|
|
142
|
-
const { Message } = await import("./Message-
|
|
272
|
+
const { Message } = await import("./Message-OFIVTTAZ.mjs");
|
|
143
273
|
const data = await this.client.rest.get(Routes.channelPins(this.id));
|
|
144
274
|
const list = Array.isArray(data) ? data : data?.items ?? [];
|
|
145
275
|
return list.map((item) => {
|
|
@@ -154,6 +284,10 @@ var TextChannel = class extends GuildChannel {
|
|
|
154
284
|
* @deprecated Use channel.messages.fetch(messageId) instead.
|
|
155
285
|
*/
|
|
156
286
|
async fetchMessage(messageId) {
|
|
287
|
+
emitDeprecationWarning(
|
|
288
|
+
"Channel.fetchMessage()",
|
|
289
|
+
"Use channel.messages.fetch(messageId) instead."
|
|
290
|
+
);
|
|
157
291
|
return this.client.channels.fetchMessage(this.id, messageId);
|
|
158
292
|
}
|
|
159
293
|
};
|
|
@@ -179,30 +313,50 @@ var LinkChannel = class extends GuildChannel {
|
|
|
179
313
|
};
|
|
180
314
|
var DMChannel = class extends Channel {
|
|
181
315
|
lastMessageId;
|
|
316
|
+
/** Group DM creator ID. Null for 1:1 DMs. */
|
|
317
|
+
ownerId;
|
|
318
|
+
/** Group DM recipients as User objects. Empty for 1:1 DMs. */
|
|
319
|
+
recipients;
|
|
320
|
+
/** Group DM member display names (userId -> nickname). */
|
|
321
|
+
nicks;
|
|
182
322
|
constructor(client, data) {
|
|
183
323
|
super(client, data);
|
|
184
324
|
this.lastMessageId = data.last_message_id ?? null;
|
|
325
|
+
this.ownerId = data.owner_id ?? null;
|
|
326
|
+
this.recipients = (data.recipients ?? []).map(
|
|
327
|
+
(u) => client.getOrCreateUser(u)
|
|
328
|
+
);
|
|
329
|
+
this.nicks = data.nicks ?? {};
|
|
185
330
|
}
|
|
186
331
|
/**
|
|
187
332
|
* Send a message to this DM channel.
|
|
188
|
-
* @param options - Text content or object with
|
|
333
|
+
* @param options - Text content or object with content, embeds, and/or files
|
|
189
334
|
*/
|
|
190
335
|
async send(options) {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
const
|
|
336
|
+
const opts = typeof options === "string" ? { content: options } : options;
|
|
337
|
+
const body = buildSendBody(options);
|
|
338
|
+
const { Message } = await import("./Message-OFIVTTAZ.mjs");
|
|
339
|
+
const postOptions = opts.files?.length ? { body, files: opts.files } : { body };
|
|
340
|
+
const data = await this.client.rest.post(Routes.channelMessages(this.id), postOptions);
|
|
194
341
|
return new Message(this.client, data);
|
|
195
342
|
}
|
|
196
343
|
/** Message manager for this channel. Use channel.messages.fetch(messageId). */
|
|
197
344
|
get messages() {
|
|
198
345
|
return new MessageManager(this.client, this.id);
|
|
199
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Create a message collector for this DM channel.
|
|
349
|
+
* @param options - Filter, time (ms), and max count
|
|
350
|
+
*/
|
|
351
|
+
createMessageCollector(options) {
|
|
352
|
+
return new MessageCollector(this.client, this.id, options);
|
|
353
|
+
}
|
|
200
354
|
/**
|
|
201
355
|
* Fetch pinned messages in this DM channel.
|
|
202
356
|
* @returns Pinned messages
|
|
203
357
|
*/
|
|
204
358
|
async fetchPinnedMessages() {
|
|
205
|
-
const { Message } = await import("./Message-
|
|
359
|
+
const { Message } = await import("./Message-OFIVTTAZ.mjs");
|
|
206
360
|
const data = await this.client.rest.get(Routes.channelPins(this.id));
|
|
207
361
|
const list = Array.isArray(data) ? data : data?.items ?? [];
|
|
208
362
|
return list.map((item) => {
|
|
@@ -217,12 +371,17 @@ var DMChannel = class extends Channel {
|
|
|
217
371
|
* @deprecated Use channel.messages.fetch(messageId) instead.
|
|
218
372
|
*/
|
|
219
373
|
async fetchMessage(messageId) {
|
|
374
|
+
emitDeprecationWarning(
|
|
375
|
+
"Channel.fetchMessage()",
|
|
376
|
+
"Use channel.messages.fetch(messageId) instead."
|
|
377
|
+
);
|
|
220
378
|
return this.client.channels.fetchMessage(this.id, messageId);
|
|
221
379
|
}
|
|
222
380
|
};
|
|
223
381
|
|
|
224
382
|
export {
|
|
225
383
|
MessageManager,
|
|
384
|
+
MessageCollector,
|
|
226
385
|
Channel,
|
|
227
386
|
GuildChannel,
|
|
228
387
|
TextChannel,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/util/messageUtils.ts
|
|
2
|
+
import { EmbedBuilder } from "@fluxerjs/builders";
|
|
3
|
+
function buildSendBody(options) {
|
|
4
|
+
const body = typeof options === "string" ? { content: options } : options;
|
|
5
|
+
const result = {};
|
|
6
|
+
if (body.content !== void 0) result.content = body.content;
|
|
7
|
+
if (body.embeds?.length) {
|
|
8
|
+
result.embeds = body.embeds.map((e) => e instanceof EmbedBuilder ? e.toJSON() : e);
|
|
9
|
+
}
|
|
10
|
+
if (body.files?.length && body.attachments) {
|
|
11
|
+
result.attachments = body.attachments.map((a) => ({
|
|
12
|
+
id: a.id,
|
|
13
|
+
filename: a.filename,
|
|
14
|
+
...a.title != null && { title: a.title },
|
|
15
|
+
...a.description != null && { description: a.description },
|
|
16
|
+
...a.flags != null && { flags: a.flags }
|
|
17
|
+
}));
|
|
18
|
+
} else if (body.files?.length) {
|
|
19
|
+
result.attachments = body.files.map((f, i) => ({
|
|
20
|
+
id: i,
|
|
21
|
+
filename: f.filename ?? f.name
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
buildSendBody
|
|
29
|
+
};
|
|
@@ -9,6 +9,8 @@ var GuildBan = class extends Base {
|
|
|
9
9
|
guildId;
|
|
10
10
|
user;
|
|
11
11
|
reason;
|
|
12
|
+
/** ISO timestamp when a temporary ban expires. Null for permanent bans. */
|
|
13
|
+
expiresAt;
|
|
12
14
|
/** @param data - API ban from GET /guilds/{id}/bans or gateway GUILD_BAN_ADD */
|
|
13
15
|
constructor(client, data, guildId) {
|
|
14
16
|
super();
|
|
@@ -16,6 +18,7 @@ var GuildBan = class extends Base {
|
|
|
16
18
|
this.guildId = data.guild_id ?? guildId;
|
|
17
19
|
this.user = client.getOrCreateUser(data.user);
|
|
18
20
|
this.reason = data.reason ?? null;
|
|
21
|
+
this.expiresAt = data.expires_at ?? null;
|
|
19
22
|
}
|
|
20
23
|
/**
|
|
21
24
|
* Remove this ban (unban the user).
|