mirror of
https://github.com/sern-handler/handler
synced 2026-06-17 21:32:14 +00:00
refactor: shorten code, add UnionToTuple type
This commit is contained in:
@@ -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<CommandType.Both>([ctx, <Args>['slash', i.options]]
|
||||
), controller);
|
||||
[ctx, <Args>['slash', i.options]]
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
//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<CommandType.MenuMsg | CommandType.MenuUser>(args
|
||||
), controller);
|
||||
|
||||
[ctx] as UnionToTuple<CommandType.MenuMsg | CommandType.MenuUser>
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
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<CommandType.Button>([i]), controller);
|
||||
return e.execute([ctx] as UnionToTuple<CommandType.Button | CommandType.MenuSelect>, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
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<CommandType.MenuSelect>([i]), controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
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 => {
|
||||
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -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<CommandType.Both>([ctx, args]), controller);
|
||||
return ePlug.execute([ctx, args], controller);
|
||||
}),
|
||||
);
|
||||
return from(res).pipe(map(res => ({ plugged, ctx, args, res })));
|
||||
|
||||
@@ -31,9 +31,11 @@ export type BothCommand = {
|
||||
export type ContextMenuUser = {
|
||||
type: CommandType.MenuUser;
|
||||
} & Override<BaseModule, { execute: (ctx: UserContextMenuCommandInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type ContextMenuMsg = {
|
||||
type: CommandType.MenuMsg;
|
||||
} & Override<BaseModule, { execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type ButtonCommand = {
|
||||
type: CommandType.Button;
|
||||
} & Override<BaseModule, { execute: (ctx: ButtonInteraction) => Awaitable<void> }>;
|
||||
|
||||
@@ -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<T extends CommandType> = {
|
||||
[K in T] : Parameters<ModuleDefs[K]['execute']>
|
||||
}[T]
|
||||
|
||||
|
||||
/**
|
||||
* Identity function x => x to narrow type of parameters
|
||||
* @param params
|
||||
*/
|
||||
export function resolveParameters<T extends CommandType>
|
||||
( params: ParamMap<T> )
|
||||
{
|
||||
return params;
|
||||
}
|
||||
export type UnionToTuple<T> = T extends readonly [ infer V, infer S ]
|
||||
? V extends V
|
||||
? S extends S
|
||||
? [ V, S ]
|
||||
: [ V ]
|
||||
: never
|
||||
: never;
|
||||
|
||||
Reference in New Issue
Block a user