import { Endpoints, Intents } from "./util/Constants.ts"
import { Channel } from "./structures/Channel.ts"import { Guild } from "./structures/Guild.ts"import { GuildMember } from "./structures/GuildMember.ts"import { DMChannel } from "./structures/DMChannel.ts"import { Message } from "./structures/Message.ts"import { User } from "./structures/User.ts"import { Role } from "./structures/Role.ts"import { Invite } from "./structures/Invite.ts"
import * as evt from "./Events.ts";import { RequestHandler } from "./network/rest/RequestHandler.ts"import Gateway from "./network/gateway/WebsocketHandler.ts"
export class Client { private requestHandler: RequestHandler
public gateway: Gateway public guilds: Map<string, Guild> = new Map<string, Guild>() public users: Map<string, User> = new Map<string, User>() public dmChannels: Map<string, DMChannel> = new Map<string, DMChannel>() public dmChannelUsers: Map<string, string> = new Map<string, string>() public channelGuildIDs: Map<string, string> = new Map<string, string>()
public constructor(public token: string, public options: Options.clientConstructor = {}) { if(this.options.intents !== undefined) { let bitmask = 0; if(this.options.intents instanceof Array) { for(const intent of this.options.intents) { bitmask |= intent } } else { bitmask = this.options.intents } this.options.intents = bitmask }
this.gateway = new Gateway(token, this) this.requestHandler = new RequestHandler(this) }
public evt = evt;
connect() { this.gateway.connect() }
modifyPresence(options: Options.modifyPresence = { status: "online" }): Promise<void> { return this.gateway.modifyPresence(options) }
createChannel(guildID: string, options: Options.createChannel): Promise<Channel> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "POST", Endpoints.GUILD_CHANNELS(guildID), options ) .then((data: any) => { resolve(Channel.from(data, this)) }) .catch((err: any) => { reject(err) }) }) }
modifyChannel(channelID: string, options: Options.modifyChannel): Promise<Channel> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "PATCH", Endpoints.CHANNEL(channelID), options ) .then((data: any) => { resolve(Channel.from(data, this)) }) .catch((err: any) => { reject(err) }) }) }
deleteChannel(channelID: string): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL(channelID) ) }
getDMChannel(userID: string): Promise<DMChannel> { return new Promise(async (resolve, reject) => { let dmChannelID = this.dmChannelUsers.get(userID); if(dmChannelID !== undefined) { resolve(this.dmChannels.get(dmChannelID)) } else { this.requestHandler.request( "POST", Endpoints.USER_CHANNELS("@me"), {recipients: [userID], type: 1}) .then((data: any) => { resolve(new DMChannel(data, this)) }) .catch((err: any) => { reject(err) }) } }) }
createMessage(channelID: string, content: string | Options.createMessage): Promise<Message> { if(typeof content === "string") { content = { content: content } } return new Promise(async (resolve, reject) => { this.requestHandler.request( "POST", Endpoints.CHANNEL_MESSAGES(channelID), content ) .then((data: any) => { resolve(new Message(data, this)) }) .catch((err: any) => { reject(err) }) }) }
modifyMessage( channelID: string, messageID: string, content: string | Options.modifyMessage ): Promise<Message> { if(typeof content === "string") { content = { content: content } } return new Promise(async (resolve, reject) => { this.requestHandler.request( "PATCH", Endpoints.CHANNEL_MESSAGE(channelID, messageID), content ) .then((data: any) => { resolve(new Message(data, this)) }) .catch((err: any) => { reject(err) }) }) }
deleteMessage( channelID: string, messageID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL_MESSAGE(channelID, messageID) ) }
putReaction( channelID: string, messageID: string, emoji: string ): Promise<void> { return this.requestHandler.request( "PUT", Endpoints.CHANNEL_MESSAGE_REACTION_USER(channelID, messageID, encodeURI(emoji), "@me")) }
deleteReaction( channelID: string, messageID: string, emoji: string, userID?: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL_MESSAGE_REACTION_USER(channelID, messageID, encodeURI(emoji), userID || "@me")) }
deleteAllReactions( channelID: string, messageID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL_MESSAGE_REACTIONS(channelID, messageID)) }
deleteAllEmojiReactions( channelID: string, messageID: string, emoji: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL_MESSAGE_REACTION(channelID, messageID, encodeURI(emoji))) }
getChannelInvites(channelID: string): Promise<Array<Invite>> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "GET", Endpoints.CHANNEL_INVITES(channelID)) .then((data: any) => { const arrayInvites: Array<Invite> = [] data.forEach((invite: any) => { arrayInvites.push(new Invite(invite, this)) }) resolve(arrayInvites) }) .catch((err: any) => { reject(err) }) }) }
postTypingIndicator(channelID: string): Promise<void> { return this.requestHandler.request( "POST", Endpoints.CHANNEL_TYPING(channelID) ) }
putPin( channelID: string, messageID: string ): Promise<void> { return this.requestHandler.request( "PUT", Endpoints.CHANNEL_PIN(channelID, messageID) ) }
deletePin( channelID: string, messageID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.CHANNEL_PIN(channelID, messageID) ) }
modifyGuild(guildID: string, options: Options.modifyGuild): Promise<Guild> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "PATCH", Endpoints.GUILD(guildID), options ) .then((data: any) => { resolve(new Guild(data, this)) }) .catch((err: any) => { reject(err) } ) }) }
deleteGuild(guildID: string): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.GUILD(guildID) ) }
modifyMember(guildID: string, userID: string, options: Options.modifyMember): Promise<GuildMember> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "PATCH", Endpoints.GUILD_MEMBER(guildID, userID), options ) .then((data: any) => { const guild = this.guilds.get(guildID) if(!guild) { reject() } else { const member = new GuildMember(data, guild, this) guild.members.set(member.user.id, member) resolve(member) } }) .catch((err: any) => { reject(err) }) }) }
putRole( guildID: string, userID: string, roleID: string ): Promise<void> { return this.requestHandler.request( "PUT", Endpoints.GUILD_MEMBER_ROLE(guildID, userID, roleID) ) }
removeRole( guildID: string, userID: string, roleID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.GUILD_MEMBER_ROLE(guildID, userID, roleID) ) }
removeMember( guildID: string, userID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.GUILD_MEMBER(guildID, userID) ) }
putBan( guildID: string, userID: string, options: Options.putBan ): Promise<void> { return this.requestHandler.request( "PUT", Endpoints.GUILD_BAN(guildID, userID), options ) }
deleteBan( guildID: string, userID: string ): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.GUILD_BAN(guildID, userID) ) }
createRole(guildID: string, options: Options.createRole): Promise<Role> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "POST", Endpoints.GUILD_ROLES(guildID), options ) .then((data: any) => { const guild = this.guilds.get(guildID) if(!guild) { reject() } else { const role = new Role(data, guild, this) guild.roles.set(role.id, role) resolve(role) } }) .catch((err: any) => { reject(err) }) }) }
modifyRole(guildID: string, roleID: string, options: Options.modifyRole): Promise<Role> { return new Promise(async (resolve, reject) => { this.requestHandler.request( "PATCH", Endpoints.GUILD_ROLE(guildID, roleID), options ) .then((data: any) => { const guild = this.guilds.get(guildID) if(!guild) { reject() } else { const role = new Role(data, guild, this) guild.roles.set(role.id, role) resolve(role) } }) .catch((err: any) => { reject(err) }) }) }
deleteRole(guildID: string, roleID: string): Promise<void> { return this.requestHandler.request( "DELETE", Endpoints.GUILD_ROLE(guildID, roleID) ) }
}
export namespace Options { export interface clientConstructor { intents?: number[] | number }
export interface modifyPresence { status?: "online" | "dnd" | "idle" | "invisible" | "offline", game?: { name: string, type: number } }
export interface createChannel { name: string, type: number, position?: number, topic?: string, nsfw?: boolean, bitrate?: number, user_limit?: number, rate_limit_per_user?: number, parent_id?: string }
export interface modifyChannel { name?: string, type?: number, position?: number, topic?: string, nsfw?: boolean, rate_limit_per_user?: number, bitrate?: number, user_limit?: number, parent_id?: string }
export interface createMessage { content?: string, tts?: boolean, file?: {name: string, file: File | Blob}, embed?: any }
export interface modifyMessage { content?: string, embed?: any }
export interface modifyGuild { name?: string, region?: string, verification_level?: number, default_message_notifcations?: number, explicit_content_filter?: number, afk_channel_id?: string, afk_timeout?: number, owner_id?: string, system_channel_id?: string, rules_channel_id?: string, public_updates_channel_id?: string, preferred_locale?: string }
export interface modifyMember { nick?: string, mute?: boolean, deaf?: boolean, channel_id?: string }
export interface putBan { "delete-message-days"?: number reason?: string }
export interface createRole { name?: string, color?: number, hoist?: boolean, mentionable?: boolean }
export interface modifyRole { name?: string, color?: number, hoist?: boolean, mentionable?: boolean }}