✨ Add "easy to use" Overwrite type, Make GuildChannel(for base), Separate GuildTextChannel from textChannel.ts
This commit is contained in:
		
							parent
							
								
									b532a99eb4
								
							
						
					
					
						commit
						21ccf4c054
					
				
					 22 changed files with 663 additions and 417 deletions
				
			
		|  | @ -31,7 +31,8 @@ import { webhooksUpdate } from './webhooksUpdate.ts' | |||
| import { messageDeleteBulk } from './messageDeleteBulk.ts' | ||||
| import { userUpdate } from './userUpdate.ts' | ||||
| import { typingStart } from './typingStart.ts' | ||||
| import { GuildTextChannel, TextChannel } from '../../structures/textChannel.ts' | ||||
| import { TextChannel } from '../../structures/textChannel.ts' | ||||
| import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | ||||
| import { Guild } from '../../structures/guild.ts' | ||||
| import { User } from '../../structures/user.ts' | ||||
| import { Emoji } from '../../structures/emoji.ts' | ||||
|  | @ -263,7 +264,7 @@ export type ClientEvents = { | |||
|    * @param uncached Set of Messages deleted's IDs which were not cached | ||||
|    */ | ||||
|   messageDeleteBulk: [ | ||||
|     channel: GuildTextChannel, | ||||
|     channel: GuildTextBasedChannel, | ||||
|     messages: Collection<string, Message>, | ||||
|     uncached: Set<string> | ||||
|   ] | ||||
|  | @ -356,7 +357,7 @@ export type ClientEvents = { | |||
|    * @param guild Guild in which Webhooks were updated | ||||
|    * @param channel Channel of which Webhooks were updated | ||||
|    */ | ||||
|   webhooksUpdate: [guild: Guild, channel: GuildTextChannel] | ||||
|   webhooksUpdate: [guild: Guild, channel: GuildTextBasedChannel] | ||||
|   /** | ||||
|    * An Interaction was created | ||||
|    * @param interaction Created interaction object | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { Member } from '../../structures/member.ts' | ||||
| import { Interaction } from '../../structures/slash.ts' | ||||
| import { GuildTextChannel } from '../../structures/textChannel.ts' | ||||
| import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | ||||
| import { InteractionPayload } from '../../types/slash.ts' | ||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| 
 | ||||
|  | @ -17,8 +17,8 @@ export const interactionCreate: GatewayEventHandler = async ( | |||
|   )) as unknown) as Member | ||||
| 
 | ||||
|   const channel = | ||||
|     (await gateway.client.channels.get<GuildTextChannel>(d.channel_id)) ?? | ||||
|     (await gateway.client.channels.fetch<GuildTextChannel>(d.channel_id)) | ||||
|     (await gateway.client.channels.get<GuildTextBasedChannel>(d.channel_id)) ?? | ||||
|     (await gateway.client.channels.fetch<GuildTextBasedChannel>(d.channel_id)) | ||||
| 
 | ||||
|   const interaction = new Interaction(gateway.client, d, { | ||||
|     member, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { Message } from '../../structures/message.ts' | ||||
| import { GuildTextChannel } from '../../structures/textChannel.ts' | ||||
| import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | ||||
| import { MessageDeleteBulkPayload } from '../../types/gateway.ts' | ||||
| import { Collection } from '../../utils/collection.ts' | ||||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
|  | @ -8,7 +8,7 @@ export const messageDeleteBulk: GatewayEventHandler = async ( | |||
|   gateway: Gateway, | ||||
|   d: MessageDeleteBulkPayload | ||||
| ) => { | ||||
|   let channel = await gateway.client.channels.get<GuildTextChannel>( | ||||
|   let channel = await gateway.client.channels.get<GuildTextBasedChannel>( | ||||
|     d.channel_id | ||||
|   ) | ||||
|   // Fetch the channel if not cached
 | ||||
|  | @ -16,7 +16,7 @@ export const messageDeleteBulk: GatewayEventHandler = async ( | |||
|     // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||
|     channel = (await gateway.client.channels.fetch( | ||||
|       d.channel_id | ||||
|     )) as GuildTextChannel | ||||
|     )) as GuildTextBasedChannel | ||||
| 
 | ||||
|   const messages = new Collection<string, Message>() | ||||
|   const uncached = new Set<string>() | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { Gateway, GatewayEventHandler } from '../index.ts' | ||||
| import { Guild } from '../../structures/guild.ts' | ||||
| import { WebhooksUpdatePayload } from '../../types/gateway.ts' | ||||
| import { GuildTextChannel } from '../../structures/textChannel.ts' | ||||
| import { GuildTextBasedChannel } from '../../structures/guildTextChannel.ts' | ||||
| 
 | ||||
| export const webhooksUpdate: GatewayEventHandler = async ( | ||||
|   gateway: Gateway, | ||||
|  | @ -10,9 +10,9 @@ export const webhooksUpdate: GatewayEventHandler = async ( | |||
|   const guild: Guild | undefined = await gateway.client.guilds.get(d.guild_id) | ||||
|   if (guild === undefined) return | ||||
| 
 | ||||
|   const channel: GuildTextChannel | undefined = (await guild.channels.get( | ||||
|   const channel: GuildTextBasedChannel | undefined = (await guild.channels.get( | ||||
|     d.channel_id | ||||
|   )) as GuildTextChannel | ||||
|   )) as GuildTextBasedChannel | ||||
|   if (channel === undefined) | ||||
|     gateway.client.emit('webhooksUpdateUncached', guild, d.channel_id) | ||||
|   else gateway.client.emit('webhooksUpdate', guild, channel) | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ import { CategoryChannel } from '../structures/guildCategoryChannel.ts' | |||
| import { | ||||
|   ChannelTypes, | ||||
|   GuildChannelPayload, | ||||
|   Overwrite | ||||
|   OverwritePayload | ||||
| } from '../types/channel.ts' | ||||
| import { GuildChannels, GuildChannelPayloads } from '../types/guild.ts' | ||||
| import { CHANNEL, GUILD_CHANNELS } from '../types/endpoint.ts' | ||||
|  | @ -20,7 +20,7 @@ export interface CreateChannelOptions { | |||
|   userLimit?: number | ||||
|   rateLimitPerUser?: number | ||||
|   position?: number | ||||
|   permissionOverwrites?: Overwrite[] | ||||
|   permissionOverwrites?: OverwritePayload[] | ||||
|   parent?: CategoryChannel | string | ||||
|   nsfw?: boolean | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import { Message } from '../structures/message.ts' | ||||
| import { GuildTextChannel } from '../structures/textChannel.ts' | ||||
| import { GuildTextBasedChannel } from '../structures/guildTextChannel.ts' | ||||
| import { Client, ClientOptions } from './client.ts' | ||||
| import { | ||||
|   CategoriesManager, | ||||
|  | @ -275,7 +275,7 @@ export class CommandClient extends Client implements CommandClientOptions { | |||
|     if ( | ||||
|       command.nsfw === true && | ||||
|       (msg.guild === undefined || | ||||
|         ((msg.channel as unknown) as GuildTextChannel).nsfw !== true) | ||||
|         ((msg.channel as unknown) as GuildTextBasedChannel).nsfw !== true) | ||||
|     ) | ||||
|       return this.emit('commandNSFW', ctx) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,22 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { ChannelPayload, ChannelTypes } from '../types/channel.ts' | ||||
| 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' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { Role } from './role.ts' | ||||
| 
 | ||||
| export class Channel extends SnowflakeBase { | ||||
|   type: ChannelTypes | ||||
|  | @ -21,3 +37,313 @@ export class Channel extends SnowflakeBase { | |||
|     this.id = data.id ?? this.id | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 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 }) | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,42 +1,14 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { Channel } from './channel.ts' | ||||
| import { GuildChannel } from './channel.ts' | ||||
| import { | ||||
|   GuildCategoryChannelPayload, | ||||
|   ModifyGuildCategoryChannelOption, | ||||
|   ModifyGuildCategoryChannelPayload, | ||||
|   Overwrite | ||||
|   ModifyGuildCategoryChannelPayload | ||||
| } from '../types/channel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { CHANNEL } from '../types/endpoint.ts' | ||||
| 
 | ||||
| export class CategoryChannel extends Channel { | ||||
|   guildID: string | ||||
|   name: string | ||||
|   position: number | ||||
|   permissionOverwrites: Overwrite[] | ||||
|   guild: Guild | ||||
|   parentID?: string | ||||
| 
 | ||||
|   constructor(client: Client, data: GuildCategoryChannelPayload, 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.parentID = data.parent_id | ||||
|     // TODO: Cache in Gateway Event Code
 | ||||
|     // cache.set('guildcategorychannel', this.id, this)
 | ||||
|   } | ||||
| 
 | ||||
| export class CategoryChannel extends GuildChannel { | ||||
|   readFromData(data: GuildCategoryChannelPayload): 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.parentID = data.parent_id ?? this.parentID | ||||
|   } | ||||
| 
 | ||||
|   async edit( | ||||
|  |  | |||
|  | @ -1,61 +1,3 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { | ||||
|   GuildNewsChannelPayload, | ||||
|   ModifyGuildNewsChannelOption, | ||||
|   ModifyGuildNewsChannelPayload, | ||||
|   Overwrite | ||||
| } from '../types/channel.ts' | ||||
| import { CHANNEL } from '../types/endpoint.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { GuildTextBasedChannel } from './guildTextChannel.ts' | ||||
| 
 | ||||
| export class NewsChannel extends TextChannel { | ||||
|   guildID: string | ||||
|   guild: Guild | ||||
|   name: string | ||||
|   position: number | ||||
|   permissionOverwrites: Overwrite[] | ||||
|   nsfw: boolean | ||||
|   parentID?: string | ||||
|   topic?: string | ||||
| 
 | ||||
|   constructor(client: Client, data: GuildNewsChannelPayload, 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 | ||||
|     this.topic = data.topic | ||||
|   } | ||||
| 
 | ||||
|   readFromData(data: GuildNewsChannelPayload): 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 | ||||
|     this.topic = data.topic ?? this.topic | ||||
|   } | ||||
| 
 | ||||
|   async edit(options?: ModifyGuildNewsChannelOption): Promise<NewsChannel> { | ||||
|     const body: ModifyGuildNewsChannelPayload = { | ||||
|       name: options?.name, | ||||
|       position: options?.position, | ||||
|       permission_overwrites: options?.permissionOverwrites, | ||||
|       parent_id: options?.parentID, | ||||
|       type: options?.type, | ||||
|       topic: options?.topic, | ||||
|       nsfw: options?.nsfw | ||||
|     } | ||||
| 
 | ||||
|     const resp = await this.client.rest.patch(CHANNEL(this.id), body) | ||||
| 
 | ||||
|     return new NewsChannel(this.client, resp, this.guild) | ||||
|   } | ||||
| } | ||||
| export class NewsChannel extends GuildTextBasedChannel {} | ||||
|  |  | |||
							
								
								
									
										168
									
								
								src/structures/guildTextChannel.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								src/structures/guildTextChannel.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,168 @@ | |||
| import { Mixin } from '../../deps.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { GuildChannel } from './channel.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| import { | ||||
|   ChannelTypes, | ||||
|   GuildTextBasedChannelPayload, | ||||
|   GuildTextChannelPayload, | ||||
|   ModifyGuildTextBasedChannelOption, | ||||
|   ModifyGuildTextBasedChannelPayload, | ||||
|   ModifyGuildTextChannelOption, | ||||
|   ModifyGuildTextChannelPayload | ||||
| } from '../types/channel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { CHANNEL } from '../types/endpoint.ts' | ||||
| import { Message } from './message.ts' | ||||
| import { CreateInviteOptions } from '../managers/invites.ts' | ||||
| import { Invite } from './invite.ts' | ||||
| import { CategoryChannel } from './guildCategoryChannel.ts' | ||||
| 
 | ||||
| const GUILD_TEXT_BASED_CHANNEL_TYPES: ChannelTypes[] = [ | ||||
|   ChannelTypes.GUILD_TEXT, | ||||
|   ChannelTypes.GUILD_NEWS | ||||
| ] | ||||
| 
 | ||||
| /** Represents a Text Channel but in a Guild */ | ||||
| export class GuildTextBasedChannel extends Mixin(TextChannel, GuildChannel) { | ||||
|   topic?: string | ||||
| 
 | ||||
|   get mention(): string { | ||||
|     return `<#${this.id}>` | ||||
|   } | ||||
| 
 | ||||
|   toString(): string { | ||||
|     return this.mention | ||||
|   } | ||||
| 
 | ||||
|   constructor( | ||||
|     client: Client, | ||||
|     data: GuildTextBasedChannelPayload, | ||||
|     guild: Guild | ||||
|   ) { | ||||
|     super(client, data, guild) | ||||
|     this.topic = data.topic | ||||
|   } | ||||
| 
 | ||||
|   readFromData(data: GuildTextBasedChannelPayload): void { | ||||
|     super.readFromData(data) | ||||
|     this.topic = data.topic ?? this.topic | ||||
|   } | ||||
| 
 | ||||
|   /** Edit the Guild Text Channel */ | ||||
|   async edit( | ||||
|     options?: ModifyGuildTextBasedChannelOption | ||||
|   ): Promise<GuildTextBasedChannel> { | ||||
|     const body: ModifyGuildTextBasedChannelPayload = { | ||||
|       name: options?.name, | ||||
|       position: options?.position, | ||||
|       permission_overwrites: options?.permissionOverwrites, | ||||
|       parent_id: options?.parentID, | ||||
|       nsfw: options?.nsfw, | ||||
|       topic: options?.topic | ||||
|       // rate_limit_per_user: options?.slowmode
 | ||||
|     } | ||||
| 
 | ||||
|     const resp = await this.client.rest.patch(CHANNEL(this.id), body) | ||||
| 
 | ||||
|     return new GuildTextBasedChannel(this.client, resp, this.guild) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Bulk Delete Messages in a Guild Text Channel | ||||
|    * @param messages Messages to delete. Can be a number, or Array of Message or IDs | ||||
|    */ | ||||
|   async bulkDelete( | ||||
|     messages: Array<Message | string> | number | ||||
|   ): Promise<GuildTextBasedChannel> { | ||||
|     let ids: string[] = [] | ||||
| 
 | ||||
|     if (Array.isArray(messages)) | ||||
|       ids = messages.map((e) => (typeof e === 'string' ? e : e.id)) | ||||
|     else { | ||||
|       let list = await this.messages.array() | ||||
|       if (list.length < messages) list = (await this.fetchMessages()).array() | ||||
|       ids = list | ||||
|         .sort((b, a) => a.createdAt.getTime() - b.createdAt.getTime()) | ||||
|         .filter((e, i) => i < messages) | ||||
|         .filter( | ||||
|           (e) => | ||||
|             new Date().getTime() - e.createdAt.getTime() <= | ||||
|             1000 * 60 * 60 * 24 * 14 | ||||
|         ) | ||||
|         .map((e) => e.id) | ||||
|     } | ||||
| 
 | ||||
|     ids = [...new Set(ids)] | ||||
|     if (ids.length < 2 || ids.length > 100) | ||||
|       throw new Error('bulkDelete can only delete messages in range 2-100') | ||||
| 
 | ||||
|     await this.client.rest.api.channels[this.id].messages['bulk-delete'].post({ | ||||
|       messages: ids | ||||
|     }) | ||||
| 
 | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Create an Invite for this Channel */ | ||||
|   async createInvite(options?: CreateInviteOptions): Promise<Invite> { | ||||
|     return this.guild.invites.create(this.id, options) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit topic of the channel */ | ||||
|   async setTopic(topic: string): Promise<GuildTextBasedChannel> { | ||||
|     return await this.edit({ topic }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit category of the channel */ | ||||
|   async setCategory( | ||||
|     category: CategoryChannel | string | ||||
|   ): Promise<GuildTextBasedChannel> { | ||||
|     return await this.edit({ | ||||
|       parentID: typeof category === 'object' ? category.id : category | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export const checkGuildTextBasedChannel = ( | ||||
|   channel: TextChannel | ||||
| ): channel is GuildTextBasedChannel => | ||||
|   GUILD_TEXT_BASED_CHANNEL_TYPES.includes(channel.type) | ||||
| 
 | ||||
| export class GuildTextChannel extends GuildTextBasedChannel { | ||||
|   slowmode: number | ||||
| 
 | ||||
|   constructor(client: Client, data: GuildTextChannelPayload, guild: Guild) { | ||||
|     super(client, data, guild) | ||||
|     this.slowmode = data.rate_limit_per_user | ||||
|   } | ||||
| 
 | ||||
|   readFromData(data: GuildTextChannelPayload): void { | ||||
|     super.readFromData(data) | ||||
|     this.slowmode = data.rate_limit_per_user ?? this.slowmode | ||||
|   } | ||||
| 
 | ||||
|   /** Edit the Guild Text Channel */ | ||||
|   async edit( | ||||
|     options?: ModifyGuildTextChannelOption | ||||
|   ): Promise<GuildTextChannel> { | ||||
|     const body: ModifyGuildTextChannelPayload = { | ||||
|       name: options?.name, | ||||
|       position: options?.position, | ||||
|       permission_overwrites: options?.permissionOverwrites, | ||||
|       parent_id: options?.parentID, | ||||
|       nsfw: options?.nsfw, | ||||
|       topic: options?.topic, | ||||
|       rate_limit_per_user: options?.slowmode | ||||
|     } | ||||
| 
 | ||||
|     const resp = await this.client.rest.patch(CHANNEL(this.id), body) | ||||
| 
 | ||||
|     return new GuildTextChannel(this.client, resp, this.guild) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit Slowmode of the channel */ | ||||
|   async setSlowmode(slowmode?: number | null): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ slowmode: slowmode ?? null }) | ||||
|   } | ||||
| } | ||||
|  | @ -4,11 +4,10 @@ import { Client } from '../models/client.ts' | |||
| import { | ||||
|   GuildVoiceChannelPayload, | ||||
|   ModifyVoiceChannelOption, | ||||
|   ModifyVoiceChannelPayload, | ||||
|   Overwrite | ||||
|   ModifyVoiceChannelPayload | ||||
| } from '../types/channel.ts' | ||||
| import { CHANNEL } from '../types/endpoint.ts' | ||||
| import { Channel } from './channel.ts' | ||||
| import { GuildChannel } from './channel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { VoiceState } from './voiceState.ts' | ||||
| 
 | ||||
|  | @ -16,26 +15,14 @@ export interface VoiceServerData extends VoiceServerUpdateData { | |||
|   sessionID: string | ||||
| } | ||||
| 
 | ||||
| export class VoiceChannel extends Channel { | ||||
| export class VoiceChannel extends GuildChannel { | ||||
|   bitrate: string | ||||
|   userLimit: number | ||||
|   guildID: string | ||||
|   name: string | ||||
|   guild: Guild | ||||
|   position: number | ||||
|   permissionOverwrites: Overwrite[] | ||||
|   parentID?: string | ||||
| 
 | ||||
|   constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) { | ||||
|     super(client, data) | ||||
|     super(client, data, guild) | ||||
|     this.bitrate = data.bitrate | ||||
|     this.userLimit = data.user_limit | ||||
|     this.guildID = data.guild_id | ||||
|     this.name = data.name | ||||
|     this.position = data.position | ||||
|     this.guild = guild | ||||
|     this.permissionOverwrites = data.permission_overwrites | ||||
|     this.parentID = data.parent_id | ||||
|   } | ||||
| 
 | ||||
|   /** Join the Voice Channel */ | ||||
|  | @ -104,12 +91,6 @@ export class VoiceChannel extends Channel { | |||
|     super.readFromData(data) | ||||
|     this.bitrate = data.bitrate ?? this.bitrate | ||||
|     this.userLimit = data.user_limit ?? this.userLimit | ||||
|     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.parentID = data.parent_id ?? this.parentID | ||||
|   } | ||||
| 
 | ||||
|   async edit(options?: ModifyVoiceChannelOption): Promise<VoiceChannel> { | ||||
|  |  | |||
|  | @ -13,7 +13,8 @@ import { Member } from './member.ts' | |||
| import { Embed } from './embed.ts' | ||||
| import { CHANNEL_MESSAGE } from '../types/endpoint.ts' | ||||
| import { MessageMentions } from './messageMentions.ts' | ||||
| import { GuildTextChannel, TextChannel } from './textChannel.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { GuildTextBasedChannel } from './guildTextChannel.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { MessageReactionsManager } from '../managers/messageReactions.ts' | ||||
| import { MessageSticker } from './messageSticker.ts' | ||||
|  | @ -126,8 +127,10 @@ export class Message extends SnowflakeBase { | |||
|       const newMember = await this.guild?.members.get(this.member?.id) | ||||
|       if (newMember !== undefined) this.member = newMember | ||||
|     } | ||||
|     if (((this.channel as unknown) as GuildTextChannel).guild !== undefined) | ||||
|       this.guild = ((this.channel as unknown) as GuildTextChannel).guild | ||||
|     if ( | ||||
|       ((this.channel as unknown) as GuildTextBasedChannel).guild !== undefined | ||||
|     ) | ||||
|       this.guild = ((this.channel as unknown) as GuildTextBasedChannel).guild | ||||
|     if (this.guild !== undefined && this.guildID === undefined) | ||||
|       this.guildID = this.guild.id | ||||
|   } | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { MessagePayload } from '../types/channel.ts' | ||||
| import { Collection } from '../utils/collection.ts' | ||||
| import { GuildTextChannel } from './textChannel.ts' | ||||
| import { GuildTextBasedChannel } from './guildTextChannel.ts' | ||||
| import { Message } from './message.ts' | ||||
| import { Role } from './role.ts' | ||||
| import { User } from './user.ts' | ||||
|  | @ -11,7 +11,7 @@ export class MessageMentions { | |||
|   message: Message | ||||
|   users: Collection<string, User> = new Collection() | ||||
|   roles: Collection<string, Role> = new Collection() | ||||
|   channels: Collection<string, GuildTextChannel> = new Collection() | ||||
|   channels: Collection<string, GuildTextBasedChannel> = new Collection() | ||||
|   everyone: boolean = false | ||||
| 
 | ||||
|   static EVERYONE_MENTION = /@(everyone|here)/g | ||||
|  | @ -39,7 +39,7 @@ export class MessageMentions { | |||
|     } | ||||
|     if (payload.mention_channels !== undefined) { | ||||
|       for (const mentionChannel of payload.mention_channels) { | ||||
|         const channel = await this.client.channels.get<GuildTextChannel>( | ||||
|         const channel = await this.client.channels.get<GuildTextBasedChannel>( | ||||
|           mentionChannel.id | ||||
|         ) | ||||
|         if (channel !== undefined) this.channels.set(channel.id, channel) | ||||
|  | @ -51,7 +51,7 @@ export class MessageMentions { | |||
|     if (matchChannels !== null) { | ||||
|       for (const id of matchChannels) { | ||||
|         const parsedID = id.substr(2, id.length - 3) | ||||
|         const channel = await this.client.channels.get<GuildTextChannel>( | ||||
|         const channel = await this.client.channels.get<GuildTextBasedChannel>( | ||||
|           parsedID | ||||
|         ) | ||||
|         if (channel !== undefined) this.channels.set(channel.id, channel) | ||||
|  |  | |||
|  | @ -13,7 +13,8 @@ import { Embed } from './embed.ts' | |||
| import { Guild } from './guild.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { Message } from './message.ts' | ||||
| import { GuildTextChannel, TextChannel } from './textChannel.ts' | ||||
| import { TextChannel } from './textChannel.ts' | ||||
| import { GuildTextBasedChannel } from './guildTextChannel.ts' | ||||
| import { User } from './user.ts' | ||||
| import { Webhook } from './webhook.ts' | ||||
| 
 | ||||
|  | @ -46,7 +47,7 @@ export class Interaction extends SnowflakeBase { | |||
|   token: string | ||||
|   id: string | ||||
|   data: InteractionData | ||||
|   channel: GuildTextChannel | ||||
|   channel: GuildTextBasedChannel | ||||
|   guild: Guild | ||||
|   member: Member | ||||
|   _savedHook?: Webhook | ||||
|  | @ -55,7 +56,7 @@ export class Interaction extends SnowflakeBase { | |||
|     client: Client, | ||||
|     data: InteractionPayload, | ||||
|     others: { | ||||
|       channel: GuildTextChannel | ||||
|       channel: GuildTextBasedChannel | ||||
|       guild: Guild | ||||
|       member: Member | ||||
|     } | ||||
|  |  | |||
|  | @ -1,28 +1,18 @@ | |||
| import { CreateInviteOptions } from '../managers/invites.ts' | ||||
| import { MessagesManager } from '../managers/messages.ts' | ||||
| import { Client } from '../models/client.ts' | ||||
| import { | ||||
|   GuildTextChannelPayload, | ||||
|   MessageOptions, | ||||
|   MessagePayload, | ||||
|   ModifyGuildTextChannelOption, | ||||
|   ModifyGuildTextChannelPayload, | ||||
|   Overwrite, | ||||
|   TextChannelPayload | ||||
| } from '../types/channel.ts' | ||||
| import { | ||||
|   CHANNEL, | ||||
|   MESSAGE_REACTION_ME, | ||||
|   MESSAGE_REACTION_USER | ||||
| } from '../types/endpoint.ts' | ||||
| import { Collection } from '../utils/collection.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { Channel } from './channel.ts' | ||||
| import { Embed } from './embed.ts' | ||||
| import { Emoji } from './emoji.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { CategoryChannel } from './guildCategoryChannel.ts' | ||||
| import { Invite } from './invite.ts' | ||||
| import { Member } from './member.ts' | ||||
| import { Message } from './message.ts' | ||||
| import { User } from './user.ts' | ||||
|  | @ -185,225 +175,3 @@ export class TextChannel extends Channel { | |||
|     return this | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** Represents a Text Channel but in a Guild */ | ||||
| export class GuildTextChannel extends TextChannel { | ||||
|   guildID: string | ||||
|   name: string | ||||
|   position: number | ||||
|   permissionOverwrites: Overwrite[] | ||||
|   nsfw: boolean | ||||
|   parentID?: string | ||||
|   slowmode: number | ||||
|   topic?: string | ||||
|   guild: Guild | ||||
| 
 | ||||
|   get mention(): string { | ||||
|     return `<#${this.id}>` | ||||
|   } | ||||
| 
 | ||||
|   toString(): string { | ||||
|     return this.mention | ||||
|   } | ||||
| 
 | ||||
|   constructor(client: Client, data: GuildTextChannelPayload, 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 | ||||
|     this.topic = data.topic | ||||
|     this.slowmode = data.rate_limit_per_user | ||||
|   } | ||||
| 
 | ||||
|   readFromData(data: GuildTextChannelPayload): 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 | ||||
|     this.topic = data.topic ?? this.topic | ||||
|     this.slowmode = data.rate_limit_per_user ?? this.slowmode | ||||
|   } | ||||
| 
 | ||||
|   /** Edit the Guild Text Channel */ | ||||
|   async edit( | ||||
|     options?: ModifyGuildTextChannelOption | ||||
|   ): Promise<GuildTextChannel> { | ||||
|     const body: ModifyGuildTextChannelPayload = { | ||||
|       name: options?.name, | ||||
|       position: options?.position, | ||||
|       permission_overwrites: options?.permissionOverwrites, | ||||
|       parent_id: options?.parentID, | ||||
|       nsfw: options?.nsfw, | ||||
|       topic: options?.topic, | ||||
|       rate_limit_per_user: options?.slowmode | ||||
|     } | ||||
| 
 | ||||
|     const resp = await this.client.rest.patch(CHANNEL(this.id), body) | ||||
| 
 | ||||
|     return new GuildTextChannel(this.client, resp, this.guild) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Bulk Delete Messages in a Guild Text Channel | ||||
|    * @param messages Messages to delete. Can be a number, or Array of Message or IDs | ||||
|    */ | ||||
|   async bulkDelete( | ||||
|     messages: Array<Message | string> | number | ||||
|   ): Promise<GuildTextChannel> { | ||||
|     let ids: string[] = [] | ||||
| 
 | ||||
|     if (Array.isArray(messages)) | ||||
|       ids = messages.map((e) => (typeof e === 'string' ? e : e.id)) | ||||
|     else { | ||||
|       let list = await this.messages.array() | ||||
|       if (list.length < messages) list = (await this.fetchMessages()).array() | ||||
|       ids = list | ||||
|         .sort((b, a) => a.createdAt.getTime() - b.createdAt.getTime()) | ||||
|         .filter((e, i) => i < messages) | ||||
|         .filter( | ||||
|           (e) => | ||||
|             new Date().getTime() - e.createdAt.getTime() <= | ||||
|             1000 * 60 * 60 * 24 * 14 | ||||
|         ) | ||||
|         .map((e) => e.id) | ||||
|     } | ||||
| 
 | ||||
|     ids = [...new Set(ids)] | ||||
|     if (ids.length < 2 || ids.length > 100) | ||||
|       throw new Error('bulkDelete can only delete messages in range 2-100') | ||||
| 
 | ||||
|     await this.client.rest.api.channels[this.id].messages['bulk-delete'].post({ | ||||
|       messages: ids | ||||
|     }) | ||||
| 
 | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Create an Invite for this Channel */ | ||||
|   async createInvite(options?: CreateInviteOptions): Promise<Invite> { | ||||
|     return this.guild.invites.create(this.id, options) | ||||
|   } | ||||
| 
 | ||||
|   /** Get Permission Overties for a specific Member */ | ||||
|   async overwritesFor(member: Member | string): Promise<Overwrite[]> { | ||||
|     member = (typeof member === 'string' | ||||
|       ? await this.guild.members.get(member) | ||||
|       : member) as Member | ||||
|     if (member === undefined) throw new Error('Member not found') | ||||
|     const roles = await member.roles.array() | ||||
| 
 | ||||
|     const overwrites: Overwrite[] = [] | ||||
| 
 | ||||
|     for (const overwrite of this.permissionOverwrites) { | ||||
|       if (overwrite.id === this.guild.id) { | ||||
|         overwrites.push(overwrite) | ||||
|       } else if (roles.some((e) => e.id === overwrite.id) === true) { | ||||
|         overwrites.push(overwrite) | ||||
|       } else if (overwrite.id === member.id) { | ||||
|         overwrites.push(overwrite) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return overwrites | ||||
|   } | ||||
| 
 | ||||
|   /** Get Permissions for a Member in this Channel */ | ||||
|   async permissionsFor(member: Member | string): Promise<Permissions> { | ||||
|     const id = typeof member === 'string' ? member : member.id | ||||
|     if (id === this.guild.ownerID) return new Permissions(Permissions.ALL) | ||||
| 
 | ||||
|     member = (typeof member === 'string' | ||||
|       ? await this.guild.members.get(member) | ||||
|       : member) as Member | ||||
|     if (member === undefined) throw new Error('Member not found') | ||||
| 
 | ||||
|     if (member.permissions.has('ADMINISTRATOR') === true) | ||||
|       return new Permissions(Permissions.ALL) | ||||
| 
 | ||||
|     const overwrites = await this.overwritesFor(member) | ||||
|     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 member.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))) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit name of the channel */ | ||||
|   async setName(name: string): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ name }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit topic of the channel */ | ||||
|   async setTopic(topic: string): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ topic }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit topic of the channel */ | ||||
|   async setCategory( | ||||
|     category: CategoryChannel | string | ||||
|   ): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ | ||||
|       parentID: typeof category === 'object' ? category.id : category | ||||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit position of the channel */ | ||||
|   async setPosition(position: number): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ position }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit Slowmode of the channel */ | ||||
|   async setSlowmode(slowmode?: number | null): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ slowmode: slowmode ?? null }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit NSFW property of the channel */ | ||||
|   async setNSFW(nsfw: boolean): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ nsfw }) | ||||
|   } | ||||
| 
 | ||||
|   /** Set Permission Overwrites of the Channel */ | ||||
|   async setOverwrites(overwrites: Overwrite[]): Promise<GuildTextChannel> { | ||||
|     return await this.edit({ permissionOverwrites: overwrites }) | ||||
|   } | ||||
| 
 | ||||
|   /** Add a Permission Overwrite */ | ||||
|   async addOverwrite(overwrite: Overwrite): Promise<GuildTextChannel> { | ||||
|     const overwrites = this.permissionOverwrites | ||||
|     overwrites.push(overwrite) | ||||
|     return await this.edit({ permissionOverwrites: overwrites }) | ||||
|   } | ||||
| 
 | ||||
|   /** Remove a Permission Overwrite */ | ||||
|   async removeOverwrite(id: string): Promise<GuildTextChannel> { | ||||
|     if (this.permissionOverwrites.findIndex((e) => e.id === id) < 0) | ||||
|       throw new Error('Permission Overwrite not found') | ||||
|     const overwrites = this.permissionOverwrites.filter((e) => e.id !== id) | ||||
|     return await this.edit({ permissionOverwrites: overwrites }) | ||||
|   } | ||||
| 
 | ||||
|   /** Edit a Permission Overwrite */ | ||||
|   async editOverwrite(overwrite: Overwrite): Promise<GuildTextChannel> { | ||||
|     const index = this.permissionOverwrites.findIndex( | ||||
|       (e) => e.id === overwrite.id | ||||
|     ) | ||||
|     if (index < 0) throw new Error('Permission Overwrite not found') | ||||
|     const overwrites = this.permissionOverwrites | ||||
|     overwrites[index] = overwrite | ||||
|     return await this.edit({ permissionOverwrites: overwrites }) | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -9,11 +9,12 @@ import { | |||
|   Guild, | ||||
|   EveryChannelTypes, | ||||
|   ChannelTypes, | ||||
|   GuildTextChannel | ||||
|   GuildTextChannel, | ||||
|   checkGuildTextBasedChannel, | ||||
|   Permissions | ||||
| } from '../../mod.ts' | ||||
| import { Collector } from '../models/collectors.ts' | ||||
| import { MessageAttachment } from '../structures/message.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { TOKEN } from './config.ts' | ||||
| 
 | ||||
| const client = new Client({ | ||||
|  | @ -190,7 +191,8 @@ client.on('messageCreate', async (msg: Message) => { | |||
|     if (typeof vs !== 'object') return | ||||
|     vs.channel?.join() | ||||
|   } else if (msg.content === '!getOverwrites') { | ||||
|     if (msg.channel.type !== ChannelTypes.GUILD_TEXT) { | ||||
|     // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
 | ||||
|     if (!checkGuildTextBasedChannel(msg.channel)) { | ||||
|       return msg.channel.send("This isn't a guild text channel!") | ||||
|     } | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||
|  | @ -202,16 +204,15 @@ client.on('messageCreate', async (msg: Message) => { | |||
|       `Your permission overwrites:\n${overwrites | ||||
|         .map( | ||||
|           (over) => | ||||
|             `ID: ${over.id}\nAllowed:\n${new Permissions(over.allow) | ||||
|             `ID: ${over.id}\nAllowed:\n${over.allow | ||||
|               .toArray() | ||||
|               .join('\n')}\nDenied:\n${new Permissions(over.deny) | ||||
|               .toArray() | ||||
|               .join('\n')}` | ||||
|               .join('\n')}\nDenied:\n${over.deny.toArray().join('\n')}` | ||||
|         ) | ||||
|         .join('\n\n')}` | ||||
|     ) | ||||
|   } else if (msg.content === '!getPermissions') { | ||||
|     if (msg.channel.type !== ChannelTypes.GUILD_TEXT) { | ||||
|     // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
 | ||||
|     if (!checkGuildTextBasedChannel(msg.channel)) { | ||||
|       return msg.channel.send("This isn't a guild text channel!") | ||||
|     } | ||||
|     // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
 | ||||
|  | @ -220,6 +221,18 @@ client.on('messageCreate', async (msg: Message) => { | |||
|       msg.member as Member | ||||
|     ) | ||||
|     msg.channel.send(`Your permissions:\n${permissions.toArray().join('\n')}`) | ||||
|   } else if (msg.content === '!addBasicOverwrites') { | ||||
|     // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
 | ||||
|     if (!checkGuildTextBasedChannel(msg.channel)) { | ||||
|       return msg.channel.send("This isn't a guild text channel!") | ||||
|     } | ||||
|     if (msg.member !== undefined) { | ||||
|       await msg.channel.addOverwrite({ | ||||
|         id: msg.member, | ||||
|         allow: Permissions.DEFAULT.toString() | ||||
|       }) | ||||
|       msg.channel.send(`Done!`) | ||||
|     } | ||||
|   } else if (msg.content === '!addAllRoles') { | ||||
|     const roles = await msg.guild?.roles.array() | ||||
|     if (roles !== undefined) { | ||||
|  |  | |||
|  | @ -1,5 +1,8 @@ | |||
| import { Embed } from '../structures/embed.ts' | ||||
| import type { Message, MessageAttachment } from '../structures/message.ts' | ||||
| import { Member } from '../structures/member.ts' | ||||
| import { Message, MessageAttachment } from '../structures/message.ts' | ||||
| import { Role } from '../structures/role.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { EmojiPayload } from './emoji.ts' | ||||
| import { MemberPayload } from './guild.ts' | ||||
| import { UserPayload } from './user.ts' | ||||
|  | @ -18,25 +21,23 @@ export interface GuildChannelPayload extends ChannelPayload { | |||
|   guild_id: string | ||||
|   name: string | ||||
|   position: number | ||||
|   permission_overwrites: Overwrite[] | ||||
|   permission_overwrites: OverwritePayload[] | ||||
|   nsfw: boolean | ||||
|   parent_id?: string | ||||
| } | ||||
| 
 | ||||
| export interface GuildTextChannelPayload | ||||
| export interface GuildTextBasedChannelPayload | ||||
|   extends TextChannelPayload, | ||||
|     GuildChannelPayload { | ||||
|   nsfw: boolean | ||||
|   rate_limit_per_user: number | ||||
|   topic?: string | ||||
| } | ||||
| 
 | ||||
| export interface GuildNewsChannelPayload | ||||
|   extends TextChannelPayload, | ||||
|     GuildChannelPayload { | ||||
|   topic?: string | ||||
|   nsfw: boolean | ||||
| export interface GuildTextChannelPayload extends GuildTextBasedChannelPayload { | ||||
|   rate_limit_per_user: number | ||||
| } | ||||
| 
 | ||||
| export interface GuildNewsChannelPayload extends GuildTextBasedChannelPayload {} | ||||
| 
 | ||||
| export interface GuildVoiceChannelPayload extends GuildChannelPayload { | ||||
|   bitrate: string | ||||
|   user_limit: number | ||||
|  | @ -59,25 +60,27 @@ export interface GuildCategoryChannelPayload | |||
| export interface ModifyChannelPayload { | ||||
|   name?: string | ||||
|   position?: number | null | ||||
|   permission_overwrites?: Overwrite[] | null | ||||
|   permission_overwrites?: OverwritePayload[] | null | ||||
|   parent_id?: string | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildCategoryChannelPayload | ||||
|   extends ModifyChannelPayload {} | ||||
| 
 | ||||
| export interface ModifyGuildTextChannelPayload extends ModifyChannelPayload { | ||||
| export interface ModifyGuildTextBasedChannelPayload | ||||
|   extends ModifyChannelPayload { | ||||
|   type?: number | ||||
|   topic?: string | null | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildTextChannelPayload | ||||
|   extends ModifyGuildTextBasedChannelPayload { | ||||
|   rate_limit_per_user?: number | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildNewsChannelPayload extends ModifyChannelPayload { | ||||
|   type?: number | ||||
|   topic?: string | null | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| export interface ModifyGuildNewsChannelPayload | ||||
|   extends ModifyGuildTextBasedChannelPayload {} | ||||
| 
 | ||||
| export interface ModifyVoiceChannelPayload extends ModifyChannelPayload { | ||||
|   bitrate?: number | null | ||||
|  | @ -87,37 +90,65 @@ export interface ModifyVoiceChannelPayload extends ModifyChannelPayload { | |||
| export interface ModifyChannelOption { | ||||
|   name?: string | ||||
|   position?: number | null | ||||
|   permissionOverwrites?: Overwrite[] | null | ||||
|   permissionOverwrites?: OverwritePayload[] | null | ||||
|   parentID?: string | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildCategoryChannelOption extends ModifyChannelOption {} | ||||
| 
 | ||||
| export interface ModifyGuildTextChannelOption extends ModifyChannelOption { | ||||
| export interface ModifyGuildTextBasedChannelOption extends ModifyChannelOption { | ||||
|   type?: number | ||||
|   topic?: string | null | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildTextChannelOption | ||||
|   extends ModifyGuildTextBasedChannelOption { | ||||
|   slowmode?: number | null | ||||
| } | ||||
| 
 | ||||
| export interface ModifyGuildNewsChannelOption extends ModifyChannelOption { | ||||
|   type?: number | ||||
|   topic?: string | null | ||||
|   nsfw?: boolean | null | ||||
| } | ||||
| export interface ModifyGuildNewsChannelOption | ||||
|   extends ModifyGuildTextBasedChannelOption {} | ||||
| 
 | ||||
| export interface ModifyVoiceChannelOption extends ModifyChannelOption { | ||||
|   bitrate?: number | null | ||||
|   userLimit?: number | null | ||||
| } | ||||
| 
 | ||||
| export interface Overwrite { | ||||
| export enum OverwriteType { | ||||
|   ROLE = 0, | ||||
|   USER = 1 | ||||
| } | ||||
| 
 | ||||
| export interface OverwritePayload { | ||||
|   id: string | ||||
|   type: number | ||||
|   type: OverwriteType | ||||
|   allow: string | ||||
|   deny: string | ||||
| } | ||||
| 
 | ||||
| export interface Overwrite { | ||||
|   id: string | Role | Member | ||||
|   type: OverwriteType | ||||
|   allow: Permissions | ||||
|   deny: Permissions | ||||
| } | ||||
| 
 | ||||
| export interface OverwriteAsOptions { | ||||
|   id: string | Role | Member | ||||
|   type?: OverwriteType | ||||
|   allow?: string | Permissions | ||||
|   deny?: string | Permissions | ||||
| } | ||||
| 
 | ||||
| export type OverwriteAsArg = OverwriteAsOptions | OverwritePayload | ||||
| 
 | ||||
| export enum OverrideType { | ||||
|   ADD = 0, | ||||
|   REMOVE = 1, | ||||
|   REPLACE = 2 | ||||
| } | ||||
| 
 | ||||
| export enum ChannelTypes { | ||||
|   GUILD_TEXT = 0, | ||||
|   DM = 1, | ||||
|  |  | |||
|  | @ -1,13 +1,20 @@ | |||
| import { GuildChannel } from '../structures/channel.ts' | ||||
| import { Emoji } from '../structures/emoji.ts' | ||||
| import { CategoryChannel } from '../structures/guildCategoryChannel.ts' | ||||
| import { NewsChannel } from '../structures/guildNewsChannel.ts' | ||||
| import { VoiceChannel } from '../structures/guildVoiceChannel.ts' | ||||
| import { Role } from '../structures/role.ts' | ||||
| import { GuildTextChannel } from '../structures/textChannel.ts' | ||||
| import { | ||||
|   GuildTextChannel, | ||||
|   GuildTextBasedChannel | ||||
| } from '../structures/guildTextChannel.ts' | ||||
| import { ApplicationPayload } from './application.ts' | ||||
| import { | ||||
|   ChannelPayload, | ||||
|   ChannelTypes, | ||||
|   GuildCategoryChannelPayload, | ||||
|   GuildNewsChannelPayload, | ||||
|   GuildTextBasedChannelPayload, | ||||
|   GuildTextChannelPayload, | ||||
|   GuildVoiceChannelPayload | ||||
| } from './channel.ts' | ||||
|  | @ -171,11 +178,26 @@ export interface GuildWidgetPayload { | |||
|   presence_count: number | ||||
| } | ||||
| 
 | ||||
| export type GuildChannelPayloads = | ||||
| export type GuildTextBasedPayloads = | ||||
|   | GuildTextBasedChannelPayload | ||||
|   | GuildTextChannelPayload | ||||
|   | GuildNewsChannelPayload | ||||
| 
 | ||||
| export type GuildChannelPayloads = | ||||
|   | GuildTextBasedPayloads | ||||
|   | GuildVoiceChannelPayload | ||||
|   | GuildCategoryChannelPayload | ||||
| export type GuildChannels = GuildTextChannel | VoiceChannel | CategoryChannel | ||||
| 
 | ||||
| export type GuildTextBasedChannels = | ||||
|   | GuildTextBasedChannel | ||||
|   | GuildTextChannel | ||||
|   | NewsChannel | ||||
| 
 | ||||
| export type GuildChannels = | ||||
|   | GuildChannel | ||||
|   | GuildTextBasedChannels | ||||
|   | VoiceChannel | ||||
|   | CategoryChannel | ||||
| 
 | ||||
| export interface GuildCreatePayload { | ||||
|   name: string | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ import { | |||
|   GroupDMChannelPayload, | ||||
|   GuildCategoryChannelPayload, | ||||
|   GuildNewsChannelPayload, | ||||
|   GuildTextBasedChannelPayload, | ||||
|   GuildTextChannelPayload, | ||||
|   GuildVoiceChannelPayload, | ||||
|   TextChannelPayload | ||||
|  | @ -13,16 +14,21 @@ import { | |||
| import { DMChannel } from '../structures/dmChannel.ts' | ||||
| import { GroupDMChannel } from '../structures/groupChannel.ts' | ||||
| import { CategoryChannel } from '../structures/guildCategoryChannel.ts' | ||||
| import { | ||||
|   GuildTextBasedChannel, | ||||
|   GuildTextChannel | ||||
| } from '../structures/guildTextChannel.ts' | ||||
| import { NewsChannel } from '../structures/guildNewsChannel.ts' | ||||
| import { VoiceChannel } from '../structures/guildVoiceChannel.ts' | ||||
| import { Guild } from '../structures/guild.ts' | ||||
| import { GuildTextChannel, TextChannel } from '../structures/textChannel.ts' | ||||
| import { Channel } from '../structures/channel.ts' | ||||
| import { TextChannel } from '../structures/textChannel.ts' | ||||
| import { Channel, GuildChannel } from '../structures/channel.ts' | ||||
| 
 | ||||
| export type EveryTextChannelTypes = | ||||
|   | TextChannel | ||||
|   | NewsChannel | ||||
|   | GuildTextChannel | ||||
|   | GuildTextBasedChannel | ||||
|   | DMChannel | ||||
|   | GroupDMChannel | ||||
| 
 | ||||
|  | @ -30,11 +36,13 @@ export type EveryTextChannelPayloadTypes = | |||
|   | TextChannelPayload | ||||
|   | GuildNewsChannelPayload | ||||
|   | GuildTextChannelPayload | ||||
|   | GuildTextBasedChannelPayload | ||||
|   | DMChannelPayload | ||||
|   | GroupDMChannelPayload | ||||
| 
 | ||||
| export type EveryChannelTypes = | ||||
|   | Channel | ||||
|   | GuildChannel | ||||
|   | CategoryChannel | ||||
|   | VoiceChannel | ||||
|   | EveryTextChannelTypes | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue