@fluxerjs/core 1.0.9 → 1.1.1
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/LICENSE +203 -0
- package/dist/{Channel-ICWNKXBR.mjs → Channel-4WVFDOCG.mjs} +4 -1
- package/dist/{ClientUser-WWXUMO5O.mjs → ClientUser-PXAAKR2P.mjs} +1 -1
- package/dist/Guild-FMBCTAV4.mjs +12 -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-AYSOCOMX.mjs} +2 -1
- package/dist/{Role-SVLWIAMN.mjs → Role-5MWSGL66.mjs} +1 -1
- package/dist/Webhook-RWDDYW2Q.mjs +10 -0
- package/dist/{chunk-GCIJYVRC.mjs → chunk-4F765HVV.mjs} +54 -3
- package/dist/chunk-AH7KYH2Z.mjs +50 -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-FRVZ7D6D.mjs +293 -0
- package/dist/{chunk-HBF5QEDH.mjs → chunk-K6NLD6SB.mjs} +23 -1
- package/dist/chunk-PM2IUGNR.mjs +29 -0
- package/dist/chunk-RWFKZ3DF.mjs +413 -0
- package/dist/{chunk-RCP27MRC.mjs → chunk-UXIF75BV.mjs} +3 -0
- package/dist/chunk-V6T5VMWD.mjs +26 -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 +1335 -426
- package/dist/index.mjs +189 -125
- package/package.json +8 -8
- 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-FJS5FBXO.mjs +0 -233
- 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
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ErrorCodes,
|
|
3
|
+
FluxerError
|
|
4
|
+
} from "./chunk-V6T5VMWD.mjs";
|
|
5
|
+
import {
|
|
6
|
+
GuildMember
|
|
7
|
+
} from "./chunk-DUQAD7F6.mjs";
|
|
8
|
+
import {
|
|
9
|
+
CDN_URL
|
|
10
|
+
} from "./chunk-HQMYRYMY.mjs";
|
|
11
|
+
import {
|
|
12
|
+
Role
|
|
13
|
+
} from "./chunk-DQ4TNBPG.mjs";
|
|
14
|
+
import {
|
|
15
|
+
Base
|
|
16
|
+
} from "./chunk-XNS4O6QJ.mjs";
|
|
17
|
+
|
|
18
|
+
// src/structures/Guild.ts
|
|
19
|
+
import { parseRoleMention } from "@fluxerjs/util";
|
|
20
|
+
import { FluxerAPIError } from "@fluxerjs/rest";
|
|
21
|
+
import { Collection } from "@fluxerjs/collection";
|
|
22
|
+
import { Routes } from "@fluxerjs/types";
|
|
23
|
+
var Guild = class extends Base {
|
|
24
|
+
client;
|
|
25
|
+
id;
|
|
26
|
+
name;
|
|
27
|
+
icon;
|
|
28
|
+
banner;
|
|
29
|
+
ownerId;
|
|
30
|
+
/** Invite splash image hash. Null if none. */
|
|
31
|
+
splash;
|
|
32
|
+
/** Custom vanity URL code (e.g. fluxer.gg/code). Null if none. */
|
|
33
|
+
vanityURLCode;
|
|
34
|
+
/** Enabled guild features. */
|
|
35
|
+
features;
|
|
36
|
+
verificationLevel;
|
|
37
|
+
defaultMessageNotifications;
|
|
38
|
+
explicitContentFilter;
|
|
39
|
+
/** AFK voice channel ID. Null if none. */
|
|
40
|
+
afkChannelId;
|
|
41
|
+
/** AFK timeout in seconds. */
|
|
42
|
+
afkTimeout;
|
|
43
|
+
/** System messages channel ID. Null if none. */
|
|
44
|
+
systemChannelId;
|
|
45
|
+
/** Rules/guidelines channel ID. Null if none. */
|
|
46
|
+
rulesChannelId;
|
|
47
|
+
nsfwLevel;
|
|
48
|
+
mfaLevel;
|
|
49
|
+
/** Banner image width. Optional. */
|
|
50
|
+
bannerWidth;
|
|
51
|
+
/** Banner image height. Optional. */
|
|
52
|
+
bannerHeight;
|
|
53
|
+
/** Splash image width. Optional. */
|
|
54
|
+
splashWidth;
|
|
55
|
+
/** Splash image height. Optional. */
|
|
56
|
+
splashHeight;
|
|
57
|
+
members = new Collection();
|
|
58
|
+
channels = new Collection();
|
|
59
|
+
roles = new Collection();
|
|
60
|
+
/** @param data - API guild from GET /guilds/{id} or gateway GUILD_CREATE */
|
|
61
|
+
constructor(client, data) {
|
|
62
|
+
super();
|
|
63
|
+
this.client = client;
|
|
64
|
+
this.id = data.id;
|
|
65
|
+
this.name = data.name;
|
|
66
|
+
this.icon = data.icon ?? null;
|
|
67
|
+
this.banner = data.banner ?? null;
|
|
68
|
+
this.ownerId = data.owner_id ?? data.ownerId ?? "";
|
|
69
|
+
this.splash = data.splash ?? null;
|
|
70
|
+
this.vanityURLCode = data.vanity_url_code ?? null;
|
|
71
|
+
this.features = data.features ?? [];
|
|
72
|
+
this.verificationLevel = data.verification_level ?? 0;
|
|
73
|
+
this.defaultMessageNotifications = data.default_message_notifications ?? 0;
|
|
74
|
+
this.explicitContentFilter = data.explicit_content_filter ?? 0;
|
|
75
|
+
this.afkChannelId = data.afk_channel_id ?? null;
|
|
76
|
+
this.afkTimeout = data.afk_timeout ?? 0;
|
|
77
|
+
this.systemChannelId = data.system_channel_id ?? null;
|
|
78
|
+
this.rulesChannelId = data.rules_channel_id ?? null;
|
|
79
|
+
this.nsfwLevel = data.nsfw_level ?? 0;
|
|
80
|
+
this.mfaLevel = data.mfa_level ?? 0;
|
|
81
|
+
this.bannerWidth = data.banner_width ?? null;
|
|
82
|
+
this.bannerHeight = data.banner_height ?? null;
|
|
83
|
+
this.splashWidth = data.splash_width ?? null;
|
|
84
|
+
this.splashHeight = data.splash_height ?? null;
|
|
85
|
+
for (const r of data.roles ?? []) {
|
|
86
|
+
this.roles.set(r.id, new Role(client, r, this.id));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Get the guild icon URL, or null if no icon. */
|
|
90
|
+
iconURL(options) {
|
|
91
|
+
if (!this.icon) return null;
|
|
92
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
93
|
+
return `${CDN_URL}/icons/${this.id}/${this.icon}.png${size}`;
|
|
94
|
+
}
|
|
95
|
+
/** Get the guild banner URL, or null if no banner. */
|
|
96
|
+
bannerURL(options) {
|
|
97
|
+
if (!this.banner) return null;
|
|
98
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
99
|
+
return `${CDN_URL}/banners/${this.id}/${this.banner}.png${size}`;
|
|
100
|
+
}
|
|
101
|
+
/** Get the guild splash (invite background) URL, or null if no splash. */
|
|
102
|
+
splashURL(options) {
|
|
103
|
+
if (!this.splash) return null;
|
|
104
|
+
const size = options?.size ? `?size=${options.size}` : "";
|
|
105
|
+
return `${CDN_URL}/splashes/${this.id}/${this.splash}.png${size}`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Add a role to a member by user ID. Does not require fetching the member first.
|
|
109
|
+
* @param userId - The user ID of the member
|
|
110
|
+
* @param roleId - The role ID to add (or use guild.resolveRoleId for mention/name resolution)
|
|
111
|
+
* Requires Manage Roles permission.
|
|
112
|
+
*/
|
|
113
|
+
async addRoleToMember(userId, roleId) {
|
|
114
|
+
await this.client.rest.put(Routes.guildMemberRole(this.id, userId, roleId));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Remove a role from a member by user ID. Does not require fetching the member first.
|
|
118
|
+
* @param userId - The user ID of the member
|
|
119
|
+
* @param roleId - The role ID to remove
|
|
120
|
+
* Requires Manage Roles permission.
|
|
121
|
+
*/
|
|
122
|
+
async removeRoleFromMember(userId, roleId) {
|
|
123
|
+
await this.client.rest.delete(Routes.guildMemberRole(this.id, userId, roleId));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Resolve a role ID from an argument (role mention, raw ID, or name).
|
|
127
|
+
* Fetches guild roles if name is provided.
|
|
128
|
+
* @param arg - Role mention (@role), role ID, or role name
|
|
129
|
+
* @returns The role ID, or null if not found
|
|
130
|
+
*/
|
|
131
|
+
async resolveRoleId(arg) {
|
|
132
|
+
const parsed = parseRoleMention(arg);
|
|
133
|
+
if (parsed) return parsed;
|
|
134
|
+
if (/^\d{17,19}$/.test(arg.trim())) return arg.trim();
|
|
135
|
+
const cached = this.roles.find(
|
|
136
|
+
(r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase())
|
|
137
|
+
);
|
|
138
|
+
if (cached) return cached.id;
|
|
139
|
+
const roles = await this.client.rest.get(Routes.guildRoles(this.id));
|
|
140
|
+
const list = Array.isArray(roles) ? roles : Object.values(roles ?? {});
|
|
141
|
+
const role = list.find((r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase()));
|
|
142
|
+
if (role) {
|
|
143
|
+
this.roles.set(role.id, new Role(this.client, role, this.id));
|
|
144
|
+
return role.id;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Ban a user from this guild.
|
|
150
|
+
* @param userId - The user ID to ban
|
|
151
|
+
* @param options - Optional reason, delete_message_days (0–7), and ban_duration_seconds (temporary ban).
|
|
152
|
+
* ban_duration_seconds: 0 = permanent, or use 3600, 43200, 86400, 259200, 432000, 604800, 1209600, 2592000.
|
|
153
|
+
* Requires Ban Members permission.
|
|
154
|
+
*/
|
|
155
|
+
async ban(userId, options) {
|
|
156
|
+
const body = {};
|
|
157
|
+
if (options?.reason) body.reason = options.reason;
|
|
158
|
+
if (options?.delete_message_days != null)
|
|
159
|
+
body.delete_message_days = options.delete_message_days;
|
|
160
|
+
if (options?.ban_duration_seconds != null)
|
|
161
|
+
body.ban_duration_seconds = options.ban_duration_seconds;
|
|
162
|
+
await this.client.rest.put(Routes.guildBan(this.id, userId), {
|
|
163
|
+
body: Object.keys(body).length ? body : void 0,
|
|
164
|
+
auth: true
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Fetch guild bans. Requires Ban Members permission.
|
|
169
|
+
* @returns List of GuildBan objects
|
|
170
|
+
*/
|
|
171
|
+
async fetchBans() {
|
|
172
|
+
const { GuildBan } = await import("./GuildBan-7CXLTPKY.mjs");
|
|
173
|
+
const data = await this.client.rest.get(Routes.guildBans(this.id));
|
|
174
|
+
const list = Array.isArray(data) ? data : data?.bans ?? [];
|
|
175
|
+
return list.map((b) => new GuildBan(this.client, { ...b, guild_id: this.id }, this.id));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Remove a ban (unban a user).
|
|
179
|
+
* @param userId - The user ID to unban
|
|
180
|
+
* Requires Ban Members permission.
|
|
181
|
+
*/
|
|
182
|
+
async unban(userId) {
|
|
183
|
+
await this.client.rest.delete(Routes.guildBan(this.id, userId), { auth: true });
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Kick a member from this guild.
|
|
187
|
+
* @param userId - The user ID to kick
|
|
188
|
+
* Requires Kick Members permission.
|
|
189
|
+
*/
|
|
190
|
+
async kick(userId) {
|
|
191
|
+
await this.client.rest.delete(Routes.guildMember(this.id, userId), { auth: true });
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Fetch a guild member by user ID.
|
|
195
|
+
* @param userId - The user ID of the member to fetch
|
|
196
|
+
* @returns The guild member
|
|
197
|
+
* @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
|
|
198
|
+
* @throws FluxerError with cause for permission denied (403) or other REST errors
|
|
199
|
+
*/
|
|
200
|
+
async fetchMember(userId) {
|
|
201
|
+
try {
|
|
202
|
+
const data = await this.client.rest.get(
|
|
203
|
+
Routes.guildMember(this.id, userId)
|
|
204
|
+
);
|
|
205
|
+
const member = new GuildMember(this.client, { ...data, guild_id: this.id }, this);
|
|
206
|
+
this.members.set(member.id, member);
|
|
207
|
+
return member;
|
|
208
|
+
} catch (err) {
|
|
209
|
+
const statusCode = err instanceof FluxerAPIError ? err.statusCode : err?.statusCode;
|
|
210
|
+
if (statusCode === 404) {
|
|
211
|
+
throw new FluxerError(`Member ${userId} not found in guild`, {
|
|
212
|
+
code: ErrorCodes.MemberNotFound,
|
|
213
|
+
cause: err
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
throw err instanceof FluxerError ? err : new FluxerError("Failed to fetch guild member", { cause: err });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Fetch guild audit logs. Requires View Audit Log permission.
|
|
221
|
+
* @param options - Optional limit, before, after, user_id, action_type for filtering
|
|
222
|
+
*/
|
|
223
|
+
async fetchAuditLogs(options) {
|
|
224
|
+
const params = new URLSearchParams();
|
|
225
|
+
if (options?.limit != null) params.set("limit", String(options.limit));
|
|
226
|
+
if (options?.before) params.set("before", options.before);
|
|
227
|
+
if (options?.after) params.set("after", options.after);
|
|
228
|
+
if (options?.userId) params.set("user_id", options.userId);
|
|
229
|
+
if (options?.actionType != null) params.set("action_type", String(options.actionType));
|
|
230
|
+
const qs = params.toString();
|
|
231
|
+
const url = Routes.guildAuditLogs(this.id) + (qs ? `?${qs}` : "");
|
|
232
|
+
return this.client.rest.get(url);
|
|
233
|
+
}
|
|
234
|
+
/** Fetch all webhooks in this guild. Returned webhooks do not include the token (cannot send). */
|
|
235
|
+
async fetchWebhooks() {
|
|
236
|
+
const { Webhook } = await import("./Webhook-RWDDYW2Q.mjs");
|
|
237
|
+
const data = await this.client.rest.get(Routes.guildWebhooks(this.id));
|
|
238
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
239
|
+
return list.map((w) => new Webhook(this.client, w));
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Create a channel in this guild.
|
|
243
|
+
* @param data - Channel data: type (0=text, 2=voice, 4=category, 5=link), name, and optional parent_id, topic, bitrate, user_limit, nsfw, permission_overwrites
|
|
244
|
+
* Requires Manage Channels permission.
|
|
245
|
+
*/
|
|
246
|
+
async createChannel(data) {
|
|
247
|
+
const { Channel } = await import("./Channel-4WVFDOCG.mjs");
|
|
248
|
+
const created = await this.client.rest.post(Routes.guildChannels(this.id), {
|
|
249
|
+
body: data,
|
|
250
|
+
auth: true
|
|
251
|
+
});
|
|
252
|
+
const channel = Channel.from(this.client, created);
|
|
253
|
+
if (channel) {
|
|
254
|
+
this.client.channels.set(channel.id, channel);
|
|
255
|
+
this.channels.set(channel.id, channel);
|
|
256
|
+
}
|
|
257
|
+
return channel;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Fetch all channels in this guild.
|
|
261
|
+
* @returns Array of GuildChannel objects (cached in guild.channels and client.channels)
|
|
262
|
+
*/
|
|
263
|
+
async fetchChannels() {
|
|
264
|
+
const { Channel } = await import("./Channel-4WVFDOCG.mjs");
|
|
265
|
+
const data = await this.client.rest.get(Routes.guildChannels(this.id));
|
|
266
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
267
|
+
const channels = [];
|
|
268
|
+
for (const ch of list) {
|
|
269
|
+
const channel = Channel.from(this.client, ch);
|
|
270
|
+
if (channel) {
|
|
271
|
+
this.client.channels.set(channel.id, channel);
|
|
272
|
+
this.channels.set(channel.id, channel);
|
|
273
|
+
channels.push(channel);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return channels;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Update channel positions.
|
|
280
|
+
* @param updates - Array of { id, position?, parent_id?, lock_permissions? }
|
|
281
|
+
* Requires Manage Channels permission.
|
|
282
|
+
*/
|
|
283
|
+
async setChannelPositions(updates) {
|
|
284
|
+
await this.client.rest.patch(Routes.guildChannels(this.id), {
|
|
285
|
+
body: updates,
|
|
286
|
+
auth: true
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export {
|
|
292
|
+
Guild
|
|
293
|
+
};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ErrorCodes,
|
|
3
|
+
FluxerError
|
|
4
|
+
} from "./chunk-V6T5VMWD.mjs";
|
|
1
5
|
import {
|
|
2
6
|
Base
|
|
3
7
|
} from "./chunk-XNS4O6QJ.mjs";
|
|
4
8
|
|
|
5
9
|
// src/structures/MessageReaction.ts
|
|
10
|
+
import { Routes } from "@fluxerjs/types";
|
|
11
|
+
import { FluxerAPIError, RateLimitError } from "@fluxerjs/rest";
|
|
6
12
|
var MessageReaction = class extends Base {
|
|
7
13
|
client;
|
|
8
14
|
messageId;
|
|
@@ -31,9 +37,25 @@ var MessageReaction = class extends Base {
|
|
|
31
37
|
/**
|
|
32
38
|
* Fetch the message this reaction belongs to.
|
|
33
39
|
* Use when you need to edit, delete, or otherwise interact with the message.
|
|
40
|
+
* @throws FluxerError with MESSAGE_NOT_FOUND if the message does not exist
|
|
34
41
|
*/
|
|
35
42
|
async fetchMessage() {
|
|
36
|
-
|
|
43
|
+
try {
|
|
44
|
+
const { Message } = await import("./Message-OFIVTTAZ.mjs");
|
|
45
|
+
const data = await this.client.rest.get(
|
|
46
|
+
Routes.channelMessage(this.channelId, this.messageId)
|
|
47
|
+
);
|
|
48
|
+
return new Message(this.client, data);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
if (err instanceof RateLimitError) throw err;
|
|
51
|
+
if (err instanceof FluxerAPIError && err.statusCode === 404) {
|
|
52
|
+
throw new FluxerError(
|
|
53
|
+
`Message ${this.messageId} not found in channel ${this.channelId}`,
|
|
54
|
+
{ code: ErrorCodes.MessageNotFound, cause: err }
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
throw err instanceof FluxerError ? err : new FluxerError(String(err), { cause: err });
|
|
58
|
+
}
|
|
37
59
|
}
|
|
38
60
|
};
|
|
39
61
|
|
|
@@ -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
|
+
};
|