From 05027e4e144bfc518f5cb48ebab6f484f8782d79 Mon Sep 17 00:00:00 2001 From: Skillz Date: Wed, 20 May 2020 13:33:00 -0400 Subject: [PATCH] refactor export type into interfaces --- module/shardingManager.ts | 20 ++++------------ structures/channel.ts | 2 +- structures/guild.ts | 16 ++++++------- structures/member.ts | 48 ++++++++++++++++++--------------------- structures/message.ts | 2 +- structures/role.ts | 2 +- structures/user.ts | 2 +- types/member.ts | 3 --- types/message.ts | 3 ++- types/options.ts | 2 +- utils/permissions.ts | 25 ++++++++++++-------- 11 files changed, 58 insertions(+), 67 deletions(-) diff --git a/module/shardingManager.ts b/module/shardingManager.ts index 9c794d5ed..20d165abc 100644 --- a/module/shardingManager.ts +++ b/module/shardingManager.ts @@ -190,9 +190,7 @@ function handleDiscordPayload(data: DiscordPayload) { guild.memberCount = memberCount; const member = createMember( options, - guild.id, - [...guild.roles.values()].map((role) => role.raw), - guild.ownerID, + guild, ); guild.members.set(options.user.id, member); cache.users.set(options.user.id, createUser(member.user)); @@ -232,9 +230,7 @@ function handleDiscordPayload(data: DiscordPayload) { }; const member = createMember( newMemberData, - options.guild_id, - [...guild.roles.values()].map((r) => r.raw), - guild.ownerID, + guild, ); guild.members.set(options.user.id, member); cache.users.set(options.user.id, createUser(member.user)); @@ -274,9 +270,7 @@ function handleDiscordPayload(data: DiscordPayload) { member.user.id, createMember( member, - options.guild_id, - [...guild.roles.values()].map((r) => r.raw), - guild.ownerID, + guild, ), ); cache.users.set(member.user.id, createUser(member.user)); @@ -341,9 +335,7 @@ function handleDiscordPayload(data: DiscordPayload) { options.author.id, createMember( { ...options.member, user: options.author }, - options.guild_id, - [...guild.roles.values()].map((r) => r.raw), - guild.ownerID, + guild, ), ); } @@ -418,9 +410,7 @@ function handleDiscordPayload(data: DiscordPayload) { if (guild) { const member = createMember( options.member, - options.guild_id, - [...guild.roles.values()].map((r) => r.raw), - guild.ownerID, + guild, ); guild.members.set( options.member.user.id, diff --git a/structures/channel.ts b/structures/channel.ts index 304474f74..cf90b746f 100644 --- a/structures/channel.ts +++ b/structures/channel.ts @@ -213,4 +213,4 @@ export function createChannel(data: ChannelCreatePayload) { return channel; } -export type Channel = ReturnType; +export interface Channel extends ReturnType {} diff --git a/structures/guild.ts b/structures/guild.ts index 7a5dc8e23..da82d2291 100644 --- a/structures/guild.ts +++ b/structures/guild.ts @@ -15,7 +15,7 @@ import { FetchMembersOptions, } from "../types/guild.ts"; import { createRole } from "./role.ts"; -import { createMember } from "./member.ts"; +import { createMember, Member } from "./member.ts"; import { createChannel } from "./channel.ts"; import { CreateChannelOptions, @@ -70,11 +70,7 @@ export const createGuild = (data: CreateGuildPayload) => { /** When this guild was joined at. */ joinedAt: Date.parse(data.joined_at), /** The users in this guild. */ - members: new Map( - data.members.map(( - m, - ) => [m.user.id, createMember(m, data.id, data.roles, data.owner_id)]), - ), + members: new Map(), /** The channels in the guild */ channels: new Map(data.channels.map((c) => [c.id, createChannel(c)])), /** The presences of all the users in the guild. */ @@ -225,7 +221,7 @@ export const createGuild = (data: CreateGuildPayload) => { const roleData = role_data as RoleData; const role = createRole(roleData); - guild.roles.set(roleData.id, role); + // guild.roles.set(roleData.id, role); return role; }, /** Edit a guild role. Requires the MANAGE_ROLES permission. */ @@ -473,7 +469,11 @@ export const createGuild = (data: CreateGuildPayload) => { }, }; + data.members.forEach((m) => + guild.members.set(m.user.id, createMember(m, guild)) + ); + return guild; }; -export type Guild = ReturnType; +export interface Guild extends ReturnType {} diff --git a/structures/member.ts b/structures/member.ts index 798d63590..5b0702a94 100644 --- a/structures/member.ts +++ b/structures/member.ts @@ -3,7 +3,6 @@ import { formatImageURL } from "../utils/cdn.ts"; import { MemberCreatePayload, EditMemberOptions } from "../types/member.ts"; import { ImageSize, ImageFormats } from "../types/cdn.ts"; import { Permission, Permissions } from "../types/permission.ts"; -import { RoleData } from "../types/role.ts"; import { memberHasPermission, botHasPermission, @@ -13,13 +12,9 @@ import { import { Errors } from "../types/errors.ts"; import { RequestManager } from "../module/requestManager.ts"; import { botID } from "../module/client.ts"; +import { Guild } from "./guild.ts"; -export const createMember = ( - data: MemberCreatePayload, - guildID: string, - roleData: RoleData[], - ownerID: string, -) => ({ +export const createMember = (data: MemberCreatePayload, guild: Guild) => ({ ...data, /** The complete raw data from the member create payload */ raw: data, @@ -43,45 +38,45 @@ export const createMember = ( : endpoints.USER_DEFAULT_AVATAR(Number(data.user.discriminator) % 5), /** Add a role to the member */ addRole: (roleID: string, reason?: string) => { - const botsHighestRole = highestRole(guildID, botID); + const botsHighestRole = highestRole(guild.id, botID); if ( botsHighestRole && - !higherRolePosition(guildID, botsHighestRole.id, roleID) + !higherRolePosition(guild.id, botsHighestRole.id, roleID) ) { throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - if (!botHasPermission(guildID, [Permissions.MANAGE_ROLES])) { + if (!botHasPermission(guild.id, [Permissions.MANAGE_ROLES])) { throw new Error(Errors.MISSING_MANAGE_ROLES); } return RequestManager.put( - endpoints.GUILD_MEMBER_ROLE(guildID, data.user.id, roleID), + endpoints.GUILD_MEMBER_ROLE(guild.id, data.user.id, roleID), { reason }, ); }, /** Remove a role from the member */ removeRole: (roleID: string, reason?: string) => { - const botsHighestRole = highestRole(guildID, botID); + const botsHighestRole = highestRole(guild.id, botID); if ( botsHighestRole && - !higherRolePosition(guildID, botsHighestRole.id, roleID) + !higherRolePosition(guild.id, botsHighestRole.id, roleID) ) { throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - if (!botHasPermission(guildID, [Permissions.MANAGE_ROLES])) { + if (!botHasPermission(guild.id, [Permissions.MANAGE_ROLES])) { throw new Error(Errors.MISSING_MANAGE_ROLES); } return RequestManager.delete( - endpoints.GUILD_MEMBER_ROLE(guildID, data.user.id, roleID), + endpoints.GUILD_MEMBER_ROLE(guild.id, data.user.id, roleID), { reason }, ); }, /** Kick a member from the server */ kick: (reason?: string) => { - const botsHighestRole = highestRole(guildID, botID); - const membersHighestRole = highestRole(guildID, data.user.id); + const botsHighestRole = highestRole(guild.id, botID); + const membersHighestRole = highestRole(guild.id, data.user.id); if ( botsHighestRole && membersHighestRole && botsHighestRole.position <= membersHighestRole.position @@ -89,11 +84,11 @@ export const createMember = ( throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - if (!botHasPermission(guildID, [Permissions.KICK_MEMBERS])) { + if (!botHasPermission(guild.id, [Permissions.KICK_MEMBERS])) { throw new Error(Errors.MISSING_KICK_MEMBERS); } return RequestManager.delete( - endpoints.GUILD_MEMBER(guildID, data.user.id), + endpoints.GUILD_MEMBER(guild.id, data.user.id), { reason }, ); }, @@ -103,14 +98,14 @@ export const createMember = ( if (options.nick.length > 32) { throw new Error(Errors.NICKNAMES_MAX_LENGTH); } - if (!botHasPermission(guildID, [Permissions.MANAGE_NICKNAMES])) { + if (!botHasPermission(guild.id, [Permissions.MANAGE_NICKNAMES])) { throw new Error(Errors.MISSING_MANAGE_NICKNAMES); } } if ( options.roles && - !botHasPermission(guildID, [Permissions.MANAGE_ROLES]) + !botHasPermission(guild.id, [Permissions.MANAGE_ROLES]) ) { throw new Error(Errors.MISSING_MANAGE_ROLES); } @@ -118,7 +113,7 @@ export const createMember = ( if (options.mute) { // TODO: This should check if the member is in a voice channel if ( - !botHasPermission(guildID, [Permissions.MUTE_MEMBERS]) + !botHasPermission(guild.id, [Permissions.MUTE_MEMBERS]) ) { throw new Error(Errors.MISSING_MUTE_MEMBERS); } @@ -126,7 +121,7 @@ export const createMember = ( if ( options.deaf && - !botHasPermission(guildID, [Permissions.DEAFEN_MEMBERS]) + !botHasPermission(guild.id, [Permissions.DEAFEN_MEMBERS]) ) { throw new Error(Errors.MISSING_DEAFEN_MEMBERS); } @@ -134,7 +129,7 @@ export const createMember = ( // TODO: if channel id is provided check if the bot has CONNECT and MOVE in channel and current channel return RequestManager.patch( - endpoints.GUILD_MEMBER(guildID, data.user.id), + endpoints.GUILD_MEMBER(guild.id, data.user.id), options, ); }, @@ -142,10 +137,11 @@ export const createMember = ( hasPermissions: (permissions: Permission[]) => { return memberHasPermission( data.user.id, - ownerID, - roleData, + guild, data.roles, permissions, ); }, }); + +export interface Member extends ReturnType {} diff --git a/structures/message.ts b/structures/message.ts index 941a21918..b4f37570b 100644 --- a/structures/message.ts +++ b/structures/message.ts @@ -160,4 +160,4 @@ export function createMessage(data: MessageCreateOptions) { }; } -export type Message = ReturnType; +export interface Message extends ReturnType {} diff --git a/structures/role.ts b/structures/role.ts index 28471ee46..f7c6194ae 100644 --- a/structures/role.ts +++ b/structures/role.ts @@ -8,4 +8,4 @@ export const createRole = (data: RoleData) => ({ mention: `<@&${data.id}>`, }); -export type Role = ReturnType; +export interface Role extends ReturnType {} diff --git a/structures/user.ts b/structures/user.ts index 1d8d2316b..37241aebf 100644 --- a/structures/user.ts +++ b/structures/user.ts @@ -29,4 +29,4 @@ export const createUser = (data: UserPayload) => ({ : endpoints.USER_DEFAULT_AVATAR(Number(data.discriminator) % 5), }); -export type User = ReturnType; +export interface User extends ReturnType {} diff --git a/types/member.ts b/types/member.ts index f10ba74dd..199e0fef5 100644 --- a/types/member.ts +++ b/types/member.ts @@ -1,4 +1,3 @@ -import { createMember } from "../structures/member.ts"; import { UserPayload } from "./guild.ts"; export interface EditMemberOptions { @@ -30,5 +29,3 @@ export interface MemberCreatePayload { /** Whether the user is muted in voice channels */ mute: boolean; } - -export type Member = ReturnType; diff --git a/types/message.ts b/types/message.ts index 0178158ca..be7f38cc4 100644 --- a/types/message.ts +++ b/types/message.ts @@ -1,7 +1,8 @@ import { ChannelType, UserPayload } from "./guild.ts"; import { User } from "../structures/user.ts"; -import { Member, MemberCreatePayload } from "./member.ts"; +import { MemberCreatePayload } from "./member.ts"; import { Channel } from "../structures/channel.ts"; +import { Member } from "../structures/member.ts"; export interface MentionedUser extends User { member: Member; diff --git a/types/options.ts b/types/options.ts index e3f6d4d5a..5949e240d 100644 --- a/types/options.ts +++ b/types/options.ts @@ -7,7 +7,6 @@ import { VoiceStateUpdatePayload, } from "./discord.ts"; import { User } from "../structures/user.ts"; -import { Member } from "./member.ts"; import { Role } from "../structures/role.ts"; import { Message } from "../structures/message.ts"; import { @@ -19,6 +18,7 @@ import { } from "./message.ts"; import { Channel } from "../structures/channel.ts"; import { Guild } from "../structures/guild.ts"; +import { Member } from "../structures/member.ts"; export interface Fulfilled_Client_Options { token: string; diff --git a/utils/permissions.ts b/utils/permissions.ts index c39006c1c..7973aeb37 100644 --- a/utils/permissions.ts +++ b/utils/permissions.ts @@ -1,26 +1,33 @@ import { Permission, Permissions } from "../types/permission.ts"; -import { RoleData } from "../types/role.ts"; import { cache } from "./cache.ts"; import { botID } from "../module/client.ts"; import { Role } from "../structures/role.ts"; +import { Guild } from "../structures/guild.ts"; export function memberHasPermission( memberID: string, - ownerID: string, - roleData: RoleData[], + guild: Guild, memberRoleIDs: string[], permissions: Permission[], ) { - if (memberID === ownerID) return true; - - const permissionBits = roleData - .filter((role) => memberRoleIDs.includes(role.id)) - .reduce((bits, data) => { - bits |= data.permissions; + if (memberID === guild.ownerID) return true; + const permissionBits = memberRoleIDs.map((id) => + guild.roles.get(id)?.permissions || 0 + ) + .reduce((bits, permissions) => { + bits |= permissions; return bits; }, 0); + // const permissionBits = [...guild.roles.values()] + // .filter((role) => memberRoleIDs.includes(role.id)) + // .map((role) => role.permissions) + // .reduce((bits, permissions) => { + // bits |= permissions; + // return bits; + // }, 0); + if (permissionBits & Permissions.ADMINISTRATOR) return true; return permissions.every((permission) =>