diff --git a/src/structures/base.ts b/src/structures/base.ts index 9edc83d..503b992 100644 --- a/src/structures/base.ts +++ b/src/structures/base.ts @@ -1,8 +1,38 @@ import { Client } from '../models/client.ts' +import * as cache from '../models/cache.ts' export class Base { client: Client - constructor (client: Client) { + static useCache = true + static cacheName: string + static cacheArgIndex = 0 + static restFunc: (...restArgs: string[]) => string + + constructor (client: Client, _data?: any) { this.client = client } + + static async autoInit (client: Client, ...restURLfuncArgs: string[]) { + if (this.useCache) { + const cached = cache.get( + this.cacheName, + restURLfuncArgs[this.cacheArgIndex] + ) + if (cached !== undefined && cached instanceof this) { + return cached + } + } + + const resp = await fetch(this.restFunc(...restURLfuncArgs), { + headers: { + Authorization: `Bot ${client.token}` + } + }) + + const jsonParsed = await resp.json() + const initialized = new this(client, jsonParsed) + cache.set(this.cacheName, restURLfuncArgs[this.cacheArgIndex], initialized) + + return initialized + } } diff --git a/src/structures/channel.ts b/src/structures/channel.ts index 80c5878..c520d6a 100644 --- a/src/structures/channel.ts +++ b/src/structures/channel.ts @@ -14,12 +14,14 @@ import { CategoryChannel } from './guildCategoryChannel.ts' import { VoiceChannel } from './guildVoiceChannel.ts' import { NewsChannel } from './guildnewsChannel.ts' import { DMChannel } from './dmChannel.ts' -import { GroupChannel } from './groupChannel.ts' +import { GroupDMChannel } from './groupChannel.ts' import { TextChannel } from './textChannel.ts' export class Channel extends Base { type: ChannelTypes id: string + static cacheName = 'channel' + static cacheArgIndex = 0 constructor (client: Client, data: ChannelPayload) { super(client) @@ -31,6 +33,10 @@ export class Channel extends Base { return `<#${this.id}>` } + static async autoInit (client: Client, channelID: string) { + return super.autoInit(client, channelID) + } + static from ( data: | GuildChannelCategoryPayload @@ -53,7 +59,7 @@ export class Channel extends Base { case ChannelTypes.DM: return new DMChannel(client, data as DMChannelPayload) case ChannelTypes.GROUP_DM: - return new GroupChannel(client, data as GroupDMChannelPayload) + return new GroupDMChannel(client, data as GroupDMChannelPayload) } } } diff --git a/src/structures/embed.ts b/src/structures/embed.ts index aeee780..8092dcf 100644 --- a/src/structures/embed.ts +++ b/src/structures/embed.ts @@ -28,5 +28,36 @@ export class Embed extends Base { fields?: EmbedField[] constructor (client: Client, data: EmbedPayload) { super(client) + this.title = data.title + this.type = data.type + this.description = data.description + this.url = data.url + this.timestamp = data.timestamp + this.color = data.color + this.footer = data.footer + this.image = data.image + this.thumbnail = data.thumbnail + this.video = data.video + this.provider = data.provider + this.author = data.author + this.fields = data.fields + } + + toJSON () { + return { + title: this.title, + type: this.type, + description: this.description, + url: this.url, + timestamp: this.timestamp, + color: this.color, + footer: this.footer, + image: this.image, + thumbnail: this.thumbnail, + video: this.video, + provider: this.provider, + author: this.author, + fields: this.fields + } } } diff --git a/src/structures/groupChannel.ts b/src/structures/groupChannel.ts index 38ff8c2..8ffbb5f 100644 --- a/src/structures/groupChannel.ts +++ b/src/structures/groupChannel.ts @@ -2,7 +2,7 @@ import { Client } from '../models/client.ts' import { GroupDMChannelPayload } from '../types/channelTypes.ts' import { Channel } from './channel.ts' -export class GroupChannel extends Channel { +export class GroupDMChannel extends Channel { name: string icon?: string ownerID: string diff --git a/src/structures/guild.ts b/src/structures/guild.ts index 293aa0b..24767c1 100644 --- a/src/structures/guild.ts +++ b/src/structures/guild.ts @@ -109,7 +109,7 @@ export class Guild extends Base { } static async autoInit (client: Client, guildID: string) { - const cached = cache.get('guilds', guildID) + const cached = cache.get('guild', guildID) if (cached === undefined || !(cached instanceof Guild)) { const resp = await fetch(GUILD(guildID), { headers: { @@ -119,10 +119,68 @@ export class Guild extends Base { const guildParsed: GuildPayload = await resp.json() const newGuild = new Guild(client, guildParsed) - cache.set('guilds', guildID, newGuild) + cache.set('guild', guildID, newGuild) return newGuild } else { return cached } } + + async refresh () { + const resp = await fetch(GUILD(this.id), { + headers: { + Authorization: `Bot ${this.client.token}` + } + }) + + const guildParsed: GuildPayload = await resp.json() + /*for (const rawKey of Object.keys(guildParsed)) { + const _key: string[] = rawKey.split('_').map((v, i) => i === 0 ? v : v.substr(0, 1).toUpperCase() + v.substr(1)) + const key = _key.join('') + if (this.hasOwnProperty(key)) this[key] // fucking ts + }*/ + this.name = guildParsed.name + this.icon = guildParsed.icon + this.iconHash = guildParsed.icon_hash + this.splash = guildParsed.splash + this.discoverySplash = guildParsed.discovery_splash + this.owner = guildParsed.owner + this.ownerID = guildParsed.owner_id + this.permissions = guildParsed.permissions + this.region = guildParsed.region + this.afkTimeout = guildParsed.afk_timeout + this.afkChannelID = guildParsed.afk_channel_id + this.widgetEnabled = guildParsed.widget_enabled + this.widgetChannelID = guildParsed.widget_channel_id + this.verificationLevel = guildParsed.verification_level + this.defaultMessageNotifications = guildParsed.default_message_notifications + this.explicitContentFilter = guildParsed.explicit_content_filter + this.roles = guildParsed.roles + this.emojis = guildParsed.emojis + this.features = guildParsed.features + this.mfaLevel = guildParsed.mfa_level + this.systemChannelID = guildParsed.system_channel_id + this.systemChannelFlags = guildParsed.system_channel_flags + this.rulesChannelID = guildParsed.rules_channel_id + this.joinedAt = guildParsed.joined_at + this.large = guildParsed.large + this.unavailable = guildParsed.unavailable + this.memberCount = guildParsed.member_count + this.voiceStates = guildParsed.voice_states + this.members = guildParsed.members + this.channels = guildParsed.channels + this.presences = guildParsed.presences + this.maxPresences = guildParsed.max_presences + this.maxMembers = guildParsed.max_members + this.vanityURLCode = guildParsed.vanity_url_code + this.description = guildParsed.description + this.banner = guildParsed.banner + this.premiumTier = guildParsed.premium_tier + this.premiumSubscriptionCount = guildParsed.premium_subscription_count + this.preferredLocale = guildParsed.preferred_locale + this.publicUpdatesChannelID = guildParsed.public_updates_channel_id + this.maxVideoChannelUsers = guildParsed.max_video_channel_users + this.approximateNumberCount = guildParsed.approximate_number_count + this.approximatePresenceCount = guildParsed.approximate_presence_count + } } diff --git a/src/structures/guildChannel.ts b/src/structures/guildChannel.ts index fa39e88..213295b 100644 --- a/src/structures/guildChannel.ts +++ b/src/structures/guildChannel.ts @@ -1,6 +1,9 @@ import { Client } from '../models/client.ts' import { GuildChannelPayload, Overwrite } from '../types/channelTypes.ts' import { Channel } from './channel.ts' +import * as cache from '../models/cache.ts' +import { Guild } from './guild.ts' +import { GUILD_CHANNEL } from '../types/endpoint.ts' export class GuildChannel extends Channel { guildID: string @@ -19,4 +22,22 @@ export class GuildChannel extends Channel { this.nsfw = data.nsfw this.parentID = data.parent_id } + + static async autoInit (client: Client, guildID: string) { + const cached = cache.get('guildChannel', guildID) + if (cached === undefined || !(cached instanceof GuildChannel)) { + const resp = await fetch(GUILD_CHANNEL(guildID), { + headers: { + Authorization: `Bot ${client.token}` + } + }) + const guildChannelParsed: GuildChannelPayload = await resp.json() + + const newGuild = new GuildChannel(client, guildChannelParsed) + cache.set('guildChannel', guildID, newGuild) + return newGuild + } else { + return cached + } + } } diff --git a/src/structures/guildTextChannel.ts b/src/structures/guildTextChannel.ts index 14b3b79..5fe0075 100644 --- a/src/structures/guildTextChannel.ts +++ b/src/structures/guildTextChannel.ts @@ -1,7 +1,6 @@ import { Client } from '../models/client.ts' import { GuildChannel } from './guildChannel.ts' import { GuildTextChannelPayload } from '../types/channelTypes.ts' -import { User } from './user.ts' export class GuildTextChannel extends GuildChannel { rateLimit: number diff --git a/src/structures/snowflake.ts b/src/structures/snowflake.ts new file mode 100644 index 0000000..369a98e --- /dev/null +++ b/src/structures/snowflake.ts @@ -0,0 +1,22 @@ +export class Snowflake { + snowflake: bigint + constructor (id: string) { + this.snowflake = BigInt.asUintN(64, BigInt(id)) + } + + get timestamp () { + return ((this.snowflake >> BigInt(22)) + BigInt(1420070400000)).toString() + } + + get workerID () { + return ((this.snowflake & BigInt(0x3e0000)) >> BigInt(17)).toString() + } + + get processID () { + return ((this.snowflake & BigInt(0x1f000)) >> BigInt(12)).toString() + } + + get increment () { + return (this.snowflake & BigInt(0xfff)).toString() + } +} diff --git a/src/structures/user.ts b/src/structures/user.ts index 501bd92..bb9a5e2 100644 --- a/src/structures/user.ts +++ b/src/structures/user.ts @@ -1,6 +1,8 @@ import { Client } from '../models/client.ts' import { UserPayload } from '../types/userTypes.ts' import { Base } from './base.ts' +import * as cache from '../models/cache.ts' +import { USER } from '../types/endpoint.ts' export class User extends Base { id: string @@ -41,4 +43,23 @@ export class User extends Base { this.premiumType = data.premium_type this.publicFlags = data.public_flags } + + static async autoInit (client: Client, userID: string) { + // user? users? + const cached = cache.get('user', userID) + if (cached === undefined || !(cached instanceof User)) { + const resp = await fetch(USER(userID), { + headers: { + Authorization: `Bot ${client.token}` + } + }) + const userParsed: UserPayload = await resp.json() + + const newUser = new User(client, userParsed) + cached.set('user', userID, newUser) + return newUser + } else { + return cached + } + } } diff --git a/src/types/endpoint.ts b/src/types/endpoint.ts index 32afb96..cd56653 100644 --- a/src/types/endpoint.ts +++ b/src/types/endpoint.ts @@ -193,6 +193,7 @@ export { GUILD_INTEGRATION, GUILD_INTEGRATIONS, GUILD_INTEGARTION_SYNC, + GUILD_WIDGET_IMAGE, GUILD_BAN, GUILD_BANS, GUILD_CHANNEL, diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 3b441b9..df6973a 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -19,7 +19,7 @@ interface GuildPayload { afk_channel_id?: string afk_timeout: number widget_enabled?: boolean - widge_channel_id?: string + widget_channel_id?: string verification_level: string default_message_notifications: string explicit_content_filter: string diff --git a/src/types/snowflake.ts b/src/types/snowflake.ts deleted file mode 100644 index 4fbd6a6..0000000 --- a/src/types/snowflake.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class Snowflake { - id: string - constructor (id: string) { - this.id = id - } - - deconstruct () { - const snowflake = BigInt.asUintN(64, BigInt(this.id)) - const res = { - timestamp: ((snowflake << BigInt(22)) + BigInt(1420070400000)).toString(), - workerId: ((snowflake & BigInt(0x3e0000)) >> BigInt(17)).toString(), - processId: ((snowflake & BigInt(0x1f000)) >> BigInt(12)).toString(), - increment: (snowflake & BigInt(0xfff)).toString() - } - return res - } -}