fix: didn't run prettier, now i am

This commit is contained in:
Jacob Nguyen
2022-05-19 23:03:39 -05:00
parent 2d28800953
commit 6c144defca
11 changed files with 236 additions and 208 deletions

View File

@@ -20,66 +20,63 @@ import { CommandType } from '../structures/enums';
import type { Result } from 'ts-results';
function applicationCommandHandler(mod: Module | undefined, interaction: CommandInteraction) {
const mod$ = <T extends CommandType>(cmdTy: T) => of(mod).pipe(
filterCorrectModule(cmdTy),
);
return match(interaction)
.when(isChatInputCommand, i => {
const mod$ = <T extends CommandType>(cmdTy: T) => of(mod).pipe(filterCorrectModule(cmdTy));
return (
match(interaction)
.when(isChatInputCommand, i => {
const ctx = Context.wrap(i);
//SUPPORT COMMANDTYPE.BOTH
return mod$(CommandType.Slash).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute(
[ctx, ['slash', i.options]],
controller,
)) ?? []).pipe(map(res => ({
mod, res, execute() {
return m.execute(ctx, ['slash', i.options]);
},
})));
return of(m.onEvent?.map(e => e.execute([ctx, ['slash', i.options]], controller)) ?? []).pipe(
map(res => ({
mod,
res,
execute() {
return m.execute(ctx, ['slash', i.options]);
},
})),
);
}),
);
},
)
//Todo: refactor so that we dont have to have two separate branches. They're near identical!!
//Only thing that differs is type of interaction
.when(isMessageCtxMenuCmd, ctx => {
})
//Todo: refactor so that we dont have to have two separate branches. They're near identical!!
//Only thing that differs is type of interaction
.when(isMessageCtxMenuCmd, ctx => {
return mod$(CommandType.MenuMsg).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute(
[ctx],
controller,
)) ?? []).pipe(map(res => ({
mod, res, execute() {
return m.execute(ctx);
},
})));
return of(m.onEvent?.map(e => e.execute([ctx], controller)) ?? []).pipe(
map(res => ({
mod,
res,
execute() {
return m.execute(ctx);
},
})),
);
}),
);
},
)
.when(isUserContextMenuCmd, ctx => {
return mod$(CommandType.MenuUser).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute(
[ctx],
controller,
)) ?? []).pipe(map(res => ({
mod, res, execute() {
return m.execute(ctx);
},
})));
}),
);
})
.run();
})
.when(isUserContextMenuCmd, ctx => {
return mod$(CommandType.MenuUser).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute([ctx], controller)) ?? []).pipe(
map(res => ({
mod,
res,
execute() {
return m.execute(ctx);
},
})),
);
}),
);
})
.run()
);
}
function messageComponentInteractionHandler(
mod: Module | undefined,
interaction: MessageComponentInteraction,
) {
function messageComponentInteractionHandler(mod: Module | undefined, interaction: MessageComponentInteraction) {
const mod$ = <T extends CommandType>(ty: T) => of(mod).pipe(filterCorrectModule(ty));
//Todo: refactor so that we dont have to have two separate branches. They're near identical!!
//Only thing that differs is type of interaction
@@ -87,28 +84,30 @@ function messageComponentInteractionHandler(
.when(isButton, ctx => {
return mod$(CommandType.Button).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute(
[ctx],
controller,
)) ?? []).pipe(map(res => ({
mod, res, execute() {
return m.execute(ctx);
},
})));
return of(m.onEvent?.map(e => e.execute([ctx], controller)) ?? []).pipe(
map(res => ({
mod,
res,
execute() {
return m.execute(ctx);
},
})),
);
}),
);
})
.when(isSelectMenu, (ctx: SelectMenuInteraction) => {
return mod$(CommandType.MenuSelect).pipe(
concatMap(m => {
return of(m.onEvent?.map(e => e.execute(
[ctx],
controller,
)) ?? []).pipe(map(res => ({
mod, res, execute() {
return m.execute(ctx);
},
})));
return of(m.onEvent?.map(e => e.execute([ctx], controller)) ?? []).pipe(
map(res => ({
mod,
res,
execute() {
return m.execute(ctx);
},
})),
);
}),
);
})
@@ -131,34 +130,33 @@ export function onInteractionCreate(wrapper: Wrapper) {
return applicationCommandHandler(modul, interaction);
}
if (interaction.isMessageComponent()) {
const modul = Files
.MessageCompCommands[interaction.componentType]
.get(interaction.customId);
const modul = Files.MessageCompCommands[interaction.componentType].get(interaction.customId);
return messageComponentInteractionHandler(modul, interaction);
} else return throwError(() => SernError.NotSupportedInteraction);
}),
).subscribe({
async next({ mod, res: eventPluginRes, execute }) {
const ePlugArr: Result<void, void>[] = [];
for await (const res of eventPluginRes) {
if (isPromise(res)) {
ePlugArr.push(res);
)
.subscribe({
async next({ mod, res: eventPluginRes, execute }) {
const ePlugArr: Result<void, void>[] = [];
for await (const res of eventPluginRes) {
if (isPromise(res)) {
ePlugArr.push(res);
}
ePlugArr.push(res as Awaited<Result<void, void>>);
}
ePlugArr.push(res as Awaited<Result<void, void>>);
}
if (ePlugArr.every(e => e.ok)) {
await execute();
wrapper.sernEmitter?.emit('module.activate', { success: true, module: mod! });
} else {
wrapper.sernEmitter?.emit('module.activate', {
success: false,
module: mod!,
reason: SernError.PluginFailure,
});
}
},
error(err) {
wrapper.sernEmitter?.emit('error', err);
},
});
}
if (ePlugArr.every(e => e.ok)) {
await execute();
wrapper.sernEmitter?.emit('module.activate', { success: true, module: mod! });
} else {
wrapper.sernEmitter?.emit('module.activate', {
success: false,
module: mod!,
reason: SernError.PluginFailure,
});
}
},
error(err) {
wrapper.sernEmitter?.emit('error', err);
},
});
}

View File

@@ -23,16 +23,14 @@ export const onMessageCreate = (wrapper: Wrapper) => {
return {
ctx: Context.wrap(message), //TODO : check for BothCommand
args: <Args>['text', rest],
mod:
Files.BothCommands.get(prefix) ??
Files.TextCommands.aliases.get(prefix),
mod: Files.BothCommands.get(prefix) ?? Files.TextCommands.aliases.get(prefix),
};
}),
);
const ensureModuleType$ = processMessage$.pipe(
concatMap(payload =>
of(payload.mod).pipe(
//SUPPORT COMMANDTYPE.BOTH
//SUPPORT COMMAND TYPE.BOTH
filterCorrectModule(CommandType.Text),
map(mod => ({ ...payload, mod })),
),

View File

@@ -47,4 +47,3 @@ export function ignoreNonBot(prefix: string) {
});
});
}

View File

@@ -26,14 +26,15 @@ export const onReady = (wrapper: Wrapper) => {
}),
);
const processPlugins$ = processCommandFiles$.pipe(
concatMap((mod) => {
const cmdPluginsRes = mod.plugins?.map(plug => {
return {
...plug,
name: plug?.name ?? 'Unnamed Plugin',
execute: plug.execute(client, mod, controller),
};
}) ?? [];
concatMap(mod => {
const cmdPluginsRes =
mod.plugins?.map(plug => {
return {
...plug,
name: plug?.name ?? 'Unnamed Plugin',
execute: plug.execute(client, mod, controller),
};
}) ?? [];
return of({ mod, cmdPluginsRes });
}),
);

View File

@@ -18,27 +18,35 @@ import type { BaseModule, ModuleDefs } from '../structures/module';
import type { PluginType } from '../structures/enums';
import type { ValueOf } from 'ts-pattern/dist/types/helpers';
export interface Controller {
next: () => Ok<void>;
stop: () => Err<void>;
}
type BasePlugin = Override<BaseModule, {
type: PluginType,
}>;
type BasePlugin = Override<
BaseModule,
{
type: PluginType;
}
>;
export type CommandPlugin = Override<BasePlugin, {
type: PluginType.Command;
execute: (wrapper: Client, module: Module, controller: Controller) => Awaitable<Result<void, void>>;
}>;
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 EventPlugin<T extends keyof ModuleDefs> = Override<
BasePlugin,
{
type: PluginType.Event;
execute: (event: Parameters<ModuleDefs[T]['execute']>, controller: Controller) => Awaitable<Result<void, void>>;
}
>;
export function plugins(...plug: CommandPlugin[]): CommandPlugin[];
export function plugins<T extends keyof ModuleDefs>(...plug: EventPlugin<T>[]): EventPlugin<T>[];
@@ -47,16 +55,14 @@ export function plugins<T extends keyof ModuleDefs>(...plug: EventPlugin<T>[] |
}
type ModuleNoPlugins = ValueOf<{
[T in keyof ModuleDefs]: Omit<ModuleDefs[T], 'plugins'>
}>
[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(plugins: CommandPlugin[], mod: ModuleNoPlugins): Module {
return {
plugins,
...mod,
};
}
}

View File

@@ -24,7 +24,7 @@ export function init(wrapper: Wrapper) {
}
function eventObserver(client: Client, events: (DiscordEvent | EventEmitterRegister)[]) {
events.forEach((event) => {
events.forEach(event => {
if (isDiscordEvent(event)) {
fromEvent(client, event[0], event[1]).subscribe();
} else {

View File

@@ -2,22 +2,27 @@ import { EventEmitter } from 'events';
import type { Module } from './structures/module';
type Payload =
{ success: true, module: Module }
| { success: false, module: Module | undefined, reason: string | Error }
| { success: true; module: Module }
| { success: false; module: Module | undefined; reason: string | Error };
type SernEventsMapping = {
['module.register']: [Payload];
['module.activate']: [Payload];
['error']: [Error | string];
}
};
export default class SernEmitter extends EventEmitter {
public override on<T extends keyof SernEventsMapping>(eventName: T, listener: (...args: SernEventsMapping[T][]) => void): this {
public override on<T extends keyof SernEventsMapping>(
eventName: T,
listener: (...args: SernEventsMapping[T][]) => void,
): this {
return super.on(eventName, listener);
}
public override once<T extends keyof SernEventsMapping>(eventName: T, listener: (...args: SernEventsMapping[T][]) => void): this {
public override once<T extends keyof SernEventsMapping>(
eventName: T,
listener: (...args: SernEventsMapping[T][]) => void,
): this {
return super.once(eventName, listener);
}
@@ -25,5 +30,3 @@ export default class SernEmitter extends EventEmitter {
return super.emit(eventName, ...args);
}
}

View File

@@ -19,55 +19,76 @@ export interface BaseModule {
}
//possible refactoring types into interfaces and not types
export type TextCommand = Override<BaseModule, {
type: CommandType.Text;
onEvent?: EventPlugin<CommandType.Text>[]
plugins?: CommandPlugin[];
alias?: string[];
}>;
export type TextCommand = Override<
BaseModule,
{
type: CommandType.Text;
onEvent?: EventPlugin<CommandType.Text>[];
plugins?: CommandPlugin[];
alias?: string[];
}
>;
export type SlashCommand = Override<BaseModule, {
type: CommandType.Slash;
onEvent?: EventPlugin<CommandType.Slash>[]
plugins?: CommandPlugin[];
options?: ApplicationCommandOptionData[];
}>;
export type SlashCommand = Override<
BaseModule,
{
type: CommandType.Slash;
onEvent?: EventPlugin<CommandType.Slash>[];
plugins?: CommandPlugin[];
options?: ApplicationCommandOptionData[];
}
>;
export type BothCommand = Override<BaseModule, {
type: CommandType.Both;
onEvent?: EventPlugin<CommandType.Both>[]
plugins?: CommandPlugin[]
alias?: string[];
options?: ApplicationCommandOptionData[];
}>;
export type BothCommand = Override<
BaseModule,
{
type: CommandType.Both;
onEvent?: EventPlugin<CommandType.Both>[];
plugins?: CommandPlugin[];
alias?: string[];
options?: ApplicationCommandOptionData[];
}
>;
export type ContextMenuUser = Override<BaseModule, {
type: CommandType.MenuUser;
onEvent?: EventPlugin<CommandType.MenuUser>[];
plugins?: CommandPlugin[];
execute: (ctx: UserContextMenuCommandInteraction) => Awaitable<void>
}>
export type ContextMenuUser = Override<
BaseModule,
{
type: CommandType.MenuUser;
onEvent?: EventPlugin<CommandType.MenuUser>[];
plugins?: CommandPlugin[];
execute: (ctx: UserContextMenuCommandInteraction) => Awaitable<void>;
}
>;
export type ContextMenuMsg = Override<BaseModule, {
type: CommandType.MenuMsg;
onEvent?: EventPlugin<CommandType.MenuMsg>[];
plugins?: CommandPlugin[];
execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void>
}>;
export type ContextMenuMsg = Override<
BaseModule,
{
type: CommandType.MenuMsg;
onEvent?: EventPlugin<CommandType.MenuMsg>[];
plugins?: CommandPlugin[];
execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void>;
}
>;
export type ButtonCommand = Override<BaseModule, {
type: CommandType.Button;
onEvent?: EventPlugin<CommandType.Button>[];
plugins?: CommandPlugin[];
execute: (ctx: ButtonInteraction) => Awaitable<void>
}>;
export type ButtonCommand = Override<
BaseModule,
{
type: CommandType.Button;
onEvent?: EventPlugin<CommandType.Button>[];
plugins?: CommandPlugin[];
execute: (ctx: ButtonInteraction) => Awaitable<void>;
}
>;
export type SelectMenuCommand = Override<BaseModule, {
type: CommandType.MenuSelect;
onEvent?: EventPlugin<CommandType.MenuSelect>[];
plugins?: CommandPlugin[];
execute: (ctx: SelectMenuInteraction) => Awaitable<void>
}>;
export type SelectMenuCommand = Override<
BaseModule,
{
type: CommandType.MenuSelect;
onEvent?: EventPlugin<CommandType.MenuSelect>[];
plugins?: CommandPlugin[];
execute: (ctx: SelectMenuInteraction) => Awaitable<void>;
}
>;
export type Module =
| TextCommand
@@ -88,4 +109,4 @@ export type ModuleDefs = {
[CommandType.MenuUser]: ContextMenuUser;
[CommandType.Button]: ButtonCommand;
[CommandType.MenuSelect]: SelectMenuCommand;
};
};

View File

@@ -657,37 +657,43 @@ class MatchInner {
while ((match = regex.exec(this.raw))) {
const result: DiscordRegexMatch = { matched: match[0], species: type };
switch (type) {
case DiscordRegexNames.EMOJI: {
result.name = match[1] as string;
result.id = match[2] as string;
result.animated = this.raw.startsWith('<a:');
}
case DiscordRegexNames.EMOJI:
{
result.name = match[1] as string;
result.id = match[2] as string;
result.animated = this.raw.startsWith('<a:');
}
break;
case DiscordRegexNames.JUMP_CHANNEL: {
result.guildId = match[1] as string;
result.channelId = match[2] as string;
}
case DiscordRegexNames.JUMP_CHANNEL:
{
result.guildId = match[1] as string;
result.channelId = match[2] as string;
}
break;
case DiscordRegexNames.JUMP_CHANNEL_MESSAGE: {
result.guildId = match[1] as string;
result.channelId = match[2] as string;
result.messageId = match[3] as string;
}
case DiscordRegexNames.JUMP_CHANNEL_MESSAGE:
{
result.guildId = match[1] as string;
result.channelId = match[2] as string;
result.messageId = match[3] as string;
}
break;
case DiscordRegexNames.MENTION_CHANNEL:
case DiscordRegexNames.MENTION_ROLE: {
result.id = match[1] as string;
}
case DiscordRegexNames.MENTION_ROLE:
{
result.id = match[1] as string;
}
break;
case DiscordRegexNames.MENTION_USER: {
result.id = match[2] as string;
result.mentionType = match[1] as string;
}
case DiscordRegexNames.MENTION_USER:
{
result.id = match[2] as string;
result.mentionType = match[1] as string;
}
break;
case DiscordRegexNames.TEXT_CODEBLOCK: {
result.language = match[2] as string;
result.text = match[3] as string;
}
case DiscordRegexNames.TEXT_CODEBLOCK:
{
result.language = match[2] as string;
result.text = match[3] as string;
}
break;
case DiscordRegexNames.TEXT_BOLD:
case DiscordRegexNames.TEXT_CODESTRING:
@@ -696,9 +702,10 @@ class MatchInner {
case DiscordRegexNames.TEXT_SPOILER:
case DiscordRegexNames.TEXT_STRIKE:
case DiscordRegexNames.TEXT_UNDERLINE:
case DiscordRegexNames.TEXT_URL: {
result.text = match[1] as string;
}
case DiscordRegexNames.TEXT_URL:
{
result.text = match[1] as string;
}
break;
default: {
throw new global.Error(`Unknown regex type: ${type}`);

View File

@@ -11,7 +11,6 @@ import type {
} from 'discord.js';
import type { DiscordEvent, EventEmitterRegister } from '../..';
export function correctModuleType<T extends keyof ModuleDefs>(
plug: Module | undefined,
type: T,
@@ -47,4 +46,3 @@ export function isPromise<T>(promiseLike: Awaitable<T>): promiseLike is Promise<
export function isDiscordEvent(el: DiscordEvent | EventEmitterRegister): el is DiscordEvent {
return el.length === 2;
}

View File

@@ -19,12 +19,9 @@ export type Args = ParseType<{ text: string[]; slash: SlashOptions }>;
export type DiscordEvent = ParseType<{ [K in keyof ClientEvents]: (...args: ClientEvents[K]) => Awaitable<void> }>;
export type EventEmitterRegister = [emitter: EventEmitter, k: string, cb: (...args: unknown[]) => Awaitable<void>];
export type SlashOptions = Omit<CommandInteractionOptionResolver, 'getMessage' | 'getFocused'>;
//https://dev.to/vborodulin/ts-how-to-override-properties-with-type-intersection-554l
export type Override<T1, T2> = Omit<T1, keyof T2> & T2;
export type DefinitelyDefined<T, K> = T & Override<T, K>;