mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +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 BaseManager = require('./BaseManager');
|
||||||
const { Error, TypeError, RangeError } = require('../errors');
|
const { Error, TypeError, RangeError } = require('../errors');
|
||||||
const GuildMember = require('../structures/GuildMember');
|
const GuildMember = require('../structures/GuildMember');
|
||||||
|
const Role = require('../structures/Role');
|
||||||
const Collection = require('../util/Collection');
|
const Collection = require('../util/Collection');
|
||||||
const { Events, OPCodes } = require('../util/Constants');
|
const { Events, OPCodes } = require('../util/Constants');
|
||||||
const SnowflakeUtil = require('../util/SnowflakeUtil');
|
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());
|
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.
|
* 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>
|
* <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);
|
.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.
|
* Bans a user from the guild.
|
||||||
* @param {UserResolvable} user The user to ban
|
* @param {UserResolvable} user The user to ban
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Base = require('./Base');
|
const Base = require('./Base');
|
||||||
const Role = require('./Role');
|
|
||||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||||
const { Error } = require('../errors');
|
const { Error } = require('../errors');
|
||||||
const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
|
const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
|
||||||
@@ -283,34 +282,8 @@ class GuildMember extends Base {
|
|||||||
* @param {string} [reason] Reason for editing this user
|
* @param {string} [reason] Reason for editing this user
|
||||||
* @returns {Promise<GuildMember>}
|
* @returns {Promise<GuildMember>}
|
||||||
*/
|
*/
|
||||||
async edit(data, reason) {
|
edit(data, reason) {
|
||||||
if (data.channel) {
|
return this.guild.members.edit(this, data, reason);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -345,11 +318,7 @@ class GuildMember extends Base {
|
|||||||
* @returns {Promise<GuildMember>}
|
* @returns {Promise<GuildMember>}
|
||||||
*/
|
*/
|
||||||
kick(reason) {
|
kick(reason) {
|
||||||
return this.client.api
|
return this.guild.members.kick(this, reason);
|
||||||
.guilds(this.guild.id)
|
|
||||||
.members(this.user.id)
|
|
||||||
.delete({ reason })
|
|
||||||
.then(() => this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
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>);
|
constructor(guild: Guild, iterable?: Iterable<any>);
|
||||||
public guild: Guild;
|
public guild: Guild;
|
||||||
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
|
public ban(user: UserResolvable, options?: BanOptions): Promise<GuildMember | User | Snowflake>;
|
||||||
|
public edit(user: UserResolvable, data: GuildMemberEditData, reason?: string): Promise<void>;
|
||||||
public fetch(
|
public fetch(
|
||||||
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
|
options: UserResolvable | FetchMemberOptions | (FetchMembersOptions & { user: UserResolvable }),
|
||||||
): Promise<GuildMember>;
|
): Promise<GuildMember>;
|
||||||
public fetch(options?: FetchMembersOptions): Promise<Collection<Snowflake, 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 & { dry?: false; count: false }): Promise<null>;
|
||||||
public prune(options?: GuildPruneMembersOptions): Promise<number>;
|
public prune(options?: GuildPruneMembersOptions): Promise<number>;
|
||||||
public search(options: GuildSearchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
|
public search(options: GuildSearchMembersOptions): Promise<Collection<Snowflake, GuildMember>>;
|
||||||
|
|||||||
Reference in New Issue
Block a user