From 47677d3fa6f885e9ac3ff487426ec44ad26cc4b9 Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Mon, 29 Apr 2024 00:08:50 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20feat:=20lets=20go=20to=20jsr=20[?= =?UTF-8?q?SMALL=20BREAKING:=20READ=20COMMIT=20MSG]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ➕ feat: use node redis instead of denodrivers redis --- deno.json | 13 +++++++++- src/cache/redis.ts | 39 ++++++++++++----------------- src/client/client.ts | 9 +++++-- src/commands/client.ts | 18 ++++++++++--- src/rest/bucket.ts | 2 +- src/structures/guildNewsChannel.ts | 19 +++++++++++--- src/structures/guildTextChannel.ts | 29 +++++++++++++++++---- src/structures/guildVoiceChannel.ts | 24 +++++++++++++----- src/utils/permissions.ts | 2 +- 9 files changed, 109 insertions(+), 46 deletions(-) diff --git a/deno.json b/deno.json index f429b755..f4de7669 100644 --- a/deno.json +++ b/deno.json @@ -7,5 +7,16 @@ }, "name": "@harmony/harmony", "version": "2.9.1", - "exports": "./mod.ts" + "exports": "./mod.ts", + "publish": { + "include": [ + "mod.ts", + "deps.ts", + "deploy.ts", + "src/**/*", + "assets/*", + "README.md", + "tsconfig.json" + ] + } } diff --git a/src/cache/redis.ts b/src/cache/redis.ts index eeec0032..f55311bf 100644 --- a/src/cache/redis.ts +++ b/src/cache/redis.ts @@ -1,22 +1,17 @@ import { ICacheAdapter } from './adapter.ts' // Not in deps.ts to allow optional dep loading -import { - connect, - Redis, - RedisConnectOptions, - RedisValue -} from 'https://deno.land/x/redis@v0.25.1/mod.ts' +import { createClient, RedisClientOptions } from 'npm:redis@4.6.13' /** Redis Cache Adapter for using Redis as a cache-provider. */ export class RedisCacheAdapter implements ICacheAdapter { - _redis: Promise - redis?: Redis + _redis: Promise> + redis?: ReturnType ready: boolean = false readonly _expireIntervalTimer: number = 5000 private _expireInterval?: number - constructor(options: RedisConnectOptions) { - this._redis = connect(options) + constructor(options: RedisClientOptions) { + this._redis = createClient(options).connect() this._redis.then( (redis) => { this.redis = redis @@ -31,9 +26,9 @@ export class RedisCacheAdapter implements ICacheAdapter { private _startExpireInterval(): void { this._expireInterval = setInterval(() => { - this.redis?.scan(0, { pattern: '*:expires' }).then(([_, names]) => { + this.redis?.scan(0, { MATCH: '*:expires' }).then(({ keys: names }) => { for (const name of names) { - this.redis?.hvals(name).then((vals) => { + this.redis?.hVals(name).then((vals) => { for (const val of vals) { const expireVal: { name: string @@ -41,7 +36,7 @@ export class RedisCacheAdapter implements ICacheAdapter { at: number } = JSON.parse(val) const expired = new Date().getTime() > expireVal.at - if (expired) this.redis?.hdel(expireVal.name, expireVal.key) + if (expired) this.redis?.hDel(expireVal.name, expireVal.key) } }) } @@ -55,7 +50,7 @@ export class RedisCacheAdapter implements ICacheAdapter { async get(cacheName: string, key: string): Promise { await this._checkReady() - const cache = await this.redis?.hget(cacheName, key) + const cache = await this.redis?.hGet(cacheName, key) if (cache === undefined) return try { return JSON.parse(cache) as T @@ -71,15 +66,13 @@ export class RedisCacheAdapter implements ICacheAdapter { expire?: number ): Promise { await this._checkReady() - await this.redis?.hset( + await this.redis?.hSet( cacheName, key, - typeof value === 'object' - ? JSON.stringify(value) - : (value as unknown as RedisValue) + typeof value === 'object' ? JSON.stringify(value) : (value as any) ) if (expire !== undefined) { - await this.redis?.hset( + await this.redis?.hSet( `${cacheName}:expires`, key, JSON.stringify({ @@ -93,18 +86,18 @@ export class RedisCacheAdapter implements ICacheAdapter { async delete(cacheName: string, ...keys: string[]): Promise { await this._checkReady() - return ((await this.redis?.hdel(cacheName, ...keys)) ?? 0) === keys.length + return ((await this.redis?.hDel(cacheName, keys)) ?? 0) === keys.length } async array(cacheName: string): Promise { await this._checkReady() - const data = await this.redis?.hvals(cacheName) + const data = await this.redis?.hVals(cacheName) return data?.map((e: string) => JSON.parse(e)) } async keys(cacheName: string): Promise { await this._checkReady() - return this.redis?.hkeys(cacheName) + return this.redis?.hKeys(cacheName) } async deleteCache(cacheName: string): Promise { @@ -114,6 +107,6 @@ export class RedisCacheAdapter implements ICacheAdapter { async size(cacheName: string): Promise { await this._checkReady() - return this.redis?.hlen(cacheName) + return this.redis?.hLen(cacheName) } } diff --git a/src/client/client.ts b/src/client/client.ts index 1489f76f..e22afedc 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -136,7 +136,7 @@ export class Client extends HarmonyEventEmitter { fetchGatewayInfo: boolean = true /** Voice Connections Manager */ - readonly voice = new VoiceManager(this) + readonly voice: VoiceManager = new VoiceManager(this) /** Users Manager, containing all Users cached */ readonly users: UsersManager = new UsersManager(this) @@ -487,7 +487,12 @@ export class Client extends HarmonyEventEmitter { /** Event decorator to create an Event handler from function */ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export function event(name?: keyof ClientEvents) { +export function event( + name?: keyof ClientEvents +): ( + original: (...args: any[]) => any, + ctx: ClassMethodDecoratorContext +) => (...args: any[]) => any { return function ( original: (...args: any[]) => any, { diff --git a/src/commands/client.ts b/src/commands/client.ts index e9b29fab..cf4a688c 100644 --- a/src/commands/client.ts +++ b/src/commands/client.ts @@ -94,7 +94,9 @@ export class CommandClient extends Client implements CommandClientOptions { commands: CommandsManager = new CommandsManager(this) categories: CategoriesManager = new CategoriesManager(this) - middlewares = new Array>() + middlewares: Array> = new Array< + CommandContextMiddleware + >() globalCommandCooldown = 0 globalCooldown = 0 @@ -518,7 +520,12 @@ export class CommandClient extends Client implements CommandClientOptions { /** * Command decorator. Decorates the function with optional metadata as a Command registered upon constructing class. */ -export function command(options?: CommandOptions) { +export function command( + options?: CommandOptions +): ( + original: (...args: any[]) => any, + ctx: ClassMethodDecoratorContext +) => (...args: any[]) => any { return function ( original: (...args: any[]) => any, { @@ -552,7 +559,12 @@ export function command(options?: CommandOptions) { /** * Sub Command decorator. Decorates the function with optional metadata as a Sub Command registered upon constructing class. */ -export function subcommand(options?: CommandOptions) { +export function subcommand( + options?: CommandOptions +): ( + original: (...args: any[]) => any, + ctx: ClassMethodDecoratorContext +) => (...args: any[]) => any { return function ( original: (...args: any[]) => any, { diff --git a/src/rest/bucket.ts b/src/rest/bucket.ts index 0a7c1fd0..f300c8e6 100644 --- a/src/rest/bucket.ts +++ b/src/rest/bucket.ts @@ -40,7 +40,7 @@ let invalidCount = 0 let invalidCountResetTime: number | null = null export class BucketHandler { - queue = new RequestQueue() + queue: RequestQueue = new RequestQueue() reset = -1 remaining = -1 limit = -1 diff --git a/src/structures/guildNewsChannel.ts b/src/structures/guildNewsChannel.ts index 1c96fb25..f9884ce5 100644 --- a/src/structures/guildNewsChannel.ts +++ b/src/structures/guildNewsChannel.ts @@ -1,8 +1,19 @@ import { Mixin } from '../../deps.ts' +import type { GuildNewsChannelPayload } from '../types/channel.ts' +import type { Client } from '../client/mod.ts' +import type { Guild } from './guild.ts' import { GuildTextBasedChannel } from './guildTextChannel.ts' import { GuildThreadAvailableChannel } from './guildThreadAvailableChannel.ts' -export class NewsChannel extends Mixin( - GuildTextBasedChannel, - GuildThreadAvailableChannel -) {} +const NewsChannelSuper: (abstract new ( + client: Client, + data: GuildNewsChannelPayload, + guild: Guild +) => GuildTextBasedChannel & GuildThreadAvailableChannel) & + Pick & + Pick< + typeof GuildThreadAvailableChannel, + keyof typeof GuildThreadAvailableChannel + > = Mixin(GuildTextBasedChannel, GuildThreadAvailableChannel) + +export class NewsChannel extends NewsChannelSuper {} diff --git a/src/structures/guildTextChannel.ts b/src/structures/guildTextChannel.ts index 7e54225a..e9fb7473 100644 --- a/src/structures/guildTextChannel.ts +++ b/src/structures/guildTextChannel.ts @@ -12,8 +12,19 @@ import { CHANNEL } from '../types/endpoint.ts' import type { Message } from './message.ts' import { GuildThreadAvailableChannel } from './guildThreadAvailableChannel.ts' +const GuildTextBasedChannelSuper: (abstract new ( + client: Client, + data: GuildTextBasedChannelPayload, + guild: Guild +) => TextChannel & GuildChannel) & + Pick & + Pick = Mixin( + TextChannel, + GuildChannel +) + /** Represents a Text Channel but in a Guild */ -export class GuildTextBasedChannel extends Mixin(TextChannel, GuildChannel) { +export class GuildTextBasedChannel extends GuildTextBasedChannelSuper { constructor( client: Client, data: GuildTextBasedChannelPayload, @@ -81,8 +92,16 @@ export class GuildTextBasedChannel extends Mixin(TextChannel, GuildChannel) { } } +const GuildTextChannelSuper: (abstract new ( + client: Client, + data: any, + guild: Guild +) => GuildTextBasedChannel & GuildThreadAvailableChannel) & + Pick & + Pick< + typeof GuildThreadAvailableChannel, + keyof typeof GuildThreadAvailableChannel + > = Mixin(GuildTextBasedChannel, GuildThreadAvailableChannel) + // Still exist for API compatibility -export class GuildTextChannel extends Mixin( - GuildTextBasedChannel, - GuildThreadAvailableChannel -) {} +export class GuildTextChannel extends GuildTextChannelSuper {} diff --git a/src/structures/guildVoiceChannel.ts b/src/structures/guildVoiceChannel.ts index a245ce65..7cce030b 100644 --- a/src/structures/guildVoiceChannel.ts +++ b/src/structures/guildVoiceChannel.ts @@ -17,14 +17,26 @@ import type { import { Mixin } from '../../deps.ts' import { TextChannel } from './textChannel.ts' -export class VoiceChannel extends Mixin(GuildChannel, TextChannel) { +const VoiceChannelSuper: (abstract new ( + client: Client, + data: GuildVoiceChannelPayload, + guild: Guild +) => TextChannel & GuildChannel) & + Pick & + Pick = Mixin( + TextChannel, + GuildChannel +) + +export class VoiceChannel extends VoiceChannelSuper { bitrate!: string userLimit!: number - voiceStates = new GuildChannelVoiceStatesManager( - this.client, - this.guild.voiceStates, - this - ) + voiceStates: GuildChannelVoiceStatesManager = + new GuildChannelVoiceStatesManager( + this.client, + this.guild.voiceStates, + this + ) constructor(client: Client, data: GuildVoiceChannelPayload, guild: Guild) { super(client, data, guild) diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts index b4514b19..daa8d517 100644 --- a/src/utils/permissions.ts +++ b/src/utils/permissions.ts @@ -7,7 +7,7 @@ export type PermissionResolvable = BitFieldResolvable /** Represents permissions BitField */ export class Permissions extends BitField { static DEFAULT = 104324673n - static ALL = Object.values(PermissionFlags).reduce( + static ALL: bigint = Object.values(PermissionFlags).reduce( (all, p) => BigInt(all) | BigInt(p), 0n )