all repos — stealth-developers @ adf2a1f4e94a5e420bad1b1b4b48ffdae274a4f9

bot: move to feats/ directory
vi did:web:vt3e.cat
Wed, 24 Jun 2026 02:47:01 +0100
commit

adf2a1f4e94a5e420bad1b1b4b48ffdae274a4f9

parent

772a28dcd81f6f2195c77ef1b6dbfd304277ca82

D apps/bot/src/commands/index.ts

@@ -1,7 +0,0 @@

-import type { Command, SubcommandGroupBuilder } from "@purrkit/router"; - -import ticketCommand from "./tickets/command"; -import meowCommand from "./meow"; - -export const commands: (SubcommandGroupBuilder | Command)[] = [ticketCommand, meowCommand]; -export default commands;
M apps/bot/src/commands/meow.tsapps/bot/src/feats/misc/meow.ts

@@ -1,6 +1,6 @@

import { kitten } from "@/client"; -const meowCommand = kitten.command("meow", { +export const meowCommand = kitten.command("meow", { description: "mrrrp mew", async run(interaction) { const meowVariants = [

@@ -97,5 +97,3 @@

interaction.reply({ content }); }, }); - -export default meowCommand;
D apps/bot/src/commands/tickets/README.md

@@ -1,24 +0,0 @@

-commands: - -- [ ] /ticket - - [x] new - - [x] for - - [ ] actions - - [ ] open - - [ ] close - - [ ] add - - [ ] claim - - [ ] unclaim - - [ ] delete - - [ ] view - - [ ] info - - [ ] transcript - - [ ] list - - [ ] export - - [x] manage - - [x] transcript-channel - - [x] entrypoint-channel - - [x] category - - [x] prompt - - [x] send-prompt - - [x] greeting
M apps/bot/src/commands/tickets/actions.tsapps/bot/src/feats/tickets/actions.ts

@@ -8,6 +8,7 @@ TextDisplayBuilder,

ActionRowBuilder, } from "discord.js"; import { Result } from "@sapphire/framework"; +import { ButtonBuilder } from "discord.js"; import db, { desc,

@@ -19,13 +20,10 @@ tickets,

type Actor, } from "@stealth-developers/db"; -export * from "./config"; - import { upsertUser, getCategory, PublicError, logger } from "@/lib"; import type { AnyUser } from "@/types"; -import { ButtonBuilder } from "discord.js"; -import TicketButtonPresets from "@/components/buttons/tickets"; -import { TicketModalPresets } from "@/components/modals"; +import { TicketButtonPresets } from "./buttons"; +import { TicketModalPresets } from "./modals"; type CreateTicketArgs = | undefined
M apps/bot/src/commands/tickets/command.tsapps/bot/src/feats/tickets/commands.ts

@@ -4,9 +4,10 @@ import { ButtonBuilder, ContainerBuilder, TextDisplayBuilder, ActionRowBuilder } from "discord.js";

import { getGuildByDiscordId } from "@stealth-developers/db"; import { kitten } from "@/client"; -import { errorMessage, getTextChannel, PublicError } from "@/lib"; -import { TicketButtonPresets } from "@/components/buttons"; +import { errorMessage, getTextChannel, logger, PublicError } from "@/lib"; +import { TicketButtonPresets } from "./buttons"; import * as actions from "./actions"; +import { manageConfig } from "./config"; const ticketCommand = kitten.command("ticket", { description: "Ticket-related commands",

@@ -62,7 +63,7 @@

if (error instanceof PublicError) { return errorMessage(interaction, error.message); } else { - console.error(error); + logger.error(error); return errorMessage(interaction, "An unexpected error occurred while creating the ticket."); } }

@@ -112,7 +113,7 @@ options: {

channel: option.channel("The channel to send transcripts to", { required: true }), }, async run(interaction) { - await actions.manageConfig(interaction); + await manageConfig(interaction); }, });

@@ -122,7 +123,7 @@ options: {

channel: option.channel("The channel to send the ticket prompt to", { required: true }), }, async run(interaction) { - await actions.manageConfig(interaction); + await manageConfig(interaction); }, });

@@ -132,7 +133,7 @@ options: {

category: option.channel("The category to create new tickets in", { required: true }), }, async run(interaction) { - await actions.manageConfig(interaction); + await manageConfig(interaction); }, });

@@ -140,14 +141,14 @@ // text

group.subcommand("prompt", { description: "Set the message sent in the entry point channel", async run(interaction) { - await actions.manageConfig(interaction); + await manageConfig(interaction); }, }); group.subcommand("greeting", { description: "Set the message sent in new tickets", async run(interaction) { - await actions.manageConfig(interaction); + await manageConfig(interaction); }, });
M apps/bot/src/commands/tickets/config.tsapps/bot/src/feats/tickets/config.ts

@@ -3,7 +3,7 @@ import type { Subcommand } from "@sapphire/plugin-subcommands";

import db, { eq, getGuildByDiscordId, guilds } from "@stealth-developers/db"; import { errorMessage } from "@/lib"; -import { configTextModal } from "@/components/modals/configModal"; +import { configTextModal } from "./modals"; type GuildKeys = keyof typeof guilds.$inferSelect; type ConfigOptionBase = {
D apps/bot/src/components/buttons/index.ts

@@ -1,4 +0,0 @@

-export { TicketButtons, TicketButtonPresets } from "./tickets"; -import { TicketButtons } from "./tickets"; - -export const AllButtons = [TicketButtons];
D apps/bot/src/components/buttons/newTicket.ts

@@ -1,1 +0,0 @@

-export { newTicketButton } from "./tickets/index";
M apps/bot/src/components/buttons/tickets/index.tsapps/bot/src/feats/tickets/buttons.ts

@@ -4,7 +4,7 @@ import { option } from "@purrkit/router";

import { kitten } from "@/client"; import { errorMessage, PublicError } from "@/lib"; -import * as actions from "@/commands/tickets/actions"; +import * as actions from "./actions"; export const closeTicketButton = kitten.button("b-close-ticket", { options: {
D apps/bot/src/components/index.ts

@@ -1,7 +0,0 @@

-export { configTextModal } from "./modals/configModal"; -export { newTicketButton } from "./buttons/newTicket"; - -import { AllModals } from "./modals"; -import { AllButtons } from "./buttons"; - -export const AllComponents = [...AllModals, ...AllButtons];
D apps/bot/src/components/modals/configModal.ts

@@ -1,35 +0,0 @@

-import { MessageFlags } from "discord.js"; -import { option } from "@purrkit/router"; - -import db, { eq, getGuildByDiscordId, guilds } from "@stealth-developers/db"; -import { kitten } from "@/client"; -import { errorMessage } from "@/lib"; - -export const configTextModal = kitten.modal("config-text", { - options: { - key: option.string({ required: true }), - }, - run: async (interaction, { key }) => { - const value = interaction.fields.getTextInputValue("text-value"); - - if (!interaction.guildId) - return errorMessage(interaction, "This interaction can only be used in a server."); - - const guild = await getGuildByDiscordId(interaction.guildId); - if (!guild) - return errorMessage(interaction, "Failed to update configuration: Guild not found."); - - const [res] = await db - .update(guilds) - .set({ [key]: value }) - .where(eq(guilds.id, guild.id)) - .returning(); - - if (!res) return errorMessage(interaction, "Failed to update configuration."); - - return interaction.reply({ - content: "Configuration updated successfully!", - flags: [MessageFlags.Ephemeral], - }); - }, -});
D apps/bot/src/components/modals/index.ts

@@ -1,5 +0,0 @@

-import { configTextModal } from "./configModal"; -import { TicketModals } from "./tickets"; -export { TicketModalPresets, TicketModals } from "./tickets"; - -export const AllModals = [...TicketModals, configTextModal];
M apps/bot/src/components/modals/tickets/index.tsapps/bot/src/feats/tickets/modals.ts

@@ -1,11 +1,45 @@

-import { TextInputBuilder, LabelBuilder, ModalBuilder } from "discord.js"; -import { TextInputStyle } from "discord-api-types/v9"; +import { + LabelBuilder, + MessageFlags, + ModalBuilder, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; import { option } from "@purrkit/router"; -import { getTicket } from "@stealth-developers/db"; +import db, { eq, getGuildByDiscordId, getTicket, guilds } from "@stealth-developers/db"; import { kitten } from "@/client"; import { errorMessage, upsertUser } from "@/lib"; -import * as actions from "@/commands/tickets/actions"; +import * as actions from "./actions"; + +export const configTextModal = kitten.modal("config-text", { + options: { + key: option.string({ required: true }), + }, + run: async (interaction, { key }) => { + const value = interaction.fields.getTextInputValue("text-value"); + + if (!interaction.guildId) + return errorMessage(interaction, "This interaction can only be used in a server."); + + const guild = await getGuildByDiscordId(interaction.guildId); + if (!guild) + return errorMessage(interaction, "Failed to update configuration: Guild not found."); + + const [res] = await db + .update(guilds) + .set({ [key]: value }) + .where(eq(guilds.id, guild.id)) + .returning(); + + if (!res) return errorMessage(interaction, "Failed to update configuration."); + + return interaction.reply({ + content: "Configuration updated successfully!", + flags: [MessageFlags.Ephemeral], + }); + }, +}); export const closeTicketModal = kitten.modal("close-ticket", { options: {

@@ -31,8 +65,6 @@ await actions.closeTicket(user, ticket.id, reasons);

return interaction.followUp({ content: "Ticket closed successfully" }); }, }); - -export const TicketModals = [closeTicketModal]; export const TicketModalPresets = { close: (id: string, isModerator: boolean) => {

@@ -70,3 +102,5 @@

return modal; }, }; + +export const TicketModals = [closeTicketModal, configTextModal];
A apps/bot/src/feats/index.ts

@@ -0,0 +1,5 @@

+import { ticketCommands, ticketComponents } from "./tickets"; +import { miscCommands } from "./misc"; + +export const commands = [...ticketCommands, ...miscCommands]; +export const components = [...ticketComponents];
A apps/bot/src/feats/misc/index.ts

@@ -0,0 +1,3 @@

+import { meowCommand } from "./meow"; + +export const miscCommands = [meowCommand];
A apps/bot/src/feats/tickets/index.ts

@@ -0,0 +1,6 @@

+import ticketCommand from "./commands"; +import { TicketButtons } from "./buttons"; +import { TicketModals } from "./modals"; + +export const ticketCommands = [ticketCommand]; +export const ticketComponents = [...TicketModals, ...TicketButtons];
M apps/bot/src/index.tsapps/bot/src/index.ts

@@ -1,9 +1,8 @@

import config from "@stealth-developers/config"; import { logger } from "$/logger"; -import { client, kitten } from "./client"; -import { AllComponents } from "./components"; -import commands from "./commands"; +import { client, kitten } from "@/client"; +import { commands, components } from "f/index"; const main = async () => { try {

@@ -18,7 +17,7 @@

client.once("clientReady", async (client) => { kitten.register({ commands: commands, - components: AllComponents, + components: components, }); await kitten.sync();
M apps/bot/tsconfig.jsonapps/bot/tsconfig.json

@@ -1,11 +1,12 @@

{ - "extends": ["../../tsconfig.json"], - "compilerOptions": { - "paths": { - "@/*": ["./src/*"], - "$/*": ["./src/lib/*"] - }, - "rootDir": "./src" - }, - "include": ["src/**/*"] + "extends": ["../../tsconfig.json"], + "compilerOptions": { + "paths": { + "@/*": ["./src/*"], + "$/*": ["./src/lib/*"], + "f/*": ["./src/feats/*"], + }, + "rootDir": "./src", + }, + "include": ["src/**/*"], }