feat : remove parse option, allowing user to custom parse arguments

This commit is contained in:
Jacob Nguyen
2022-03-21 17:25:21 -05:00
parent 99aae7d780
commit 05fadf0e33
4 changed files with 64 additions and 35 deletions

View File

@@ -1,27 +1,46 @@
import type { CommandInteraction, Interaction } from "discord.js";
import { map, filter, fromEvent, Observable, of, concatMap } from "rxjs";
import type { Awaitable, ChatInputCommandInteraction, Interaction } from "discord.js";
import { map, filter, fromEvent, Observable, of, mergeMap, tap} from "rxjs";
import { None, Some } from "ts-results";
import { CommandType } from "../sern";
import Context from "../structures/context";
import type Wrapper from "../structures/wrapper";
import { isNotFromDM, isNotFromBot, hasPrefix, fmt } from "../utilities/messageHelpers";
import * as Files from '../utilities/readFile';
export const onInteractionCreate = ( wrapper : Wrapper ) => {
const { client } = wrapper;
(fromEvent(client, 'interactionCreate') as Observable<Interaction>)
.pipe(
)
.pipe(
mergeMap ( interaction => {
if (interaction.isChatInputCommand()) {
return of(interaction.commandName).pipe(
map ( Files.Commands.get ),
filter ( mod => mod !== undefined && (mod.type & CommandType.SLASH) != 0),
tap ( mod => {
const ctx = new Context(None, Some(interaction));
mod!.execute(ctx, ['slash', interaction.options]);
}),
)
}
if (interaction.isContextMenuCommand()) {
return of()
}
else { return of() }
})
).subscribe({
error() {
//log things
console.log('Failed to finished message subscription!');
},
next(command) {
//log on each command emitted
console.log(command);
},
})
}

View File

@@ -1,5 +1,5 @@
import type { Message } from "discord.js";
import { map, filter, fromEvent, Observable, of, concatMap } from "rxjs";
import { map, filter, fromEvent, Observable, of, concatMap, tap } from "rxjs";
import { None, Some } from "ts-results";
import { CommandType } from "../sern";
import Context from "../structures/context";
@@ -16,15 +16,16 @@ export const onMessageCreate = (wrapper : Wrapper) => {
filter( m => hasPrefix(m, defaultPrefix)),
concatMap ( m => of( fmt(m, defaultPrefix) )
.pipe (
map(([prefix, ...args ]) =>{
return [Files.Commands.get(prefix) ?? Files.Alias.get(prefix), new Context(Some(m), None), args ] as const;
}),
map(([prefix, ...args ]) =>
[
Files.Commands.get(prefix) ?? Files.Alias.get(prefix),
new Context(Some(m), None),
args
] as const
),
filter( ([mod]) => mod !== undefined && (mod.type & CommandType.TEXT) != 0 ),
map ( async ([ mod, ctx, args ]) => {
const parsedArgs = mod!.parse?.(ctx, args);
const res = await mod!.execute(ctx, parsedArgs);
// some ducktape lol
return res !== undefined ? ctx.messageUnchecked.channel.send(res) : null;
tap ( ([ mod, ctx, args ]) => {
mod!.execute(ctx, ['text', args])
}),
)
)
@@ -36,7 +37,7 @@ export const onMessageCreate = (wrapper : Wrapper) => {
},
next(command) {
//log on each command emitted
command.then( res => console.log(`a command returned ${ res ?? `no value`}`));
console.log(command);
},
})

View File

@@ -1,5 +1,5 @@
import type { ApplicationCommandOptionData, Awaitable } from "discord.js";
import type { parseArgs, possibleOutput } from "../../../types/handler";
import type { Args } from "../../../types/handler";
import type { CommandType } from "../../sern";
import type Context from "../context";
@@ -8,11 +8,22 @@ import type Context from "../context";
export interface BaseModule {
name? : string;
description : string;
execute(ctx: Context, args: unknown) : Awaitable<possibleOutput | void>
execute<T>(ctx: Context, args: Args) : Awaitable<T>
}
export type Text = {
type : CommandType.TEXT;
alias : string[] | [],
};
export type Slash = {
type : CommandType.SLASH;
options : ApplicationCommandOptionData[] | [],
};
export type Both = {
type : CommandType.BOTH;
alias : string[] | [];
options : ApplicationCommandOptionData[] | [],
}
export type Text = { type : CommandType.TEXT; alias : string[] | [], parse? : parseArgs };
export type Slash = { type : CommandType.SLASH; options : ApplicationCommandOptionData[] | [], parse? : parseArgs };
export type Both = { type : CommandType.BOTH; alias : string[] | []; options : ApplicationCommandOptionData[] | [], parse? : parseArgs }
export type Module =
(BaseModule & Slash) | (BaseModule & Both) | (BaseModule & Text);

View File

@@ -7,10 +7,8 @@ import type {
Awaitable,
} from 'discord.js';
import type { Context, Modules } from '../handler/structures/structxports';
import type { Modules } from '../handler/structures/structxports';
export type Visibility = 'private' | 'public';
export type parseArgs = <T>( ctx: Context, args : string[] ) => T | possibleOutput;
// Anything that can be sent in a `<TextChannel>#send` or `<CommandInteraction>#reply`
export type possibleOutput<T = string> = T | (MessagePayload & MessageOptions);
export type execute = Modules.Module['execute'];
@@ -21,7 +19,7 @@ export type ParseType<T> = {
}[keyof T];
export type Arg = ParseType<{ text: string[]; slash: SlashOptions }>;
export type Args = ParseType<{ text: string[]; slash: SlashOptions }>;
export type DiscordEvent =
ParseType< { [K in keyof ClientEvents ] : (...args : ClientEvents[K]) => Awaitable<void> }>;