refactor: 🚸 refactor and improve ux in heplers and middlewares
This commit is contained in:
parent
c4c03eecfa
commit
8b79bf11c0
11 changed files with 140 additions and 111 deletions
|
@ -16,7 +16,7 @@ export default async (interaction: ChatInputCommandInteraction) => {
|
|||
const { client, commandName } = interaction;
|
||||
|
||||
const currentCommand = client.commands.get(commandName);
|
||||
if (!currentCommand) throw new Error(`Unknown command ${commandName}`);
|
||||
if (!currentCommand) throw new Error("Command unavailable");
|
||||
|
||||
await currentCommand.execute(interaction).catch((error: Error) => {
|
||||
const buttons = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||
|
|
|
@ -12,7 +12,11 @@ export const options: IEventOptions = {
|
|||
|
||||
// Execute the event
|
||||
export const execute = async (client: Client) => {
|
||||
logger.info("Discord's API client is ready!");
|
||||
if (!client.user) throw new Error("Client user unavailable");
|
||||
|
||||
logger.info({
|
||||
message: `Connected to Discord!`,
|
||||
});
|
||||
|
||||
updatePresence(client);
|
||||
await deployCommands(client);
|
||||
|
|
|
@ -6,32 +6,30 @@ import logger from "../../middlewares/logger";
|
|||
|
||||
// Register the commands.
|
||||
export const register = async (client: Client) => {
|
||||
logger.info("🔧 Started command management");
|
||||
await checkDirectory("commands").then(async (commandNames) => {
|
||||
for await (const commandName of commandNames) {
|
||||
const commandProfiler = logger.startTimer();
|
||||
|
||||
const commandNames = await checkDirectory("commands");
|
||||
if (!commandNames) return logger.warn("No available commands found");
|
||||
await import(`../../commands/${commandName}`)
|
||||
.then((command: ICommand) => {
|
||||
client.commands.set(command.builder.name, command);
|
||||
|
||||
const totalCommands = commandNames.length;
|
||||
let loadedCommands = 0;
|
||||
commandProfiler.done({
|
||||
commandName,
|
||||
message: `Registered command '${commandName}'`,
|
||||
level: "debug",
|
||||
});
|
||||
|
||||
logger.info(`🔧 Loading ${totalCommands} commands`);
|
||||
|
||||
// Import an command.
|
||||
const importCommand = async (name: string) => {
|
||||
const command: ICommand = await import(`../../commands/${name}`);
|
||||
|
||||
client.commands.set(command.builder.name, command);
|
||||
return loadedCommands++;
|
||||
};
|
||||
|
||||
for await (const commandName of commandNames) {
|
||||
await importCommand(commandName).then(() => {
|
||||
return logger.verbose(`🔧 Loaded command "${commandName}"`);
|
||||
});
|
||||
|
||||
if (loadedCommands === totalCommands) {
|
||||
return logger.info("🔧 All commands loaded");
|
||||
return command;
|
||||
})
|
||||
.catch((error) => {
|
||||
commandProfiler.done({
|
||||
message: `Failed to register command '${commandName}'`,
|
||||
commandName,
|
||||
error,
|
||||
level: "error",
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -14,6 +14,12 @@ prisma.$use(async (params, next) => {
|
|||
`Query ${params.model}.${params.action} took ${after - before}ms`
|
||||
);
|
||||
|
||||
if (after - before >= 50) {
|
||||
logger.warn(
|
||||
`Query ${params.model}.${params.action} took ${after - before}ms`
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseInteraction, EmbedBuilder } from "discord.js";
|
||||
import getEmbedConfig from "../../helpers/getEmbedData";
|
||||
import getEmbedData from "../../helpers/getEmbedData";
|
||||
|
||||
export default async (interaction: BaseInteraction, ephemeral: boolean) => {
|
||||
if (!interaction.isRepliable())
|
||||
|
@ -9,7 +9,7 @@ export default async (interaction: BaseInteraction, ephemeral: boolean) => {
|
|||
ephemeral,
|
||||
});
|
||||
|
||||
const embedConfig = await getEmbedConfig(interaction.guild);
|
||||
const embedConfig = await getEmbedData(interaction.guild);
|
||||
|
||||
await interaction.editReply({
|
||||
embeds: [
|
||||
|
|
|
@ -1,39 +1,29 @@
|
|||
import { Client, RESTPostAPIApplicationCommandsJSONBody } from "discord.js";
|
||||
import { ICommand } from "../../interfaces/Command";
|
||||
import logger from "../../middlewares/logger";
|
||||
|
||||
export default async (client: Client) => {
|
||||
// 1. Destructure the client.
|
||||
const { application } = client;
|
||||
if (!application) throw new Error("No application found");
|
||||
|
||||
// 2. Log that we are starting the command management.
|
||||
logger.info("🔧 Started command deployment");
|
||||
const builders: Array<RESTPostAPIApplicationCommandsJSONBody> = [];
|
||||
|
||||
// 3. Get the commands.
|
||||
const commands: Array<RESTPostAPIApplicationCommandsJSONBody> = [];
|
||||
client.commands.forEach((command: ICommand) => {
|
||||
commands.push(command.builder.toJSON());
|
||||
|
||||
logger.verbose(`🔧 Loaded command "${command.builder.name}"`);
|
||||
client.commands.forEach((command) => {
|
||||
builders.push(command.builder.toJSON());
|
||||
});
|
||||
|
||||
// 4. Set the commands.
|
||||
await application.commands.set(commands).then(() => {
|
||||
logger.info("🔧 Deployed commands globally");
|
||||
await application.commands.set(builders).then(() => {
|
||||
logger.info({ builders, message: "Registered commands to users!" });
|
||||
});
|
||||
|
||||
// 5. Tell the user that development mode is enabled.
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
logger.info("🔧 Development mode enabled");
|
||||
|
||||
await application.commands
|
||||
.set(commands, process.env.DISCORD_GUILD_ID)
|
||||
.set(builders, process.env.DISCORD_GUILD_ID)
|
||||
.then(() => {
|
||||
logger.info(`🔧 Deployed commands to guild`);
|
||||
logger.info({
|
||||
builders,
|
||||
devGuildId: process.env.DISCORD_GUILD_ID,
|
||||
message: "Registered commands to development guild!",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 6. Log that we are done with the command management.
|
||||
logger.info("🔧 Finished command deployment");
|
||||
};
|
||||
|
|
|
@ -6,49 +6,51 @@ import logger from "../../middlewares/logger";
|
|||
|
||||
// Registers all available events.
|
||||
export const register = async (client: Client) => {
|
||||
logger.info("📡 Started event management");
|
||||
const profiler = logger.startTimer();
|
||||
|
||||
const eventNames = await checkDirectory("events");
|
||||
if (!eventNames) return logger.warn("No available events found");
|
||||
await checkDirectory("events").then(async (eventNames) => {
|
||||
const totalEvents = eventNames.length;
|
||||
let loadedEvents = 0;
|
||||
|
||||
const totalEvents = eventNames.length;
|
||||
let loadedEvents = 0;
|
||||
// Import an event.
|
||||
const importEvent = async (name: string) => {
|
||||
await import(`../../events/${name}`).then((event: IEvent) => {
|
||||
// Create a new event execute function.
|
||||
const eventExecutor = async (...args: Promise<void>[]) => {
|
||||
await event.execute(...args);
|
||||
};
|
||||
|
||||
logger.info(`📡 Loading ${totalEvents} events`);
|
||||
switch (event.options.type) {
|
||||
case "once":
|
||||
client.once(name, eventExecutor);
|
||||
break;
|
||||
|
||||
// Import an event.
|
||||
const importEvent = async (name: string) => {
|
||||
const event: IEvent = await import(`../../events/${name}`);
|
||||
case "on":
|
||||
client.on(name, eventExecutor);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown event type`);
|
||||
}
|
||||
|
||||
// Create a new event execute function.
|
||||
const eventExecutor = async (...args: Promise<void>[]) => {
|
||||
await event.execute(...args);
|
||||
logger.debug({
|
||||
eventName: name,
|
||||
type: event.options.type,
|
||||
message: `Listening to event '${name}'`,
|
||||
});
|
||||
return loadedEvents++;
|
||||
});
|
||||
};
|
||||
|
||||
switch (event.options.type) {
|
||||
case "once":
|
||||
client.once(name, eventExecutor);
|
||||
break;
|
||||
for await (const eventName of eventNames) {
|
||||
await importEvent(eventName);
|
||||
|
||||
case "on":
|
||||
client.on(name, eventExecutor);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`📡 Invalid event type for event: ${name}`);
|
||||
if (loadedEvents === totalEvents) {
|
||||
return profiler.done({
|
||||
message: "Successfully listening to all events!",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return loadedEvents++;
|
||||
};
|
||||
|
||||
for await (const eventName of eventNames) {
|
||||
await importEvent(eventName).then(() => {
|
||||
return logger.verbose(`📡 Loaded event "${eventName}"`);
|
||||
});
|
||||
|
||||
if (loadedEvents === totalEvents) {
|
||||
return logger.info("📡 All events loaded");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -6,19 +6,25 @@ import logger from "../../middlewares/logger";
|
|||
|
||||
// Start all jobs that are in the schedules directory
|
||||
export const start = async (client: Client) => {
|
||||
logger.info("⏰ Started job management");
|
||||
|
||||
const jobNames = await checkDirectory("schedules");
|
||||
if (!jobNames) return logger.warn("⏰ No available jobs found");
|
||||
|
||||
return await Promise.all(
|
||||
jobNames.map(async (jobName) => {
|
||||
const job: IJob = await import(`../../schedules/${jobName}`);
|
||||
|
||||
return schedule.scheduleJob(job.options.schedule, async () => {
|
||||
logger.verbose(`⏰ Performed the job "${jobName}"`);
|
||||
await job.execute(client);
|
||||
});
|
||||
await import(`../../schedules/${jobName}`)
|
||||
.then((job: IJob) => {
|
||||
return schedule.scheduleJob(job.options.schedule, async () => {
|
||||
logger.verbose(`⏰ Performed the job "${jobName}"`);
|
||||
await job.execute(client);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.warn({
|
||||
jobName,
|
||||
message: `Failed to start job ${jobName}`,
|
||||
error,
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { ActivityType, Client } from "discord.js";
|
||||
import { ActivitiesOptions, ActivityType, Client } from "discord.js";
|
||||
import logger from "../../middlewares/logger";
|
||||
|
||||
// Function
|
||||
|
@ -12,18 +12,27 @@ export default (client: Client) => {
|
|||
const memberCount = guilds.cache.reduce((a, g) => a + g.memberCount, 0);
|
||||
const guildCount = guilds.cache.size;
|
||||
|
||||
const activities: ActivitiesOptions[] = [
|
||||
{
|
||||
name: `${guildCount} guilds`,
|
||||
type: ActivityType.Watching,
|
||||
},
|
||||
{
|
||||
name: `${memberCount} members`,
|
||||
type: ActivityType.Watching,
|
||||
},
|
||||
];
|
||||
|
||||
const activity = activities[Math.floor(Math.random() * activities.length)];
|
||||
|
||||
// 3. Set the presence.
|
||||
user.setPresence({
|
||||
activities: [
|
||||
{
|
||||
name: `${guildCount} guilds | ${memberCount} members`,
|
||||
type: ActivityType.Watching,
|
||||
},
|
||||
],
|
||||
});
|
||||
user.setActivity(activity);
|
||||
|
||||
// 4. Log the presence.
|
||||
return logger.info(
|
||||
`👀 Presence set to "${guildCount} guilds | ${memberCount} members"`
|
||||
);
|
||||
return logger.debug({
|
||||
guildCount,
|
||||
memberCount,
|
||||
message: `Presence updated`,
|
||||
activity,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
import fs from "fs";
|
||||
import logger from "../../middlewares/logger";
|
||||
const fsPromises = fs.promises;
|
||||
|
||||
export default async (path: string) => {
|
||||
const result = await fsPromises.readdir(`${__dirname}/../../${path}`);
|
||||
return result;
|
||||
const directoryPath = `${process.cwd()}/dist/${path}`;
|
||||
|
||||
return await fsPromises.readdir(directoryPath).then((result) => {
|
||||
logger.debug({
|
||||
message: `Checked directory ${path}`,
|
||||
directoryPath,
|
||||
result,
|
||||
});
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import winston from "winston";
|
||||
import "winston-daily-rotate-file";
|
||||
|
||||
const { combine, timestamp, printf, errors, colorize, align, json } =
|
||||
const { combine, timestamp, json, errors, colorize, align, printf } =
|
||||
winston.format;
|
||||
|
||||
export default winston.createLogger({
|
||||
const logger = winston.createLogger({
|
||||
level: process.env.LOG_LEVEL || "info",
|
||||
format: combine(errors({ stack: true }), timestamp(), json()),
|
||||
transports: [
|
||||
new winston.transports.DailyRotateFile({
|
||||
filename: "logs/combined-%DATE%.log",
|
||||
datePattern: "YYYY-MM-DD",
|
||||
maxFiles: "14d",
|
||||
format: combine(timestamp(), json()),
|
||||
format: combine(errors({ stack: true }), timestamp(), json()),
|
||||
}),
|
||||
new winston.transports.Console({
|
||||
format: combine(
|
||||
|
@ -21,8 +21,13 @@ export default winston.createLogger({
|
|||
format: "YYYY-MM-DD HH:MM:ss",
|
||||
}),
|
||||
align(),
|
||||
printf((info) => `[${info.timestamp}] ${info.level}: ${info.message}`)
|
||||
printf(
|
||||
(info) =>
|
||||
`[${info.timestamp}] ${info.level}: ${info.stack || info.message}`
|
||||
)
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export default logger;
|
||||
|
|
Loading…
Add table
Reference in a new issue