mirror of
https://github.com/sern-handler/handler
synced 2026-06-27 18:22:14 +00:00
refactor: DRY Principles
This commit is contained in:
@@ -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$ = <T extends CommandType>(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 (<EventPlugin<CommandType.Slash>>e).execute(
|
||||
[ctx, <Args>['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 (<EventPlugin<CommandType.MenuMsg>>e).execute([ctx]
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
//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<CommandType.MenuMsg | CommandType.MenuUser>
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
return of({ type: mod.type, res, mod, ctx });
|
||||
},
|
||||
)
|
||||
.when(isUserContextMenuCmd, ctx => {
|
||||
const res = eventPlugins.map( e=> (<EventPlugin<CommandType.MenuUser>>e).execute([ctx]
|
||||
, controller)
|
||||
) as Awaited<Result<void, void>>[];
|
||||
//Possible unsafe cast
|
||||
// could result in the promises not being resolved
|
||||
return of({ type: mod.type, res, mod, ctx });
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Module, ModuleDefs } from '../structures/module';
|
||||
import { correctModuleType } from '../utilities/predicates';
|
||||
|
||||
export function filterCorrectModule<T extends keyof ModuleDefs>(cmdType: T) {
|
||||
return (src: Observable<Module | undefined>) =>
|
||||
return (src: Observable<Module>) =>
|
||||
new Observable<ModuleDefs[T]>(subscriber => {
|
||||
return src.subscribe({
|
||||
next(mod) {
|
||||
|
||||
@@ -50,9 +50,6 @@ export type EventPlugin<T extends CommandType> = {
|
||||
{
|
||||
execute: (event: Parameters<ModuleDefs[T]['execute']>, controller: Controller) => Awaitable<Result<void, void>>;
|
||||
}>;
|
||||
export type EventPluginType = {
|
||||
[K in CommandType] : EventPlugin<K>
|
||||
}
|
||||
|
||||
export function plugins(...plug: CommandPlugin[]): CommandPlugin[];
|
||||
export function plugins<T extends CommandType>(...plug: EventPlugin<T>[]): EventPlugin<T>[];
|
||||
|
||||
@@ -49,7 +49,7 @@ export type ContextMenuUser = {
|
||||
|
||||
export type ContextMenuMsg = {
|
||||
type: CommandType.MenuMsg;
|
||||
onEvent: EventPlugin<CommandType.MenuUser>[];
|
||||
onEvent: EventPlugin<CommandType.MenuMsg>[];
|
||||
plugins: CommandPlugin[];
|
||||
} & Override<BaseModule, { execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void> }>;
|
||||
|
||||
|
||||
@@ -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<T extends keyof ModuleDefs>(
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user