2020-10-22 15:50:47 +00:00
|
|
|
import { Client } from '../models/client.ts'
|
2021-03-19 15:39:14 +00:00
|
|
|
import {
|
|
|
|
ChannelPayload,
|
|
|
|
ChannelTypes,
|
|
|
|
ModifyChannelOption,
|
|
|
|
ModifyChannelPayload,
|
|
|
|
Overwrite,
|
|
|
|
OverwritePayload,
|
|
|
|
OverwriteAsArg,
|
|
|
|
OverrideType
|
|
|
|
} from '../types/channel.ts'
|
|
|
|
import { CHANNEL } from '../types/endpoint.ts'
|
|
|
|
import { GuildChannelPayloads, GuildChannels } from '../types/guild.ts'
|
|
|
|
import getChannelByType from '../utils/getChannelByType.ts'
|
|
|
|
import { Permissions } from '../utils/permissions.ts'
|
2021-01-25 11:28:46 +00:00
|
|
|
import { SnowflakeBase } from './base.ts'
|
2021-03-19 15:39:14 +00:00
|
|
|
import { Guild } from './guild.ts'
|
|
|
|
import { Member } from './member.ts'
|
|
|
|
import { Role } from './role.ts'
|
2020-10-22 15:50:47 +00:00
|
|
|
|
2021-01-25 11:28:46 +00:00
|
|
|
export class Channel extends SnowflakeBase {
|
2020-10-22 15:50:47 +00:00
|
|
|
type: ChannelTypes
|
|
|
|
id: string
|
2020-10-24 15:00:42 +00:00
|
|
|
static cacheName = 'channel'
|
2020-12-02 12:29:52 +00:00
|
|
|
get mention(): string {
|
2020-10-25 17:03:53 +00:00
|
|
|
return `<#${this.id}>`
|
|
|
|
}
|
2020-10-22 15:50:47 +00:00
|
|
|
|
2020-12-02 12:29:52 +00:00
|
|
|
constructor(client: Client, data: ChannelPayload) {
|
2020-10-25 06:50:32 +00:00
|
|
|
super(client, data)
|
2020-10-22 15:50:47 +00:00
|
|
|
this.type = data.type
|
|
|
|
this.id = data.id
|
2020-10-29 14:43:27 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 05:28:20 +00:00
|
|
|
readFromData(data: ChannelPayload): void {
|
2020-10-29 14:43:27 +00:00
|
|
|
this.type = data.type ?? this.type
|
|
|
|
this.id = data.id ?? this.id
|
2020-10-22 15:50:47 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-19 15:39:14 +00:00
|
|
|
|
|
|
|
export class GuildChannel extends Channel {
|
|
|
|
guildID: string
|
|
|
|
name: string
|
|
|
|
position: number
|
|
|
|
permissionOverwrites: OverwritePayload[]
|
|
|
|
guild: Guild
|
|
|
|
nsfw: boolean
|
|
|
|
parentID?: string
|
|
|
|
|
|
|
|
constructor(client: Client, data: GuildChannelPayloads, guild: Guild) {
|
|
|
|
super(client, data)
|
|
|
|
this.guildID = data.guild_id
|
|
|
|
this.name = data.name
|
|
|
|
this.guild = guild
|
|
|
|
this.position = data.position
|
|
|
|
this.permissionOverwrites = data.permission_overwrites
|
|
|
|
this.nsfw = data.nsfw
|
|
|
|
this.parentID = data.parent_id
|
|
|
|
}
|
|
|
|
|
|
|
|
readFromData(data: GuildChannelPayloads): void {
|
|
|
|
super.readFromData(data)
|
|
|
|
this.guildID = data.guild_id ?? this.guildID
|
|
|
|
this.name = data.name ?? this.name
|
|
|
|
this.position = data.position ?? this.position
|
|
|
|
this.permissionOverwrites =
|
|
|
|
data.permission_overwrites ?? this.permissionOverwrites
|
|
|
|
this.nsfw = data.nsfw ?? this.nsfw
|
|
|
|
this.parentID = data.parent_id ?? this.parentID
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get Permission Overties for a specific Member or Role */
|
|
|
|
async overwritesFor(target: Member | Role | string): Promise<Overwrite[]> {
|
|
|
|
const stringToObject =
|
|
|
|
typeof target === 'string'
|
|
|
|
? (await this.guild.members.get(target)) ??
|
|
|
|
(await this.guild.roles.get(target))
|
|
|
|
: target
|
|
|
|
|
|
|
|
if (stringToObject === undefined) {
|
|
|
|
throw new Error('Member or Role not found')
|
|
|
|
} else {
|
|
|
|
target = stringToObject
|
|
|
|
}
|
|
|
|
|
|
|
|
const roles =
|
|
|
|
target instanceof Member ? await target.roles.array() : undefined
|
|
|
|
|
|
|
|
const overwrites: Overwrite[] = []
|
|
|
|
|
|
|
|
for (const overwrite of this.permissionOverwrites) {
|
|
|
|
if (
|
|
|
|
overwrite.id === this.guild.id ||
|
|
|
|
roles?.some((e) => e.id === overwrite.id) === true ||
|
|
|
|
overwrite.id === target.id
|
|
|
|
) {
|
|
|
|
const id =
|
|
|
|
(await this.guild.members.get(overwrite.id)) ??
|
|
|
|
(await this.guild.roles.get(overwrite.id)) ??
|
|
|
|
overwrite.id
|
|
|
|
const allow = new Permissions(overwrite.allow)
|
|
|
|
const deny = new Permissions(overwrite.deny)
|
|
|
|
|
|
|
|
overwrites.push({
|
|
|
|
id,
|
|
|
|
type: overwrite.type,
|
|
|
|
allow,
|
|
|
|
deny
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return overwrites
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get Permissions for a Member in this Channel */
|
|
|
|
async permissionsFor(target: Member | Role | string): Promise<Permissions> {
|
|
|
|
const id = typeof target === 'string' ? target : target.id
|
|
|
|
if (id === this.guild.ownerID) return new Permissions(Permissions.ALL)
|
|
|
|
|
|
|
|
const stringToObject =
|
|
|
|
typeof target === 'string'
|
|
|
|
? (await this.guild.members.get(target)) ??
|
|
|
|
(await this.guild.roles.get(target))
|
|
|
|
: target
|
|
|
|
|
|
|
|
if (stringToObject === undefined) {
|
|
|
|
throw new Error('Member or Role not found')
|
|
|
|
} else {
|
|
|
|
target = stringToObject
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target.permissions.has('ADMINISTRATOR') === true)
|
|
|
|
return new Permissions(Permissions.ALL)
|
|
|
|
|
|
|
|
const overwrites = await this.overwritesFor(target)
|
|
|
|
const everyoneOW = overwrites.find((e) => e.id === this.guild.id)
|
|
|
|
const roleOWs = overwrites.filter((e) => e.type === 0)
|
|
|
|
const memberOWs = overwrites.filter((e) => e.type === 1)
|
|
|
|
|
|
|
|
return target.permissions
|
|
|
|
.remove(everyoneOW !== undefined ? Number(everyoneOW.deny) : 0)
|
|
|
|
.add(everyoneOW !== undefined ? Number(everyoneOW.allow) : 0)
|
|
|
|
.remove(roleOWs.length === 0 ? 0 : roleOWs.map((e) => Number(e.deny)))
|
|
|
|
.add(roleOWs.length === 0 ? 0 : roleOWs.map((e) => Number(e.allow)))
|
|
|
|
.remove(memberOWs.length === 0 ? 0 : memberOWs.map((e) => Number(e.deny)))
|
|
|
|
.add(memberOWs.length === 0 ? 0 : memberOWs.map((e) => Number(e.allow)))
|
|
|
|
}
|
|
|
|
|
|
|
|
async edit(options?: ModifyChannelOption): Promise<GuildChannels> {
|
|
|
|
const body: ModifyChannelPayload = {
|
|
|
|
name: options?.name,
|
|
|
|
position: options?.position,
|
|
|
|
permission_overwrites: options?.permissionOverwrites,
|
|
|
|
parent_id: options?.parentID,
|
|
|
|
nsfw: options?.nsfw
|
|
|
|
}
|
|
|
|
|
|
|
|
const resp = await this.client.rest.patch(CHANNEL(this.id), body)
|
|
|
|
|
|
|
|
return (
|
|
|
|
(getChannelByType(this.client, resp, this.guild) as
|
|
|
|
| GuildChannels
|
|
|
|
| undefined) ?? new GuildChannel(this.client, resp, this.guild)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Edit name of the channel */
|
|
|
|
async setName(name: string): Promise<GuildChannels> {
|
|
|
|
return await this.edit({ name })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Edit NSFW property of the channel */
|
|
|
|
async setNSFW(nsfw: boolean): Promise<GuildChannels> {
|
|
|
|
return await this.edit({ nsfw })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set Permission Overwrites of the Channel */
|
|
|
|
async setOverwrites(overwrites: OverwriteAsArg[]): Promise<GuildChannels> {
|
|
|
|
const result = overwrites.map(
|
|
|
|
(overwrite): OverwritePayload => {
|
|
|
|
const id =
|
|
|
|
typeof overwrite.id === 'string' ? overwrite.id : overwrite.id.id
|
|
|
|
const allow =
|
|
|
|
typeof overwrite.allow === 'string'
|
|
|
|
? overwrite.allow
|
|
|
|
: overwrite.allow?.toJSON() ?? '0'
|
|
|
|
const deny =
|
|
|
|
typeof overwrite.deny === 'string'
|
|
|
|
? overwrite.deny
|
|
|
|
: overwrite.deny?.toJSON() ?? '0'
|
|
|
|
const type =
|
|
|
|
overwrite.id instanceof Role
|
|
|
|
? 0
|
|
|
|
: overwrite.id instanceof Member
|
|
|
|
? 1
|
|
|
|
: overwrite.type
|
|
|
|
if (type === undefined) {
|
|
|
|
throw new Error('Overwrite type is undefined.')
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
id,
|
|
|
|
type,
|
|
|
|
allow,
|
|
|
|
deny
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
return await this.edit({ permissionOverwrites: result })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Add a Permission Overwrite */
|
|
|
|
async addOverwrite(overwrite: OverwriteAsArg): Promise<GuildChannels> {
|
|
|
|
const overwrites = this.permissionOverwrites
|
|
|
|
const id = typeof overwrite.id === 'string' ? overwrite.id : overwrite.id.id
|
|
|
|
const allow =
|
|
|
|
typeof overwrite.allow === 'string'
|
|
|
|
? overwrite.allow
|
|
|
|
: overwrite.allow?.toJSON() ?? '0'
|
|
|
|
const deny =
|
|
|
|
typeof overwrite.deny === 'string'
|
|
|
|
? overwrite.deny
|
|
|
|
: overwrite.deny?.toJSON() ?? '0'
|
|
|
|
const type =
|
|
|
|
overwrite.id instanceof Role
|
|
|
|
? 0
|
|
|
|
: overwrite.id instanceof Member
|
|
|
|
? 1
|
|
|
|
: overwrite.type
|
|
|
|
if (type === undefined) {
|
|
|
|
throw new Error('Overwrite type is undefined.')
|
|
|
|
}
|
|
|
|
|
|
|
|
overwrites.push({
|
|
|
|
id,
|
|
|
|
type,
|
|
|
|
allow,
|
|
|
|
deny
|
|
|
|
})
|
|
|
|
|
|
|
|
return await this.edit({ permissionOverwrites: overwrites })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Remove a Permission Overwrite */
|
|
|
|
async removeOverwrite(
|
|
|
|
target: Member | Role | string
|
|
|
|
): Promise<GuildChannels> {
|
|
|
|
target = typeof target === 'string' ? target : target.id
|
|
|
|
if (this.permissionOverwrites.find((e) => e.id === target) === undefined)
|
|
|
|
throw new Error('Permission Overwrite not found')
|
|
|
|
const overwrites = this.permissionOverwrites.filter((e) => e.id !== target)
|
|
|
|
return await this.edit({ permissionOverwrites: overwrites })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Edit a Permission Overwrite */
|
|
|
|
async editOverwrite(
|
|
|
|
overwrite: OverwriteAsArg,
|
|
|
|
{
|
|
|
|
overriteAllow = OverrideType.ADD,
|
|
|
|
overriteDeny = OverrideType.ADD
|
|
|
|
}: {
|
|
|
|
overriteAllow: OverrideType
|
|
|
|
overriteDeny: OverrideType
|
|
|
|
}
|
|
|
|
): Promise<GuildChannels> {
|
|
|
|
const id = typeof overwrite.id === 'string' ? overwrite.id : overwrite.id.id
|
|
|
|
const index = this.permissionOverwrites.findIndex((e) => e.id === id)
|
|
|
|
if (index < 0) throw new Error('Permission Overwrite not found')
|
|
|
|
const overwrites = this.permissionOverwrites
|
|
|
|
|
|
|
|
let allow: string
|
|
|
|
let deny: string
|
|
|
|
|
|
|
|
if (
|
|
|
|
overwrite.allow !== undefined &&
|
|
|
|
overriteAllow !== OverrideType.REPLACE
|
|
|
|
) {
|
|
|
|
switch (overriteAllow) {
|
|
|
|
case OverrideType.ADD: {
|
|
|
|
const originalAllow = new Permissions(overwrites[index].allow)
|
|
|
|
const newAllow = new Permissions(overwrite.allow)
|
|
|
|
|
|
|
|
allow = originalAllow.add([newAllow]).toJSON()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
case OverrideType.REMOVE: {
|
|
|
|
const originalAllow = new Permissions(overwrites[index].allow)
|
|
|
|
const newAllow = new Permissions(overwrite.allow)
|
|
|
|
|
|
|
|
allow = originalAllow.remove([newAllow]).toJSON()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
allow =
|
|
|
|
typeof overwrite.allow === 'string'
|
|
|
|
? overwrite.allow
|
|
|
|
: overwrite.allow?.toJSON() ?? overwrites[index].allow
|
|
|
|
}
|
|
|
|
|
|
|
|
if (overwrite.deny !== undefined && overriteDeny !== OverrideType.REPLACE) {
|
|
|
|
switch (overriteDeny) {
|
|
|
|
case OverrideType.ADD: {
|
|
|
|
const originalDeny = new Permissions(overwrites[index].deny)
|
|
|
|
const newDeny = new Permissions(overwrite.deny)
|
|
|
|
|
|
|
|
deny = originalDeny.add([newDeny]).toJSON()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
case OverrideType.REMOVE: {
|
|
|
|
const originalDeny = new Permissions(overwrites[index].deny)
|
|
|
|
const newDeny = new Permissions(overwrite.deny)
|
|
|
|
|
|
|
|
deny = originalDeny.remove([newDeny]).toJSON()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
deny =
|
|
|
|
typeof overwrite.deny === 'string'
|
|
|
|
? overwrite.deny
|
|
|
|
: overwrite.deny?.toJSON() ?? overwrites[index].deny
|
|
|
|
}
|
|
|
|
|
|
|
|
const type =
|
|
|
|
overwrite.id instanceof Role
|
|
|
|
? 0
|
|
|
|
: overwrite.id instanceof Member
|
|
|
|
? 1
|
|
|
|
: overwrite.type
|
|
|
|
if (type === undefined) {
|
|
|
|
throw new Error('Overwrite type is undefined.')
|
|
|
|
}
|
|
|
|
|
|
|
|
overwrites[index] = {
|
|
|
|
id,
|
|
|
|
type,
|
|
|
|
allow,
|
|
|
|
deny
|
|
|
|
}
|
|
|
|
return await this.edit({ permissionOverwrites: overwrites })
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Edit position of the channel */
|
|
|
|
async setPosition(position: number): Promise<GuildChannels> {
|
|
|
|
return await this.edit({ position })
|
|
|
|
}
|
|
|
|
}
|