From 58b7a6c21b3de88cd18819c2fea764624dfdf2b0 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 14 May 2022 19:28:30 -0500 Subject: [PATCH] refactor: shorten code, add UnionToTuple type --- src/handler/events/interactionCreate.ts | 72 ++++++++----------- src/handler/events/messageEvent.ts | 3 +- .../structures/modules/commands/module.ts | 2 + src/handler/utilities/resolveParameters.ts | 25 ++----- 4 files changed, 40 insertions(+), 62 deletions(-) diff --git a/src/handler/events/interactionCreate.ts b/src/handler/events/interactionCreate.ts index 95a6db5..7494e9b 100644 --- a/src/handler/events/interactionCreate.ts +++ b/src/handler/events/interactionCreate.ts @@ -5,7 +5,7 @@ import type { MessageContextMenuCommandInteraction as MessageCtxInt, UserContextMenuCommandInteraction as UserCtxInt, } from 'discord.js'; -import { concatMap, fromEvent, Observable, of, throwError } from 'rxjs'; +import { concatMap, fromEvent, Observable, of, throwError, map } from 'rxjs'; import type Wrapper from '../structures/wrapper'; import * as Files from '../utilities/readFile'; import { isEventPlugin } from './readyEvent'; @@ -15,80 +15,65 @@ import Context from '../structures/context'; import type { Result } from 'ts-results'; import type { PluggedModule } from '../structures/modules/module'; import { CommandType, controller } from '../sern'; -import { resolveParameters } from '../utilities/resolveParameters'; import type { Args } from '../../types/handler'; import type { MessageComponentInteraction } from 'discord.js'; -import { ButtonInteraction, ComponentType, SelectMenuInteraction } from 'discord.js'; +import { ComponentType } from 'discord.js'; +import type { UnionToTuple } from '../utilities/resolveParameters'; - -function applicationCommandHandler< - T extends CommandType.Both | CommandType.MenuUser | CommandType.MenuMsg | CommandType.Slash, ->(mod: PluggedModule | undefined, interaction: CommandInteraction) { - if (mod === undefined) { +function isChatInputCommand(i : CommandInteraction) : i is ChatInputCommandInteraction { + return i.isChatInputCommand(); +} +function applicationCommandHandler(plugged: PluggedModule | undefined, interaction: CommandInteraction) { + if (plugged === undefined) { return throwError(() => SernError.UndefinedModule); } - const eventPlugins = mod.plugins.filter(isEventPlugin); + const eventPlugins = plugged.plugins.filter(isEventPlugin); return match(interaction) - .when( - i => i.isChatInputCommand(), - (i: ChatInputCommandInteraction) => { + .when(isChatInputCommand, i => { const ctx = Context.wrap(i); const res = eventPlugins.map(e => { return e.execute( - resolveParameters([ctx, ['slash', i.options]] - ), controller); + [ctx, ['slash', i.options]] + , controller); }) as Awaited>[]; //Possible unsafe cast // could result in the promises not being resolved - return of({ res, mod, ctx }); + return of({ type : plugged.mod.type, res, plugged, ctx }); }, ) .when( () => P._, (ctx : UserCtxInt | MessageCtxInt) => { //Kinda hackish - const args : [UserCtxInt] | [MessageCtxInt] = ctx.isUserContextMenuCommand() - ? [ ctx as UserCtxInt ] : [ ctx as MessageCtxInt ]; const res = eventPlugins.map(e => { return e.execute( - resolveParameters(args - ), controller); - + [ctx] as UnionToTuple + , controller); }) as Awaited>[]; - return of({ res, mod, ctx }); + return of({ type : plugged.mod.type, res, plugged, ctx }); }, ) .run(); } function messageComponentInteractionHandler( - mod: PluggedModule | undefined, + plugged: PluggedModule | undefined, interaction: MessageComponentInteraction, ) { - if (mod === undefined) { + if (plugged === undefined) { return throwError(() => SernError.UndefinedModule); } - const eventPlugins = mod.plugins.filter(isEventPlugin); + const eventPlugins = plugged.plugins.filter(isEventPlugin); return match(interaction) - .with({ componentType : ComponentType.Button }, (i : ButtonInteraction) => { + .with({ + componentType : P.union(ComponentType.Button, ComponentType.SelectMenu) + },(ctx ) => { const res = eventPlugins.map(e => { - return e.execute(resolveParameters([i]), controller); + return e.execute([ctx] as UnionToTuple, controller); }) as Awaited>[]; - return of({ res, mod, i}); + return of({ type : plugged.mod.type, res, plugged, ctx }); }) - .with( { componentType : ComponentType.SelectMenu }, (i : SelectMenuInteraction) => { - const res = eventPlugins.map(e => { - return e.execute(resolveParameters([i]), controller); - }) as Awaited>[]; - return of({ res, mod, i}); - }) - .with( { componentType : ComponentType.TextInput }, _ => { - return throwError(() => SernError.NotImplemented); - } ) - .with( { componentType : P._ }, i => { - return throwError(() => SernError.NotSupportedInteraction); - }) - .exhaustive(); + .otherwise(_ => throwError( () => SernError.NotSupportedInteraction) ); } export const onInteractionCreate = (wrapper: Wrapper) => { @@ -98,6 +83,7 @@ export const onInteractionCreate = (wrapper: Wrapper) => { interactionEvent$ .pipe( + /*processing plugins*/ concatMap(interaction => { if (interaction.isCommand()) { const modul = @@ -111,10 +97,12 @@ export const onInteractionCreate = (wrapper: Wrapper) => { .get(interaction.customId); return messageComponentInteractionHandler(modul, interaction); } - return of({}); + else return throwError(() => SernError.NotSupportedInteraction); }), ) - .subscribe(console.log); + .subscribe(modul => { + + }); }; diff --git a/src/handler/events/messageEvent.ts b/src/handler/events/messageEvent.ts index 58d0b85..96ba638 100644 --- a/src/handler/events/messageEvent.ts +++ b/src/handler/events/messageEvent.ts @@ -9,7 +9,6 @@ import { fmt } from '../utilities/messageHelpers'; import * as Files from '../utilities/readFile'; import { filterCorrectModule, ignoreNonBot } from './observableHandling'; import { isEventPlugin } from './readyEvent'; -import { resolveParameters } from '../utilities/resolveParameters'; export const onMessageCreate = (wrapper: Wrapper) => { const { client, defaultPrefix } = wrapper; @@ -48,7 +47,7 @@ export const onMessageCreate = (wrapper: Wrapper) => { if ((ePlug.modType & plugged.mod.type) === 0) { return Err.EMPTY; } - return ePlug.execute(resolveParameters([ctx, args]), controller); + return ePlug.execute([ctx, args], controller); }), ); return from(res).pipe(map(res => ({ plugged, ctx, args, res }))); diff --git a/src/handler/structures/modules/commands/module.ts b/src/handler/structures/modules/commands/module.ts index 2fd3df2..3864b0d 100644 --- a/src/handler/structures/modules/commands/module.ts +++ b/src/handler/structures/modules/commands/module.ts @@ -31,9 +31,11 @@ export type BothCommand = { export type ContextMenuUser = { type: CommandType.MenuUser; } & Override Awaitable }>; + export type ContextMenuMsg = { type: CommandType.MenuMsg; } & Override Awaitable }>; + export type ButtonCommand = { type: CommandType.Button; } & Override Awaitable }>; diff --git a/src/handler/utilities/resolveParameters.ts b/src/handler/utilities/resolveParameters.ts index 45b7a37..c21d8e5 100644 --- a/src/handler/utilities/resolveParameters.ts +++ b/src/handler/utilities/resolveParameters.ts @@ -1,18 +1,7 @@ -import type { CommandType } from '../sern'; -import type { ModuleDefs } from '../structures/modules/commands/moduleHandler'; -import type { ParseType } from '../../types/handler'; - -type ParamMap = { - [K in T] : Parameters -}[T] - - -/** - * Identity function x => x to narrow type of parameters - * @param params - */ -export function resolveParameters - ( params: ParamMap ) - { - return params; -} \ No newline at end of file +export type UnionToTuple = T extends readonly [ infer V, infer S ] + ? V extends V + ? S extends S + ? [ V, S ] + : [ V ] + : never + : never;