mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 00:23:30 +01:00
feat(GuildMemberManager): extend API coverage (#4872)
Co-authored-by: Antonio Román <kyradiscord@gmail.com> Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
const BaseManager = require('./BaseManager');
|
||||
const { Error, TypeError, RangeError } = require('../errors');
|
||||
const GuildMember = require('../structures/GuildMember');
|
||||
const Role = require('../structures/Role');
|
||||
const Collection = require('../util/Collection');
|
||||
const { Events, OPCodes } = require('../util/Constants');
|
||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
||||
@@ -149,6 +150,47 @@ class GuildMemberManager extends BaseManager {
|
||||
return data.reduce((col, member) => col.set(member.user.id, this.add(member, cache)), new Collection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits a member of the guild.
|
||||
* <info>The user must be a member of the guild</info>
|
||||
* @param {UserResolvable} user The member to edit
|
||||
* @param {GuildMemberEditData} data The data to edit the member with
|
||||
* @param {string} [reason] Reason for editing this user
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
async edit(user, data, reason) {
|
||||
const id = this.client.users.resolveID(user);
|
||||
if (!id) throw new TypeError('INVALID_TYPE', 'user', 'UserResolvable');
|
||||
|
||||
// Clone the data object for immutability
|
||||
const _data = { ...data };
|
||||
if (_data.channel) {
|
||||
_data.channel = this.guild.channels.resolve(_data.channel);
|
||||
if (!_data.channel || _data.channel.type !== 'voice') {
|
||||
throw new Error('GUILD_VOICE_CHANNEL_RESOLVE');
|
||||
}
|
||||
_data.channel_id = _data.channel.id;
|
||||
_data.channel = undefined;
|
||||
} else if (_data.channel === null) {
|
||||
_data.channel_id = null;
|
||||
_data.channel = undefined;
|
||||
}
|
||||
if (_data.roles) _data.roles = _data.roles.map(role => (role instanceof Role ? role.id : role));
|
||||
let endpoint = this.client.api.guilds(this.guild.id);
|
||||
if (id === this.client.user.id) {
|
||||
const keys = Object.keys(_data);
|
||||
if (keys.length === 1 && keys[0] === 'nick') endpoint = endpoint.members('@me').nick;
|
||||
else endpoint = endpoint.members(id);
|
||||
} else {
|
||||
endpoint = endpoint.members(id);
|
||||
}
|
||||
const d = await endpoint.patch({ data: _data, reason });
|
||||
|
||||
const clone = this.cache.get(id)?._clone();
|
||||
clone?.patch(d);
|
||||
return clone ?? this.add(d, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes members from the guild based on how long they have been inactive.
|
||||
* <info>It's recommended to set options.count to `false` for large guilds.</info>
|
||||
@@ -207,6 +249,29 @@ class GuildMemberManager extends BaseManager {
|
||||
.then(data => data.pruned);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks a user from the guild.
|
||||
* <info>The user must be a member of the guild</info>
|
||||
* @param {UserResolvable} user The member to kick
|
||||
* @param {string} [reason] Reason for kicking
|
||||
* @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
|
||||
* If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
|
||||
* be resolved, the user ID will be the result.
|
||||
* @example
|
||||
* // Kick a user by ID (or with a user/guild member object)
|
||||
* guild.members.kick('84484653687267328')
|
||||
* .then(user => console.log(`Kicked ${user.username || user.id || user} from ${guild.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
async kick(user, reason) {
|
||||
const id = this.client.users.resolveID(user);
|
||||
if (!id) return Promise.reject(new TypeError('INVALID_TYPE', 'user', 'UserResolvable'));
|
||||
|
||||
await this.client.api.guilds(this.guild.id).members(id).delete({ reason });
|
||||
|
||||
return this.resolve(user) ?? this.client.users.resolve(user) ?? id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bans a user from the guild.
|
||||
* @param {UserResolvable} user The user to ban
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const Base = require('./Base');
|
||||
const Role = require('./Role');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { Error } = require('../errors');
|
||||
const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
|
||||
@@ -283,34 +282,8 @@ class GuildMember extends Base {
|
||||
* @param {string} [reason] Reason for editing this user
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
async edit(data, reason) {
|
||||
if (data.channel) {
|
||||
const voiceChannelID = this.guild.channels.resolveID(data.channel);
|
||||
const voiceChannel = this.guild.channels.cache.get(voiceChannelID);
|
||||
if (!voiceChannelID || (voiceChannel && voiceChannel?.type !== 'voice')) {
|
||||
throw new Error('GUILD_VOICE_CHANNEL_RESOLVE');
|
||||
}
|
||||
data.channel_id = voiceChannelID;
|
||||
data.channel = undefined;
|
||||
} else if (data.channel === null) {
|
||||
data.channel_id = null;
|
||||
data.channel = undefined;
|
||||
}
|
||||
if (data.roles) data.roles = data.roles.map(role => (role instanceof Role ? role.id : role));
|
||||
let endpoint = this.client.api.guilds(this.guild.id);
|
||||
if (this.user.id === this.client.user.id) {
|
||||
const keys = Object.keys(data);
|
||||
if (keys.length === 1 && keys[0] === 'nick') endpoint = endpoint.members('@me').nick;
|
||||
else endpoint = endpoint.members(this.id);
|
||||
} else {
|
||||
endpoint = endpoint.members(this.id);
|
||||
}
|
||||
await endpoint.patch({ data, reason });
|
||||
|
||||
const clone = this._clone();
|
||||
data.user = this.user;
|
||||
clone._patch(data);
|
||||
return clone;
|
||||
edit(data, reason) {
|
||||
return this.guild.members.edit(this, data, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,11 +318,7 @@ class GuildMember extends Base {
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
kick(reason) {
|
||||
return this.client.api
|
||||
.guilds(this.guild.id)
|
||||
.members(this.user.id)
|
||||
.delete({ reason })
|
||||
.then(() => this);
|
||||
return this.guild.members.kick(this, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
typings/index.d.ts
vendored
2
typings/index.d.ts
vendored
@@ -2145,10 +2145,12 @@ declare module 'discord.js' {
|
||||
constructor(guild: Guild, iterable?: Iterable<any>);
|
||||
public guild: Guild;
|
||||
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
|
||||
public edit(user: UserResolvable, data: GuildMemberEditData, reason?: string): Promise<void>;
|
||||
public fetch(
|
||||
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
|
||||
): Promise<GuildMember>;
|
||||
public fetch(options?: FetchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
|
||||
public kick(user: UserResolvable, reason?: string): Promise<GuildMember | User | Snowflake>;
|
||||
public prune(options: GuildPruneMembersOptions & { dry?: false; count: false }): Promise<null>;
|
||||
public prune(options?: GuildPruneMembersOptions): Promise<number>;
|
||||
public search(options: GuildSearchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
|
||||
|
||||
Reference in New Issue
Block a user