diff --git a/src/structures/member.ts b/src/structures/member.ts index a85ae2c37..9f26e5b91 100644 --- a/src/structures/member.ts +++ b/src/structures/member.ts @@ -1,6 +1,43 @@ import { cacheHandlers } from "../controllers/cache.ts"; -import { GuildMember, MemberCreatePayload, Unpromise } from "../types/types.ts"; +import { ban } from "../handlers/guild.ts"; +import { addRole, editMember, kick, removeRole, sendDirectMessage } from "../handlers/member.ts"; +import { BanOptions, EditMemberOptions, GuildMember, MemberCreatePayload, MessageContent, Unpromise } from "../types/types.ts"; +import { cache } from "../utils/cache.ts"; import { Collection } from "../utils/collection.ts"; +import { createNewProp } from "../utils/utils.ts"; +import { Guild } from "./guild.ts"; + +const baseMember: Partial = { + // METHODS + + guild(guildID) { + return cache.guilds.get(guildID); + }, + name(guildID) { + return this.guildMember!(guildID)?.nick || this.username!; + }, + guildMember(guildID) { + return this.guilds?.get(guildID) + }, + sendDM(content) { + return sendDirectMessage(this.id!, content); + }, + kick(guildID, reason) { + return kick(guildID, this.id!, reason) + }, + edit(guildID, options) { + return editMember(guildID, this.id!, options) + }, + ban(guildID, options) { + return ban(guildID, this.id!, options); + }, + addRole(guildID, roleID, reason) { + return addRole(guildID, this.id!, roleID, reason); + }, + removeRole(guildID, roleID, reason) { + return removeRole(guildID, this.id!, roleID, reason); + }, +} export async function createMember(data: MemberCreatePayload, guildID: string) { const { @@ -20,17 +57,25 @@ export async function createMember(data: MemberCreatePayload, guildID: string) { ...user } = data.user || {}; - const member = { - ...rest, - // Only use those that we have not removed above - ...user, - /** Whether or not this user has 2FA enabled. */ - mfaEnabled, - /** The premium type for this user */ - premiumType, + const restProps = {}; + for (const key of Object.keys(rest)) { + // @ts-ignore + restProps[key] = createNewProp(rest[key]); + } + + for (const key of Object.keys(user)) { + // @ts-ignore + restProps[key] = createNewProp(user[key]); + } + + const member = Object.create(baseMember, { + // INCASE DISCORD ADDS MORE DATA USERS OF OUR LIB GET IT INSTANTLY + ...restProps, + mfaEnabled: createNewProp(mfaEnabled), + premiumType: createNewProp(premiumType), /** The guild related data mapped by guild id */ - guilds: new Collection(), - }; + guilds: createNewProp(new Collection()), + }); const cached = await cacheHandlers.get("members", user.id); if (cached) { @@ -54,4 +99,52 @@ export async function createMember(data: MemberCreatePayload, guildID: string) { return member; } -export interface Member extends Unpromise> {} +export interface Member { + /** The user's id */ + id: string; + /** the user's username, not unique across the platform */ + username: string; + /** The user's 4 digit discord tag */ + discriminator: string; + /** The user's avatar hash */ + avatar: string | null; + /** Whether the user is a bot */ + bot?: boolean; + /** Whether the user is an official discord system user (part of the urgent message system.) */ + system?: boolean; + /** the user's chosen language option */ + locale?: string; + /** Whether the email on this account has been verified */ + verified?: boolean; + /** The user's email */ + email?: string; + /** The flags on a user's account. */ + flags?: number; + /** Whether or not this user has 2FA enabled. */ + mfaEnabled?: boolean; + /** The premium type for this user */ + premiumType?: number; + /** The guild related data mapped by guild id */ + guilds: Collection; + + // METHODS + + /** Returns the guild for this guildID */ + guild(guildID: string): Guild | undefined; + /** Get the nickname or the username if no nickname */ + name(guildID: string): string; + /** Get the nickname */ + guildMember(guildID: string): GuildMember; + /** Send a direct message to the user is possible */ + sendDM(content: string | MessageContent): Promise; + /** Kick the member from a guild */ + kick(guildID: string, reason?: string): Promise; + /** Edit the member in a guild */ + edit(guildID: string, options: EditMemberOptions): Promise; + /** Ban a member in a guild */ + ban(guildID: string, options: BanOptions): Promise; + /** Add a role to the member */ + addRole(guildID: string, roleID: string, reason?: string): Promise; + /** Remove a role from the member */ + removeRole(guildID: string, roleID: string, reason?: string): Promise; +}