Skip to content

Commit

Permalink
Full ES6 Re-Factor
Browse files Browse the repository at this point in the history
- We are using an experimental feature of ES6, import assertions. This allows us to import JSON files without causing issues, while sticking to the standardized ES6 module structure.
- IA will most likely become stable in the future, if not we would most likely convert JSON's to JS exportable objects, or start storing that information in other ways.
  • Loading branch information
Tyger-Git committed Sep 15, 2023
1 parent cab13c3 commit 8f6cf68
Show file tree
Hide file tree
Showing 53 changed files with 329 additions and 731 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
Expand Down
10 changes: 6 additions & 4 deletions src/commandEvents/interactionCreate/checkCommands.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//Handler for slash commands

const { devs, modServer } = require('../../../config.json');
const getLocalCommands = require('../../commandUtils/getLocalCommands');
import { devs, modServer } from '../../../config.json' assert { type: 'json' };
import getLocalCommands from '../../commandUtils/getLocalCommands';

module.exports = async (client, interaction) => {
const checkCommands = async (client, interaction) => {
if (!interaction.isChatInputCommand()) return;

const localCommands = getLocalCommands();
Expand Down Expand Up @@ -64,4 +64,6 @@ module.exports = async (client, interaction) => {
} catch (error) {
console.log(`There was an error running this command: ${error}`);
}
};
};

export default checkCommands;
5 changes: 3 additions & 2 deletions src/commandEvents/ready/consoleLog.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = (client) => {
const consoleLog = (client) => {
console.log(`${client.user.tag} is online.`);
};
};
export default consoleLog;
22 changes: 11 additions & 11 deletions src/commandEvents/ready/registerCommands.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// Initial runthrough of all slash commands, reading through and initializing them

const { modServer } = require('../../../config.json');
const areCommandsDifferent = require('../../commandUtils/areCommandsDifferent');
const getApplicationCommands = require('../../commandUtils/getApplicationCommands');
const getLocalCommands = require('../../commandUtils/getLocalCommands');
import config from '../../../config.json' assert { type: 'json' };
import areCommandsDifferent from '../../commandUtils/areCommandsDifferent.js';
import getApplicationCommands from '../../commandUtils/getApplicationCommands.js';
import getLocalCommands from '../../commandUtils/getLocalCommands.js';

module.exports = async (client) => {
const registerCommands = async (client) => {
try {
const localCommands = getLocalCommands();
const applicationCommands = await getApplicationCommands(
client,
modServer
);
const localCommands = await getLocalCommands();
const applicationCommands = await getApplicationCommands(client, config.modServer);

for (const localCommand of localCommands) {
const { name, description, options } = localCommand;
Expand Down Expand Up @@ -51,10 +48,13 @@ module.exports = async (client) => {

console.log(`👍 Registered command "${name}."`);
}
console.log(`👍 Command ${name} already registered.`)
}
} catch (error) {
console.log(`There was an error: ${error}`);
}

console.log('👍 Registered all commands.');
};
};

export default registerCommands;
104 changes: 53 additions & 51 deletions src/commandUtils/areCommandsDifferent.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
module.exports = (existingCommand, localCommand) => {
const areChoicesDifferent = (existingChoices, localChoices) => {
for (const localChoice of localChoices) {
const existingChoice = existingChoices?.find(
(choice) => choice.name === localChoice.name
);

if (!existingChoice) {
return true;
}

if (localChoice.value !== existingChoice.value) {
return true;
}
}
return false;
};

const areOptionsDifferent = (existingOptions, localOptions) => {
for (const localOption of localOptions) {
const existingOption = existingOptions?.find(
(option) => option.name === localOption.name
);

if (!existingOption) {
return true;
}

if (
localOption.description !== existingOption.description ||
localOption.type !== existingOption.type ||
(localOption.required || false) !== existingOption.required ||
(localOption.choices?.length || 0) !==
(existingOption.choices?.length || 0) ||
areChoicesDifferent(
localOption.choices || [],
existingOption.choices || []
)
) {
return true;
}
}
return false;
};

const areChoicesDifferent = (existingChoices, localChoices) => {
for (const localChoice of localChoices) {
const existingChoice = existingChoices?.find(
(choice) => choice.name === localChoice.name
);

if (!existingChoice) {
return true;
}

if (localChoice.value !== existingChoice.value) {
return true;
}
}
return false;
};

const areOptionsDifferent = (existingOptions, localOptions) => {
for (const localOption of localOptions) {
const existingOption = existingOptions?.find(
(option) => option.name === localOption.name
);

if (!existingOption) {
return true;
}

if (
existingCommand.description !== localCommand.description ||
existingCommand.options?.length !== (localCommand.options?.length || 0) ||
areOptionsDifferent(existingCommand.options, localCommand.options || [])
localOption.description !== existingOption.description ||
localOption.type !== existingOption.type ||
(localOption.required || false) !== existingOption.required ||
(localOption.choices?.length || 0) !==
(existingOption.choices?.length || 0) ||
areChoicesDifferent(
localOption.choices || [],
existingOption.choices || []
)
) {
return true;
}

return false;
};
}
return false;
};

const areCommandsDifferent = (existingCommand, localCommand) => {
if (
existingCommand.description !== localCommand.description ||
existingCommand.options?.length !== (localCommand.options?.length || 0) ||
areOptionsDifferent(existingCommand.options, localCommand.options || [])
) {
return true;
}

return false;
};

export default areCommandsDifferent;
10 changes: 6 additions & 4 deletions src/commandUtils/getAllFiles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const fs = require('fs');
const path = require('path');
import fs from 'fs';
import path from 'path';

module.exports = (directory, foldersOnly = false) => {
const getFilesInDirectory = (directory, foldersOnly = false) => {
let fileNames = [];

const files = fs.readdirSync(directory, { withFileTypes: true });
Expand All @@ -21,4 +21,6 @@ module.exports = (directory, foldersOnly = false) => {
}

return fileNames;
};
};

export default getFilesInDirectory;
22 changes: 12 additions & 10 deletions src/commandUtils/getApplicationCommands.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
module.exports = async (client, guildId) => {
let applicationCommands;
if (guildId) {
const fetchApplicationCommands = async (client, guildId) => {
let applicationCommands;

if (guildId) {
const guild = await client.guilds.fetch(guildId);
applicationCommands = guild.commands;
} else {
} else {
applicationCommands = await client.application.commands;
}

await applicationCommands.fetch();
return applicationCommands;
};
}

await applicationCommands.fetch();
return applicationCommands;
};

export default fetchApplicationCommands;
45 changes: 24 additions & 21 deletions src/commandUtils/getLocalCommands.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
const path = require('path');
const getAllFiles = require('./getAllFiles');
import path from 'path';
import getAllFiles from '../commandUtils/getAllFiles.js';
import { fileURLToPath, pathToFileURL } from 'url';

module.exports = (exceptions = []) => {
let localCommands = [];
const __dirname = path.dirname(fileURLToPath(import.meta.url));

const commandCategories = getAllFiles(
path.join(__dirname, '..', 'commands'),
true
);

for (const commandCategory of commandCategories) {
const commandFiles = getAllFiles(commandCategory);
const getLocalCommands = async (exceptions = []) => {
let localCommands = [];

for (const commandFile of commandFiles) {
const commandObject = require(commandFile);

if (exceptions.includes(commandObject.name)) {
continue;
}
const commandCategories = getAllFiles(path.join(__dirname, '..', 'commands'), true);

for (const commandCategory of commandCategories) {
const commandFiles = getAllFiles(commandCategory);

for (const commandFile of commandFiles) {
const commandFileURL = pathToFileURL(commandFile).href;
const commandObject = await import(commandFileURL).then(module => module.default);

if (exceptions.includes(commandObject.name)) {
continue;
}

localCommands.push(commandObject);
localCommands.push(commandObject);
}
}
}

return localCommands;
};
return localCommands;
};

export default getLocalCommands;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Command to get the forum tag IDs for the parent forums
/*---- Dev Only ----*/


module.exports = {
export default {
name: 'getforumtags',
description: 'Gets the forum tag IDs for the parent forums',
devOnly: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
// Front facing UX for the ticket system. It is a button menu that allows users to select a ticket type and open a ticket.
/*---- Dev Only ----*/

const {
PermissionFlagsBits,
ButtonBuilder,
EmbedBuilder,
ActionRowBuilder,
MessageEmbed,
} = require("discord.js");
const ticketSchema = require("../../schemas/ticket");
const emojis = require("../../emojis.json");
import { ButtonBuilder, EmbedBuilder, ActionRowBuilder } from "discord.js";
import emojis from "../../emojis.json" assert { type: "json" };

module.exports = {
export default {
name: 'ticketlistener',
description: 'Adds the ticket listener to the channel',
devOnly: true,
callback: async (client, interaction) => {
await interaction.deferReply();

const channel = interaction.channel;
const ticketEmbed = new EmbedBuilder()
.setColor([108,0,18])
Expand All @@ -40,37 +32,6 @@ module.exports = {
.setFooter({text: "© Sanctuary Development Team - 2023"})
;

// No longer using a dropdown menu, but keeping this code for future reference
/*
const menu = new StringSelectMenuBuilder()
.setCustomId("Select")
.setMaxValues(1)
.setPlaceholder("Select a topic.")
.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel("Report a User")
.setDescription("Do you need to report a user?")
.setValue("Report a User")
.setEmoji("<:icon_report:1140779824793788486>"),
new StringSelectMenuOptionBuilder()
.setLabel("Technical Support")
.setDescription("Are you having technical difficulties?")
.setValue("Technical Support")
.setEmoji("<:icon_tech2:1140800254141268018>"),
new StringSelectMenuOptionBuilder()
.setLabel("VIP Applications")
.setDescription("Apply for VIP / Content Creator status.")
.setValue("VIP Applications")
.setEmoji("<:icon_vip2:1140799537942900799>"),
new StringSelectMenuOptionBuilder()
.setLabel("General Support")
.setDescription("Have some general questions?")
.setValue("General Support")
.setEmoji("<:icon_general2:1140799531496263700>"),
);
const oldRow = new ActionRowBuilder().addComponents(menu);
*/

// Create Buttons
const report_button = new ButtonBuilder()
.setCustomId('report_button')
Expand Down Expand Up @@ -98,7 +59,7 @@ module.exports = {
.setEmoji(`${emojis.generalButtonEmoji}`)
.setStyle('Success');

// Create Button Row
// Create Button Rows
const row1 = new ActionRowBuilder()
.addComponents(report_button, staff_report_button);
const row2 = new ActionRowBuilder()
Expand All @@ -108,7 +69,6 @@ module.exports = {


await interaction.deleteReply(); // Delete command for cleanliness
//await channel.send({ files: [{attachment: './resources/support.png', name: 'support.png'}] });
await channel.send({ embeds: [ticketEmbed], files: [{attachment: './resources/support.png', name: 'support.png'}], components: [row1, row2, row3] });
}
}
2 changes: 1 addition & 1 deletion src/commands/misc/ping.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
name: 'ping',
description: 'Replies with the bot ping!',

Expand Down
Loading

1 comment on commit 8f6cf68

@Tyger-Git
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More IA info:

nodejs/node#46830

Please sign in to comment.