Skip to content

Commit

Permalink
refactor: modularize commands and handlers (#48)
Browse files Browse the repository at this point in the history
Co-authored-by: Peïo Thibault <[email protected]>
  • Loading branch information
neolectron and potb committed Jan 5, 2024
1 parent 46baabd commit a8f1d96
Show file tree
Hide file tree
Showing 29 changed files with 462 additions and 362 deletions.
2 changes: 1 addition & 1 deletion src/__tests__/resolve-catch.helper.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';

import { resolveCatch } from '../helpers/resolve-catch.helper';
import { resolveCatch } from '../helpers/resolveCatch.helper';

describe('resolve-catch.helper', () => {
it('should throw an error if the promise is rejected with an error', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/summarize-cool-pages.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
isPageSummarizeSuccessData,
NoContentFoundSummaryError,
parseHtmlSummarized,
} from '../summarize-cool-pages';
} from '../modules/coolLinksManagement/summarizeCoolPages';
const createSummarizeCoolPagesFixture = () => {
return {
// from https://react.dev/learn/you-might-not-need-an-effect
Expand Down
14 changes: 0 additions & 14 deletions src/commands.ts

This file was deleted.

67 changes: 0 additions & 67 deletions src/cool-links-management.ts

This file was deleted.

File renamed without changes.
11 changes: 11 additions & 0 deletions src/core/checkUniqueSlashCommandNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { BotModule } from '../types/bot';

export const checkUniqueSlashCommandNames = (modulesToLoad: Record<string, BotModule>) => {
const slashCommandNames = Object.values(modulesToLoad)
.flatMap((module) => module.slashCommands ?? [])
.map((command) => command.schema.name);
const uniqueSlashCommandNames = new Set(slashCommandNames);
if (uniqueSlashCommandNames.size !== slashCommandNames.length) {
throw new Error('Found duplicate slash command names');
}
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { REST, Routes } from 'discord.js';

import { config } from './config';
import { config } from '../config';

export const deleteExistingCommands = async (
rest: REST,
Expand Down
19 changes: 19 additions & 0 deletions src/core/loadModules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type Client } from 'discord.js';

import type { BotModule } from '../types/bot';
import { checkUniqueSlashCommandNames } from './checkUniqueSlashCommandNames';
import { pushCommands, routeCommands } from './loaderCommands';
import { routeHandlers } from './routeHandlers';

export const loadModules = async (
client: Client<true>,
modulesToLoad: Record<string, BotModule>,
): Promise<void> => {
const botCommands = Object.values(modulesToLoad).flatMap((module) => module.slashCommands ?? []);

checkUniqueSlashCommandNames(modulesToLoad);
routeCommands(client, botCommands);
await pushCommands(botCommands.map((command) => command.schema));

routeHandlers(client, modulesToLoad);
};
56 changes: 56 additions & 0 deletions src/core/loaderCommands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
Client,
REST,
type RESTPostAPIChatInputApplicationCommandsJSONBody,
Routes,
} from 'discord.js';

import { config } from '../config';
import type { BotCommand } from '../types/bot';
import { deleteExistingCommands } from './deleteExistingCommands';

const { discord } = config;

export const pushCommands = async (commands: RESTPostAPIChatInputApplicationCommandsJSONBody[]) => {
const rest = new REST({ version: '10' }).setToken(discord.token);
await deleteExistingCommands(rest, discord);
await rest.put(Routes.applicationGuildCommands(discord.clientId, discord.guildId), {
body: commands,
});
};

export const routeCommands = (client: Client<true>, botCommands: BotCommand[]) =>
client.on('interactionCreate', async (interaction) => {
if (!interaction.inGuild() || !interaction.isChatInputCommand()) {
return;
}

const command = botCommands.find((command) => command.schema.name === interaction.commandName);

if (!command) {
await interaction.reply({
content: `Command not found ${interaction.commandName}`,
ephemeral: true,
});
return;
}

if (typeof command.handler === 'function') {
await command.handler(interaction);
return;
}

const subCommand = command.handler[interaction.options.getSubcommand()];

if (!subCommand) {
await interaction.reply({
content: `Subcommand not found ${
interaction.commandName
} ${interaction.options.getSubcommand()}`,
ephemeral: true,
});
return;
}

await subCommand(interaction);
});
21 changes: 21 additions & 0 deletions src/core/routeHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Client, ClientEvents } from 'discord.js';

import type { BotModule, EventHandler } from '../types/bot';

export const routeHandlers = (client: Client<true>, modulesToLoad: Record<string, BotModule>) => {
const eventNames = Object.values(modulesToLoad).flatMap(
(module) => Object.keys(module.eventHandlers ?? {}) as (keyof ClientEvents)[],
);
const uniqueEventNames = [...new Set(eventNames)];

uniqueEventNames.forEach((eventName) => {
const eventHandlersToCall = Object.values(modulesToLoad)
.map((module) => module.eventHandlers?.[eventName])
.filter((e): e is EventHandler => Boolean(e));

client.on(eventName, async (...args) => {
const handlersPromises = eventHandlersToCall.map(async (handler) => handler(...args));
await Promise.allSettled(handlersPromises);
});
});
};
38 changes: 0 additions & 38 deletions src/create-lobby.ts

This file was deleted.

30 changes: 0 additions & 30 deletions src/create-user-voice-channel.ts

This file was deleted.

23 changes: 0 additions & 23 deletions src/handlers/handle-guild-message-creation.ts

This file was deleted.

27 changes: 0 additions & 27 deletions src/handlers/handle-interaction-creation.ts

This file was deleted.

33 changes: 0 additions & 33 deletions src/handlers/handle-voice-channel-deletion.ts

This file was deleted.

Loading

0 comments on commit a8f1d96

Please sign in to comment.