feat(jsdoc): pretty much done
This commit is contained in:
parent
62ed3ac9f7
commit
d1aba4a981
27 changed files with 65 additions and 84 deletions
2
mod.ts
2
mod.ts
|
@ -22,7 +22,7 @@ export { MessageReactionsManager } from './src/managers/messageReactions.ts'
|
|||
export { ReactionUsersManager } from './src/managers/reactionUsers.ts'
|
||||
export { MessagesManager } from './src/managers/messages.ts'
|
||||
export { RolesManager } from './src/managers/roles.ts'
|
||||
export { UserManager } from './src/managers/users.ts'
|
||||
export { UsersManager } from './src/managers/users.ts'
|
||||
export { Application } from './src/structures/application.ts'
|
||||
export { ImageURL } from './src/structures/cdn.ts'
|
||||
export { Channel } from './src/structures/channel.ts'
|
||||
|
|
|
@ -26,6 +26,7 @@ export interface RequestMembersOptions {
|
|||
|
||||
/**
|
||||
* Handles Discord gateway connection.
|
||||
*
|
||||
* You should not use this and rather use Client class.
|
||||
*/
|
||||
class Gateway {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { Collection } from '../utils/collection.ts'
|
||||
|
||||
/**
|
||||
* Managers handle caching data. And also some REST Methods as required.
|
||||
*
|
||||
* You should not be making Managers yourself.
|
||||
*/
|
||||
export class BaseManager<T, T2> {
|
||||
client: Client
|
||||
/** Cache Name or Key used to differentiate caches */
|
||||
|
@ -14,30 +19,36 @@ export class BaseManager<T, T2> {
|
|||
this.DataType = DataType
|
||||
}
|
||||
|
||||
/** Get raw value from a cache (payload) */
|
||||
async _get(key: string): Promise<T | undefined> {
|
||||
return this.client.cache.get(this.cacheName, key)
|
||||
}
|
||||
|
||||
/** Get a value from Cache */
|
||||
async get(key: string): Promise<T2 | undefined> {
|
||||
const raw = await this._get(key)
|
||||
if (raw === undefined) return
|
||||
return new this.DataType(this.client, raw)
|
||||
}
|
||||
|
||||
/** Set a value to Cache */
|
||||
async set(key: string, value: T): Promise<any> {
|
||||
return this.client.cache.set(this.cacheName, key, value)
|
||||
}
|
||||
|
||||
/** Delete a key from Cache */
|
||||
async delete(key: string): Promise<boolean> {
|
||||
return this.client.cache.delete(this.cacheName, key)
|
||||
}
|
||||
|
||||
/** Get an Array of values from Cache */
|
||||
async array(): Promise<undefined | T2[]> {
|
||||
let arr = await (this.client.cache.array(this.cacheName) as T[])
|
||||
if (arr === undefined) arr = []
|
||||
return arr.map((e) => new this.DataType(this.client, e)) as any
|
||||
}
|
||||
|
||||
/** Get a Collection of values from Cache */
|
||||
async collection(): Promise<Collection<string, T2>> {
|
||||
const arr = await this.array()
|
||||
if (arr === undefined) return new Collection()
|
||||
|
@ -49,6 +60,7 @@ export class BaseManager<T, T2> {
|
|||
return collection
|
||||
}
|
||||
|
||||
/** Delete everything from Cache */
|
||||
flush(): any {
|
||||
return this.client.cache.deleteCache(this.cacheName)
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ import { Client } from '../models/client.ts'
|
|||
import { Collection } from '../utils/collection.ts'
|
||||
import { BaseManager } from './base.ts'
|
||||
|
||||
/** Child Managers validate data from their parents i.e. from Managers */
|
||||
export class BaseChildManager<T, T2> {
|
||||
client: Client
|
||||
/** Parent Manager */
|
||||
parent: BaseManager<T, T2>
|
||||
|
||||
constructor(client: Client, parent: BaseManager<T, T2>) {
|
||||
|
@ -32,8 +34,8 @@ export class BaseChildManager<T, T2> {
|
|||
if (arr === undefined) return new Collection()
|
||||
const collection = new Collection()
|
||||
for (const elem of arr) {
|
||||
// @ts-expect-error
|
||||
collection.set(elem.id, elem)
|
||||
// any is required here. Else you would need ts-ignore or expect-error.
|
||||
collection.set((elem as any).id, elem)
|
||||
}
|
||||
return collection
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ export class ChannelsManager extends BaseManager<ChannelPayload, Channel> {
|
|||
return result
|
||||
}
|
||||
|
||||
/** Fetch a Channel by ID, cache it, resolve it */
|
||||
async fetch<T = Channel>(id: string): Promise<T> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
this.client.rest
|
||||
|
|
|
@ -20,6 +20,7 @@ export class EmojisManager extends BaseManager<EmojiPayload, Emoji> {
|
|||
return emoji
|
||||
}
|
||||
|
||||
/** Fetch an Emoji by Guild ID and Emoji ID, cache it and resolve it */
|
||||
async fetch(guildID: string, id: string): Promise<Emoji> {
|
||||
return await new Promise((resolve, reject) => {
|
||||
this.client.rest
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
|
||||
/**
|
||||
* Cache Manager used for Caching values related to Gateway connection
|
||||
*
|
||||
* In case of Redis, this will persistently cache session ID and seq for fast resumes.
|
||||
*/
|
||||
export class GatewayCache {
|
||||
client: Client
|
||||
cacheName: string = 'discord_gateway_cache'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
import { MessageReaction } from '../structures/messageReaction.ts'
|
||||
import { UserManager } from './users.ts'
|
||||
import { UsersManager } from './users.ts'
|
||||
|
||||
export class ReactionUsersManager extends UserManager {
|
||||
export class ReactionUsersManager extends UsersManager {
|
||||
reaction: MessageReaction
|
||||
|
||||
constructor(client: Client, reaction: MessageReaction) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { USER } from '../types/endpoint.ts'
|
|||
import { UserPayload } from '../types/user.ts'
|
||||
import { BaseManager } from './base.ts'
|
||||
|
||||
export class UserManager extends BaseManager<UserPayload, User> {
|
||||
export class UsersManager extends BaseManager<UserPayload, User> {
|
||||
constructor(client: Client) {
|
||||
super(client, 'users', User)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { Gateway } from '../gateway/index.ts'
|
|||
import { RESTManager } from './rest.ts'
|
||||
import EventEmitter from 'https://deno.land/std@0.74.0/node/events.ts'
|
||||
import { DefaultCacheAdapter, ICacheAdapter } from './cacheAdapter.ts'
|
||||
import { UserManager } from '../managers/users.ts'
|
||||
import { UsersManager } from '../managers/users.ts'
|
||||
import { GuildManager } from '../managers/guilds.ts'
|
||||
import { ChannelsManager } from '../managers/channels.ts'
|
||||
import { ClientPresence } from '../structures/presence.ts'
|
||||
|
@ -72,7 +72,7 @@ export class Client extends EventEmitter {
|
|||
/** Whether to fetch Uncached Message of Reaction or not? */
|
||||
fetchUncachedReactions: boolean = false
|
||||
|
||||
users: UserManager = new UserManager(this)
|
||||
users: UsersManager = new UsersManager(this)
|
||||
guilds: GuildManager = new GuildManager(this)
|
||||
channels: ChannelsManager = new ChannelsManager(this)
|
||||
emojis: EmojisManager = new EmojisManager(this)
|
||||
|
|
|
@ -1,63 +1,9 @@
|
|||
import { Client } from '../models/client.ts'
|
||||
|
||||
interface IInit {
|
||||
useCache?: boolean
|
||||
endpoint: (...restURLfuncArgs: string[]) => string
|
||||
restURLfuncArgs: string[]
|
||||
}
|
||||
|
||||
export class Base {
|
||||
client: Client
|
||||
static cacheName?: string
|
||||
propertyConverterOverride: { [k: string]: string } = {}
|
||||
static useCache?: boolean = true
|
||||
static restFunc?: (...restURLfuncArgs: string[]) => string
|
||||
|
||||
constructor(client: Client, _data?: any) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
static async autoInit(
|
||||
client: Client,
|
||||
{ useCache, endpoint, restURLfuncArgs }: IInit
|
||||
): Promise<any> {
|
||||
this.useCache = useCache
|
||||
const cacheID = restURLfuncArgs.join(':')
|
||||
if (this.useCache !== undefined) {
|
||||
const cached = await client.cache.get(
|
||||
this.cacheName ?? this.name,
|
||||
cacheID
|
||||
)
|
||||
if (cached !== undefined) {
|
||||
return cached
|
||||
}
|
||||
}
|
||||
|
||||
const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs))
|
||||
|
||||
return new this(client, jsonParsed)
|
||||
}
|
||||
|
||||
async refreshFromAPI(
|
||||
client: Client,
|
||||
{ endpoint, restURLfuncArgs }: IInit
|
||||
): Promise<this> {
|
||||
const oldOne = Object.assign(Object.create(this), this)
|
||||
|
||||
const jsonParsed = await client.rest.get(endpoint(...restURLfuncArgs))
|
||||
|
||||
this.readFromData(jsonParsed)
|
||||
|
||||
return oldOne
|
||||
}
|
||||
|
||||
refreshFromData(data: { [k: string]: any }): this {
|
||||
const oldOne = Object.assign(Object.create(this), this)
|
||||
this.readFromData(data)
|
||||
return oldOne
|
||||
}
|
||||
|
||||
protected readFromData(data: { [k: string]: any }): void {}
|
||||
|
||||
// toJSON() {}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { ImageFormats, ImageSize } from '../types/cdn.ts'
|
||||
|
||||
/** Function to get Image URL from a resource on Discord CDN */
|
||||
export const ImageURL = (
|
||||
url: string,
|
||||
format: ImageFormats,
|
||||
size?: ImageSize | 128
|
||||
format: ImageFormats | undefined = 'png',
|
||||
size: ImageSize | undefined = 128
|
||||
): string => {
|
||||
size = size === undefined ? 128 : size
|
||||
if (url.includes('a_')) {
|
||||
return `${url}.gif?size=${size}`
|
||||
} else return `${url}.${format}?size=${size}`
|
||||
return `${url}.${format === undefined ? 'gif' : format}?size=${size}`
|
||||
} else return `${url}.${format === 'gif' ? 'png' : format}?size=${size}`
|
||||
}
|
||||
|
|
|
@ -14,12 +14,9 @@ export class Channel extends Base {
|
|||
super(client, data)
|
||||
this.type = data.type
|
||||
this.id = data.id
|
||||
// TODO: Cache in Gateway Event Code
|
||||
// this.client.channels.set(this.id, data)
|
||||
}
|
||||
|
||||
protected readFromData(data: ChannelPayload): void {
|
||||
super.readFromData(data)
|
||||
this.type = data.type ?? this.type
|
||||
this.id = data.id ?? this.id
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ export class Emoji extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: EmojiPayload): void {
|
||||
super.readFromData(data)
|
||||
this.id = data.id ?? this.id
|
||||
this.name = data.name ?? this.name
|
||||
this.roles = data.roles ?? this.roles
|
||||
|
@ -47,11 +46,6 @@ export class Emoji extends Base {
|
|||
this.managed = data.managed ?? this.managed
|
||||
this.animated = data.animated ?? this.animated
|
||||
this.available = data.available ?? this.available
|
||||
if (data.user !== undefined && data.user.id !== this.user?.id) {
|
||||
User.autoInit(this.client, {
|
||||
endpoint: USER,
|
||||
restURLfuncArgs: [data.user.id]
|
||||
}).then((user) => (this.user = user))
|
||||
}
|
||||
if (data.user !== undefined) this.user = new User(this.client, data.user)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,7 +220,6 @@ export class Guild extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: GuildPayload): void {
|
||||
super.readFromData(data)
|
||||
this.id = data.id ?? this.id
|
||||
this.unavailable = data.unavailable ?? this.unavailable
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ export class Invite extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: InvitePayload): void {
|
||||
super.readFromData(data)
|
||||
this.code = data.code ?? this.code
|
||||
this.guild = data.guild ?? this.guild
|
||||
this.channel = data.channel ?? this.channel
|
||||
|
|
|
@ -57,7 +57,6 @@ export class Member extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: MemberPayload): void {
|
||||
super.readFromData(data.user)
|
||||
this.nick = data.nick ?? this.nick
|
||||
this.joinedAt = data.joined_at ?? this.joinedAt
|
||||
this.premiumSince = data.premium_since ?? this.premiumSince
|
||||
|
|
|
@ -82,7 +82,6 @@ export class Message extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: MessagePayload): void {
|
||||
super.readFromData(data)
|
||||
this.channelID = data.channel_id ?? this.channelID
|
||||
this.guildID = data.guild_id ?? this.guildID
|
||||
this.content = data.content ?? this.content
|
||||
|
|
|
@ -34,7 +34,6 @@ export class Role extends Base {
|
|||
}
|
||||
|
||||
protected readFromData(data: RolePayload): void {
|
||||
super.readFromData(data)
|
||||
this.name = data.name ?? this.name
|
||||
this.color = data.color ?? this.color
|
||||
this.hoist = data.hoist ?? this.hoist
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
export class Snowflake {
|
||||
snowflake: bigint
|
||||
id: string
|
||||
|
||||
constructor(id: string) {
|
||||
this.snowflake = BigInt.asUintN(64, BigInt(id))
|
||||
this.id = id
|
||||
}
|
||||
|
||||
get snowflake(): bigint {
|
||||
return BigInt.asUintN(64, BigInt(this.id))
|
||||
}
|
||||
|
||||
get timestamp(): string {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Ported from https://github.com/discordjs/discord.js/blob/master/src/util/BitField.js
|
||||
export type BitFieldResolvable = number | BitField | string | BitField[]
|
||||
|
||||
/** Bit Field utility to work with Bits and Flags */
|
||||
export class BitField {
|
||||
flags: { [name: string]: number } = {}
|
||||
bitfield: number
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { Client } from '../models/client.ts'
|
||||
|
||||
/** Gets Discord Build info for self-bot support */
|
||||
export const getBuildInfo = (
|
||||
client: Client
|
||||
): {
|
||||
|
|
|
@ -1,25 +1,32 @@
|
|||
/** Enhanced Map with various utility functions */
|
||||
export class Collection<K = string, V = any> extends Map<K, V> {
|
||||
/** Set a key to value in Collection */
|
||||
set(key: K, value: V): this {
|
||||
return super.set(key, value)
|
||||
}
|
||||
|
||||
/** Get Array of values in Collection */
|
||||
array(): V[] {
|
||||
return [...this.values()]
|
||||
}
|
||||
|
||||
/** Get first value in Collection */
|
||||
first(): V {
|
||||
return this.values().next().value
|
||||
}
|
||||
|
||||
/** Get last value in Collection */
|
||||
last(): V {
|
||||
return [...this.values()][this.size - 1]
|
||||
}
|
||||
|
||||
/** Get a random value from Collection */
|
||||
random(): V {
|
||||
const arr = [...this.values()]
|
||||
return arr[Math.floor(Math.random() * arr.length)]
|
||||
}
|
||||
|
||||
/** Find a value from Collection using callback */
|
||||
find(callback: (value: V, key: K) => boolean): V | undefined {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key) as V
|
||||
|
@ -28,6 +35,7 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
/** Filter out the Collection using callback */
|
||||
filter(callback: (value: V, key: K) => boolean): Collection<K, V> {
|
||||
const relevant = new Collection<K, V>()
|
||||
this.forEach((value, key) => {
|
||||
|
@ -36,6 +44,7 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
return relevant
|
||||
}
|
||||
|
||||
/** Map the collection */
|
||||
map<T>(callback: (value: V, key: K) => T): T[] {
|
||||
const results = []
|
||||
for (const key of this.keys()) {
|
||||
|
@ -45,6 +54,7 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
return results
|
||||
}
|
||||
|
||||
/** Check if any of the values/keys in Collection satisfy callback */
|
||||
some(callback: (value: V, key: K) => boolean): boolean {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key) as V
|
||||
|
@ -53,6 +63,7 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
return false
|
||||
}
|
||||
|
||||
/** Check if every value/key in Collection satisfy callback */
|
||||
every(callback: (value: V, key: K) => boolean): boolean {
|
||||
for (const key of this.keys()) {
|
||||
const value = this.get(key) as V
|
||||
|
@ -61,6 +72,7 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
return true
|
||||
}
|
||||
|
||||
/** Reduce the Collection to a single value */
|
||||
reduce<T>(
|
||||
callback: (accumulator: T, value: V, key: K) => T,
|
||||
initialValue?: T
|
||||
|
@ -75,10 +87,12 @@ export class Collection<K = string, V = any> extends Map<K, V> {
|
|||
return accumulator
|
||||
}
|
||||
|
||||
/** Create a Collection from an Object */
|
||||
static fromObject<V>(object: { [key: string]: V }): Collection<string, V> {
|
||||
return new Collection<string, V>(Object.entries(object))
|
||||
}
|
||||
|
||||
/** Convert Collection to an object */
|
||||
toObject(): { [name: string]: V } {
|
||||
return Object.fromEntries(this)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/** Delay by `ms` miliseconds */
|
||||
export const delay = async (ms: number): Promise<true> =>
|
||||
await new Promise((resolve, reject) => {
|
||||
setTimeout(() => resolve(true), ms)
|
||||
|
|
|
@ -45,6 +45,7 @@ export type EveryChannelPayloadTypes =
|
|||
| GuildVoiceChannelPayload
|
||||
| EveryTextChannelPayloadTypes
|
||||
|
||||
/** Get appropriate Channel structure by its type */
|
||||
const getChannelByType = (
|
||||
client: Client,
|
||||
data: EveryChannelPayloadTypes,
|
||||
|
|
|
@ -2,7 +2,7 @@ import { GatewayIntents } from '../types/gateway.ts'
|
|||
|
||||
export type PriviligedIntents = 'GUILD_MEMBERS' | 'GUILD_PRESENCES'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
/** Utility class for handling Gateway Intents */
|
||||
export class Intents {
|
||||
static NonPriviliged: number[] = [
|
||||
GatewayIntents.GUILD_MESSAGES,
|
||||
|
@ -38,6 +38,7 @@ export class Intents {
|
|||
|
||||
static None: number[] = [...Intents.NonPriviliged]
|
||||
|
||||
/** Create an Array of Intents easily passing Intents you're priviliged for and disable the ones you don't need */
|
||||
static create(
|
||||
priviliged?: PriviligedIntents[],
|
||||
disable?: number[]
|
||||
|
|
|
@ -8,6 +8,7 @@ export type PermissionResolvable =
|
|||
| Permissions
|
||||
| PermissionResolvable[]
|
||||
|
||||
/** Manages Discord's Bit-based Permissions */
|
||||
export class Permissions extends BitField {
|
||||
static DEFAULT = 104324673
|
||||
static ALL = Object.values(PermissionFlags).reduce((all, p) => all | p, 0)
|
||||
|
|
Loading…
Reference in a new issue