From aea3dfd3652a7505e63486730b11c7f03398009f Mon Sep 17 00:00:00 2001 From: Vermium Sifell Date: Thu, 26 Jan 2023 13:09:22 +0100 Subject: [PATCH] refactoring --- src/helpers/baseEmbeds/index.ts | 35 ------------ src/helpers/capitalizeFirstLetter/index.ts | 3 -- .../index.ts => checkPermission.ts} | 4 +- src/helpers/credits/transactionRules.ts | 18 ------- src/helpers/deferReply.ts | 25 +++++++++ .../{encryption/index.ts => encryption.ts} | 2 +- .../index.ts => getEmbedConfig.ts} | 4 +- src/helpers/pluralize/index.ts | 7 --- .../index.ts => readDirectory.ts} | 2 +- .../{auditLogger/index.ts => sendAuditLog.ts} | 6 +-- src/helpers/updatePresence.ts | 34 ++++++++++++ .../index.ts => upsertGuildMember.ts} | 2 +- src/modules/credits/index.ts | 11 ++++ .../credits/transactionTypes}/give.ts | 7 ++- .../credits/transactionTypes}/set.ts | 6 +-- .../credits/transactionTypes}/take.ts | 6 +-- .../credits/transactionTypes}/transfer.ts | 54 ++++++++++--------- src/modules/credits/validateTransaction.ts | 17 ++++++ 18 files changed, 135 insertions(+), 108 deletions(-) delete mode 100644 src/helpers/baseEmbeds/index.ts delete mode 100644 src/helpers/capitalizeFirstLetter/index.ts rename src/helpers/{checkPermission/index.ts => checkPermission.ts} (65%) delete mode 100644 src/helpers/credits/transactionRules.ts create mode 100644 src/helpers/deferReply.ts rename src/helpers/{encryption/index.ts => encryption.ts} (92%) rename src/helpers/{getEmbedData/index.ts => getEmbedConfig.ts} (93%) delete mode 100644 src/helpers/pluralize/index.ts rename src/helpers/{checkDirectory/index.ts => readDirectory.ts} (88%) rename src/helpers/{auditLogger/index.ts => sendAuditLog.ts} (88%) create mode 100644 src/helpers/updatePresence.ts rename src/helpers/{upsertGuildMember/index.ts => upsertGuildMember.ts} (93%) create mode 100644 src/modules/credits/index.ts rename src/{helpers/credits => modules/credits/transactionTypes}/give.ts (87%) rename src/{helpers/credits => modules/credits/transactionTypes}/set.ts (89%) rename src/{helpers/credits => modules/credits/transactionTypes}/take.ts (89%) rename src/{helpers/credits => modules/credits/transactionTypes}/transfer.ts (52%) create mode 100644 src/modules/credits/validateTransaction.ts diff --git a/src/helpers/baseEmbeds/index.ts b/src/helpers/baseEmbeds/index.ts deleted file mode 100644 index 5e7b94a..0000000 --- a/src/helpers/baseEmbeds/index.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { EmbedBuilder, Guild } from "discord.js"; -import getEmbedData from "../getEmbedData"; - -// Construct a base embed for success messages -export const success = async (guild: Guild | null, title: string) => { - const { successColor, footerText, footerIcon } = await getEmbedData(guild); - - return new EmbedBuilder() - .setTimestamp(new Date()) - .setTitle(title) - .setColor(successColor) - .setFooter({ text: footerText, iconURL: footerIcon }); -}; - -// Construct a base embed for wait messages -export const wait = async (guild: Guild | null, title: string) => { - const { waitColor, footerText, footerIcon } = await getEmbedData(guild); - - return new EmbedBuilder() - .setTimestamp(new Date()) - .setTitle(title) - .setColor(waitColor) - .setFooter({ text: footerText, iconURL: footerIcon }); -}; - -// Construct a base embed for error messages -export const error = async (guild: Guild | null, title: string) => { - const { errorColor, footerText, footerIcon } = await getEmbedData(guild); - - return new EmbedBuilder() - .setTimestamp(new Date()) - .setTitle(title) - .setColor(errorColor) - .setFooter({ text: footerText, iconURL: footerIcon }); -}; diff --git a/src/helpers/capitalizeFirstLetter/index.ts b/src/helpers/capitalizeFirstLetter/index.ts deleted file mode 100644 index 1190b36..0000000 --- a/src/helpers/capitalizeFirstLetter/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default (text: string): string => { - return text.charAt(0).toUpperCase() + text.slice(1); -}; diff --git a/src/helpers/checkPermission/index.ts b/src/helpers/checkPermission.ts similarity index 65% rename from src/helpers/checkPermission/index.ts rename to src/helpers/checkPermission.ts index a14c82d..029b722 100644 --- a/src/helpers/checkPermission/index.ts +++ b/src/helpers/checkPermission.ts @@ -5,8 +5,8 @@ export default ( permission: PermissionResolvable ) => { if (!interaction.memberPermissions) - throw new Error("Could not check user for permissions"); + throw new Error("Failed to check your permissions"); if (!interaction.memberPermissions.has(permission)) - throw new Error("Permission denied"); + throw new Error(`You do not have the required permission: ${permission}`); }; diff --git a/src/helpers/credits/transactionRules.ts b/src/helpers/credits/transactionRules.ts deleted file mode 100644 index ea9d7b1..0000000 --- a/src/helpers/credits/transactionRules.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Guild, User } from "discord.js"; - -export default (guild: Guild, user: User, amount: number) => { - // 1. Verify that the amount is not above 100.000.000 credits. - if (amount > 100000000) { - throw new Error("You can't give more than 1.000.000 credits."); - } - - // 2. Verify that the amount is not below 1 credits. - if (amount <= 0) { - throw new Error("You can't give below one credit."); - } - - // 3. Verify that the user is not an bot. - if (user.bot) { - throw new Error("You can't give to an bot."); - } -}; diff --git a/src/helpers/deferReply.ts b/src/helpers/deferReply.ts new file mode 100644 index 0000000..9949754 --- /dev/null +++ b/src/helpers/deferReply.ts @@ -0,0 +1,25 @@ +import { BaseInteraction, EmbedBuilder } from "discord.js"; +import getEmbedData from "./getEmbedConfig"; + +export default async (interaction: BaseInteraction, ephemeral: boolean) => { + if (!interaction.isRepliable()) + throw new Error(`Failed to reply to your request`); + + await interaction.deferReply({ ephemeral }); + + const embedConfig = await getEmbedData(interaction.guild); + + await interaction.editReply({ + embeds: [ + new EmbedBuilder() + .setFooter({ + text: embedConfig.footerText, + iconURL: embedConfig.footerIcon, + }) + .setTimestamp(new Date()) + .setTitle("⏳︱Your request are being processed") + .setColor(embedConfig.waitColor) + .setDescription("This might take a while, please wait..."), + ], + }); +}; diff --git a/src/helpers/encryption/index.ts b/src/helpers/encryption.ts similarity index 92% rename from src/helpers/encryption/index.ts rename to src/helpers/encryption.ts index 1b9fc34..ead566b 100644 --- a/src/helpers/encryption/index.ts +++ b/src/helpers/encryption.ts @@ -1,5 +1,5 @@ import crypto from "crypto"; -import { IEncryptionData } from "../../interfaces/EncryptionData"; +import { IEncryptionData } from "../interfaces/EncryptionData"; const iv = crypto.randomBytes(16); diff --git a/src/helpers/getEmbedData/index.ts b/src/helpers/getEmbedConfig.ts similarity index 93% rename from src/helpers/getEmbedData/index.ts rename to src/helpers/getEmbedConfig.ts index e3fc516..fb7ad1b 100644 --- a/src/helpers/getEmbedData/index.ts +++ b/src/helpers/getEmbedConfig.ts @@ -1,6 +1,6 @@ import { ColorResolvable, Guild } from "discord.js"; -import prisma from "../../handlers/database"; -import logger from "../../middlewares/logger"; +import prisma from "../handlers/prisma"; +import logger from "../middlewares/logger"; export default async (guild?: Guild | null) => { const { diff --git a/src/helpers/pluralize/index.ts b/src/helpers/pluralize/index.ts deleted file mode 100644 index 10a6796..0000000 --- a/src/helpers/pluralize/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import logger from "../../middlewares/logger"; - -export default (count: number, noun: string, suffix?: string): string => { - const result = `${count} ${noun}${count !== 1 ? suffix || "s" : ""}`; - logger?.silly(`Pluralized ${count} to ${result}`); - return result; -}; diff --git a/src/helpers/checkDirectory/index.ts b/src/helpers/readDirectory.ts similarity index 88% rename from src/helpers/checkDirectory/index.ts rename to src/helpers/readDirectory.ts index 6454b9a..e60f9dd 100644 --- a/src/helpers/checkDirectory/index.ts +++ b/src/helpers/readDirectory.ts @@ -1,5 +1,5 @@ import fs from "fs"; -import logger from "../../middlewares/logger"; +import logger from "../middlewares/logger"; const fsPromises = fs.promises; export default async (path: string) => { diff --git a/src/helpers/auditLogger/index.ts b/src/helpers/sendAuditLog.ts similarity index 88% rename from src/helpers/auditLogger/index.ts rename to src/helpers/sendAuditLog.ts index 5cb4092..4fc652e 100644 --- a/src/helpers/auditLogger/index.ts +++ b/src/helpers/sendAuditLog.ts @@ -1,7 +1,7 @@ import { ChannelType, EmbedBuilder, Guild } from "discord.js"; -import prisma from "../../handlers/database"; -import getEmbedConfig from "../../helpers/getEmbedData"; -import logger from "../../middlewares/logger"; +import prisma from "../handlers/prisma"; +import logger from "../middlewares/logger"; +import getEmbedConfig from "./getEmbedConfig"; export default async (guild: Guild, embed: EmbedBuilder) => { const getGuildConfigAudits = await prisma.guildConfigAudits.findUnique({ diff --git a/src/helpers/updatePresence.ts b/src/helpers/updatePresence.ts new file mode 100644 index 0000000..e85b5b6 --- /dev/null +++ b/src/helpers/updatePresence.ts @@ -0,0 +1,34 @@ +// Dependencies +import { ActivitiesOptions, ActivityType, Client } from "discord.js"; +import logger from "../middlewares/logger"; + +// Function +export default (client: Client) => { + // 1. Destructure the client. + const { guilds, user } = client; + if (!user) throw new Error("No user found"); + + // 2. Get the total number of guilds and members. + const memberCount = guilds.cache.reduce((a, g) => a + g.memberCount, 0); + const guildCount = guilds.cache.size; + + const activities: ActivitiesOptions[] = [ + { + name: `${guildCount} servers︱${memberCount} users`, + type: ActivityType.Watching, + }, + ]; + + const activity = activities[Math.floor(Math.random() * activities.length)]; + + // 3. Set the presence. + user.setActivity(activity); + + // 4. Log the presence. + return logger.debug({ + guildCount, + memberCount, + message: `Presence updated`, + activity, + }); +}; diff --git a/src/helpers/upsertGuildMember/index.ts b/src/helpers/upsertGuildMember.ts similarity index 93% rename from src/helpers/upsertGuildMember/index.ts rename to src/helpers/upsertGuildMember.ts index 2275e32..f689c78 100644 --- a/src/helpers/upsertGuildMember/index.ts +++ b/src/helpers/upsertGuildMember.ts @@ -1,5 +1,5 @@ import { Guild, User } from "discord.js"; -import db from "../../handlers/database"; +import db from "../handlers/prisma"; export default async (guild: Guild, user: User) => { return await db.guildMember.upsert({ diff --git a/src/modules/credits/index.ts b/src/modules/credits/index.ts new file mode 100644 index 0000000..680a21c --- /dev/null +++ b/src/modules/credits/index.ts @@ -0,0 +1,11 @@ +import give from "./transactionTypes/give"; +import set from "./transactionTypes/set"; +import take from "./transactionTypes/take"; +import transfer from "./transactionTypes/transfer"; + +export default { + give, + set, + take, + transfer, +}; diff --git a/src/helpers/credits/give.ts b/src/modules/credits/transactionTypes/give.ts similarity index 87% rename from src/helpers/credits/give.ts rename to src/modules/credits/transactionTypes/give.ts index 8f141fa..995c7b0 100644 --- a/src/helpers/credits/give.ts +++ b/src/modules/credits/transactionTypes/give.ts @@ -1,12 +1,11 @@ import { Guild, User } from "discord.js"; -import prisma from "../../handlers/database"; -import logger from "../../middlewares/logger"; -import transactionRules from "./transactionRules"; +import prisma from "../../../handlers/prisma"; +import validateTransaction from "../validateTransaction"; export default async (guild: Guild, user: User, amount: number) => { return await prisma.$transaction(async (tx) => { // 1. Check if the transaction is valid. - transactionRules(guild, user, amount); + validateTransaction(guild, user, amount); // 2. Make the transaction. const recipient = await tx.guildMemberCredit.upsert({ diff --git a/src/helpers/credits/set.ts b/src/modules/credits/transactionTypes/set.ts similarity index 89% rename from src/helpers/credits/set.ts rename to src/modules/credits/transactionTypes/set.ts index ac26d4d..624e51b 100644 --- a/src/helpers/credits/set.ts +++ b/src/modules/credits/transactionTypes/set.ts @@ -1,11 +1,11 @@ import { Guild, User } from "discord.js"; -import prisma from "../../handlers/database"; -import transactionRules from "./transactionRules"; +import prisma from "../../../handlers/prisma"; +import validateTransaction from "../validateTransaction"; export default async (guild: Guild, user: User, amount: number) => { return await prisma.$transaction(async (tx) => { // 1. Check if the transaction is valid. - transactionRules(guild, user, amount); + validateTransaction(guild, user, amount); // 2. Make the transaction. const recipient = await tx.guildMemberCredit.upsert({ diff --git a/src/helpers/credits/take.ts b/src/modules/credits/transactionTypes/take.ts similarity index 89% rename from src/helpers/credits/take.ts rename to src/modules/credits/transactionTypes/take.ts index 7ef1e79..014a76e 100644 --- a/src/helpers/credits/take.ts +++ b/src/modules/credits/transactionTypes/take.ts @@ -1,11 +1,11 @@ import { Guild, User } from "discord.js"; -import prisma from "../../handlers/database"; -import transactionRules from "./transactionRules"; +import prisma from "../../../handlers/prisma"; +import validateTransaction from "../validateTransaction"; export default async (guild: Guild, user: User, amount: number) => { return await prisma.$transaction(async (tx) => { // 1. Check if the transaction is valid. - transactionRules(guild, user, amount); + validateTransaction(guild, user, amount); // 2. Make the transaction. const recipient = await tx.guildMemberCredit.upsert({ diff --git a/src/helpers/credits/transfer.ts b/src/modules/credits/transactionTypes/transfer.ts similarity index 52% rename from src/helpers/credits/transfer.ts rename to src/modules/credits/transactionTypes/transfer.ts index 053b875..42a7692 100644 --- a/src/helpers/credits/transfer.ts +++ b/src/modules/credits/transactionTypes/transfer.ts @@ -1,11 +1,15 @@ import { Guild, User } from "discord.js"; -import prisma from "../../handlers/database"; -import transactionRules from "./transactionRules"; +import prisma from "../../../handlers/prisma"; +import validateTransaction from "../validateTransaction"; -export default async (guild: Guild, from: User, to: User, amount: number) => { +export default async ( + guild: Guild, + fromUser: User, + toUser: User, + amount: number +) => { return await prisma.$transaction(async (tx) => { - // 1. Decrement amount from the sender. - const sender = await tx.guildMemberCredit.upsert({ + const fromTransaction = await tx.guildMemberCredit.upsert({ update: { balance: { decrement: amount, @@ -17,8 +21,8 @@ export default async (guild: Guild, from: User, to: User, amount: number) => { create: { user: { connectOrCreate: { - create: { id: from.id }, - where: { id: from.id }, + create: { id: fromUser.id }, + where: { id: fromUser.id }, }, }, guild: { @@ -28,33 +32,30 @@ export default async (guild: Guild, from: User, to: User, amount: number) => { }, }, }, - where: { userId_guildId: { userId: from.id, guildId: guild.id } }, + where: { + userId_guildId: { userId: fromUser.id, guildId: guild.id }, + }, }, }, balance: -amount, }, where: { userId_guildId: { - userId: from.id, + userId: fromUser.id, guildId: guild.id, }, }, }); - // 4. Verify that the sender's balance didn't go below zero. - if (sender.balance < 0) { - throw new Error(`${from} doesn't have enough to send ${amount}`); + if (fromTransaction.balance < 0) { + throw new Error(`${fromUser} do not have enough credits`); } - // 5. Check if the transactions is valid. - transactionRules(guild, from, amount); - transactionRules(guild, to, amount); + if (fromUser.id === toUser.id) { + throw new Error("You can't transfer credits to yourself"); + } - // 6. Verify that sender and recipient are not the same user. - if (from.id === to.id) throw new Error("You can't transfer to yourself."); - - // 7. Increment the recipient's balance by amount. - const recipient = await tx.guildMemberCredit.upsert({ + const toTransaction = await tx.guildMemberCredit.upsert({ update: { balance: { increment: amount, @@ -66,8 +67,8 @@ export default async (guild: Guild, from: User, to: User, amount: number) => { create: { user: { connectOrCreate: { - create: { id: to.id }, - where: { id: to.id }, + create: { id: toUser.id }, + where: { id: toUser.id }, }, }, guild: { @@ -77,19 +78,22 @@ export default async (guild: Guild, from: User, to: User, amount: number) => { }, }, }, - where: { userId_guildId: { userId: to.id, guildId: guild.id } }, + where: { userId_guildId: { userId: toUser.id, guildId: guild.id } }, }, }, balance: amount, }, where: { userId_guildId: { - userId: to.id, + userId: toUser.id, guildId: guild.id, }, }, }); - return recipient; + validateTransaction(guild, fromUser, amount); + validateTransaction(guild, toUser, amount); + + return { fromTransaction, toTransaction }; }); }; diff --git a/src/modules/credits/validateTransaction.ts b/src/modules/credits/validateTransaction.ts new file mode 100644 index 0000000..f56466b --- /dev/null +++ b/src/modules/credits/validateTransaction.ts @@ -0,0 +1,17 @@ +import { Guild, User } from "discord.js"; + +export default (guild: Guild, user: User, amount: number) => { + if (!guild) { + throw new Error("Credits is only available for guilds"); + } + + // 2. Verify that the amount is not below 1 credits. + if (amount <= 0) { + throw new Error("You can't make an transaction below 1 credits"); + } + + // 3. Verify that the user is not an bot. + if (user.bot) { + throw new Error(""); + } +};