mirror of
https://github.com/sern-handler/handler
synced 2026-06-15 04:12:17 +00:00
feat: adding better typings, refactoring
This commit is contained in:
@@ -1,14 +1,8 @@
|
||||
import type { Awaitable, Message } from 'discord.js';
|
||||
import type { Message } from 'discord.js';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { SernError } from '../structures/errors';
|
||||
import type { InteractionDefs, Module, ModuleDefs } from '../structures/module';
|
||||
import type { Module, ModuleDefs } from '../structures/module';
|
||||
import { correctModuleType } from '../utilities/predicates';
|
||||
import type { CommandType } from '../structures/enums';
|
||||
import type { UnionToIntersection } from '../../types/handler';
|
||||
import { controller } from '../sern';
|
||||
import type { Result } from 'ts-results';
|
||||
import type { SelectMenuInteraction } from 'discord.js';
|
||||
|
||||
export function filterCorrectModule<T extends keyof ModuleDefs>(cmdType: T) {
|
||||
return (src: Observable<Module | undefined>) =>
|
||||
new Observable<ModuleDefs[T]>(subscriber => {
|
||||
@@ -48,21 +42,3 @@ export function ignoreNonBot(prefix: string) {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// export function processOnEvents<T extends CommandType>(ty: T, interaction: InteractionDefs[T]) {
|
||||
// return (src: Observable<ModuleDefs[T]>) =>
|
||||
// new Observable<Awaitable<Result<void, void>>>(subscriber => {
|
||||
// return src.subscribe({
|
||||
// next(m) {
|
||||
// subscriber.next(m.onEvent?.map(e => {
|
||||
// return (<UnionToIntersection<typeof e>>e).execute(
|
||||
// [interaction as SelectMenuInteraction], //This is just to satisfy compiler
|
||||
// controller,
|
||||
// );
|
||||
// })) ;
|
||||
// },
|
||||
// error: e => subscriber.error(e),
|
||||
// complete: () => subscriber.complete(),
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
@@ -15,9 +15,8 @@ import type { Awaitable, Client } from 'discord.js';
|
||||
import type { Err, Ok, Result } from 'ts-results';
|
||||
import type { Module, Override } from '../..';
|
||||
import { CommandType } from '../..';
|
||||
import type { BaseModule, ModuleDefs } from '../structures/module';
|
||||
import type { PluginType } from '../structures/enums';
|
||||
import type { ValueOf } from 'ts-pattern/dist/types/helpers';
|
||||
import type { AutocompleteCommand, BaseModule, ModuleDefs } from '../structures/module';
|
||||
import { PluginType } from '../structures/enums';
|
||||
|
||||
export interface Controller {
|
||||
next: () => Ok<void>;
|
||||
@@ -31,31 +30,19 @@ type BasePlugin = Override<
|
||||
}
|
||||
>;
|
||||
|
||||
export type CommandPlugin = Override<
|
||||
BasePlugin,
|
||||
{
|
||||
type: PluginType.Command;
|
||||
execute: (
|
||||
wrapper: Client,
|
||||
module: Module,
|
||||
controller: Controller,
|
||||
) => Awaitable<Result<void, void>>;
|
||||
}
|
||||
>;
|
||||
|
||||
//TODO: rn adding the modType check a little hackish. Find better way to determine the
|
||||
// module type of the event plugin
|
||||
// export type EventPlugin<T extends keyof ModuleDefs> = Override<
|
||||
// BasePlugin,
|
||||
// {
|
||||
// type: PluginType.Event;
|
||||
// execute: (
|
||||
// event: Parameters<ModuleDefs[T]['execute']>,
|
||||
// controller: Controller,
|
||||
// ) => Awaitable<Result<void, void>>;
|
||||
// }
|
||||
// >;
|
||||
|
||||
export type CommandPlugin<T extends keyof ModuleDefs = keyof ModuleDefs> = {
|
||||
[K in T]: Override<
|
||||
BasePlugin,
|
||||
{
|
||||
type: PluginType.Command;
|
||||
execute: (
|
||||
wrapper: Client,
|
||||
module: ModuleDefs[T],
|
||||
controller: Controller,
|
||||
) => Awaitable<Result<void, void>>;
|
||||
}
|
||||
>;
|
||||
}[T];
|
||||
export type EventPlugin<T extends keyof ModuleDefs = keyof ModuleDefs> = {
|
||||
[K in T]: Override<
|
||||
BasePlugin,
|
||||
@@ -69,23 +56,53 @@ export type EventPlugin<T extends keyof ModuleDefs = keyof ModuleDefs> = {
|
||||
>;
|
||||
}[T];
|
||||
|
||||
export function plugins(...plug: CommandPlugin[]): CommandPlugin[];
|
||||
export function plugins<T extends keyof ModuleDefs>(...plug: EventPlugin<T>[]): EventPlugin<T>[];
|
||||
export function plugins<T extends keyof ModuleDefs>(...plug: EventPlugin<T>[] | CommandPlugin[]) {
|
||||
return plug;
|
||||
//Syntactic sugar on hold
|
||||
// export function plugins<T extends keyof ModuleDefs>(
|
||||
// ...plug: (EventPlugin<T> | CommandPlugin<T>)[]
|
||||
// ) {
|
||||
// return plug;
|
||||
// }
|
||||
|
||||
type ModuleNoPlugins = {
|
||||
[T in keyof ModuleDefs]: Omit<ModuleDefs[T], 'plugins' | 'onEvent'>;
|
||||
};
|
||||
|
||||
function isEventPlugin<T extends CommandType>(
|
||||
e: CommandPlugin<T> | EventPlugin<T>,
|
||||
): e is EventPlugin<T> {
|
||||
return e.type === PluginType.Event;
|
||||
}
|
||||
function isCommandPlugin<T extends CommandType>(
|
||||
e: CommandPlugin<T> | EventPlugin<T>,
|
||||
): e is CommandPlugin<T> {
|
||||
return !isEventPlugin(e);
|
||||
}
|
||||
|
||||
type ModuleNoPlugins = ValueOf<{
|
||||
[T in keyof ModuleDefs]: Omit<ModuleDefs[T], 'plugins'>;
|
||||
}>;
|
||||
|
||||
//TODO: I WANT BETTER TYPINGS AHHHHHHHHHHHHHHH
|
||||
export function sernModule(plugins: CommandPlugin[], mod: ModuleNoPlugins): Module {
|
||||
export function sernModule<T extends CommandType>(
|
||||
plugin: (CommandPlugin<T> | EventPlugin<T>)[],
|
||||
mod: ModuleNoPlugins[T],
|
||||
): Module {
|
||||
const onEvent = plugin.filter(isEventPlugin);
|
||||
const plugins = plugin.filter(isCommandPlugin);
|
||||
if (mod.type === CommandType.Autocomplete) {
|
||||
return mod;
|
||||
throw new Error(
|
||||
'You cannot use this function declaration for Autocomplete Interactions! use the raw object for options or' +
|
||||
'sernAutoComplete function',
|
||||
);
|
||||
} else
|
||||
return {
|
||||
onEvent,
|
||||
plugins,
|
||||
...mod,
|
||||
};
|
||||
} as Module;
|
||||
}
|
||||
|
||||
export function sernAutocomplete(
|
||||
onEvent: EventPlugin<CommandType.Autocomplete>[],
|
||||
mod: Omit<AutocompleteCommand, 'type' | 'name' | 'description' | 'onEvent'>,
|
||||
): Omit<AutocompleteCommand, 'type' | 'name' | 'description'> {
|
||||
return {
|
||||
onEvent,
|
||||
...mod,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import type Context from './context';
|
||||
import { CommandType, PluginType } from './enums';
|
||||
import type { AutocompleteInteraction } from 'discord.js';
|
||||
import type { ApplicationCommandOptionType } from 'discord.js';
|
||||
import { ChatInputCommandInteraction, Message, User } from 'discord.js';
|
||||
|
||||
export interface BaseModule {
|
||||
type: CommandType | PluginType;
|
||||
@@ -35,8 +34,8 @@ export type TextCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.Text;
|
||||
onEvent?: EventPlugin<CommandType.Text>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.Text>[];
|
||||
plugins: CommandPlugin[];
|
||||
alias?: string[];
|
||||
}
|
||||
>;
|
||||
@@ -45,8 +44,8 @@ export type SlashCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.Slash;
|
||||
onEvent?: EventPlugin<CommandType.Slash>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.Slash>[];
|
||||
plugins: CommandPlugin[];
|
||||
options?: SernOptionsData[];
|
||||
}
|
||||
>;
|
||||
@@ -55,8 +54,8 @@ export type BothCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.Both;
|
||||
onEvent?: EventPlugin<CommandType.Both>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.Both>[];
|
||||
plugins: CommandPlugin[];
|
||||
alias?: string[];
|
||||
options?: SernOptionsData[];
|
||||
}
|
||||
@@ -66,8 +65,8 @@ export type ContextMenuUser = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.MenuUser;
|
||||
onEvent?: EventPlugin<CommandType.MenuUser>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.MenuUser>[];
|
||||
plugins: CommandPlugin[];
|
||||
execute: (ctx: UserContextMenuCommandInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -76,8 +75,8 @@ export type ContextMenuMsg = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.MenuMsg;
|
||||
onEvent?: EventPlugin<CommandType.MenuMsg>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.MenuMsg>[];
|
||||
plugins: CommandPlugin[];
|
||||
execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -86,8 +85,8 @@ export type ButtonCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.Button;
|
||||
onEvent?: EventPlugin<CommandType.Button>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.Button>[];
|
||||
plugins: CommandPlugin[];
|
||||
execute: (ctx: ButtonInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -96,8 +95,8 @@ export type SelectMenuCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.MenuSelect;
|
||||
onEvent?: EventPlugin<CommandType.MenuSelect>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.MenuSelect>[];
|
||||
plugins: CommandPlugin[];
|
||||
execute: (ctx: SelectMenuInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -106,8 +105,8 @@ export type ModalSubmitCommand = Override<
|
||||
BaseModule,
|
||||
{
|
||||
type: CommandType.Modal;
|
||||
onEvent?: EventPlugin<CommandType.Modal>[];
|
||||
plugins?: CommandPlugin[];
|
||||
onEvent: EventPlugin<CommandType.Modal>[];
|
||||
plugins: CommandPlugin[];
|
||||
execute: (ctx: ModalSubmitInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -121,7 +120,7 @@ export type AutocompleteCommand = Override<
|
||||
{
|
||||
type: CommandType.Autocomplete;
|
||||
name: string;
|
||||
onEvent?: EventPlugin<CommandType.Autocomplete>[];
|
||||
onEvent: EventPlugin<CommandType.Autocomplete>[];
|
||||
execute: (ctx: AutocompleteInteraction) => Awaitable<void>;
|
||||
}
|
||||
>;
|
||||
@@ -150,17 +149,6 @@ export type ModuleDefs = {
|
||||
[CommandType.Modal]: ModalSubmitCommand;
|
||||
[CommandType.Autocomplete]: AutocompleteCommand;
|
||||
};
|
||||
export type InteractionDefs = {
|
||||
[CommandType.Text]: Context;
|
||||
[CommandType.Slash]: Context;
|
||||
[CommandType.Both]: Context;
|
||||
[CommandType.MenuMsg]: MessageContextMenuCommandInteraction;
|
||||
[CommandType.MenuUser]: UserContextMenuCommandInteraction;
|
||||
[CommandType.Button]: ButtonInteraction;
|
||||
[CommandType.MenuSelect]: SelectMenuInteraction;
|
||||
[CommandType.Modal]: ModalSubmitInteraction;
|
||||
[CommandType.Autocomplete]: AutocompleteInteraction;
|
||||
};
|
||||
|
||||
//TODO: support deeply nested Autocomplete
|
||||
// objective: construct union of ApplicationCommandOptionData change any Autocomplete data
|
||||
|
||||
Reference in New Issue
Block a user