all repos — stealth-developers @ 17c5a7d4788aa3428e55b9efc140e90ae78914da

refactor: move some things around
vi v@vt3e.cat
Tue, 07 Apr 2026 00:39:51 +0100
commit

17c5a7d4788aa3428e55b9efc140e90ae78914da

parent

f7faa6f84477635281ec459f4a3880a198bd839c

M src/database/index.tssrc/database/index.ts

@@ -3,7 +3,7 @@ import { join } from "node:path";

import { drizzle } from "drizzle-orm/bun-sqlite"; import { migrate } from "drizzle-orm/bun-sqlite/migrator"; -import { DB_FILE } from "@/utils/constants"; +import { DB_FILE } from "@/utils/config/constants"; const sqlite = new Database(DB_FILE); export const db = drizzle({ client: sqlite });
M src/events/messageCreate.tssrc/events/messageCreate.ts

@@ -18,9 +18,9 @@ import { nanoid } from "nanoid";

import Uwuifier from "uwuifier"; import config from "@/config"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import { loggers } from "@/utils/logging"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { checkUwuifyRateLimit, getRateLimitInfo } from "@/utils/rateLimit"; +import { getRateLimitInfo } from "@/utils/rateLimit"; const logger = loggers.events.child({ name: "messageCreate" }); type UploadStatus = "queued" | "uploading" | "done" | "failed";
M src/interactions/buttons/transcript-btn.tssrc/interactions/buttons/transcript-btn.ts

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

import type { ButtonInteraction, Client, GuildMember } from "discord.js"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { getTicketById } from "@/utils/queries"; -import { generateTranscript } from "@/utils/transcripts"; +import { getTicketById } from "@/database/queries"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; +import { generateTranscript } from "@/utils/tickets/transcripts"; import { db, ticketAccessLogs } from "@/database";
M src/interactions/commands/bug/_shared.tssrc/interactions/commands/bug/_shared.ts

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

import config from "@/config"; import type { Bug } from "@/database"; -import { text, thumbnail } from "@/utils/components"; +import { text, thumbnail } from "@/utils/discord/components"; import { ActionRowBuilder, type AttachmentBuilder,

@@ -21,7 +21,6 @@ TextInputBuilder,

TextInputStyle, ThumbnailBuilder, } from "discord.js"; -import { and, eq } from "drizzle-orm"; // -- types ---------------------------------------------------------------------------------------- type ProjectChoice<T extends "name" | "label" = "name"> = T extends "name"
M src/interactions/commands/bug/buttons.tssrc/interactions/commands/bug/buttons.ts

@@ -1,10 +1,10 @@

import config from "@/config"; import { bugs, db } from "@/database"; -import { getGuild } from "@/utils/queries"; +import { getGuild } from "@/database/queries"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import type { ButtonInteraction, Client, GuildMember } from "discord.js"; import { eq } from "drizzle-orm"; import { buildReportModal, updateBugEmbed } from "./_shared"; -import { hasManagerPermissions } from "@/utils/permissions"; async function fetchBugById(id: string) { const parsedId = Number(id);

@@ -155,18 +155,20 @@ content: "❌ Bug not found.",

flags: ["Ephemeral"], }); return; - } + } - const isManager = await hasManagerPermissions(interaction.member as GuildMember) - const isBugReporter = bug.authorId === interaction.user.id + const isManager = await hasManagerPermissions( + interaction.member as GuildMember, + ); + const isBugReporter = bug.authorId === interaction.user.id; - if (!isManager && !isBugReporter) { - await interaction.reply({ - content: "❌ You don't have permission to delete this bug.", - flags: ["Ephemeral"], - }); - return; - } + if (!isManager && !isBugReporter) { + await interaction.reply({ + content: "❌ You don't have permission to delete this bug.", + flags: ["Ephemeral"], + }); + return; + } await db.delete(bugs).where(eq(bugs.id, bug.id)); const { data, exists } = await getGuild(interaction.guildId);
M src/interactions/commands/bug/modals.tssrc/interactions/commands/bug/modals.ts

@@ -2,7 +2,7 @@ import { unlink, writeFile } from "node:fs/promises";

import os from "node:os"; import path from "node:path"; import { bugs, db } from "@/database"; -import { getGuild } from "@/utils/queries"; +import { getGuild } from "@/database/queries"; import { AttachmentBuilder } from "discord.js"; import type { Client, ModalSubmitInteraction } from "discord.js"; import { eq, sql } from "drizzle-orm";
M src/interactions/commands/codes.tssrc/interactions/commands/codes.ts

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

import config from "@/config"; -import { text } from "@/utils/components"; -import { tsExact, tsRelative } from "@/utils/profile"; +import { tsExact, tsRelative } from "@/roblox/profile"; +import { text } from "@/utils/discord/components"; import { type ChatInputCommandInteraction, type Client,
M src/interactions/commands/config.tssrc/interactions/commands/config.ts

@@ -9,9 +9,9 @@ import { ChannelType, type GuildChannel, type Role } from "discord.js";

import cfg from "@/config"; import { db, guild as guildTable, manager as managerTable } from "@/database"; +import { getGuild } from "@/database/queries"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import { loggers } from "@/utils/logging"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { getGuild } from "@/utils/queries"; import { eq } from "drizzle-orm"; const logger = loggers.interactions.child({ name: "configCommand" });
M src/interactions/commands/meow.tssrc/interactions/commands/meow.ts

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

-import { text } from "@/utils/components"; +import { text } from "@/utils/discord/components"; import { type ChatInputCommandInteraction, type Client,
M src/interactions/commands/roblox/getBanHistory.tssrc/interactions/commands/roblox/getBanHistory.ts

@@ -8,13 +8,13 @@ } from "discord.js";

import config from "@/config"; import { isApiErrorV2, roblox } from "@/roblox/client"; -import type { RobloxUserId } from "@/roblox/types"; -import { hasManagerPermissions } from "@/utils/permissions"; import { constructBansContainer, constructBansSummaryContainer, constructUserContainer, -} from "@/utils/profile"; +} from "@/roblox/profile"; +import type { RobloxUserId } from "@/roblox/types"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; const commandData = new SlashCommandBuilder() .setName("ban-history")
M src/interactions/commands/roblox/getUser.tssrc/interactions/commands/roblox/getUser.ts

@@ -6,9 +6,9 @@ SlashCommandBuilder,

} from "discord.js"; import { roblox } from "@/roblox/client"; +import { processRobloxUserInteraction } from "@/roblox/robloxUser"; import type { RobloxUserId } from "@/roblox/types"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { processRobloxUserInteraction } from "@/utils/robloxUser"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; const commandData = new SlashCommandBuilder() .setName("user")
M src/interactions/commands/roblox/searchUsers.tssrc/interactions/commands/roblox/searchUsers.ts

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

import { roblox } from "@/roblox/client"; -import { text } from "@/utils/components"; +import { text } from "@/utils/discord/components"; import { type ChatInputCommandInteraction, type Client,
M src/interactions/commands/ticket-manage.tssrc/interactions/commands/ticket-manage.ts

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

import { db, guild as guildTable } from "@/database"; -import { getTicketMessage } from "@/utils/queries"; +import { getTicketMessage } from "@/database/queries"; import { ActionRowBuilder, ButtonBuilder,

@@ -18,10 +18,10 @@ TextInputBuilder,

TextInputStyle, } from "discord.js"; -import { makeComponentId } from "@/utils/components"; -import { formatMessage } from "@/utils/formatting"; +import { makeComponentId } from "@/utils/discord/components"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import { loggers } from "@/utils/logging"; -import { hasManagerPermissions } from "@/utils/permissions"; +import { formatMessage } from "@/utils/tickets/formatting"; import { eq } from "drizzle-orm"; const logger = loggers.interactions.child({ name: "messageCommand" });
M src/interactions/commands/tickets/_shared.tssrc/interactions/commands/tickets/_shared.ts

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

import type { Attachment, Ticket } from "@/database"; import { getPublicUrl } from "@/utils/s3"; -import { generateTranscript } from "@/utils/transcripts"; +import { generateTranscript } from "@/utils/tickets/transcripts"; import { ActionRowBuilder, AttachmentBuilder,
M src/interactions/commands/tickets/actions.tssrc/interactions/commands/tickets/actions.ts

@@ -1,15 +1,15 @@

import { type Guild, type Ticket, db, tickets } from "@/database"; -import { text } from "@/utils/components"; -import { formatMessage } from "@/utils/formatting"; -import { loggers } from "@/utils/logging"; -import { hasManagerPermissions } from "@/utils/permissions"; import { getGuild, getManagerRoleIds, getTicket, getTicketById, -} from "@/utils/queries"; -import { generateTranscript } from "@/utils/transcripts"; +} from "@/database/queries"; +import { text } from "@/utils/discord/components"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; +import { loggers } from "@/utils/logging"; +import { formatMessage } from "@/utils/tickets/formatting"; +import { generateTranscript } from "@/utils/tickets/transcripts"; import { ActionRowBuilder, ButtonBuilder,

@@ -173,8 +173,8 @@ });

} async function sendMessage(interaction: Interaction, content: string) { - if (!interaction.channel?.isSendable()) return - await interaction.channel.send(content) + if (!interaction.channel?.isSendable()) return; + await interaction.channel.send(content); } export async function handleClose(

@@ -196,7 +196,9 @@ await interaction.editReply("❌ This ticket is already closed.");

return; } const closedByReporter = interaction.user.id === _ticket.authorId; - const isManager = await hasManagerPermissions(interaction.member as GuildMember); + const isManager = await hasManagerPermissions( + interaction.member as GuildMember, + ); const channel = interaction.channel; if (!channel || !("permissionOverwrites" in channel)) return;

@@ -240,9 +242,9 @@ ViewChannel: false,

}); } } catch (error) { - logger.error(error, `could not remove permissions for ${ticket.authorId}`); - channel.send(`Failed to update channel permissions for the ticket author.`) - } + logger.error(error, `could not remove permissions for ${ticket.authorId}`); + channel.send(`Failed to update channel permissions for the ticket author.`); + } const controls = new ActionRowBuilder<ButtonBuilder>().addComponents( new ButtonBuilder()

@@ -370,8 +372,8 @@ );

} catch (error) { logger.error(error, `Failed after all retries for ticket ${ticket.id}`); channel.send( - "⚠️ Ticket closed but failed to send transcript/notification after multiple attempts.", - ) + "⚠️ Ticket closed but failed to send transcript/notification after multiple attempts.", + ); } }
M src/interactions/commands/tickets/gdpr.tssrc/interactions/commands/tickets/gdpr.ts

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

import { db, tickets } from "@/database"; +import { getTicketByNumericId } from "@/database/queries"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import { loggers } from "@/utils/logging"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { getTicketByNumericId } from "@/utils/queries"; -import { generateTranscript } from "@/utils/transcripts"; +import { generateTranscript } from "@/utils/tickets/transcripts"; import { ActionRowBuilder, ButtonBuilder,
M src/interactions/commands/tickets/index.tssrc/interactions/commands/tickets/index.ts

@@ -9,8 +9,8 @@ } from "discord.js";

const closeLock = new Map<number, { by: string; expiresAt: number }>(); -import { parseComponentId } from "@/utils/components"; -import { getGuild, getTicket } from "@/utils/queries"; +import { getGuild, getTicket } from "@/database/queries"; +import { parseComponentId } from "@/utils/discord/components"; import { getTicketReasonModal } from "./_shared"; import { handleClose,
M src/interactions/commands/tickets/modals.tssrc/interactions/commands/tickets/modals.ts

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

+import { getGuild, getTicket } from "@/database/queries"; import { loggers } from "@/utils/logging"; -import { getGuild, getTicket } from "@/utils/queries"; import type { Client, ModalSubmitInteraction } from "discord.js"; import { INPUT_IDS } from "./_shared"; import { handleClose } from "./actions";
M src/interactions/commands/uwuify.tssrc/interactions/commands/uwuify.ts

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

import config from "@/config"; -import { text } from "@/utils/components"; -import { tsExact, tsRelative } from "@/utils/profile"; +import { tsExact, tsRelative } from "@/roblox/profile"; +import { text } from "@/utils/discord/components"; import { type ChatInputCommandInteraction, type Client,
M src/interactions/menus/getUser.tssrc/interactions/menus/getUser.ts

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

import { roblox } from "@/roblox/client"; +import { processRobloxUserInteraction } from "@/roblox/robloxUser"; import type { RobloxUserId } from "@/roblox/types"; -import { hasManagerPermissions } from "@/utils/permissions"; -import { processRobloxUserInteraction } from "@/utils/robloxUser"; +import { hasManagerPermissions } from "@/utils/discord/permissions"; import { ApplicationCommandType, type Client,
M src/interactions/menus/highlight.tssrc/interactions/menus/highlight.ts

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

-import { getGuild } from "@/utils/queries"; +import { getGuild } from "@/database/queries"; import { ApplicationCommandType, type Attachment,
M src/tasks/ticketWatcher.tssrc/tasks/ticketWatcher.ts

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

import { db, ticketMessages, tickets } from "@/database"; +import { getGuild } from "@/database/queries"; import { loggers } from "@/utils/logging"; -import { getGuild } from "@/utils/queries"; import type { Client } from "discord.js"; import { and, eq } from "drizzle-orm";
M src/utils/permissions.tssrc/utils/discord/permissions.ts

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

-import { db, guild, manager } from "@/database"; import type { GuildMember } from "discord.js"; -import { getGuild, getManagerRoleIds } from "./queries"; +import { getGuild, getManagerRoleIds } from "../../database/queries"; export async function hasManagerPermissions( member: GuildMember,
M src/utils/profile.tssrc/roblox/profile.ts

@@ -14,7 +14,7 @@ SectionBuilder,

SeparatorBuilder, TextDisplayBuilder, } from "discord.js"; -import { text, thumbnail } from "./components"; +import { text, thumbnail } from "../utils/discord/components"; // -- utils ----------------------------------------------------------------------------------------
M src/utils/robloxUser.tssrc/roblox/robloxUser.ts

@@ -1,10 +1,10 @@

import { isApiErrorV2, roblox } from "@/roblox/client"; -import type { RobloxUserId } from "@/roblox/types"; import { constructBansSummaryContainer, constructUserContainer, getBans, -} from "@/utils/profile"; +} from "@/roblox/profile"; +import type { RobloxUserId } from "@/roblox/types"; import type { ChatInputCommandInteraction, MessageContextMenuCommandInteraction,