feat: GuildTextChannel#{permissionsFor,overwritesFor}, TextChannel#triggerTyping, many other things
This commit is contained in:
		
							parent
							
								
									04c4e7760b
								
							
						
					
					
						commit
						c1cd6276ae
					
				
					 17 changed files with 236 additions and 78 deletions
				
			
		|  | @ -1,9 +1,9 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { ApplicationPayload } from '../types/application.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { User } from './user.ts' | ||||
| 
 | ||||
| export class Application extends Base { | ||||
| export class Application extends SnowflakeBase { | ||||
|   id: string | ||||
|   name: string | ||||
|   icon: string | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { Snowflake } from '../utils/snowflake.ts' | ||||
| 
 | ||||
| export class Base { | ||||
|   client: Client | ||||
|  | @ -7,3 +8,17 @@ export class Base { | |||
|     this.client = client | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class SnowflakeBase extends Base { | ||||
|   id!: string | ||||
| 
 | ||||
|   /** Get Snowflake Object */ | ||||
|   get snowflake(): Snowflake { | ||||
|     return new Snowflake(this.id) | ||||
|   } | ||||
| 
 | ||||
|   /** Timestamp of when resource was created */ | ||||
|   get timestamp(): Date { | ||||
|     return new Date(this.snowflake.timestamp) | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { ChannelPayload, ChannelTypes } from '../types/channel.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| 
 | ||||
| export class Channel extends Base { | ||||
| export class Channel extends SnowflakeBase { | ||||
|   type: ChannelTypes | ||||
|   id: string | ||||
|   static cacheName = 'channel' | ||||
|  |  | |||
|  | @ -9,7 +9,9 @@ import { | |||
|   EmbedTypes, | ||||
|   EmbedVideo | ||||
| } from '../types/channel.ts' | ||||
| import { Colors, ColorUtil } from '../utils/colorutil.ts' | ||||
| 
 | ||||
| /** Message Embed Object */ | ||||
| export class Embed { | ||||
|   title?: string | ||||
|   type?: EmbedTypes | ||||
|  | @ -41,7 +43,7 @@ export class Embed { | |||
|     this.fields = data?.fields | ||||
|   } | ||||
| 
 | ||||
|   // khk4912
 | ||||
|   /** Convert Embed Object to Embed Payload JSON */ | ||||
|   toJSON(): EmbedPayload { | ||||
|     return { | ||||
|       title: this.title, | ||||
|  | @ -60,63 +62,116 @@ export class Embed { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** Set Title of the Embed */ | ||||
|   setTitle(title: string): Embed { | ||||
|     this.title = title | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set Embed description */ | ||||
|   setDescription(description: string): Embed { | ||||
|     this.description = description | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set Embed Type */ | ||||
|   setType(type: EmbedTypes): Embed { | ||||
|     this.type = type | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setURL(url: string): Embed { | ||||
|     this.url = url | ||||
|   /** Set URL of the Embed */ | ||||
|   setURL(url: string): Embed | ||||
|   setURL(url: URL): Embed | ||||
|   setURL(url: string | URL): Embed { | ||||
|     this.url = typeof url === 'object' ? url.toString() : url | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setTimestamp(timestamp: string): Embed { | ||||
|     this.timestamp = timestamp | ||||
|   /** Set Timestamp of the Embed */ | ||||
|   setTimestamp(timeString: string): Embed | ||||
|   setTimestamp(unixTimestamp: number): Embed | ||||
|   setTimestamp(dateObject: Date): Embed | ||||
|   setTimestamp(timestamp: string | Date | number): Embed { | ||||
|     this.timestamp = new Date(timestamp).toISOString() | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setColor(hex: number): Embed { | ||||
|     this.color = hex | ||||
|   /** Set Color of the Embed */ | ||||
|   setColor(hexInt: number): Embed | ||||
|   setColor(r: number, g: number, b: number): Embed | ||||
|   setColor(random: 'random'): Embed | ||||
|   setColor(hexStr: string): Embed | ||||
|   setColor(namedColor: keyof Colors): Embed | ||||
|   setColor( | ||||
|     color: number | 'random' | string | keyof Colors, | ||||
|     g?: number, | ||||
|     b?: number | ||||
|   ): Embed { | ||||
|     if (typeof color === 'number' && g === undefined && b === undefined) { | ||||
|       this.color = color | ||||
|     } else if (typeof color === 'string' && color.toLowerCase() === 'random') { | ||||
|       this.color = ColorUtil.resolveHex(ColorUtil.randomHex()) | ||||
|     } else if (typeof color === 'string' && color.startsWith('#')) { | ||||
|       this.color = ColorUtil.resolveHex(color) | ||||
|     } else if ( | ||||
|       typeof color === 'number' && | ||||
|       g !== undefined && | ||||
|       b !== undefined | ||||
|     ) { | ||||
|       this.color = ColorUtil.resolveRGB([color, g, b]) | ||||
|     } else if (typeof color === 'string') { | ||||
|       this.color = ColorUtil.resolveColor(color as keyof Colors) | ||||
|     } else | ||||
|       throw new Error( | ||||
|         'Invalid Embed Color. Must be RGB, Hex (string or number), valid color name or a valid CSS color.' | ||||
|       ) | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setFooter(footer: EmbedFooter): Embed { | ||||
|     this.footer = footer | ||||
|   /** Set Footer of the Embed */ | ||||
|   setFooter(text: string, icon?: string): Embed | ||||
|   setFooter(footer: EmbedFooter): Embed | ||||
|   setFooter(footer: EmbedFooter | string, icon?: string): Embed { | ||||
|     this.footer = | ||||
|       typeof footer === 'string' ? { text: footer, icon_url: icon } : footer | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setImage(image: EmbedImage): Embed { | ||||
|     this.image = image | ||||
|   /** Set Image of the Embed */ | ||||
|   setImage(image: EmbedImage | string): Embed { | ||||
|     this.image = typeof image === 'string' ? { url: image } : image | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setThumbnail(thumbnail: EmbedThumbnail): Embed { | ||||
|     this.thumbnail = thumbnail | ||||
|   /** Set Thumbnail Image of the Embed */ | ||||
|   setThumbnail(thumbnail: EmbedThumbnail | string): Embed { | ||||
|     this.thumbnail = | ||||
|       typeof thumbnail === 'string' ? { url: thumbnail } : thumbnail | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setVideo(video: EmbedVideo): Embed { | ||||
|     this.video = video | ||||
|   /** Set Embed Video */ | ||||
|   setVideo(video: EmbedVideo | string): Embed { | ||||
|     this.video = typeof video === 'string' ? { url: video } : video | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setProvider(provider: EmbedProvider): Embed { | ||||
|     this.provider = provider | ||||
|   /** Set Provider of the Embed */ | ||||
|   setProvider(name: string, url?: string): Embed | ||||
|   setProvider(provider: EmbedProvider): Embed | ||||
|   setProvider(provider: EmbedProvider | string, url?: string): Embed { | ||||
|     this.provider = | ||||
|       typeof provider === 'string' ? { name: provider, url } : provider | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   setAuthor(author: EmbedAuthor): Embed { | ||||
|     this.author = author | ||||
|   /** Set Author of the Embed */ | ||||
|   setAuthor(author: EmbedAuthor): Embed | ||||
|   setAuthor(name: string, image?: string): Embed | ||||
|   setAuthor(author: EmbedAuthor | string, image?: string): Embed { | ||||
|     this.author = | ||||
|       typeof author === 'string' ? { name: author, icon_url: image } : author | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|  | @ -125,23 +180,29 @@ export class Embed { | |||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   addField(name: string, value: string, inline?: boolean): Embed { | ||||
|   /** Adds a Field to the Embed */ | ||||
|   addField(field: EmbedField): Embed | ||||
|   addField(name: string, value: string, inline?: boolean): Embed | ||||
|   addField(name: string | EmbedField, value?: string, inline?: boolean): Embed { | ||||
|     if (typeof name !== 'object' && value === undefined) | ||||
|       throw new Error('field value is required') | ||||
|     const field: EmbedField = | ||||
|       typeof name === 'object' ? name : { name, value: value as string, inline } | ||||
| 
 | ||||
|     if (this.fields === undefined) { | ||||
|       this.fields = [ | ||||
|         { | ||||
|           name: name, | ||||
|           value: value, | ||||
|           inline: inline | ||||
|         } | ||||
|       ] | ||||
|       this.fields = [field] | ||||
|     } else { | ||||
|       this.fields.push({ | ||||
|         name: name, | ||||
|         value: value, | ||||
|         inline: inline | ||||
|       }) | ||||
|       this.fields.push(field) | ||||
|     } | ||||
| 
 | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Adds multiple fields to the Embed */ | ||||
|   addFields(...fields: EmbedField[]): Embed { | ||||
|     for (const field of fields) { | ||||
|       this.addField(field) | ||||
|     } | ||||
|     return this | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,13 +1,24 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { EmojiPayload } from '../types/emoji.ts' | ||||
| import { EMOJI } from '../types/endpoint.ts' | ||||
| import { Snowflake } from '../utils/snowflake.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { Role } from './role.ts' | ||||
| import { User } from './user.ts' | ||||
| 
 | ||||
| /** Guild Emoji Object */ | ||||
| export class Emoji extends Base { | ||||
|   id: string | null | ||||
| 
 | ||||
|   get snowflake(): Snowflake | null { | ||||
|     return this.id === null ? null : new Snowflake(this.id) | ||||
|   } | ||||
| 
 | ||||
|   get timestamp(): Date | null { | ||||
|     return this.snowflake === null ? null : new Date(this.snowflake.timestamp) | ||||
|   } | ||||
| 
 | ||||
|   name: string | null | ||||
|   roles?: string[] | ||||
|   user?: User | ||||
|  | @ -48,7 +59,7 @@ export class Emoji extends Base { | |||
|     if (this.id === null) throw new Error('Emoji ID is not valid.') | ||||
|     if (this.guild === undefined) throw new Error('Guild is undefined') | ||||
|     const roles = Array.isArray(data.roles) | ||||
|       ? data.roles.map(role => (role instanceof Role ? role.id : role)) | ||||
|       ? data.roles.map((role) => (role instanceof Role ? role.id : role)) | ||||
|       : [data.roles instanceof Role ? data.roles.id : data.roles] | ||||
|     const res = await this.client.rest.patch(EMOJI(this.guild.id, this.id), { | ||||
|       ...data, | ||||
|  | @ -82,5 +93,5 @@ export interface ModifyGuildEmojiParams { | |||
|   /** Name of the emoji */ | ||||
|   name?: string | ||||
|   /** Roles to which this emoji will be whitelisted */ | ||||
|   roles?: string | Role | Array<string | Role>; | ||||
|   roles?: string | Role | Array<string | Role> | ||||
| } | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ import { | |||
|   GuildPruneCountPayload, | ||||
|   GuildBeginPrunePayload | ||||
| } from '../types/guild.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { Base, SnowflakeBase } from './base.ts' | ||||
| import { CreateGuildRoleOptions, RolesManager } from '../managers/roles.ts' | ||||
| import { InviteManager } from '../managers/invites.ts' | ||||
| import { | ||||
|  | @ -132,7 +132,7 @@ export class GuildBans { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Guild extends Base { | ||||
| export class Guild extends SnowflakeBase { | ||||
|   id: string | ||||
|   name?: string | ||||
|   icon?: string | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ import { Client } from '../models/client.ts' | |||
| import { GUILD_MEMBER } from '../types/endpoint.ts' | ||||
| import { MemberPayload } from '../types/guild.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { Role } from './role.ts' | ||||
| import { User } from './user.ts' | ||||
|  | @ -15,7 +15,7 @@ export interface MemberData { | |||
|   mute?: boolean | ||||
| } | ||||
| 
 | ||||
| export class Member extends Base { | ||||
| export class Member extends SnowflakeBase { | ||||
|   id: string | ||||
|   user: User | ||||
|   nick?: string | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { | ||||
|   Attachment, | ||||
|   MessageActivity, | ||||
|  | @ -21,7 +21,7 @@ import { Emoji } from './emoji.ts' | |||
| 
 | ||||
| type AllMessageOptions = MessageOptions | Embed | ||||
| 
 | ||||
| export class Message extends Base { | ||||
| export class Message extends SnowflakeBase { | ||||
|   id: string | ||||
|   channelID: string | ||||
|   channel: TextChannel | ||||
|  | @ -30,7 +30,6 @@ export class Message extends Base { | |||
|   author: User | ||||
|   member?: Member | ||||
|   content: string | ||||
|   timestamp: string | ||||
|   editedTimestamp?: string | ||||
|   tts: boolean | ||||
|   mentions: MessageMentions | ||||
|  | @ -63,7 +62,6 @@ export class Message extends Base { | |||
|     this.guildID = data.guild_id | ||||
|     this.author = author | ||||
|     this.content = data.content | ||||
|     this.timestamp = data.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp | ||||
|     this.tts = data.tts | ||||
|     this.mentions = new MessageMentions(this.client, this) | ||||
|  | @ -91,7 +89,6 @@ export class Message extends Base { | |||
|     this.channelID = data.channel_id ?? this.channelID | ||||
|     this.guildID = data.guild_id ?? this.guildID | ||||
|     this.content = data.content ?? this.content | ||||
|     this.timestamp = data.timestamp ?? this.timestamp | ||||
|     this.editedTimestamp = data.edited_timestamp ?? this.editedTimestamp | ||||
|     this.tts = data.tts ?? this.tts | ||||
|     this.attachments = data.attachments ?? this.attachments | ||||
|  |  | |||
|  | @ -3,9 +3,9 @@ import { | |||
|   MessageStickerFormatTypes, | ||||
|   MessageStickerPayload | ||||
| } from '../types/channel.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| 
 | ||||
| export class MessageSticker extends Base { | ||||
| export class MessageSticker extends SnowflakeBase { | ||||
|   id: string | ||||
|   packID: string | ||||
|   name: string | ||||
|  |  | |||
|  | @ -77,6 +77,7 @@ export class ClientPresence { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** Parses from Payload */ | ||||
|   parse(payload: StatusPayload): ClientPresence { | ||||
|     this.afk = payload.afk | ||||
|     this.activity = payload.activities ?? undefined | ||||
|  | @ -86,10 +87,12 @@ export class ClientPresence { | |||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Parses from Payload and creates new ClientPresence */ | ||||
|   static parse(payload: StatusUpdatePayload): ClientPresence { | ||||
|     return new ClientPresence().parse(payload) | ||||
|   } | ||||
| 
 | ||||
|   /** Creates Presence Payload */ | ||||
|   create(): StatusPayload { | ||||
|     return { | ||||
|       afk: this.afk === undefined ? false : this.afk, | ||||
|  | @ -100,6 +103,7 @@ export class ClientPresence { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** Creates Activity Payload */ | ||||
|   createActivity(): ActivityGame[] | null { | ||||
|     // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
 | ||||
|     const activity = | ||||
|  | @ -118,47 +122,45 @@ export class ClientPresence { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /** Set Status of Presence */ | ||||
|   setStatus(status: StatusType): ClientPresence { | ||||
|     this.status = status | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set Activity for Presence */ | ||||
|   setActivity(activity: ActivityGame): ClientPresence { | ||||
|     this.activity = activity | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set Activities for Presence */ | ||||
|   setActivities(activities: ActivityGame[]): ClientPresence { | ||||
|     this.activity = activities | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set AFK value */ | ||||
|   setAFK(afk: boolean): ClientPresence { | ||||
|     this.afk = afk | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Remove AFK (set false) */ | ||||
|   removeAFK(): ClientPresence { | ||||
|     this.afk = false | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Toggle AFK (boolean) value */ | ||||
|   toggleAFK(): ClientPresence { | ||||
|     this.afk = this.afk === undefined ? true : !this.afk | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   /** Set Since property of Activity */ | ||||
|   setSince(since?: number): ClientPresence { | ||||
|     this.since = since | ||||
|     return this | ||||
|   } | ||||
| 
 | ||||
|   // setClientStatus(
 | ||||
|   //   client: 'desktop' | 'web' | 'mobile',
 | ||||
|   //   status: StatusType
 | ||||
|   // ): ClientPresence {
 | ||||
|   //   if (this.clientStatus === undefined) this.clientStatus = {}
 | ||||
|   //   this.clientStatus[client] = status
 | ||||
|   //   return this
 | ||||
|   // }
 | ||||
| } | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { RoleModifyPayload, RolePayload } from '../types/role.ts' | ||||
| import { Permissions } from '../utils/permissions.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| 
 | ||||
| export class Role extends Base { | ||||
| export class Role extends SnowflakeBase { | ||||
|   id: string | ||||
|   guild: Guild | ||||
|   name: string | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ import { | |||
|   InteractionResponsePayload, | ||||
|   InteractionResponseType | ||||
| } from '../types/slash.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { Embed } from './embed.ts' | ||||
| import { Guild } from './guild.ts' | ||||
| import { Member } from './member.ts' | ||||
|  | @ -39,7 +40,7 @@ export interface InteractionResponse { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| export class Interaction { | ||||
| export class Interaction extends SnowflakeBase { | ||||
|   client: Client | ||||
|   type: number | ||||
|   token: string | ||||
|  | @ -59,6 +60,7 @@ export class Interaction { | |||
|       member: Member | ||||
|     } | ||||
|   ) { | ||||
|     super(client) | ||||
|     this.client = client | ||||
|     this.type = data.type | ||||
|     this.token = data.token | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ import { | |||
|   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' | ||||
|  | @ -30,6 +31,7 @@ import { User } from './user.ts' | |||
| 
 | ||||
| export type AllMessageOptions = MessageOptions | Embed | ||||
| 
 | ||||
| /** Channel object for Text Channel type */ | ||||
| export class TextChannel extends Channel { | ||||
|   lastMessageID?: string | ||||
|   lastPinTimestamp?: string | ||||
|  | @ -226,8 +228,15 @@ export class TextChannel extends Channel { | |||
| 
 | ||||
|     return res | ||||
|   } | ||||
| 
 | ||||
|   /** Trigger the typing indicator. NOT recommended to be used by bots unless you really want to. */ | ||||
|   async triggerTyping(): Promise<TextChannel> { | ||||
|     await this.client.rest.api.channels[this.id].typing.psot() | ||||
|     return this | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** Represents a Text Channel but in a Guild */ | ||||
| export class GuildTextChannel extends TextChannel { | ||||
|   guildID: string | ||||
|   name: string | ||||
|  | @ -273,6 +282,7 @@ export class GuildTextChannel extends TextChannel { | |||
|     this.rateLimit = data.rate_limit_per_user ?? this.rateLimit | ||||
|   } | ||||
| 
 | ||||
|   /** Edit the Guild Text Channel */ | ||||
|   async edit( | ||||
|     options?: ModifyGuildTextChannelOption | ||||
|   ): Promise<GuildTextChannel> { | ||||
|  | @ -328,4 +338,54 @@ export class GuildTextChannel extends TextChannel { | |||
|   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))) | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,12 +1,12 @@ | |||
| import { Client } from '../models/client.ts' | ||||
| import { UserPayload } from '../types/user.ts' | ||||
| import { UserFlagsManager } from '../utils/userFlags.ts' | ||||
| import { Base } from './base.ts' | ||||
| import { SnowflakeBase } from './base.ts' | ||||
| import { ImageURL } from './cdn.ts' | ||||
| import { ImageSize, ImageFormats } from '../types/cdn.ts' | ||||
| import { DEFAULT_USER_AVATAR, USER_AVATAR } from '../types/endpoint.ts' | ||||
| 
 | ||||
| export class User extends Base { | ||||
| export class User extends SnowflakeBase { | ||||
|   id: string | ||||
|   username: string | ||||
|   discriminator: string | ||||
|  |  | |||
|  | @ -1,5 +1,11 @@ | |||
| // Ported from https://github.com/discordjs/discord.js/blob/master/src/util/BitField.js
 | ||||
| export type BitFieldResolvable = number | BitField | string | BitField[] | ||||
| export type BitFieldResolvable = | ||||
|   | number | ||||
|   | number[] | ||||
|   | BitField | ||||
|   | string | ||||
|   | string[] | ||||
|   | BitField[] | ||||
| 
 | ||||
| /** Bit Field utility to work with Bits and Flags */ | ||||
| export class BitField { | ||||
|  | @ -20,7 +26,7 @@ export class BitField { | |||
|   } | ||||
| 
 | ||||
|   has(bit: BitFieldResolvable, ...args: any[]): boolean { | ||||
|     if (Array.isArray(bit)) return bit.every((p) => this.has(p)) | ||||
|     if (Array.isArray(bit)) return (bit.every as any)((p: any) => this.has(p)) | ||||
|     return (this.bitfield & BitField.resolve(this.flags, bit)) === bit | ||||
|   } | ||||
| 
 | ||||
|  | @ -89,9 +95,10 @@ export class BitField { | |||
|     if (typeof bit === 'number' && bit >= 0) return bit | ||||
|     if (bit instanceof BitField) return this.resolve(flags, bit.bitfield) | ||||
|     if (Array.isArray(bit)) | ||||
|       return bit | ||||
|         .map((p) => this.resolve(flags, p)) | ||||
|         .reduce((prev, p) => prev | p, 0) | ||||
|       return (bit.map as any)((p: any) => this.resolve(flags, p)).reduce( | ||||
|         (prev: any, p: any) => prev | p, | ||||
|         0 | ||||
|       ) | ||||
|     if (typeof bit === 'string' && typeof flags[bit] !== 'undefined') | ||||
|       return flags[bit] | ||||
|     const error = new RangeError('BITFIELD_INVALID') | ||||
|  |  | |||
|  | @ -1,10 +1,12 @@ | |||
| // Ported from https://github.com/discordjs/discord.js/blob/master/src/util/Permissions.js
 | ||||
| import { PermissionFlags } from '../types/permissionFlags.ts' | ||||
| import { BitField } from './bitfield.ts' | ||||
| import { BitField, BitFieldResolvable } from './bitfield.ts' | ||||
| 
 | ||||
| export type PermissionResolvable = | ||||
|   | string | ||||
|   | string[] | ||||
|   | number | ||||
|   | number[] | ||||
|   | Permissions | ||||
|   | PermissionResolvable[] | ||||
| 
 | ||||
|  | @ -13,7 +15,7 @@ export class Permissions extends BitField { | |||
|   static DEFAULT = 104324673 | ||||
|   static ALL = Object.values(PermissionFlags).reduce((all, p) => all | p, 0) | ||||
| 
 | ||||
|   constructor(bits: any) { | ||||
|   constructor(bits: BitFieldResolvable) { | ||||
|     super(PermissionFlags, bits) | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| /** Utility class to extract data from a Snowflake (Discord ID) */ | ||||
| export class Snowflake { | ||||
|   id: string | ||||
| 
 | ||||
|  | @ -9,19 +10,19 @@ export class Snowflake { | |||
|     return BigInt.asUintN(64, BigInt(this.id)) | ||||
|   } | ||||
| 
 | ||||
|   get timestamp(): string { | ||||
|     return ((this.snowflake >> 22n) + 1420070400000n).toString() | ||||
|   get timestamp(): number { | ||||
|     return Number(((this.snowflake >> 22n) + 1420070400000n).toString()) | ||||
|   } | ||||
| 
 | ||||
|   get workerID(): string { | ||||
|     return ((this.snowflake & 0x3e0000n) >> 17n).toString() | ||||
|   get workerID(): number { | ||||
|     return Number(((this.snowflake & 0x3e0000n) >> 17n).toString()) | ||||
|   } | ||||
| 
 | ||||
|   get processID(): string { | ||||
|     return ((this.snowflake & 0x1f00n) >> 12n).toString() | ||||
|   get processID(): number { | ||||
|     return Number(((this.snowflake & 0x1f00n) >> 12n).toString()) | ||||
|   } | ||||
| 
 | ||||
|   get increment(): string { | ||||
|     return (this.snowflake & 0xfffn).toString() | ||||
|   get increment(): number { | ||||
|     return Number((this.snowflake & 0xfffn).toString()) | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue