merge main repo

This commit is contained in:
DjDeveloperr 2020-12-01 13:55:34 +05:30
commit 50d1da11e6
10 changed files with 144 additions and 81 deletions

View file

@ -16,12 +16,11 @@ on:
jobs:
test:
runs-on: ${{ matrix.os }} # runs a test on Ubuntu, Windows and macOS
runs-on: ubuntu-latest
strategy:
matrix:
deno: ["v1.x", "nightly"]
os: [macOS-latest, windows-latest, ubuntu-latest]
steps:
- name: Setup repo

View file

@ -12,11 +12,7 @@ on:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macOS-latest, windows-latest, ubuntu-latest]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

View file

@ -1,14 +1,15 @@
import { Channel } from '../../structures/channel.ts'
import { ChannelPayload } from "../../types/channel.ts"
import { ChannelPayload } from '../../types/channel.ts'
import { Gateway, GatewayEventHandler } from '../index.ts'
export const channelUpdate: GatewayEventHandler = async (
gateway: Gateway,
d: ChannelPayload
) => {
const oldChannel: Channel | undefined = await gateway.client.channels.get(d.id)
const oldChannel = await gateway.client.channels.get(d.id)
await gateway.client.channels.set(d.id, d)
const newChannel: Channel = (await gateway.client.channels.get(d.id) as unknown) as Channel
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const newChannel = (await gateway.client.channels.get(d.id)) as Channel
if (oldChannel !== undefined) {
// (DjDeveloperr): Already done by ChannelsManager. I'll recheck later

View file

@ -2,7 +2,7 @@ import { Gateway, GatewayEventHandler } from '../index.ts'
import { Guild } from '../../structures/guild.ts'
import { GuildMemberUpdatePayload } from '../../types/gateway.ts'
import { MemberPayload } from '../../types/guild.ts'
import { Member } from "../../structures/member.ts"
import { Member } from '../../structures/member.ts'
export const guildMemberUpdate: GatewayEventHandler = async (
gateway: Gateway,
@ -26,7 +26,7 @@ export const guildMemberUpdate: GatewayEventHandler = async (
const newMember = await guild.members.get(d.user.id)
if (member !== undefined)
gateway.client.emit('guildMemberUpdate', member, (newMember as unknown) as Member)
gateway.client.emit('guildMemberUpdate', member, newMember as Member)
else {
gateway.client.emit('guildMemberUpdateUncached', newMember)
}

View file

@ -1,7 +1,7 @@
import { Gateway, GatewayEventHandler } from '../index.ts'
import { Guild } from '../../structures/guild.ts'
import { GuildRoleCreatePayload } from "../../types/gateway.ts"
import { Role } from "../../structures/role.ts"
import { GuildRoleCreatePayload } from '../../types/gateway.ts'
import { Role } from '../../structures/role.ts'
export const guildRoleCreate: GatewayEventHandler = async (
gateway: Gateway,
@ -12,6 +12,6 @@ export const guildRoleCreate: GatewayEventHandler = async (
if (guild === undefined) return
await guild.roles.set(d.role.id, d.role)
const role = await guild.roles.get(d.role.id)
gateway.client.emit('guildRoleCreate', (role as unknown) as Role)
}
const role = (await guild.roles.get(d.role.id)) as Role
gateway.client.emit('guildRoleCreate', role)
}

View file

@ -1,7 +1,7 @@
import { Gateway, GatewayEventHandler } from '../index.ts'
import { Guild } from '../../structures/guild.ts'
import { GuildRoleUpdatePayload } from "../../types/gateway.ts"
import { Role } from "../../structures/role.ts"
import { GuildRoleUpdatePayload } from '../../types/gateway.ts'
import { Role } from '../../structures/role.ts'
export const guildRoleUpdate: GatewayEventHandler = async (
gateway: Gateway,
@ -13,10 +13,11 @@ export const guildRoleUpdate: GatewayEventHandler = async (
const role = await guild.roles.get(d.role.id)
await guild.roles.set(d.role.id, d.role)
const newRole = await guild.roles.get(d.role.id)
const newRole = (await guild.roles.get(d.role.id)) as Role
// Shouldn't happen either
if(role === undefined) return gateway.client.emit('guildRoleUpdateUncached', newRole)
if (role === undefined)
return gateway.client.emit('guildRoleUpdateUncached', newRole)
gateway.client.emit('guildRoleUpdate', role, (newRole as unknown) as Role)
}
gateway.client.emit('guildRoleUpdate', role, newRole)
}

View file

@ -1,6 +1,6 @@
import { Member } from "../../structures/member.ts"
import { TextChannel } from "../../structures/textChannel.ts"
import { TypingStartPayload } from "../../types/gateway.ts"
import { Member } from '../../structures/member.ts'
import { TextChannel } from '../../structures/textChannel.ts'
import { TypingStartPayload } from '../../types/gateway.ts'
import { Gateway, GatewayEventHandler } from '../index.ts'
// TODO: Do we need to add uncached events here?
@ -11,13 +11,29 @@ export const typingStart: GatewayEventHandler = async (
const user = await gateway.client.users.get(d.user_id)
if (user === undefined) return console.log('user not cached')
const channel = await gateway.client.channels.get(d.channel_id)
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const channel = (await gateway.client.channels.get(
d.channel_id
)) as TextChannel
if (channel === undefined) return console.log(`channel not cached`)
const guild = d.guild_id !== undefined ? await gateway.client.guilds.get(d.guild_id) : undefined
if(guild === undefined && d.guild_id !== undefined) return console.log('guild not cached')
const guild =
d.guild_id !== undefined
? await gateway.client.guilds.get(d.guild_id)
: undefined
if (guild === undefined && d.guild_id !== undefined)
return console.log('guild not cached')
const member = d.member !== undefined && guild !== undefined ? new Member(gateway.client, d.member, user, guild) : undefined
const member =
d.member !== undefined && guild !== undefined
? new Member(gateway.client, d.member, user, guild)
: undefined
gateway.client.emit('typingStart', user, (channel as unknown) as TextChannel, new Date(d.timestamp), guild !== undefined && member !== undefined ? { guild, member } : undefined)
gateway.client.emit(
'typingStart',
user,
channel,
new Date(d.timestamp),
guild !== undefined && member !== undefined ? { guild, member } : undefined
)
}

View file

@ -1,5 +1,5 @@
import { User } from "../../structures/user.ts"
import { UserPayload } from "../../types/user.ts"
import { User } from '../../structures/user.ts'
import { UserPayload } from '../../types/user.ts'
import { Gateway, GatewayEventHandler } from '../index.ts'
export const userUpdate: GatewayEventHandler = async (
@ -8,7 +8,8 @@ export const userUpdate: GatewayEventHandler = async (
) => {
const oldUser: User | undefined = await gateway.client.users.get(d.id)
await gateway.client.users.set(d.id, d)
const newUser: User = (await gateway.client.users.get(d.id) as unknown) as User
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const newUser = (await gateway.client.users.get(d.id)) as User
if (oldUser !== undefined) {
gateway.client.emit('userUpdate', oldUser, newUser)

View file

@ -1,5 +1,11 @@
import { Client } from '../models/client.ts'
import { GuildFeatures, GuildIntegrationPayload, GuildPayload, IntegrationAccountPayload, IntegrationExpireBehavior } from '../types/guild.ts'
import {
GuildFeatures,
GuildIntegrationPayload,
GuildPayload,
IntegrationAccountPayload,
IntegrationExpireBehavior
} from '../types/guild.ts'
import { PresenceUpdatePayload } from '../types/gateway.ts'
import { Base } from './base.ts'
import { RolesManager } from '../managers/roles.ts'
@ -7,10 +13,10 @@ import { GuildChannelsManager } from '../managers/guildChannels.ts'
import { MembersManager } from '../managers/members.ts'
import { Role } from './role.ts'
import { GuildEmojisManager } from '../managers/guildEmojis.ts'
import { Member } from "./member.ts"
import { User } from "./user.ts"
import { Application } from "./application.ts"
import { GUILD_INTEGRATIONS } from "../types/endpoint.ts"
import { Member } from './member.ts'
import { User } from './user.ts'
import { Application } from './application.ts'
import { GUILD_INTEGRATIONS } from '../types/endpoint.ts'
import { GuildVoiceStatesManager } from "../managers/guildVoiceStates.ts"
export class Guild extends Base {
@ -67,8 +73,8 @@ export class Guild extends Base {
this.members = new MembersManager(this.client, this)
this.voiceStates = new GuildVoiceStatesManager(client, this)
this.channels = new GuildChannelsManager(
this.client,
this.client.channels,
this.client,
this.client.channels,
this
)
this.roles = new RolesManager(this.client, this)
@ -217,17 +223,20 @@ export class Guild extends Base {
}
async getEveryoneRole (): Promise<Role> {
return (await this.roles.get(this.id) as unknown) as Role
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
return (await this.roles.get(this.id)) as Role
}
async me(): Promise<Member> {
async me (): Promise<Member> {
const get = await this.members.get(this.client.user?.id as string)
if (get === undefined) throw new Error('Guild#me is not cached')
return get
}
async fetchIntegrations(): Promise<GuildIntegration[]> {
const raw = await this.client.rest.get(GUILD_INTEGRATIONS(this.id)) as GuildIntegrationPayload[]
async fetchIntegrations (): Promise<GuildIntegration[]> {
const raw = (await this.client.rest.get(
GUILD_INTEGRATIONS(this.id)
)) as GuildIntegrationPayload[]
return raw.map(e => new GuildIntegration(this.client, e))
}
}
@ -249,11 +258,11 @@ export class GuildIntegration extends Base {
revoked?: boolean
application?: Application
constructor(client: Client, data: GuildIntegrationPayload) {
constructor (client: Client, data: GuildIntegrationPayload) {
super(client, data)
this.id = data.id
this.name= data.name
this.name = data.name
this.type = data.type
this.enabled = data.enabled
this.syncing = data.syncing
@ -261,11 +270,15 @@ export class GuildIntegration extends Base {
this.enableEmoticons = data.enable_emoticons
this.expireBehaviour = data.expire_behaviour
this.expireGracePeriod = data.expire_grace_period
this.user = data.user !== undefined ? new User(client, data.user) : undefined
this.user =
data.user !== undefined ? new User(client, data.user) : undefined
this.account = data.account
this.syncedAt = data.synced_at
this.subscriberCount = data.subscriber_count
this.revoked = data.revoked
this.application = data.application !== undefined ? new Application(client, data.application) : undefined
this.application =
data.application !== undefined
? new Application(client, data.application)
: undefined
}
}
}

View file

@ -1,13 +1,16 @@
import { DISCORD_API_URL, DISCORD_API_VERSION } from "../consts/urlsAndVersions.ts"
import {
DISCORD_API_URL,
DISCORD_API_VERSION
} from '../consts/urlsAndVersions.ts'
import { Client } from '../models/client.ts'
import { RESTManager } from "../models/rest.ts"
import { MessageOption } from "../types/channel.ts"
import { RESTManager } from '../models/rest.ts'
import { MessageOption } from '../types/channel.ts'
import { UserPayload } from '../types/user.ts'
import { WebhookPayload } from '../types/webhook.ts'
import { Embed } from "./embed.ts"
import { Message } from "./message.ts"
import { TextChannel } from "./textChannel.ts"
import { User } from "./user.ts"
import { Embed } from './embed.ts'
import { Message } from './message.ts'
import { TextChannel } from './textChannel.ts'
import { User } from './user.ts'
import { fetchAuto } from 'https://raw.githubusercontent.com/DjDeveloperr/fetch-base64/main/mod.ts'
export interface WebhookMessageOptions extends MessageOption {
@ -42,17 +45,21 @@ export class Webhook {
applicationID?: string
rest: RESTManager
get url(): string {
get url (): string {
return `${DISCORD_API_URL}/v${DISCORD_API_VERSION}/webhooks/${this.id}/${this.token}`
}
constructor(data: WebhookPayload, client?: Client, rest?: RESTManager) {
constructor (data: WebhookPayload, client?: Client, rest?: RESTManager) {
this.id = data.id
this.type = data.type
this.channelID = data.channel_id
this.guildID = data.guild_id
this.user = data.user === undefined || client === undefined ? undefined : new User(client, data.user)
if (data.user !== undefined && client === undefined) this.userRaw = data.user
this.user =
data.user === undefined || client === undefined
? undefined
: new User(client, data.user)
if (data.user !== undefined && client === undefined)
this.userRaw = data.user
this.name = data.name
this.avatar = data.avatar
this.token = data.token
@ -63,13 +70,17 @@ export class Webhook {
else this.rest = new RESTManager()
}
private fromPayload(data: WebhookPayload): Webhook {
private fromPayload (data: WebhookPayload): Webhook {
this.id = data.id
this.type = data.type
this.channelID = data.channel_id
this.guildID = data.guild_id
this.user = data.user === undefined || this.client === undefined ? undefined : new User(this.client, data.user)
if (data.user !== undefined && this.client === undefined) this.userRaw = data.user
this.user =
data.user === undefined || this.client === undefined
? undefined
: new User(this.client, data.user)
if (data.user !== undefined && this.client === undefined)
this.userRaw = data.user
this.name = data.name
this.avatar = data.avatar
this.token = data.token
@ -79,8 +90,11 @@ export class Webhook {
}
/** Send a Message through Webhook. */
async send(text?: string | AllWebhookMessageOptions, option?: AllWebhookMessageOptions): Promise<Message> {
if (typeof text === "object") {
async send (
text?: string | AllWebhookMessageOptions,
option?: AllWebhookMessageOptions
): Promise<Message> {
if (typeof text === 'object') {
option = text
text = undefined
}
@ -89,31 +103,47 @@ export class Webhook {
throw new Error('Either text or option is necessary.')
}
if (option instanceof Embed) option = {
embeds: [ option ],
}
if (option instanceof Embed)
option = {
embeds: [option]
}
const payload: any = {
content: text,
embeds: (option as WebhookMessageOptions)?.embed !== undefined ? [ (option as WebhookMessageOptions).embed ] : ((option as WebhookMessageOptions)?.embeds !== undefined ? (option as WebhookMessageOptions).embeds : undefined),
embeds:
(option as WebhookMessageOptions)?.embed !== undefined
? [(option as WebhookMessageOptions).embed]
: (option as WebhookMessageOptions)?.embeds !== undefined
? (option as WebhookMessageOptions).embeds
: undefined,
file: (option as WebhookMessageOptions)?.file,
tts: (option as WebhookMessageOptions)?.tts,
allowed_mentions: (option as WebhookMessageOptions)?.allowedMentions
}
if ((option as WebhookMessageOptions).name !== undefined) {
if ((option as WebhookMessageOptions)?.name !== undefined) {
payload.username = (option as WebhookMessageOptions)?.name
}
if ((option as WebhookMessageOptions).avatar !== undefined) {
if ((option as WebhookMessageOptions)?.avatar !== undefined) {
payload.avatar = (option as WebhookMessageOptions)?.avatar
}
if (payload.embeds !== undefined && payload.embeds instanceof Array && payload.embeds.length > 10) throw new Error(`Cannot send more than 10 embeds through Webhook`)
if (
payload.embeds !== undefined &&
payload.embeds instanceof Array &&
payload.embeds.length > 10
)
throw new Error(`Cannot send more than 10 embeds through Webhook`)
const resp = await this.rest.post(this.url + '?wait=true', payload)
const res = new Message(this.client as Client, resp, (this as unknown) as TextChannel, (this as unknown) as User)
const res = new Message(
this.client as Client,
resp,
(this as unknown) as TextChannel,
(this as unknown) as User
)
await res.mentions.fromPayload(resp)
return res
}
@ -122,12 +152,13 @@ export class Webhook {
* Create a Webhook object from URL
* @param url URL of the Webhook
* @param client Client (bot) object, if any.
*/
static async fromURL(url: string | URL, client?: Client): Promise<Webhook> {
*/
static async fromURL (url: string | URL, client?: Client): Promise<Webhook> {
const rest = client !== undefined ? client.rest : new RESTManager()
const raw = await rest.get(typeof url === 'string' ? url : url.toString())
if (typeof raw !== 'object') throw new Error(`Failed to load Webhook from URL: ${url}`)
if (typeof raw !== 'object')
throw new Error(`Failed to load Webhook from URL: ${url}`)
const webhook = new Webhook(raw, client, rest)
return webhook
@ -137,9 +168,14 @@ export class Webhook {
* Edit the Webhook name, avatar, or channel (requires authentication).
* @param options Options to edit the Webhook.
*/
async edit(options: WebhookEditOptions): Promise<Webhook> {
if (options.channelID !== undefined && this.rest.client === undefined) throw new Error('Authentication is required for editing Webhook Channel')
if (options.avatar !== undefined && (options.avatar.startsWith('http:') || options.avatar.startsWith('https:'))) {
async edit (options: WebhookEditOptions): Promise<Webhook> {
if (options.channelID !== undefined && this.rest.client === undefined)
throw new Error('Authentication is required for editing Webhook Channel')
if (
options.avatar !== undefined &&
(options.avatar.startsWith('http:') ||
options.avatar.startsWith('https:'))
) {
options.avatar = await fetchAuto(options.avatar)
}
@ -150,7 +186,7 @@ export class Webhook {
}
/** Delete the Webhook. */
async delete(): Promise<boolean> {
async delete (): Promise<boolean> {
const resp = await this.rest.delete(this.url, undefined, 0, undefined, true)
if (resp.response.status !== 204) return false
else return true