From 972928b6a3b8ee70622f2c55f13ab9f0b222089f Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Mon, 16 May 2022 20:55:44 -0500 Subject: [PATCH] refactor: DRY Principles --- src/handler/events/interactionCreate.ts | 78 +++++++++++++++--------- src/handler/events/observableHandling.ts | 2 +- src/handler/plugins/plugin.ts | 3 - src/handler/structures/module.ts | 2 +- src/handler/utilities/predicates.ts | 11 +++- 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/handler/events/interactionCreate.ts b/src/handler/events/interactionCreate.ts index 713ba61..79773ec 100644 --- a/src/handler/events/interactionCreate.ts +++ b/src/handler/events/interactionCreate.ts @@ -1,55 +1,75 @@ -import type { - CommandInteraction, - Interaction, - MessageComponentInteraction, - MessageContextMenuCommandInteraction as MessageCtxInt, - UserContextMenuCommandInteraction as UserCtxInt, -} from 'discord.js'; -import type { SelectMenuInteraction } from 'discord.js'; -import { concatMap, fromEvent, Observable, of, throwError } from 'rxjs'; +import type { CommandInteraction, Interaction, MessageComponentInteraction, SelectMenuInteraction } from 'discord.js'; +import { concatMap, from, fromEvent, map, Observable, of, throwError } from 'rxjs'; import type Wrapper from '../structures/wrapper'; import * as Files from '../utilities/readFile'; -import { match, P } from 'ts-pattern'; +import { match } from 'ts-pattern'; import { SernError } from '../structures/errors'; import Context from '../structures/context'; import type { Result } from 'ts-results'; import { CommandType, controller } from '../sern'; -import type { Args, UnionToTuple } from '../../types/handler'; import type { Module } from '../structures/module'; import type { EventPlugin } from '../plugins/plugin'; -import { isButton, isChatInputCommand, isSelectMenu } from '../utilities/predicates'; - +import { + isButton, + isChatInputCommand, + isMessageCtxMenuCmd, + isSelectMenu, + isUserContextMenuCmd, +} from '../utilities/predicates'; +import { filterCorrectModule } from './observableHandling'; +//TODO : atm, i have to cast for every interaction. is there a way to not cast? +// maybe pass it through an observable function applicationCommandHandler(mod: Module | undefined, interaction: CommandInteraction) { if (mod === undefined) { return throwError(() => SernError.UndefinedModule); } + const mod$ = (cmdTy : T) => of(mod).pipe( + filterCorrectModule(cmdTy) + ); const eventPlugins = mod.onEvent; return match(interaction) .when(isChatInputCommand, i => { - const ctx = Context.wrap(i); - const res = eventPlugins.map(e => { - return (>e).execute( - [ctx, ['slash', i.options]] + return mod$(CommandType.Slash).pipe( + concatMap(m => { + const ctx = Context.wrap(i); + return from(m.onEvent.map(e => e.execute( + [ctx, ['slash', i.options]], + controller + ))); + }), + map( res => ({ mod, res })) + ); + }, + ) + //Todo: refactor so that we dont have to have two separate branches. They're near identical!! + .when(isMessageCtxMenuCmd, ctx => { + return mod$(CommandType.MenuMsg).pipe( + concatMap(m => { + return from(m.onEvent.map(e => e.execute( + [ctx], + controller + ))); + }), + map( res => ({ mod, res })) + ); + const res = eventPlugins.map(e => { + return (>e).execute([ctx] , controller); }) as Awaited>[]; //Possible unsafe cast // could result in the promises not being resolved - return of({ type: CommandType.Slash, res, mod, ctx }); - }, - ) - .when( - () => P._, - (ctx: UserCtxInt | MessageCtxInt) => { - //Kinda hackish - const res = eventPlugins.map(e => { - return e.execute( - [ctx] as UnionToTuple - , controller); - }) as Awaited>[]; return of({ type: mod.type, res, mod, ctx }); }, ) + .when(isUserContextMenuCmd, ctx => { + const res = eventPlugins.map( e=> (>e).execute([ctx] + , controller) + ) as Awaited>[]; + //Possible unsafe cast + // could result in the promises not being resolved + return of({ type: mod.type, res, mod, ctx }); + }) .run(); } diff --git a/src/handler/events/observableHandling.ts b/src/handler/events/observableHandling.ts index e61b331..787d6c8 100644 --- a/src/handler/events/observableHandling.ts +++ b/src/handler/events/observableHandling.ts @@ -6,7 +6,7 @@ import type { Module, ModuleDefs } from '../structures/module'; import { correctModuleType } from '../utilities/predicates'; export function filterCorrectModule(cmdType: T) { - return (src: Observable) => + return (src: Observable) => new Observable(subscriber => { return src.subscribe({ next(mod) { diff --git a/src/handler/plugins/plugin.ts b/src/handler/plugins/plugin.ts index c387b39..93ef489 100644 --- a/src/handler/plugins/plugin.ts +++ b/src/handler/plugins/plugin.ts @@ -50,9 +50,6 @@ export type EventPlugin = { { execute: (event: Parameters, controller: Controller) => Awaitable>; }>; -export type EventPluginType = { - [K in CommandType] : EventPlugin -} export function plugins(...plug: CommandPlugin[]): CommandPlugin[]; export function plugins(...plug: EventPlugin[]): EventPlugin[]; diff --git a/src/handler/structures/module.ts b/src/handler/structures/module.ts index edcce53..26f932b 100644 --- a/src/handler/structures/module.ts +++ b/src/handler/structures/module.ts @@ -49,7 +49,7 @@ export type ContextMenuUser = { export type ContextMenuMsg = { type: CommandType.MenuMsg; - onEvent: EventPlugin[]; + onEvent: EventPlugin[]; plugins: CommandPlugin[]; } & Override Awaitable }>; diff --git a/src/handler/utilities/predicates.ts b/src/handler/utilities/predicates.ts index a868a7b..6157606 100644 --- a/src/handler/utilities/predicates.ts +++ b/src/handler/utilities/predicates.ts @@ -1,9 +1,7 @@ import type { Module, ModuleDefs } from '../structures/module'; import type { ChatInputCommandInteraction, CommandInteraction } from 'discord.js'; -import type { EventPlugin } from '../../../dist'; -import { CommandType } from '../sern'; -import type { EventPluginType } from '../plugins/plugin'; import type { ButtonInteraction, MessageComponentInteraction, SelectMenuInteraction } from 'discord.js'; +import type { MessageContextMenuCommandInteraction, UserContextMenuCommandInteraction } from 'discord.js'; export function correctModuleType( @@ -22,4 +20,11 @@ export function isButton(i : MessageComponentInteraction) : i is ButtonInteracti } export function isSelectMenu(i : MessageComponentInteraction) : i is SelectMenuInteraction { return i.isSelectMenu(); +} +export function isMessageCtxMenuCmd(i : CommandInteraction) : i is MessageContextMenuCommandInteraction { + return i.isMessageContextMenuCommand(); +} + +export function isUserContextMenuCmd(i : CommandInteraction) : i is UserContextMenuCommandInteraction { + return i.isUserContextMenuCommand(); } \ No newline at end of file