Files
archived-handler/src/handler/events/interactionHandler.ts
Jacob Nguyen 74378f0f12 feat: shrink package size, improve dev deps, esm and cjs support (#98)
* chore: fix tsc predicate type checking

* build: add tsup as bundler

* chore: revert text

* chore: fix predicates.ts, update dependencies, bump version

* docs: update example

* build: update dependencies

* fix: crash on collectors (#89)

* fix: crash on collectors

* feat: bump version for bug fix

* fix: crash on collectors pt

* docs: adding some documentation for docasaurus

* docs: add errors.ts comments

* docs: refactor comments

* docs: adding examples

* feat: refresh package-lock.json

* refactor: destructure and clean namespaces

* feat: add regen package.json script

* feat: add tsup, remove tsc, add scripts

* feat: update ts-results import style

* feat: readd typescript because idk if i should

* feat: breakup tsconfigs and add tsup config

* feat: add esm json tsconfig to git

* build: update dependencies and move to ts-result-es

* feat: remove unused function

* feat: update ts-results for esm/cjs interop!

* revert: remove version.txt

* build: goodbye tsc, hello tsup

* build: moving discord.js as dev dependency

* style: requested changes

* feat: add tsc back ( i missed you )

* build: bump version -> 1.0.0

* feat: syncing to main

* style: pretty

* feat: fix tsconfig issues with tsup

* revert: remove ExternallyUsed

* feat: update scripts

* build: update tsup and pkg-lock.json

* feat: refresh package-lock.json

* feat: test
2022-08-06 15:51:19 -05:00

130 lines
4.7 KiB
TypeScript

import type { Interaction } from 'discord.js';
import { concatMap, from, fromEvent, map, Observable } from 'rxjs';
import type Wrapper from '../structures/wrapper';
import { EventsHandler } from './eventsHandler';
import {
isApplicationCommand,
isAutocomplete,
isMessageComponent,
isModalSubmit,
} from '../utilities/predicates';
import * as Files from '../utilities/readFile';
import type { CommandModule } from '../structures/module';
import { SernError } from '../structures/errors';
import { CommandType } from '../structures/enums';
import { match, P } from 'ts-pattern';
import {
applicationCommandDispatcher,
buttonCommandDispatcher,
ctxMenuMsgDispatcher,
ctxMenuUserDispatcher,
modalCommandDispatcher,
selectMenuCommandDispatcher,
} from './dispatchers';
import type {
ButtonInteraction,
ModalSubmitInteraction,
SelectMenuInteraction,
UserContextMenuCommandInteraction,
MessageContextMenuCommandInteraction,
} from 'discord.js';
import { executeModule } from './observableHandling';
export default class InteractionHandler extends EventsHandler<{
event: Interaction;
mod: CommandModule;
}> {
protected override discordEvent: Observable<Interaction>;
constructor(protected wrapper: Wrapper) {
super(wrapper);
this.discordEvent = <Observable<Interaction>>fromEvent(wrapper.client, 'interactionCreate');
this.init();
this.payloadSubject
.pipe(
map(this.processModules),
concatMap(({ mod, execute, eventPluginRes }) => {
//resolve all the Results from event plugins
return from(eventPluginRes).pipe(map(res => ({ mod, res, execute })));
}),
concatMap(payload => executeModule(wrapper, payload)),
)
.subscribe({
error: err => {
wrapper.sernEmitter?.emit('error', err);
},
});
}
override init() {
this.discordEvent.subscribe({
next: event => {
if (isMessageComponent(event)) {
const mod = Files.MessageCompCommands[event.componentType].get(
event.customId,
);
this.setState({ event, mod });
} else if (isApplicationCommand(event) || isAutocomplete(event)) {
const mod =
Files.ApplicationCommands[event.commandType].get(
event.commandName,
) ?? Files.BothCommands.get(event.commandName);
this.setState({ event, mod });
} else if (isModalSubmit(event)) {
/**
* maybe move modal submits into message component object maps?
*/
const mod = Files.ModalSubmitCommands.get(event.customId);
this.setState({ event, mod });
} else {
throw Error('This interaction is not supported yet');
}
},
error: e => {
this.wrapper.sernEmitter?.emit('error', e);
},
});
}
protected setState(state: { event: Interaction; mod: CommandModule | undefined }): void {
if (state.mod === undefined) {
this.wrapper?.sernEmitter?.emit('warning', 'Found no module for this interaction');
} else {
//if statement above checks already, safe cast
this.payloadSubject.next(state as { event: Interaction; mod: CommandModule });
}
}
protected processModules({ mod, event }: { event: Interaction; mod: CommandModule }) {
return match(mod)
.with(
{ type: P.union(CommandType.Slash, CommandType.Both) },
applicationCommandDispatcher(event),
)
.with(
{ type: CommandType.Modal },
modalCommandDispatcher(event as ModalSubmitInteraction),
)
.with(
{ type: CommandType.Button },
buttonCommandDispatcher(event as ButtonInteraction),
)
.with(
{ type: CommandType.MenuSelect },
selectMenuCommandDispatcher(event as SelectMenuInteraction),
)
.with(
{ type: CommandType.MenuUser },
ctxMenuUserDispatcher(event as UserContextMenuCommandInteraction),
)
.with(
{ type: CommandType.MenuMsg },
ctxMenuMsgDispatcher(event as MessageContextMenuCommandInteraction),
)
.otherwise(() => {
throw Error(SernError.MismatchModule);
});
}
}