feat(handler) run formatter and made message prefixes case insensitive

This commit is contained in:
Jacob Nguyen
2022-04-03 17:13:13 -05:00
parent 4ef0b87de7
commit ef8e3961d1
11 changed files with 33 additions and 95 deletions

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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()
})
})
});
});
}

View File

@@ -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));

View File

@@ -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
}

View File

@@ -41,6 +41,7 @@ export type SelectMenuCommand = {
type : CommandType.MENU_SELECT;
} & Override<BaseModule, { execute : (ctx : Context<SelectMenuInteraction> ) => Awaitable<void> }>;
export type Module =
TextCommand
| SlashCommand

View File

@@ -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

View File

@@ -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);

View File

@@ -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[];
}

View File

@@ -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 };
}),

View File

@@ -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> = {