mirror of
https://github.com/sern-handler/handler
synced 2026-06-19 22:32:14 +00:00
feat(handler) run formatter and made message prefixes case insensitive
This commit is contained in:
@@ -10,7 +10,7 @@ import { filterTap } from './observableHandling';
|
||||
export const onInteractionCreate = ( wrapper : Wrapper ) => {
|
||||
const { client } = wrapper;
|
||||
|
||||
(fromEvent(client, 'interactionCreate') as Observable<Interaction>)
|
||||
(<Observable<Interaction>> fromEvent(client, 'interactionCreate'))
|
||||
.pipe(
|
||||
concatMap ( interaction => {
|
||||
if (interaction.isChatInputCommand()) {
|
||||
@@ -29,7 +29,7 @@ export const onInteractionCreate = ( wrapper : Wrapper ) => {
|
||||
const ctx = Context.wrap(interaction);
|
||||
mod.execute(ctx);
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
if (interaction.isMessageContextMenuCommand()) {
|
||||
return of(Files.ContextMenuMsg.get(interaction.commandName))
|
||||
@@ -38,7 +38,7 @@ export const onInteractionCreate = ( wrapper : Wrapper ) => {
|
||||
const ctx = Context.wrap(interaction);
|
||||
mod.execute(ctx);
|
||||
}),
|
||||
)
|
||||
);
|
||||
}
|
||||
if (interaction.isButton()) {
|
||||
return of(Files.Buttons.get(interaction.customId))
|
||||
@@ -47,7 +47,7 @@ export const onInteractionCreate = ( wrapper : Wrapper ) => {
|
||||
const ctx = Context.wrap(interaction);
|
||||
mod.execute(ctx);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
if (interaction.isSelectMenu()) {
|
||||
return of(Files.SelectMenus.get(interaction.customId))
|
||||
@@ -56,10 +56,9 @@ export const onInteractionCreate = ( wrapper : Wrapper ) => {
|
||||
const ctx = Context.wrap(interaction);
|
||||
mod.execute(ctx);
|
||||
})
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
else { return of() }
|
||||
else { return of(); }
|
||||
})
|
||||
).subscribe({
|
||||
error(e) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { filterTap, ignoreNonBot } from './observableHandling';
|
||||
|
||||
export const onMessageCreate = (wrapper : Wrapper) => {
|
||||
const { client, defaultPrefix } = wrapper;
|
||||
(fromEvent( client, 'messageCreate') as Observable<Message>)
|
||||
(<Observable<Message>> fromEvent( client, 'messageCreate'))
|
||||
.pipe (
|
||||
ignoreNonBot(defaultPrefix),
|
||||
concatMap ( m => {
|
||||
@@ -22,7 +22,7 @@ export const onMessageCreate = (wrapper : Wrapper) => {
|
||||
filterTap(CommandType.TEXT, mod => {
|
||||
mod.execute(ctx, ['text', data]);
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
).subscribe ({
|
||||
error(e) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Awaitable, Message } from "discord.js";
|
||||
import type { CommandType } from "../sern";
|
||||
import type { Module } from "../structures/structxports";
|
||||
import type { Awaitable, Message } from 'discord.js';
|
||||
import type { CommandType } from '../sern';
|
||||
import type { Module } from '../structures/structxports';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import type { ModuleDefs } from "../structures/commands/moduleHandler";
|
||||
import { SernError } from "../structures/errors";
|
||||
import { isNotFromBot, isNotFromDM } from "../utilities/messageHelpers";
|
||||
import type { ModuleDefs } from '../structures/commands/moduleHandler';
|
||||
import { SernError } from '../structures/errors';
|
||||
import { isNotFromBot, isNotFromDM } from '../utilities/messageHelpers';
|
||||
|
||||
export function match(mod: Module | undefined, type : CommandType) : boolean {
|
||||
return mod !== undefined && (mod.type & type) != 0;
|
||||
@@ -18,8 +18,9 @@ export function filterTap<T extends keyof ModuleDefs>(
|
||||
return src.subscribe({
|
||||
next(modul ) {
|
||||
if(match(modul, cmdType)) {
|
||||
tap(modul as ModuleDefs[T]);
|
||||
subscriber.next(modul as ModuleDefs[T]);
|
||||
const asModT = <ModuleDefs[T]> modul;
|
||||
tap(asModT);
|
||||
subscriber.next(asModT);
|
||||
} else {
|
||||
if (modul === undefined) {
|
||||
return throwError(() => SernError.UNDEFINED_MODULE);
|
||||
@@ -29,9 +30,9 @@ export function filterTap<T extends keyof ModuleDefs>(
|
||||
},
|
||||
error: (e) => subscriber.error(e),
|
||||
complete: () => subscriber.complete()
|
||||
})
|
||||
});
|
||||
|
||||
})
|
||||
});
|
||||
}
|
||||
export function ignoreNonBot(prefix : string) {
|
||||
return (src : Observable<Message>) =>
|
||||
@@ -41,7 +42,11 @@ export function ignoreNonBot(prefix : string) {
|
||||
const passAll = [
|
||||
isNotFromDM,
|
||||
isNotFromBot,
|
||||
(m : Message) => m.content.startsWith(prefix)
|
||||
(m : Message) =>
|
||||
m.content
|
||||
.slice(0,prefix.length)
|
||||
.toLocaleLowerCase()
|
||||
.indexOf(prefix.toLocaleLowerCase()) !== -1
|
||||
].every( fn => fn(m));
|
||||
|
||||
if (passAll) {
|
||||
@@ -50,9 +55,8 @@ export function ignoreNonBot(prefix : string) {
|
||||
},
|
||||
error: (e) => subscriber.error(e),
|
||||
complete: () => subscriber.complete()
|
||||
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ const handler = ( name : string ) =>
|
||||
} as ModuleHandlers);
|
||||
|
||||
const registerModules = <T extends ModuleType >(name : string, mod : ModuleStates[T]) =>
|
||||
(handler(name)[mod.type] as HandlerCallback<T>)(mod);
|
||||
(<HandlerCallback<T>> handler(name)[mod.type])(mod);
|
||||
|
||||
function setCommands ( { mod, absPath } : { mod : Module, absPath : string } ) {
|
||||
const name = mod.name ?? Files.fmtFileName(basename(absPath));
|
||||
|
||||
@@ -27,69 +27,6 @@ function eventObserver(client: Client, events: DiscordEvent[] ) {
|
||||
fromEvent(client, event, cb).subscribe();
|
||||
});
|
||||
}
|
||||
|
||||
export class Handler {
|
||||
/**
|
||||
.on('interactionCreate', async (interaction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
if (interaction.guild === null) return; // TODO : handle dms
|
||||
const module = this.findModuleFrom(interaction);
|
||||
if (module === undefined) {
|
||||
this.defaultLogger.log(
|
||||
sEvent.MISUSE_CMD,
|
||||
interaction.guildId!,
|
||||
`Unknown slash command.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const res = await this.interactionResult(module, interaction);
|
||||
if (res === undefined) return;
|
||||
await interaction.reply(res);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async interactionResult(
|
||||
module: Files.CommandVal,
|
||||
interaction: CommandInteraction,
|
||||
): Promise<possibleOutput | undefined> {
|
||||
const name = this.findModuleFrom(interaction);
|
||||
if (name === undefined) return `Could not find ${interaction.commandName} command!`;
|
||||
|
||||
if (module.mod.type < CommandType.SLASH) return 'This is not a slash command';
|
||||
const context = new Context(None, Some(interaction));
|
||||
const parsedArgs = module.mod.parse?.(context, ['slash', interaction.options]) ?? Ok('');
|
||||
|
||||
if (parsedArgs.err) return parsedArgs.val;
|
||||
|
||||
return (module.mod.execute?.(context, parsedArgs) as possibleOutput | undefined);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async commandResult(
|
||||
module: Files.CommandVal,
|
||||
message: Message,
|
||||
): Promise<possibleOutput | undefined> {
|
||||
if (module.mod.type === CommandType.SLASH) {
|
||||
this.defaultLogger.log(
|
||||
sEvent.MISUSE_CMD,
|
||||
message.guildId!,
|
||||
`The text command ${module.mod.name} may be a slash command and not a text command`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const context = new Context ( Some(message), None );
|
||||
const args = message.content.slice(this.prefix.length).trim().split(/s+/g);
|
||||
const parsedArgs = module.mod.parse?.(context, ['text', args]) ?? Ok(args);
|
||||
if (parsedArgs.err) return parsedArgs.val;
|
||||
return (module.mod.execute?.(context, parsedArgs) as possibleOutput | undefined);
|
||||
};
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum { number };
|
||||
*/
|
||||
@@ -99,7 +36,7 @@ export enum CommandType {
|
||||
MENU_USER = 0b000100,
|
||||
MENU_MSG = 0b001000,
|
||||
BUTTON = 0b010000,
|
||||
MENU_SELECT =0b100000,
|
||||
MENU_SELECT= 0b100000,
|
||||
BOTH = 0b000011,
|
||||
ANY = 0b111111
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ export type SelectMenuCommand = {
|
||||
type : CommandType.MENU_SELECT;
|
||||
} & Override<BaseModule, { execute : (ctx : Context<SelectMenuInteraction> ) => Awaitable<void> }>;
|
||||
|
||||
|
||||
export type Module =
|
||||
TextCommand
|
||||
| SlashCommand
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { CommandType } from '../../sern';
|
||||
import type { TextCommand, BothCommand, ButtonCommand, SlashCommand, BaseModule, ContextMenuMsg, ContextMenuUser, SelectMenuCommand } from './module';
|
||||
|
||||
import type { TextCommand, BothCommand, ButtonCommand, SlashCommand, ContextMenuMsg, ContextMenuUser, SelectMenuCommand } from './module';
|
||||
//https://stackoverflow.com/questions/64092736/alternative-to-switch-statement-for-typescript-discriminated-union
|
||||
|
||||
// Explicit Module Definitions for mapping
|
||||
|
||||
@@ -29,7 +29,7 @@ export default class Context<I extends Interaction = Interaction> {
|
||||
this.oInterac = oInterac;
|
||||
}
|
||||
static wrap<I extends Interaction = Interaction>(wrappable: I|Message) : Context<I> {
|
||||
if ( "token" in wrappable ) {
|
||||
if ( 'token' in wrappable ) {
|
||||
return new Context<I>( None, Some(wrappable));
|
||||
}
|
||||
return new Context<I>(Some(wrappable), None);
|
||||
|
||||
@@ -14,6 +14,7 @@ interface Wrapper {
|
||||
readonly client: Client;
|
||||
readonly defaultPrefix: string;
|
||||
readonly commands: string;
|
||||
readonly components : string;
|
||||
init?: (handler: Wrapper) => void;
|
||||
readonly events? : DiscordEvent[];
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export async function buildData(commandDir: string ): Promise<
|
||||
> {
|
||||
return Promise.all(
|
||||
getCommands(commandDir).map( async (absPath) => {
|
||||
const mod = (await import(absPath)).module as Module;
|
||||
const mod = <Module> (await import(absPath)).module;
|
||||
if (mod === undefined) throw Error(`${SernError.UNDEFINED_MODULE} ${absPath}`);
|
||||
return { mod, absPath };
|
||||
}),
|
||||
|
||||
@@ -7,11 +7,8 @@ import type {
|
||||
Awaitable,
|
||||
} from 'discord.js';
|
||||
|
||||
import type { Module } from '../handler/structures/structxports';
|
||||
|
||||
// Anything that can be sent in a `<TextChannel>#send` or `<CommandInteraction>#reply`
|
||||
export type possibleOutput<T = string> = T | (MessagePayload & MessageOptions);
|
||||
export type execute = Module['execute'];
|
||||
export type Nullish<T> = T | undefined | null;
|
||||
// Thanks @cursorsdottsx
|
||||
export type ParseType<T> = {
|
||||
|
||||
Reference in New Issue
Block a user