diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 2ded82e..0000000 --- a/.eslintrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "env": { - "es6": true, - "browser": true, - "es2021": true - }, - "extends": ["airbnb-base", "prettier"], - "parserOptions": { - "ecmaVersion": 12, - "sourceType": "module" - }, - "rules": { - "prettier/prettier": "error" - }, - "plugins": ["prettier"] -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..57791b5 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "rules": { + "@typescript-eslint/ban-ts-comment": 0, + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-explicit-any": 0, + "no-async-promise-executor": 0, + "prettier/prettier": "error" + } +} diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index bd84c9d..0000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "trailingComma": "es5", - "tabWidth": 2, - "tabs": true, - "semi": true, - "singleQuote": true -} diff --git a/.vscode/settings.json b/.vscode/settings.json index fb1ea2a..e6780a5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,22 +1,21 @@ { + "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.wordWrapColumn": 100, "editor.tabSize": 2, "editor.formatOnSave": true, - "javascript.format.enable": false, "files.eol": "\n", "prettier.endOfLine": "lf", "prettier.singleQuote": true, "prettier.trailingComma": "es5", "peacock.color": "#369", - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true - }, + "editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"], "cSpell.words": [ "Controlpanel", "discordjs", "hoster", "pino", "runned", + "Sifell", "Timout", "upsert", "uuidv", @@ -28,7 +27,27 @@ "editor.fontFamily": "Cascadia Code", "editor.fontLigatures": true, "git.enableCommitSigning": true, - "files.associations": { - "*.yaml": "home-assistant" + "typescript.tsdk": "node_modules\\typescript\\lib", + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#407fbf", + "activityBar.activeBorder": "#77284f", + "activityBar.background": "#407fbf", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#77284f", + "activityBarBadge.foreground": "#e7e7e7", + "sash.hoverBorder": "#407fbf", + "statusBar.background": "#336699", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#407fbf", + "statusBarItem.remoteBackground": "#336699", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#336699", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#33669999", + "titleBar.inactiveForeground": "#e7e7e799" } } diff --git a/package.json b/package.json index 3e24f06..10bb333 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "xyter", "version": "3.1.0", "description": "Earn credits while chatting! And more", - "main": "src/index.js", + "main": "src/index.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon | pino-pretty -i pid,hostname -t yyyy-mm-dd HH:MM:s" @@ -28,6 +28,7 @@ "@discordjs/rest": "^0.3.0", "axios": "^0.26.0", "better-sqlite3": "^7.5.0", + "common": "^0.2.5", "dbd-dark-dashboard": "^1.6.45", "discord-api-types": "^0.31.0", "discord-dashboard": "^2.3.14", @@ -42,9 +43,15 @@ "uuid": "^8.3.2" }, "devDependencies": { + "@types/node-schedule": "^1.3.2", + "@types/uuid": "^8.3.4", + "@typescript-eslint/eslint-plugin": "^5.15.0", + "@typescript-eslint/parser": "^5.15.0", "eslint": "8.13.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-prettier": "8.5.0", "eslint-plugin-import": "2.26.0" + "eslint-plugin-prettier": "^4.0.0", + "prettier": "^2.6.0" } } diff --git a/src/commands/admin/counter/addons/add.js b/src/commands/admin/counter/addons/add.ts similarity index 65% rename from src/commands/admin/counter/addons/add.js rename to src/commands/admin/counter/addons/add.ts index 0634edc..420dcd5 100644 --- a/src/commands/admin/counter/addons/add.js +++ b/src/commands/admin/counter/addons/add.ts @@ -1,89 +1,89 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { counters } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: 'Admin', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const channel = await interaction.options.getChannel('channel'); - const word = await interaction.options.getString('word'); - const start = await interaction.options.getNumber('start'); - - if (channel.type !== 'GUILD_TEXT') { - // Create embed object - const embed = { - title: 'Admin - Counter', - description: `That channel is not supported, it needs to be a text channel.`, - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed] }); - } - - const counterExist = await counters.findOne({ - guildId: member.guild.id, - channelId: channel.id, - word, - }); - - if (!counterExist) { - await counters.create({ - guildId: member.guild.id, - channelId: channel.id, - word, - counter: start || 0, - }); - // Create embed object - const embed = { - title: 'Admin - Counter', - description: `${channel} is now counting when hearing word ${word} and it starts at number ${ - start || 0 - }.`, - timestamp: new Date(), - color: config.colors.success, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} added ${channel.id} as a counter using word "${word}" for counting.` - ); - - // Send interaction reply - return interaction.editReply({ embeds: [embed] }); - } - // Create embed object - const embed = { - title: 'Admin - Counter', - description: `${channel} is already a counting channel.`, - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed] }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models +import counters from '../../../../helpers/database/models/counterSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: 'Admin', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const channel = await interaction.options.getChannel('channel'); + const word = await interaction.options.getString('word'); + const start = await interaction.options.getNumber('start'); + + if (channel?.type !== 'GUILD_TEXT') { + // Create embed object + const embed = { + title: 'Admin - Counter', + description: `That channel is not supported, it needs to be a text channel.`, + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + const counterExist = await counters.findOne({ + guildId: interaction?.guild?.id, + channelId: channel?.id, + word, + }); + + if (!counterExist) { + await counters.create({ + guildId: interaction?.guild?.id, + channelId: channel?.id, + word, + counter: start || 0, + }); + // Create embed object + const embed = { + title: 'Admin - Counter', + description: `${channel} is now counting when hearing word ${word} and it starts at number ${ + start || 0 + }.`, + timestamp: new Date(), + color: config.colors.success as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} added ${channel.id} as a counter using word "${word}" for counting.` + ); + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + // Create embed object + const embed = { + title: 'Admin - Counter', + description: `${channel} is already a counting channel.`, + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); +}; diff --git a/src/commands/admin/counter/addons/index.js b/src/commands/admin/counter/addons/index.js deleted file mode 100644 index 6b1d08d..0000000 --- a/src/commands/admin/counter/addons/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const add = require('./add'); -const remove = require('./remove'); - -module.exports = { add, remove }; diff --git a/src/commands/admin/counter/addons/index.ts b/src/commands/admin/counter/addons/index.ts new file mode 100644 index 0000000..8b1faf0 --- /dev/null +++ b/src/commands/admin/counter/addons/index.ts @@ -0,0 +1,4 @@ +import add from './add'; +import remove from './remove'; + +export default { add, remove }; diff --git a/src/commands/admin/counter/addons/remove.js b/src/commands/admin/counter/addons/remove.js deleted file mode 100644 index 9c42959..0000000 --- a/src/commands/admin/counter/addons/remove.js +++ /dev/null @@ -1,40 +0,0 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { counters } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: 'Admin', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const channel = await interaction.options.getChannel('channel'); - - await counters - .deleteOne({ guildId: member.guild.id, channelId: channel.id }) - .then(async () => { - interaction.editReply({ content: 'Removed' }); - }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed remove counter.` - ); -}; diff --git a/src/commands/admin/counter/addons/remove.ts b/src/commands/admin/counter/addons/remove.ts new file mode 100644 index 0000000..6d82c5f --- /dev/null +++ b/src/commands/admin/counter/addons/remove.ts @@ -0,0 +1,40 @@ +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models +import counters from '../../../../helpers/database/models/counterSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: 'Admin', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const channel = await interaction.options.getChannel('channel'); + + await counters + .deleteOne({ guildId: interaction?.guild?.id, channelId: channel?.id }) + .then(async () => { + interaction.editReply({ content: 'Removed' }); + }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} executed remove counter.` + ); +}; diff --git a/src/commands/admin/counter/index.js b/src/commands/admin/counter/index.ts similarity index 58% rename from src/commands/admin/counter/index.js rename to src/commands/admin/counter/index.ts index caeae91..2e8668f 100644 --- a/src/commands/admin/counter/index.js +++ b/src/commands/admin/counter/index.ts @@ -1,44 +1,46 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { add, remove } = require('./addons'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Counter', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If subcommand is give - if (interaction.options.getSubcommand() === 'add') { - // Execute give addon - await add(interaction); - } - - // If subcommand is take - else if (interaction.options.getSubcommand() === 'remove') { - // Execute take addon - await remove(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` - ); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import add from './addons/add'; +import remove from './addons/remove'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Counter', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + } + + // If subcommand is give + if (interaction.options.getSubcommand() === 'add') { + // Execute give addon + await add(interaction); + } + + // If subcommand is take + else if (interaction.options.getSubcommand() === 'remove') { + // Execute take addon + await remove(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } executed /${ + interaction.commandName + } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` + ); +}; diff --git a/src/commands/admin/credits/addons/give.js b/src/commands/admin/credits/addons/give.ts similarity index 57% rename from src/commands/admin/credits/addons/give.js rename to src/commands/admin/credits/addons/give.ts index 29065ec..b343b9a 100644 --- a/src/commands/admin/credits/addons/give.js +++ b/src/commands/admin/credits/addons/give.ts @@ -1,106 +1,107 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { users } = require('../../../../helpers/database/models'); - -const creditNoun = require('../../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Give]', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const user = await interaction.options.getUser('user'); - const amount = await interaction.options.getInteger('amount'); - - // If amount is zero or below - if (amount <= 0) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Give]', - description: "You can't give zero or below.", - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get toUserDB object - const toUserDB = await users.findOne({ - userId: user.id, - guildId: interaction.member.guild.id, - }); - - // If toUserDB has no credits - if (!toUserDB) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Give]', - description: - 'That user has no credits, I can not give credits to the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Deposit amount to toUserDB - toUserDB.credits += amount; - - // Save toUserDB - await toUserDB - .save() - - // If successful - .then(async () => { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Give]', - description: `Gave ${creditNoun(amount)} to ${user}.`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send debug message - await logger.debug( - `Administrator: ${interaction.user.username} gave ${ - amount <= 1 ? `${amount} credit` : `${amount} credits` - } to ${user.username}` - ); - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${member.id} gave ${user.id} ${creditNoun( - amount - )}.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models +import users from '../../../../helpers/database/models/userSchema'; + +import creditNoun from '../../../../helpers/creditNoun'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { guild, user } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Give]', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const userOption = await interaction.options.getUser('user'); + const amount = await interaction.options.getInteger('amount'); + + if (amount === null) return; + + if (amount <= 0) { + // If amount is zero or below + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Give]', + description: "You can't give zero or below.", + color: 0xbb2124, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get toUserDB object + const toUserDB = await users.findOne({ + userId: userOption?.id, + guildId: interaction?.guild?.id, + }); + + // If toUserDB has no credits + if (!toUserDB) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Give]', + description: + 'That userOption has no credits, I can not give credits to the userOption', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Deposit amount to toUserDB + toUserDB.credits += amount; + + // Save toUserDB + await toUserDB + .save() + + // If successful + .then(async () => { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Give]', + description: `Gave ${creditNoun(amount)} to ${userOption}.`, + color: 0x22bb33, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send debug message + await logger.debug( + `Administrator: ${interaction.user.username} gave ${ + amount <= 1 ? `${amount} credit` : `${amount} credits` + } to ${userOption?.username}` + ); + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${user?.id} gave ${ + userOption?.id + } ${creditNoun(amount)}.` + ); + }); +}; diff --git a/src/commands/admin/credits/addons/index.js b/src/commands/admin/credits/addons/index.js deleted file mode 100644 index 599d8aa..0000000 --- a/src/commands/admin/credits/addons/index.js +++ /dev/null @@ -1,11 +0,0 @@ -const give = require('./give'); -const set = require('./set'); -const take = require('./take'); -const transfer = require('./transfer'); - -module.exports = { - give, - set, - take, - transfer, -}; diff --git a/src/commands/admin/credits/addons/index.ts b/src/commands/admin/credits/addons/index.ts new file mode 100644 index 0000000..24e6e58 --- /dev/null +++ b/src/commands/admin/credits/addons/index.ts @@ -0,0 +1,11 @@ +import give from './give'; +import set from './set'; +import take from './take'; +import transfer from './transfer'; + +export default { + give, + set, + take, + transfer, +}; diff --git a/src/commands/admin/credits/addons/set.js b/src/commands/admin/credits/addons/set.ts similarity index 67% rename from src/commands/admin/credits/addons/set.js rename to src/commands/admin/credits/addons/set.ts index bbb1784..b8df820 100644 --- a/src/commands/admin/credits/addons/set.js +++ b/src/commands/admin/credits/addons/set.ts @@ -1,105 +1,108 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models - -const { users } = require('../../../../helpers/database/models'); -const creditNoun = require('../../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Set]', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const user = await interaction.options.getUser('user'); - const amount = await interaction.options.getInteger('amount'); - - // If amount is zero or below - if (amount <= 0) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Set]', - description: "You can't give zero or below.", - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get toUserDB object - const toUserDB = await users.findOne({ - userId: user.id, - guildId: interaction.member.guild.id, - }); - - // If toUserDB has no credits - if (!toUserDB) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Set]', - description: - 'That user has no credits, I can not set credits to the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Set toUserDB with amount - toUserDB.credits = amount; - - // Save toUserDB - await toUserDB - .save() - - // If successful - .then(async () => { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Set]', - description: `You set ${creditNoun(amount)} on ${user}.`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send debug message - await logger.debug( - `Administrator: ${interaction.user.username} set ${ - amount <= 1 ? `${amount} credit` : `${amount} credits` - } on ${user.username}` - ); - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} set ${ - user.id - } to ${creditNoun(amount)}.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models + +import users from '../../../../helpers/database/models/userSchema'; + +import creditNoun from '../../../../helpers/creditNoun'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Set]', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const user = await interaction.options.getUser('user'); + const amount = await interaction.options.getInteger('amount'); + + if (amount === null) return; + + // If amount is zero or below + if (amount <= 0) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Set]', + description: "You can't give zero or below.", + color: 0xbb2124, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get toUserDB object + const toUserDB = await users.findOne({ + userId: user?.id, + guildId: interaction?.guild?.id, + }); + + // If toUserDB has no credits + if (!toUserDB) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Set]', + description: + 'That user has no credits, I can not set credits to the user', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Set toUserDB with amount + toUserDB.credits = amount; + + // Save toUserDB + await toUserDB + .save() + + // If successful + .then(async () => { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Set]', + description: `You set ${creditNoun(amount)} on ${user}.`, + color: 0x22bb33, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send debug message + await logger.debug( + `Administrator: ${interaction.user.username} set ${ + amount <= 1 ? `${amount} credit` : `${amount} credits` + } on ${user?.username}` + ); + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} set ${ + user?.id + } to ${creditNoun(amount)}.` + ); + }); +}; diff --git a/src/commands/admin/credits/addons/take.js b/src/commands/admin/credits/addons/take.ts similarity index 58% rename from src/commands/admin/credits/addons/take.js rename to src/commands/admin/credits/addons/take.ts index d406acc..fa1b9a3 100644 --- a/src/commands/admin/credits/addons/take.js +++ b/src/commands/admin/credits/addons/take.ts @@ -1,105 +1,108 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models - -const { users } = require('../../../../helpers/database/models'); -const creditNoun = require('../../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Take]', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const user = await interaction.options.getUser('user'); - const amount = await interaction.options.getInteger('amount'); - - // If amount is zero or below - if (amount <= 0) { - // Give embed object - const embed = { - title: ':toolbox: Admin - Credits [Take]', - description: "You can't take zero or below.", - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get toUser object - const toUser = await users.findOne({ - userId: user.id, - guildId: interaction.member.guild.id, - }); - - // If toUser has no credits - if (!toUser) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Take]', - description: - 'That user has no credits, I can not take credits from the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Withdraw amount from toUser - toUser.credits -= amount; - - // Save toUser - await toUser - .save() - - // If successful - .then(async () => { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Take]', - description: `You took ${creditNoun(amount)} to ${user}.`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send debug message - await logger.debug( - `Administrator: ${interaction.user.username} took ${ - amount <= 1 ? `${amount} credit` : `${amount} credits` - } from ${user.username}` - ); - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} took ${creditNoun( - amount - )} from ${user.id}.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models + +import users from '../../../../helpers/database/models/userSchema'; + +import creditNoun from '../../../../helpers/creditNoun'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { guild, user } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Take]', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const userOption = await interaction.options.getUser('userOption'); + const amount = await interaction.options.getInteger('amount'); + + if (amount === null) return; + + // If amount is zero or below + if (amount <= 0) { + // Give embed object + const embed = { + title: ':toolbox: Admin - Credits [Take]', + description: "You can't take zero or below.", + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get toUser object + const toUser = await users.findOne({ + userId: userOption?.id, + guildId: interaction?.guild?.id, + }); + + // If toUser has no credits + if (!toUser) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Take]', + description: + 'That userOption has no credits, I can not take credits from the userOption', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Withdraw amount from toUser + toUser.credits -= amount; + + // Save toUser + await toUser + .save() + + // If successful + .then(async () => { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Take]', + description: `You took ${creditNoun(amount)} to ${userOption}.`, + color: 0x22bb33, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send debug message + await logger.debug( + `Administrator: ${interaction.user.username} took ${ + amount <= 1 ? `${amount} credit` : `${amount} credits` + } from ${userOption?.username}` + ); + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${user?.id} took ${creditNoun( + amount + )} from ${user.id}.` + ); + }); +}; diff --git a/src/commands/admin/credits/addons/transfer.js b/src/commands/admin/credits/addons/transfer.ts similarity index 64% rename from src/commands/admin/credits/addons/transfer.js rename to src/commands/admin/credits/addons/transfer.ts index d5d4dbd..1feb452 100644 --- a/src/commands/admin/credits/addons/transfer.js +++ b/src/commands/admin/credits/addons/transfer.ts @@ -1,135 +1,138 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models - -const { users } = require('../../../../helpers/database/models'); -const creditNoun = require('../../../../helpers/creditNoun'); -const saveUser = require('../../../../helpers/saveUser'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Transfer]', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const from = await interaction.options.getUser('from'); - const to = await interaction.options.getUser('to'); - const amount = await interaction.options.getInteger('amount'); - - // Get fromUser object - const fromUser = await users.findOne({ - userId: from.id, - guildId: interaction.member.guild.id, - }); - - // Get toUser object - const toUser = await users.findOne({ - userId: to.id, - guildId: interaction.member.guild.id, - }); - - // If fromUser has no credits - if (!fromUser) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Transfer]', - description: - 'That user has no credits, I can not transfer credits from the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If toUser has no credits - if (!toUser) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Transfer]', - description: - 'That user has no credits, I can not transfer credits to the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If amount is zero or below - if (amount <= 0) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Transfer]', - description: "You can't transfer zero or below.", - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Withdraw amount from fromUser - fromUser.credits -= amount; - - // Deposit amount to toUser - toUser.credits += amount; - - // Save users - await saveUser(fromUser, toUser) - // If successful - .then(async () => { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits [Transfer]', - description: `You sent ${creditNoun(amount)} from ${from} to ${to}.`, - color: config.colors.success, - fields: [ - { - name: `${from.username} Balance`, - value: `${fromUser.credits}`, - inline: true, - }, - { - name: `${to.username} Balance`, - value: `${toUser.credits}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} transferred ${creditNoun( - amount - )} from ${from.id} to ${to.id}.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models + +import users from '../../../../helpers/database/models/userSchema'; + +import creditNoun from '../../../../helpers/creditNoun'; +import saveUser from '../../../../helpers/saveUser'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Transfer]', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const from = await interaction.options.getUser('from'); + const to = await interaction.options.getUser('to'); + const amount = await interaction.options.getInteger('amount'); + + // Get fromUser object + const fromUser = await users.findOne({ + userId: from?.id, + guildId: interaction?.guild?.id, + }); + + // Get toUser object + const toUser = await users.findOne({ + userId: to?.id, + guildId: interaction?.guild?.id, + }); + + // If fromUser has no credits + if (!fromUser) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Transfer]', + description: + 'That user has no credits, I can not transfer credits from the user', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If toUser has no credits + if (!toUser) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Transfer]', + description: + 'That user has no credits, I can not transfer credits to the user', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + if (amount === null) return; + + // If amount is zero or below + if (amount <= 0) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Transfer]', + description: "You can't transfer zero or below.", + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Withdraw amount from fromUser + fromUser.credits -= amount; + + // Deposit amount to toUser + toUser.credits += amount; + + // Save users + await saveUser(fromUser, toUser) + // If successful + .then(async () => { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits [Transfer]', + description: `You sent ${creditNoun(amount)} from ${from} to ${to}.`, + color: config.colors.success as any, + fields: [ + { + name: `${from?.username} Balance`, + value: `${fromUser.credits}`, + inline: true, + }, + { + name: `${to?.username} Balance`, + value: `${toUser.credits}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } transferred ${creditNoun(amount)} from ${from?.id} to ${to?.id}.` + ); + }); +}; diff --git a/src/commands/admin/credits/index.js b/src/commands/admin/credits/index.ts similarity index 50% rename from src/commands/admin/credits/index.js rename to src/commands/admin/credits/index.ts index 60d8936..4739d25 100644 --- a/src/commands/admin/credits/index.js +++ b/src/commands/admin/credits/index.ts @@ -1,56 +1,61 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { give, take, set, transfer } = require('./addons'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':toolbox: Admin - Credits', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If subcommand is give - if (interaction.options.getSubcommand() === 'give') { - // Execute give addon - await give(interaction); - } - - // If subcommand is take - else if (interaction.options.getSubcommand() === 'take') { - // Execute take addon - await take(interaction); - } - - // If subcommand is set - else if (interaction.options.getSubcommand() === 'set') { - // Execute set addon - await set(interaction); - } - - // If subcommand is transfer - else if (interaction.options.getSubcommand() === 'transfer') { - // Execute transfer addon - await transfer(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` - ); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import give from './addons/give'; +import take from './addons/take'; +import set from './addons/set'; +import transfer from './addons/transfer'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { user, guild } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':toolbox: Admin - Credits' as string, + color: config.colors.error as any, + description: 'You do not have permission to manage this!' as string, + timestamp: new Date(), + footer: { + iconURL: config.footer.icon as string, + text: config.footer.text as string, + }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + } + + // If subcommand is give + if (interaction.options.getSubcommand() === 'give') { + // Execute give addon + await give(interaction); + } + + // If subcommand is take + else if (interaction.options.getSubcommand() === 'take') { + // Execute take addon + await take(interaction); + } + + // If subcommand is set + else if (interaction.options.getSubcommand() === 'set') { + // Execute set addon + await set(interaction); + } + + // If subcommand is transfer + else if (interaction.options.getSubcommand() === 'transfer') { + // Execute transfer addon + await transfer(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${user?.id} executed /${ + interaction.commandName + } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` + ); +}; diff --git a/src/commands/admin/index.js b/src/commands/admin/index.ts similarity index 91% rename from src/commands/admin/index.js rename to src/commands/admin/index.ts index 7f9f2c5..43f0daa 100644 --- a/src/commands/admin/index.js +++ b/src/commands/admin/index.ts @@ -1,138 +1,139 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const credits = require('./credits'); -const counter = require('./counter'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('admin') - .setDescription('Admin actions.') - .addSubcommandGroup((group) => - group - .setName('credits') - .setDescription('Manage credits.') - .addSubcommand((command) => - command - .setName('give') - .setDescription('Give credits to a user') - .addUserOption((option) => - option - .setName('user') - .setDescription('The user you want to pay.') - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('The amount you will pay.') - .setRequired(true) - ) - ) - .addSubcommand((command) => - command - .setName('set') - .setDescription('Set credits to a user') - .addUserOption((option) => - option - .setName('user') - .setDescription('The user you want to set credits on.') - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('The amount you will set.') - .setRequired(true) - ) - ) - .addSubcommand((command) => - command - .setName('take') - .setDescription('Take credits from a user') - .addUserOption((option) => - option - .setName('user') - .setDescription('The user you want to take credits from.') - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('The amount you will take.') - .setRequired(true) - ) - ) - .addSubcommand((command) => - command - .setName('transfer') - .setDescription('Transfer credits from a user to another user.') - .addUserOption((option) => - option - .setName('from') - .setDescription('The user you want to take credits from.') - .setRequired(true) - ) - .addUserOption((option) => - option - .setName('to') - .setDescription('The user you want to give credits to.') - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('The amount you will transfer.') - .setRequired(true) - ) - ) - ) - .addSubcommandGroup((group) => - group - .setName('counter') - .setDescription('Manage counters.') - .addSubcommand((command) => - command - .setName('add') - .setDescription('Add a counter') - .addChannelOption((option) => - option - .setName('channel') - .setDescription('The counter channel.') - .setRequired(true) - ) - .addStringOption((option) => - option - .setName('word') - .setDescription('The counter word.') - .setRequired(true) - ) - .addNumberOption((option) => - option.setName('start').setDescription('Start at number X.') - ) - ) - .addSubcommand((command) => - command - .setName('remove') - .setDescription('Remove a counter') - .addChannelOption((option) => - option - .setName('channel') - .setDescription('The counter channel.') - .setRequired(true) - ) - ) - ), - async execute(interaction) { - // If subcommand group is credits - if (interaction.options.getSubcommandGroup() === 'credits') { - // Execute credits group - await credits(interaction); - } - - // If subcommand group is credits - else if (interaction.options.getSubcommandGroup() === 'counter') { - // Execute credits group - await counter(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import credits from './credits'; +import counter from './counter'; + +import { CommandInteraction } from 'discord.js'; + +export default { + data: new SlashCommandBuilder() + .setName('admin') + .setDescription('Admin actions.') + .addSubcommandGroup((group) => + group + .setName('credits') + .setDescription('Manage credits.') + .addSubcommand((command) => + command + .setName('give') + .setDescription('Give credits to a user') + .addUserOption((option) => + option + .setName('user') + .setDescription('The user you want to pay.') + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('The amount you will pay.') + .setRequired(true) + ) + ) + .addSubcommand((command) => + command + .setName('set') + .setDescription('Set credits to a user') + .addUserOption((option) => + option + .setName('user') + .setDescription('The user you want to set credits on.') + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('The amount you will set.') + .setRequired(true) + ) + ) + .addSubcommand((command) => + command + .setName('take') + .setDescription('Take credits from a user') + .addUserOption((option) => + option + .setName('user') + .setDescription('The user you want to take credits from.') + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('The amount you will take.') + .setRequired(true) + ) + ) + .addSubcommand((command) => + command + .setName('transfer') + .setDescription('Transfer credits from a user to another user.') + .addUserOption((option) => + option + .setName('from') + .setDescription('The user you want to take credits from.') + .setRequired(true) + ) + .addUserOption((option) => + option + .setName('to') + .setDescription('The user you want to give credits to.') + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('The amount you will transfer.') + .setRequired(true) + ) + ) + ) + .addSubcommandGroup((group) => + group + .setName('counter') + .setDescription('Manage counters.') + .addSubcommand((command) => + command + .setName('add') + .setDescription('Add a counter') + .addChannelOption((option) => + option + .setName('channel') + .setDescription('The counter channel.') + .setRequired(true) + ) + .addStringOption((option) => + option + .setName('word') + .setDescription('The counter word.') + .setRequired(true) + ) + .addNumberOption((option) => + option.setName('start').setDescription('Start at number X.') + ) + ) + .addSubcommand((command) => + command + .setName('remove') + .setDescription('Remove a counter') + .addChannelOption((option) => + option + .setName('channel') + .setDescription('The counter channel.') + .setRequired(true) + ) + ) + ), + async execute(interaction: CommandInteraction) { + // If subcommand group is credits + if (interaction.options.getSubcommandGroup() === 'credits') { + // Execute credits group + await credits(interaction); + } + + // If subcommand group is credits + else if (interaction.options.getSubcommandGroup() === 'counter') { + // Execute credits group + await counter(interaction); + } + }, +}; diff --git a/src/commands/counter/addons/view.js b/src/commands/counter/addons/view.ts similarity index 64% rename from src/commands/counter/addons/view.js rename to src/commands/counter/addons/view.ts index 54cf258..78223d9 100644 --- a/src/commands/counter/addons/view.js +++ b/src/commands/counter/addons/view.ts @@ -1,48 +1,47 @@ -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { counters } = require('../../../helpers/database/models'); - -module.exports = async (interaction) => { - try { - // Destructure member - const { member } = await interaction; - - // Get options - const channel = await interaction.options.getChannel('channel'); - - const counter = await counters.findOne({ - guildId: member.guild.id, - channelId: channel.id, - }); - - if (!counter) { - // Create embed object - const embed = { - title: 'Counter - View', - description: `${channel} is not a counting channel.`, - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return await interaction.editReply({ embeds: [embed] }); - } - - // Create embed object - const embed = { - title: 'Counter - View', - color: config.colors.success, - description: `${channel} is currently at number ${counter.counter}.`, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return await interaction.editReply({ embeds: [embed], ephemeral: true }); - } catch (e) { - // Send debug message - await logger.error(e); - } -}; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import counters from '../../../helpers/database/models/counterSchema'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + try { + // Destructure member + const { member } = await interaction; + + // Get options + const channel = await interaction.options.getChannel('channel'); + + const counter = await counters.findOne({ + guildId: interaction?.guild?.id, + channelId: channel?.id, + }); + + if (!counter) { + // Create embed object + const embed = { + title: 'Counter - View', + description: `${channel} is not a counting channel.`, + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return await interaction.editReply({ embeds: [embed] }); + } + + // Create embed object + const embed = { + title: 'Counter - View', + color: config.colors.success as any, + description: `${channel} is currently at number ${counter.counter}.`, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return await interaction.editReply({ embeds: [embed] }); + } catch (e) { + // Send debug message + await logger.error(e); + } +}; diff --git a/src/commands/counter/index.js b/src/commands/counter/index.ts similarity index 71% rename from src/commands/counter/index.js rename to src/commands/counter/index.ts index fbec58d..3c4f328 100644 --- a/src/commands/counter/index.js +++ b/src/commands/counter/index.ts @@ -1,27 +1,28 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const view = require('./addons/view'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('counter') - .setDescription('Manage counters.') - .addSubcommand((subcommand) => - subcommand - .setName('view') - .setDescription('View a counter.') - .addChannelOption((option) => - option - .setName('channel') - .setDescription('The counter channel you want to view') - .setRequired(true) - ) - ), - async execute(interaction) { - // If subcommand is view - if (interaction.options.getSubcommand() === 'view') { - // Execute view addon - await view(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import view from './addons/view'; + +import { CommandInteraction } from 'discord.js'; + +export default { + data: new SlashCommandBuilder() + .setName('counter') + .setDescription('Manage counters.') + .addSubcommand((subcommand) => + subcommand + .setName('view') + .setDescription('View a counter.') + .addChannelOption((option) => + option + .setName('channel') + .setDescription('The counter channel you want to view') + .setRequired(true) + ) + ), + async execute(interaction: CommandInteraction) { + // If subcommand is view + if (interaction.options.getSubcommand() === 'view') { + // Execute view addon + await view(interaction); + } + }, +}; diff --git a/src/commands/credits/addons/balance.js b/src/commands/credits/addons/balance.ts similarity index 62% rename from src/commands/credits/addons/balance.js rename to src/commands/credits/addons/balance.ts index 6080407..17c69cb 100644 --- a/src/commands/credits/addons/balance.js +++ b/src/commands/credits/addons/balance.ts @@ -1,68 +1,68 @@ -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { users } = require('../../../helpers/database/models'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Get options - const user = await interaction.options.getUser('user'); - - // Get credit object - const userDB = await users.findOne({ - userId: user ? user.id : interaction.user.id, - guildId: interaction.member.guild.id, - }); - - // Destructure balance - const { credits } = userDB; - - // If !userDB - if (!userDB) { - // Create embed object - const embed = { - title: ':dollar: Credits - Balance', - description: `${ - user ? `${user} is` : 'You are' - } not found in the database.`, - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If !credits - if (!credits) { - // Create embed object - const embed = { - title: ':dollar: Credits - Balance', - description: `${user ? `${user} has` : 'You have'} no credits.`, - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If credits - if (credits) { - // Create embed object - const embed = { - title: ':dollar: Credits - Balance', - description: `${user ? `${user} has` : 'You have'} ${creditNoun( - credits - )}.`, - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } -}; +import { CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import users from '../../../helpers/database/models/userSchema'; +import creditNoun from '../../../helpers/creditNoun'; + +export default async (interaction: CommandInteraction) => { + // Get options + const user = await interaction.options.getUser('user'); + + // Get credit object + const userDB = await users.findOne({ + userId: user ? user.id : interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + // Destructure balance + const { credits } = userDB; + + // If !userDB + if (!userDB) { + // Create embed object + const embed = { + title: ':dollar: Credits - Balance', + description: `${ + user ? `${user} is` : 'You are' + } not found in the database.`, + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If !credits + if (!credits) { + // Create embed object + const embed = { + title: ':dollar: Credits - Balance', + description: `${user ? `${user} has` : 'You have'} no credits.`, + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If credits + if (credits) { + // Create embed object + const embed = { + title: ':dollar: Credits - Balance', + description: `${user ? `${user} has` : 'You have'} ${creditNoun( + credits + )}.`, + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } +}; diff --git a/src/commands/credits/addons/gift.js b/src/commands/credits/addons/gift.ts similarity index 69% rename from src/commands/credits/addons/gift.js rename to src/commands/credits/addons/gift.ts index f966f6b..92690b8 100644 --- a/src/commands/credits/addons/gift.js +++ b/src/commands/credits/addons/gift.ts @@ -1,139 +1,140 @@ -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { users } = require('../../../helpers/database/models'); -const saveUser = require('../../../helpers/saveUser'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Get options - const user = await interaction.options.getUser('user'); - const amount = await interaction.options.getInteger('amount'); - const reason = await interaction.options.getString('reason'); - - const { member } = interaction; - const { guild } = member; - - // Get fromUserDB object - const fromUserDB = await users.findOne({ - userId: interaction.user.id, - guildId: interaction.member.guild.id, - }); - - // Get toUserDB object - const toUserDB = await users.findOne({ - userId: user.id, - guildId: interaction.member.guild.id, - }); - - // If receiver is same as sender - if (user.id === interaction.user.id) { - // Create embed object - const embed = { - title: ':dollar: Credits - Gift', - description: "You can't pay yourself.", - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If amount is zero or below - if (amount <= 0) { - // Create embed object - const embed = { - title: ':dollar: Credits - Gift', - description: "You can't pay zero or below.", - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If user has below gifting amount - if (fromUserDB.credits < amount) { - // Create embed - const embed = { - title: ':dollar: Credits - Gift', - description: `You have insufficient credits. Your credits is ${fromUserDB.credits}`, - color: 0xbb2124, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If toUserDB has no credits - if (!toUserDB) { - // Create embed object - const embed = { - title: ':dollar: Credits - Gift', - description: - 'That user has no credits, I can not gift credits to the user', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Withdraw amount from fromUserDB - fromUserDB.credits -= amount; - - // Deposit amount to toUserDB - toUserDB.credits += amount; - - // Save users - await saveUser(fromUserDB, toUserDB).then(async () => { - // Create interaction embed object - const interactionEmbed = { - title: ':dollar: Credits - Gift', - description: `You sent ${creditNoun(amount)} to ${user}${ - reason ? ` with reason: ${reason}` : '' - }. Your new credits is ${creditNoun(fromUserDB.credits)}.`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Create DM embed object - const dmEmbed = { - title: ':dollar: Credits - Gift', - description: `You received ${creditNoun(amount)} from ${ - interaction.user - }${ - reason ? ` with reason: ${reason}` : '' - }. Your new credits is ${creditNoun(toUserDB.credits)}.`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Get DM user object - const dmUser = await interaction.client.users.cache.get(user.id); - - // Send DM to user - await dmUser.send({ embeds: [dmEmbed] }); - - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${member.id} gift sent from: ${interaction.user.id} to: ${user.id}` - ); - - // Send interaction reply - return interaction.editReply({ - embeds: [interactionEmbed], - ephemeral: true, - }); - }); -}; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import users from '../../../helpers/database/models/userSchema'; +import saveUser from '../../../helpers/saveUser'; +import creditNoun from '../../../helpers/creditNoun'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + // Get options + const user = await interaction.options.getUser('user'); + const amount = await interaction.options.getInteger('amount'); + const reason = await interaction.options.getString('reason'); + + const { member } = interaction; + + // Get fromUserDB object + const fromUserDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + // Get toUserDB object + const toUserDB = await users.findOne({ + userId: user?.id, + guildId: interaction?.guild?.id, + }); + + // If receiver is same as sender + if (user?.id === interaction?.user?.id) { + // Create embed object + const embed = { + title: ':dollar: Credits - Gift', + description: "You can't pay yourself.", + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + if (amount === null) return; + + // If amount is zero or below + if (amount <= 0) { + // Create embed object + const embed = { + title: ':dollar: Credits - Gift', + description: "You can't pay zero or below.", + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If user has below gifting amount + if (fromUserDB.credits < amount) { + // Create embed + const embed = { + title: ':dollar: Credits - Gift', + description: `You have insufficient credits. Your credits is ${fromUserDB.credits}`, + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If toUserDB has no credits + if (!toUserDB) { + // Create embed object + const embed = { + title: ':dollar: Credits - Gift', + description: + 'That user has no credits, I can not gift credits to the user', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Withdraw amount from fromUserDB + fromUserDB.credits -= amount; + + // Deposit amount to toUserDB + toUserDB.credits += amount; + + // Save users + await saveUser(fromUserDB, toUserDB).then(async () => { + // Create interaction embed object + const interactionEmbed = { + title: ':dollar: Credits - Gift', + description: `You sent ${creditNoun(amount)} to ${user}${ + reason ? ` with reason: ${reason}` : '' + }. Your new credits is ${creditNoun(fromUserDB.credits)}.`, + color: 0x22bb33, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Create DM embed object + const dmEmbed = { + title: ':dollar: Credits - Gift', + description: `You received ${creditNoun(amount)} from ${ + interaction.user + }${ + reason ? ` with reason: ${reason}` : '' + }. Your new credits is ${creditNoun(toUserDB.credits)}.`, + color: 0x22bb33, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Get DM user object + const dmUser = await interaction.client.users.cache.get( + interaction?.user?.id + ); + + // Send DM to user + await dmUser?.send({ embeds: [dmEmbed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} gift sent from: ${interaction?.user?.id} to: ${user?.id}` + ); + + // Send interaction reply + return interaction.editReply({ + embeds: [interactionEmbed], + }); + }); +}; diff --git a/src/commands/credits/addons/index.js b/src/commands/credits/addons/index.js deleted file mode 100644 index 69163ba..0000000 --- a/src/commands/credits/addons/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const balance = require('./balance'); -const gift = require('./gift'); -const top = require('./top'); -const work = require('./work'); - -module.exports = { balance, gift, top, work }; diff --git a/src/commands/credits/addons/index.ts b/src/commands/credits/addons/index.ts new file mode 100644 index 0000000..9a61a6c --- /dev/null +++ b/src/commands/credits/addons/index.ts @@ -0,0 +1,6 @@ +import balance from './balance'; +import gift from './gift'; +import top from './top'; +import work from './work'; + +export default { balance, gift, top, work }; diff --git a/src/commands/credits/addons/top.js b/src/commands/credits/addons/top.ts similarity index 55% rename from src/commands/credits/addons/top.js rename to src/commands/credits/addons/top.ts index 4e73ef1..175754f 100644 --- a/src/commands/credits/addons/top.js +++ b/src/commands/credits/addons/top.ts @@ -1,35 +1,35 @@ -const config = require('../../../../config.json'); -const { users } = require('../../../helpers/database/models'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Get all users in the guild - - const usersDB = await users.find({ guildId: interaction.member.guild.id }); - - const topTen = usersDB - - // Sort them after credits amount (ascending) - .sort((a, b) => (a.credits > b.credits ? -1 : 1)) - - // Return the top 10 - .slice(0, 10); - - // Create entry object - const entry = (x, index) => - `**Top ${index + 1}** - <@${x.userId}> ${creditNoun(x.credits)}`; - - // Create embed object - const embed = { - title: ':dollar: Credits - Top', - description: `Below are the top ten.\n${topTen - .map((x, index) => entry(x, index)) - .join('\n')}`, - color: 0x22bb33, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); -}; +import config from '../../../../config.json'; +import users from '../../../helpers/database/models/userSchema'; +import creditNoun from '../../../helpers/creditNoun'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + // Get all users in the guild + + const usersDB = await users.find({ guildId: interaction?.guild?.id }); + + const topTen = usersDB + + // Sort them after credits amount (ascending) + .sort((a, b) => (a.credits > b.credits ? -1 : 1)) + + // Return the top 10 + .slice(0, 10); + + // Create entry object + const entry = (x: any, index: any) => + `**Top ${index + 1}** - <@${x.userId}> ${creditNoun(x.credits)}`; + + // Create embed object + const embed = { + title: ':dollar: Credits - Top', + description: `Below are the top ten.\n${topTen + .map((x, index) => entry(x, index)) + .join('\n')}`, + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); +}; diff --git a/src/commands/credits/addons/work.js b/src/commands/credits/addons/work.ts similarity index 58% rename from src/commands/credits/addons/work.js rename to src/commands/credits/addons/work.ts index fc19073..77a4ebd 100644 --- a/src/commands/credits/addons/work.js +++ b/src/commands/credits/addons/work.ts @@ -1,93 +1,96 @@ -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); -const { guilds, users, timeouts } = require('../../../helpers/database/models'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Check if user has a timeout - const isTimeout = await timeouts.findOne({ - guildId: guild.id, - userId: member.id, - timeoutId: '2022-03-15-19-16', - }); - - const guildDB = await guilds.findOne({ - guildId: guild.id, - }); - - // If user is not on timeout - if (!isTimeout) { - // Make a variable of how much credits user will earn based on random multiplied with work rate - const creditsEarned = Math.floor(Math.random() * guildDB.credits.workRate); - - const userDB = await users.findOne({ - userId: member.id, - guildId: guild.id, - }); - - userDB.credits += creditsEarned; - - await userDB.save().then(async () => { - // Send debug message - await logger.debug(`Credits added to user: ${interaction.member.id}`); - - // Create embed object - const embed = { - title: ':dollar: Credits - Work', - description: `You have earned ${creditNoun(creditsEarned)}`, - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - }); - - // Create a timeout for the user - await timeouts.create({ - guildId: guild.id, - userId: member.id, - timeoutId: '2022-03-15-19-16', - }); - - setTimeout(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${member.id} has not worked within the last ${ - guildDB.work.timeout / 1000 - } seconds, work can be done` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: guild.id, - userId: member.id, - timeoutId: '2022-03-15-19-16', - }); - }, guildDB.credits.workTimeout); - } else { - // Create embed object - const embed = { - title: ':dollar: Credits - Work', - description: `You have worked within the last ${ - guildDB.credits.workTimeout / 1000 - } seconds, you can not work now!`, - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed] }); - - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${member.id} has worked within last day, no work can be done` - ); - } -}; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import guilds from '../../../helpers/database/models/guildSchema'; +import users from '../../../helpers/database/models/userSchema'; +import timeouts from '../../../helpers/database/models/timeoutSchema'; +import creditNoun from '../../../helpers/creditNoun'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check if user has a timeout + const isTimeout = await timeouts.findOne({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: '2022-03-15-19-16', + }); + + const guildDB = await guilds.findOne({ + guildId: interaction?.guild?.id, + }); + + // If user is not on timeout + if (!isTimeout) { + // Make a variable of how much credits user will earn based on random multiplied with work rate + const creditsEarned = Math.floor(Math.random() * guildDB.credits.workRate); + + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + userDB.credits += creditsEarned; + + await userDB.save().then(async () => { + // Send debug message + await logger.debug(`Credits added to user: ${interaction?.user?.id}`); + + // Create embed object + const embed = { + title: ':dollar: Credits - Work', + description: `You have earned ${creditNoun(creditsEarned)}`, + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + }); + + // Create a timeout for the user + await timeouts.create({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: '2022-03-15-19-16', + }); + + setTimeout(async () => { + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } has not worked within the last ${ + guildDB.work.timeout / 1000 + } seconds, work can be done` + ); + + // When timeout is out, remove it from the database + await timeouts.deleteOne({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: '2022-03-15-19-16', + }); + }, guildDB.credits.workTimeout); + } else { + // Create embed object + const embed = { + title: ':dollar: Credits - Work', + description: `You have worked within the last ${ + guildDB.credits.workTimeout / 1000 + } seconds, you can not work now!`, + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has worked within last day, no work can be done` + ); + } +}; diff --git a/src/commands/credits/index.js b/src/commands/credits/index.ts similarity index 83% rename from src/commands/credits/index.js rename to src/commands/credits/index.ts index b106d18..d5fcc4a 100644 --- a/src/commands/credits/index.js +++ b/src/commands/credits/index.ts @@ -1,71 +1,73 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const { balance, gift, top, work } = require('./addons'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('credits') - .setDescription('Manage your credits.') - .addSubcommand((subcommand) => - subcommand - .setName('balance') - .setDescription("Check a user's balance.") - .addUserOption((option) => - option - .setName('user') - .setDescription('The user whose balance you want to check.') - .setRequired(false) - ) - ) - .addSubcommand((subcommand) => - subcommand - .setName('gift') - .setDescription('Gift someone credits from your credits.') - .addUserOption((option) => - option - .setName('user') - .setDescription('The user you want to pay.') - .setRequired(true) - ) - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('The amount you will pay.') - .setRequired(true) - ) - .addStringOption((option) => - option.setName('reason').setDescription('Your reason.') - ) - ) - .addSubcommand((subcommand) => - subcommand.setName('top').setDescription('Check the top balance.') - ) - .addSubcommand((subcommand) => - subcommand.setName('work').setDescription('Work for credits.') - ), - async execute(interaction) { - // If subcommand is balance - if (interaction.options.getSubcommand() === 'balance') { - // Execute balance addon - await balance(interaction); - } - - // If subcommand is gift - else if (interaction.options.getSubcommand() === 'gift') { - // Execute gift addon - await gift(interaction); - } - - // If subcommand is top - else if (interaction.options.getSubcommand() === 'top') { - // Execute top addon - await top(interaction); - } - - // If subcommand is work - else if (interaction.options.getSubcommand() === 'work') { - // Execute work addon - await work(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import balance from './addons/balance'; +import gift from './addons/gift'; +import top from './addons/top'; +import work from './addons/work'; +import { CommandInteraction } from 'discord.js'; +export default { + data: new SlashCommandBuilder() + .setName('credits') + .setDescription('Manage your credits.') + .addSubcommand((subcommand) => + subcommand + .setName('balance') + .setDescription("Check a user's balance.") + .addUserOption((option) => + option + .setName('user') + .setDescription('The user whose balance you want to check.') + .setRequired(false) + ) + ) + .addSubcommand((subcommand) => + subcommand + .setName('gift') + .setDescription('Gift someone credits from your credits.') + .addUserOption((option) => + option + .setName('user') + .setDescription('The user you want to pay.') + .setRequired(true) + ) + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('The amount you will pay.') + .setRequired(true) + ) + .addStringOption((option) => + option.setName('reason').setDescription('Your reason.') + ) + ) + .addSubcommand((subcommand) => + subcommand.setName('top').setDescription('Check the top balance.') + ) + .addSubcommand((subcommand) => + subcommand.setName('work').setDescription('Work for credits.') + ), + async execute(interaction: CommandInteraction) { + // If subcommand is balance + if (interaction.options.getSubcommand() === 'balance') { + // Execute balance addon + await balance(interaction); + } + + // If subcommand is gift + else if (interaction.options.getSubcommand() === 'gift') { + // Execute gift addon + await gift(interaction); + } + + // If subcommand is top + else if (interaction.options.getSubcommand() === 'top') { + // Execute top addon + await top(interaction); + } + + // If subcommand is work + else if (interaction.options.getSubcommand() === 'work') { + // Execute work addon + await work(interaction); + } + }, +}; diff --git a/src/commands/profile/addons/view.js b/src/commands/profile/addons/view.ts similarity index 71% rename from src/commands/profile/addons/view.js rename to src/commands/profile/addons/view.ts index 673ef7b..82536a9 100644 --- a/src/commands/profile/addons/view.js +++ b/src/commands/profile/addons/view.ts @@ -1,75 +1,69 @@ -const i18next = require('i18next'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { - users, - credits, - experiences, -} = require('../../../helpers/database/models'); - -module.exports = async (interaction) => { - try { - // Destructure member - const { member } = await interaction; - const { guild } = member; - - // Get options - const target = await interaction.options.getUser('target'); - - // Get discord user object - const discordUser = await interaction.client.users.fetch( - `${target ? target.id : member.id}` - ); - - // Get user object - const userDB = await users.findOne({ - userId: await discordUser.id, - guildId: guild.id, - }); - - // Create embed object - const embed = { - author: { - name: `${await discordUser.username}#${await discordUser.discriminator}`, - icon_url: await discordUser.displayAvatarURL(), - }, - color: config.colors.success, - fields: [ - { - name: `:dollar: Credits`, - value: `${userDB.credits || 'Not found'}`, - inline: true, - }, - { - name: `:squeeze_bottle: Level`, - value: `${userDB.level || 'Not found'}`, - inline: true, - }, - { - name: `:squeeze_bottle: Points`, - value: `${userDB.points || 'Not found'}`, - inline: true, - }, - { - name: `:loudspeaker: Reputation`, - value: `${userDB.reputation || 'Not found'}`, - inline: true, - }, - { - name: `:rainbow_flag: Language`, - value: `${userDB.language || 'Not found'}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return await interaction.editReply({ embeds: [embed], ephemeral: true }); - } catch (e) { - // Send debug message - await logger.error(e); - } -}; +import i18next from 'i18next'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import users from '../../../helpers/database/models/userSchema'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + try { + // Destructure member + const { member } = await interaction; + + // Get options + const target = await interaction.options.getUser('target'); + + // Get discord user object + const discordUser = await interaction.client.users.fetch( + `${target ? target.id : interaction?.user?.id}` + ); + + // Get user object + const userDB = await users.findOne({ + userId: await discordUser?.id, + guildId: interaction?.guild?.id, + }); + + // Create embed object + const embed = { + author: { + name: `${await discordUser.username}#${await discordUser.discriminator}`, + icon_url: await discordUser.displayAvatarURL(), + }, + color: config.colors.success as any, + fields: [ + { + name: `:dollar: Credits`, + value: `${userDB.credits || 'Not found'}`, + inline: true, + }, + { + name: `:squeeze_bottle: Level`, + value: `${userDB.level || 'Not found'}`, + inline: true, + }, + { + name: `:squeeze_bottle: Points`, + value: `${userDB.points || 'Not found'}`, + inline: true, + }, + { + name: `:loudspeaker: Reputation`, + value: `${userDB.reputation || 'Not found'}`, + inline: true, + }, + { + name: `:rainbow_flag: Language`, + value: `${userDB.language || 'Not found'}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return await interaction.editReply({ embeds: [embed] }); + } catch (e) { + // Send debug message + await logger.error(e); + } +}; diff --git a/src/commands/profile/index.js b/src/commands/profile/index.ts similarity index 69% rename from src/commands/profile/index.js rename to src/commands/profile/index.ts index 360cf67..1cb6759 100644 --- a/src/commands/profile/index.js +++ b/src/commands/profile/index.ts @@ -1,26 +1,25 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const view = require('./addons/view'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('profile') - .setDescription('Your profile.') - .addSubcommand((subcommand) => - subcommand - .setName('view') - .setDescription('View a profile.') - .addUserOption((option) => - option - .setName('target') - .setDescription('The profile you wish to view') - ) - ), - async execute(interaction) { - // If subcommand is view - if (interaction.options.getSubcommand() === 'view') { - // Execute view addon - await view(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import view from './addons/view'; +import { CommandInteraction } from 'discord.js'; +export default { + data: new SlashCommandBuilder() + .setName('profile') + .setDescription('Your profile.') + .addSubcommand((subcommand) => + subcommand + .setName('view') + .setDescription('View a profile.') + .addUserOption((option) => + option + .setName('target') + .setDescription('The profile you wish to view') + ) + ), + async execute(interaction: CommandInteraction) { + // If subcommand is view + if (interaction.options.getSubcommand() === 'view') { + // Execute view addon + await view(interaction); + } + }, +}; diff --git a/src/commands/reputation/addons/give.js b/src/commands/reputation/addons/give.ts similarity index 66% rename from src/commands/reputation/addons/give.js rename to src/commands/reputation/addons/give.ts index 1788cbc..dc1e8fb 100644 --- a/src/commands/reputation/addons/give.js +++ b/src/commands/reputation/addons/give.ts @@ -1,122 +1,124 @@ -const i18next = require('i18next'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { users, timeouts } = require('../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Get options - const target = await interaction.options.getUser('target'); - const type = await interaction.options.getString('type'); - - // Get user object - const userDB = await users.findOne({ - userId: member.id, - guildId: guild.id, - }); - - // Check if user has a timeout - const isTimeout = await timeouts.findOne({ - guildId: guild.id, - userId: member.id, - timeoutId: 2, - }); - - // If user is not on timeout - if (!isTimeout) { - // Do not allow self reputation - if (target.id === interaction.member.id) { - // Create embed object - const embed = { - title: ':loudspeaker: Reputation - Give', - description: 'You can not repute yourself.', - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed] }); - } - - // If type is positive - if (type === 'positive') { - userDB.reputation += 1; - } - - // If type is negative - if (type === 'negative') { - userDB.reputation -= 1; - } - - // Save user - await userDB.save().then(async () => { - // Create embed object - const embed = { - title: ':loudspeaker: Reputation - Give', - description: `You have given ${target} a ${type} reputation!`, - timestamp: new Date(), - color: config.colors.success, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed] }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} has given ${target.id} a ${type} reputation.` - ); - - // Create a timeout for the user - await timeouts.create({ - guildId: member.guild.id, - userId: member.id, - timeoutId: 2, - }); - }); - - setTimeout(async () => { - // send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${ - member.id - } has not repute within last ${ - config.reputation.timeout / 1000 - } seconds, reputation can be given` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: member.guild.id, - userId: member.id, - timeoutId: 2, - }); - }, config.reputation.timeout); - } else { - // Create embed object - const embed = { - title: ':loudspeaker: Reputation - Give', - description: `You have given reputation within the last ${ - config.reputation.timeout / 1000 - } seconds, you can not repute now!`, - timestamp: new Date(), - color: config.colors.error, - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed] }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} has repute within last ${ - config.reputation.timeout / 1000 - } seconds, no reputation can be given` - ); - } -}; +import i18next from 'i18next'; +import { CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import users from '../../../helpers/database/models/userSchema'; +import timeouts from '../../../helpers/database/models/timeoutSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Get options + const target = await interaction.options.getUser('target'); + const type = await interaction.options.getString('type'); + + // Get user object + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + // Check if user has a timeout + const isTimeout = await timeouts.findOne({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: 2, + }); + + // If user is not on timeout + if (!isTimeout) { + // Do not allow self reputation + if (target?.id === interaction?.user?.id) { + // Create embed object + const embed = { + title: ':loudspeaker: Reputation - Give', + description: 'You can not repute yourself.', + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // If type is positive + if (type === 'positive') { + userDB.reputation += 1; + } + + // If type is negative + if (type === 'negative') { + userDB.reputation -= 1; + } + + // Save user + await userDB.save().then(async () => { + // Create embed object + const embed = { + title: ':loudspeaker: Reputation - Give', + description: `You have given ${target} a ${type} reputation!`, + timestamp: new Date(), + color: config.colors.success as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has given ${target?.id} a ${type} reputation.` + ); + + // Create a timeout for the user + await timeouts.create({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: 2, + }); + }); + + setTimeout(async () => { + // send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } has not repute within last ${ + config.reputation.timeout / 1000 + } seconds, reputation can be given` + ); + + // When timeout is out, remove it from the database + await timeouts.deleteOne({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + timeoutId: 2, + }); + }, config.reputation.timeout); + } else { + // Create embed object + const embed = { + title: ':loudspeaker: Reputation - Give', + description: `You have given reputation within the last ${ + config.reputation.timeout / 1000 + } seconds, you can not repute now!`, + timestamp: new Date(), + color: config.colors.error as any, + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } has repute within last ${ + config.reputation.timeout / 1000 + } seconds, no reputation can be given` + ); + } +}; diff --git a/src/commands/reputation/index.js b/src/commands/reputation/index.ts similarity index 72% rename from src/commands/reputation/index.js rename to src/commands/reputation/index.ts index 878988e..772850a 100644 --- a/src/commands/reputation/index.js +++ b/src/commands/reputation/index.ts @@ -1,47 +1,48 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { Permissions } = require('discord.js'); -const logger = require('../../handlers/logger'); - -const give = require('./addons/give'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('reputation') - .setDescription('Manage reputation.') - .addSubcommand((subcommand) => - subcommand - .setName('give') - .setDescription('Give reputation for a user') - .addUserOption((option) => - option - .setName('target') - .setDescription('The user you want to repute.') - .setRequired(true) - ) - .addStringOption((option) => - option - .setName('type') - .setDescription('What type of reputation you want to repute') - .setRequired(true) - .addChoice('Positive', 'positive') - .addChoice('Negative', 'negative') - ) - ), - async execute(interaction) { - // Destructure member - const { member } = interaction; - - // If subcommand is give - if (interaction.options.getSubcommand() === 'give') { - // Execute give addon - await give(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommand()}` - ); - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import { Permissions, CommandInteraction } from 'discord.js'; +import logger from '../../handlers/logger'; +import give from './addons/give'; + +export default { + data: new SlashCommandBuilder() + .setName('reputation') + .setDescription('Manage reputation.') + .addSubcommand((subcommand) => + subcommand + .setName('give') + .setDescription('Give reputation for a user') + .addUserOption((option) => + option + .setName('target') + .setDescription('The user you want to repute.') + .setRequired(true) + ) + .addStringOption((option) => + option + .setName('type') + .setDescription('What type of reputation you want to repute') + .setRequired(true) + .addChoice('Positive', 'positive') + .addChoice('Negative', 'negative') + ) + ), + async execute(interaction: CommandInteraction) { + // Destructure member + const { member } = interaction; + + // If subcommand is give + if (interaction.options.getSubcommand() === 'give') { + // Execute give addon + await give(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } executed /${ + interaction.commandName + } ${interaction.options.getSubcommand()}` + ); + }, +}; diff --git a/src/commands/settings/guild/addons/credits.js b/src/commands/settings/guild/addons/credits.ts similarity index 76% rename from src/commands/settings/guild/addons/credits.js rename to src/commands/settings/guild/addons/credits.ts index ab1289d..cb5ebef 100644 --- a/src/commands/settings/guild/addons/credits.js +++ b/src/commands/settings/guild/addons/credits.ts @@ -1,96 +1,95 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { guilds } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':hammer: Settings - Guild [Credits]', - color: config.colors.error, - description: `You don't have permission to manage this!`, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const status = await interaction.options.getBoolean('status'); - const rate = await interaction.options.getNumber('rate'); - const timeout = await interaction.options.getNumber('timeout'); - const minimumLength = await interaction.options.getNumber('minimum-length'); - const workRate = await interaction.options.getNumber('work-rate'); - const workTimeout = await interaction.options.getNumber('work-timeout'); - - // Get guild object - const guildDB = await guilds.findOne({ - guildId: guild.id, - }); - - // Modify values - guildDB.credits.status = status !== null ? status : guildDB.credits.status; - guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate; - guildDB.credits.timeout = - timeout !== null ? timeout : guildDB.credits.timeout; - guildDB.credits.workRate = - workRate !== null ? workRate : guildDB.credits.workRate; - guildDB.credits.workTimeout = - workTimeout !== null ? workTimeout : guildDB.credits.workTimeout; - guildDB.credits.minimumLength = - minimumLength !== null ? minimumLength : guildDB.credits.minimumLength; - - // Save guild - await guildDB.save().then(async () => { - // Create embed object - const embed = { - title: ':hammer: Settings - Guild [Credits]', - description: 'Following settings is set!', - color: config.colors.success, - fields: [ - { name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true }, - { name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true }, - { - name: '📈 Work Rate', - value: `${guildDB.credits.workRate}`, - inline: true, - }, - { - name: '🔨 Minimum Length', - value: `${guildDB.credits.minimumLength}`, - inline: true, - }, - { - name: '⏰ Timeout', - value: `${guildDB.credits.timeout}`, - inline: true, - }, - { - name: '⏰ Work Timeout', - value: `${guildDB.credits.workTimeout}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} has changed credit details.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models +import guilds from '../../../../helpers/database/models/guildSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { guild, user } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':hammer: Settings - Guild [Credits]', + color: config.colors.error as any, + description: `You don't have permission to manage this!`, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const status = await interaction.options.getBoolean('status'); + const rate = await interaction.options.getNumber('rate'); + const timeout = await interaction.options.getNumber('timeout'); + const minimumLength = await interaction.options.getNumber('minimum-length'); + const workRate = await interaction.options.getNumber('work-rate'); + const workTimeout = await interaction.options.getNumber('work-timeout'); + + // Get guild object + const guildDB = await guilds.findOne({ + guildId: guild?.id, + }); + + // Modify values + guildDB.credits.status = status !== null ? status : guildDB.credits.status; + guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate; + guildDB.credits.timeout = + timeout !== null ? timeout : guildDB.credits.timeout; + guildDB.credits.workRate = + workRate !== null ? workRate : guildDB.credits.workRate; + guildDB.credits.workTimeout = + workTimeout !== null ? workTimeout : guildDB.credits.workTimeout; + guildDB.credits.minimumLength = + minimumLength !== null ? minimumLength : guildDB.credits.minimumLength; + + // Save guild + await guildDB.save().then(async () => { + // Create embed object + const embed = { + title: ':hammer: Settings - Guild [Credits]', + description: 'Following settings is set!', + color: config.colors.success as any, + fields: [ + { name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true }, + { name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true }, + { + name: '📈 Work Rate', + value: `${guildDB.credits.workRate}`, + inline: true, + }, + { + name: '🔨 Minimum Length', + value: `${guildDB.credits.minimumLength}`, + inline: true, + }, + { + name: '⏰ Timeout', + value: `${guildDB.credits.timeout}`, + inline: true, + }, + { + name: '⏰ Work Timeout', + value: `${guildDB.credits.workTimeout}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${user.id} has changed credit details.` + ); + }); +}; diff --git a/src/commands/settings/guild/addons/index.js b/src/commands/settings/guild/addons/index.js deleted file mode 100644 index 3ce8967..0000000 --- a/src/commands/settings/guild/addons/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const pterodactyl = require('./pterodactyl'); -const credits = require('./credits'); -const points = require('./points'); - -module.exports = { pterodactyl, credits, points }; diff --git a/src/commands/settings/guild/addons/index.ts b/src/commands/settings/guild/addons/index.ts new file mode 100644 index 0000000..52501a3 --- /dev/null +++ b/src/commands/settings/guild/addons/index.ts @@ -0,0 +1,5 @@ +import pterodactyl from './pterodactyl'; +import credits from './credits'; +import points from './points'; + +export default { pterodactyl, credits, points }; diff --git a/src/commands/settings/guild/addons/points.js b/src/commands/settings/guild/addons/points.ts similarity index 71% rename from src/commands/settings/guild/addons/points.js rename to src/commands/settings/guild/addons/points.ts index deab8b9..2fdfc43 100644 --- a/src/commands/settings/guild/addons/points.js +++ b/src/commands/settings/guild/addons/points.ts @@ -1,80 +1,79 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { guilds } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':hammer: Settings - Guild [Points]', - color: config.colors.error, - description: `You don't have permission to manage this!`, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - const status = await interaction.options.getBoolean('status'); - const rate = await interaction.options.getNumber('rate'); - const timeout = await interaction.options.getNumber('timeout'); - const minimumLength = await interaction.options.getNumber('minimum-length'); - - // Get guild object - const guildDB = await guilds.findOne({ - guildId: guild.id, - }); - - // Modify values - guildDB.credits.status = status !== null ? status : guildDB.credits.status; - guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate; - guildDB.credits.timeout = - timeout !== null ? timeout : guildDB.credits.timeout; - guildDB.credits.minimumLength = - minimumLength !== null ? minimumLength : guildDB.credits.minimumLength; - - // Save guild - await guildDB.save().then(async () => { - // Create embed object - const embed = { - title: ':hammer: Settings - Guild [Points]', - description: 'Following settings is set!', - color: config.colors.success, - fields: [ - { name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true }, - { name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true }, - { - name: '🔨 Minimum Length', - value: `${guildDB.credits.minimumLength}`, - inline: true, - }, - { - name: '⏰ Timeout', - value: `${guildDB.credits.timeout}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${member.id} has changed credit details.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models +import guilds from '../../../../helpers/database/models/guildSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':hammer: Settings - Guild [Points]', + color: config.colors.error as any, + description: `You don't have permission to manage this!`, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + const status = await interaction.options.getBoolean('status'); + const rate = await interaction.options.getNumber('rate'); + const timeout = await interaction.options.getNumber('timeout'); + const minimumLength = await interaction.options.getNumber('minimum-length'); + + // Get guild object + const guildDB = await guilds.findOne({ + guildId: interaction?.guild?.id, + }); + + // Modify values + guildDB.credits.status = status !== null ? status : guildDB.credits.status; + guildDB.credits.rate = rate !== null ? rate : guildDB.credits.rate; + guildDB.credits.timeout = + timeout !== null ? timeout : guildDB.credits.timeout; + guildDB.credits.minimumLength = + minimumLength !== null ? minimumLength : guildDB.credits.minimumLength; + + // Save guild + await guildDB.save().then(async () => { + // Create embed object + const embed = { + title: ':hammer: Settings - Guild [Points]', + description: 'Following settings is set!', + color: config.colors.success as any, + fields: [ + { name: '🤖 Status', value: `${guildDB.credits.status}`, inline: true }, + { name: '📈 Rate', value: `${guildDB.credits.rate}`, inline: true }, + { + name: '🔨 Minimum Length', + value: `${guildDB.credits.minimumLength}`, + inline: true, + }, + { + name: '⏰ Timeout', + value: `${guildDB.credits.timeout}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed credit details.` + ); + }); +}; diff --git a/src/commands/settings/guild/addons/pterodactyl.js b/src/commands/settings/guild/addons/pterodactyl.ts similarity index 58% rename from src/commands/settings/guild/addons/pterodactyl.js rename to src/commands/settings/guild/addons/pterodactyl.ts index df94375..ffa564f 100644 --- a/src/commands/settings/guild/addons/pterodactyl.js +++ b/src/commands/settings/guild/addons/pterodactyl.ts @@ -1,63 +1,62 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models - -const { apis } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: ':hammer: Settings - Guild [Pterodactyl]', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Get options - - const url = await interaction.options.getString('url'); - const token = await interaction.options.getString('token'); - - // Update API credentials - - await apis - .findOneAndUpdate( - { guildId: guild.id }, - { url, token }, - { new: true, upsert: true } - ) - .then(async () => { - // Build embed - - const embed = { - title: ':hammer: Settings - Guild [Pterodactyl]', - color: config.colors.success, - description: 'Pterodactyl settings is saved!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send reply - - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - - await logger.debug( - `Guild: ${guild.id} User: ${member.id} has changed api credentials.` - ); - }); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; + +// Database models + +import apis from '../../../../helpers/database/models/apiSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: ':hammer: Settings - Guild [Pterodactyl]', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + return interaction.editReply({ embeds: [embed] }); + } + + // Get options + + const url = await interaction.options.getString('url'); + const token = await interaction.options.getString('token'); + + // Update API credentials + + await apis + .findOneAndUpdate( + { guildId: interaction?.guild?.id }, + { url, token }, + { new: true, upsert: true } + ) + .then(async () => { + // Build embed + + const embed = { + title: ':hammer: Settings - Guild [Pterodactyl]', + color: config.colors.success as any, + description: 'Pterodactyl settings is saved!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send reply + + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed api credentials.` + ); + }); +}; diff --git a/src/commands/settings/guild/index.js b/src/commands/settings/guild/index.ts similarity index 60% rename from src/commands/settings/guild/index.js rename to src/commands/settings/guild/index.ts index 6e75d48..876a49f 100644 --- a/src/commands/settings/guild/index.js +++ b/src/commands/settings/guild/index.ts @@ -1,50 +1,53 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { pterodactyl, credits, points } = require('./addons'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // Check permission - if (!member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { - // Create embed object - const embed = { - title: 'Settings - Guild', - color: config.colors.error, - description: 'You do not have permission to manage this!', - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // If subcommand is pterodactyl - if (interaction.options.getSubcommand() === 'pterodactyl') { - // Execute pterodactyl addon - await pterodactyl(interaction); - } - - // If subcommand is credits - else if (interaction.options.getSubcommand() === 'credits') { - // Execute credits addon - await credits(interaction); - } - - // If subcommand is points - else if (interaction.options.getSubcommand() === 'points') { - // Execute points addon - await points(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` - ); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import pterodactyl from './addons/pterodactyl'; +import credits from './addons/credits'; +import points from './addons/points'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Check permission + if (!interaction?.memberPermissions?.has(Permissions.FLAGS.MANAGE_GUILD)) { + // Create embed object + const embed = { + title: 'Settings - Guild', + color: config.colors.error as any, + description: 'You do not have permission to manage this!', + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + } + + // If subcommand is pterodactyl + if (interaction.options.getSubcommand() === 'pterodactyl') { + // Execute pterodactyl addon + await pterodactyl(interaction); + } + + // If subcommand is credits + else if (interaction.options.getSubcommand() === 'credits') { + // Execute credits addon + await credits(interaction); + } + + // If subcommand is points + else if (interaction.options.getSubcommand() === 'points') { + // Execute points addon + await points(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } executed /${ + interaction.commandName + } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` + ); +}; diff --git a/src/commands/settings/index.js b/src/commands/settings/index.ts similarity index 91% rename from src/commands/settings/index.js rename to src/commands/settings/index.ts index 17d10a2..e2a2c17 100644 --- a/src/commands/settings/index.js +++ b/src/commands/settings/index.ts @@ -1,128 +1,127 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { Permissions } = require('discord.js'); - -const guild = require('./guild'); -const user = require('./user'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('settings') - .setDescription('Manage settings.') - .addSubcommandGroup((group) => - group - .setName('guild') - .setDescription('Manage guild settings.') - .addSubcommand((command) => - command - .setName('pterodactyl') - .setDescription('Controlpanel.gg') - .addStringOption((option) => - option - .setName('url') - .setDescription('The api url') - .setRequired(true) - ) - .addStringOption((option) => - option - .setName('token') - .setDescription('The api token') - .setRequired(true) - ) - ) - .addSubcommand((command) => - command - .setName('credits') - .setDescription('Credits') - .addBooleanOption((option) => - option - .setName('status') - .setDescription('Should credits be enabled?') - ) - .addNumberOption((option) => - option - .setName('rate') - .setDescription('Amount of credits per message.') - ) - .addNumberOption((option) => - option - .setName('minimum-length') - .setDescription('Minimum length of message to earn credits.') - ) - .addNumberOption((option) => - option - .setName('work-rate') - .setDescription('Maximum amount of credits on work.') - ) - .addNumberOption((option) => - option - .setName('work-timeout') - .setDescription( - 'Timeout between work schedules (milliseconds).' - ) - ) - .addNumberOption((option) => - option - .setName('timeout') - .setDescription( - 'Timeout between earning credits (milliseconds).' - ) - ) - ) - .addSubcommand((command) => - command - .setName('points') - .setDescription('Points') - .addBooleanOption((option) => - option - .setName('status') - .setDescription('Should credits be enabled?') - ) - .addNumberOption((option) => - option - .setName('rate') - .setDescription('Amount of credits per message.') - ) - .addNumberOption((option) => - option - .setName('minimum-length') - .setDescription('Minimum length of message to earn credits.') - ) - .addNumberOption((option) => - option - .setName('timeout') - .setDescription( - 'Timeout between earning credits (milliseconds).' - ) - ) - ) - ) - .addSubcommandGroup((group) => - group - .setName('user') - .setDescription('Manage user settings.') - .addSubcommand((command) => - command - .setName('appearance') - .setDescription('Manage your appearance') - .addStringOption((option) => - option - .setName('language') - .setDescription('Configure your language') - .addChoice('English', 'en') - .addChoice('Swedish', 'sv') - ) - ) - ), - async execute(interaction) { - // If subcommand group is guild - if (interaction.options.getSubcommandGroup() === 'guild') { - // Execute guild group - await guild(interaction); - } - // If subcommand group is user - else if (interaction.options.getSubcommandGroup() === 'user') { - // Execute user group - await user(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import { Permissions, CommandInteraction } from 'discord.js'; +import guild from './guild'; +import user from './user'; + +export default { + data: new SlashCommandBuilder() + .setName('settings') + .setDescription('Manage settings.') + .addSubcommandGroup((group) => + group + .setName('guild') + .setDescription('Manage guild settings.') + .addSubcommand((command) => + command + .setName('pterodactyl') + .setDescription('Controlpanel.gg') + .addStringOption((option) => + option + .setName('url') + .setDescription('The api url') + .setRequired(true) + ) + .addStringOption((option) => + option + .setName('token') + .setDescription('The api token') + .setRequired(true) + ) + ) + .addSubcommand((command) => + command + .setName('credits') + .setDescription('Credits') + .addBooleanOption((option) => + option + .setName('status') + .setDescription('Should credits be enabled?') + ) + .addNumberOption((option) => + option + .setName('rate') + .setDescription('Amount of credits per message.') + ) + .addNumberOption((option) => + option + .setName('minimum-length') + .setDescription('Minimum length of message to earn credits.') + ) + .addNumberOption((option) => + option + .setName('work-rate') + .setDescription('Maximum amount of credits on work.') + ) + .addNumberOption((option) => + option + .setName('work-timeout') + .setDescription( + 'Timeout between work schedules (milliseconds).' + ) + ) + .addNumberOption((option) => + option + .setName('timeout') + .setDescription( + 'Timeout between earning credits (milliseconds).' + ) + ) + ) + .addSubcommand((command) => + command + .setName('points') + .setDescription('Points') + .addBooleanOption((option) => + option + .setName('status') + .setDescription('Should credits be enabled?') + ) + .addNumberOption((option) => + option + .setName('rate') + .setDescription('Amount of credits per message.') + ) + .addNumberOption((option) => + option + .setName('minimum-length') + .setDescription('Minimum length of message to earn credits.') + ) + .addNumberOption((option) => + option + .setName('timeout') + .setDescription( + 'Timeout between earning credits (milliseconds).' + ) + ) + ) + ) + .addSubcommandGroup((group) => + group + .setName('user') + .setDescription('Manage user settings.') + .addSubcommand((command) => + command + .setName('appearance') + .setDescription('Manage your appearance') + .addStringOption((option) => + option + .setName('language') + .setDescription('Configure your language') + .addChoice('English', 'en') + .addChoice('Swedish', 'sv') + ) + ) + ), + async execute(interaction: CommandInteraction) { + // If subcommand group is guild + if (interaction.options.getSubcommandGroup() === 'guild') { + // Execute guild group + await guild(interaction); + } + // If subcommand group is user + else if (interaction.options.getSubcommandGroup() === 'user') { + // Execute user group + await user(interaction); + } + }, +}; diff --git a/src/commands/settings/user/addons/appearance.js b/src/commands/settings/user/addons/appearance.ts similarity index 56% rename from src/commands/settings/user/addons/appearance.js rename to src/commands/settings/user/addons/appearance.ts index 55d9aef..de400c0 100644 --- a/src/commands/settings/user/addons/appearance.js +++ b/src/commands/settings/user/addons/appearance.ts @@ -1,47 +1,49 @@ -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -// Database models -const { users } = require('../../../../helpers/database/models'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - const { guild } = member; - - // Get options - const language = await interaction.options.getString('language'); - - // Get user object - const userDB = await users.findOne({ userId: member.id, guildId: guild.id }); - - // Modify values - userDB.language = language !== null ? language : userDB.language; - - // Save guild - await userDB.save().then(async () => { - // Create embed object - const embed = { - title: ':hammer: Settings - User [Appearance]', - description: 'Following settings is set!', - color: config.colors.success, - fields: [ - { - name: '🏳️‍🌈 Language', - value: `${userDB.language}`, - inline: true, - }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed], ephemeral: true }); - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} has changed appearance settings.` - ); - }); -}; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; +import { CommandInteraction } from 'discord.js'; +// Database models +import users from '../../../../helpers/database/models/userSchema'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // Get options + const language = await interaction.options.getString('language'); + + // Get user object + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + // Modify values + userDB.language = language !== null ? language : userDB.language; + + // Save guild + await userDB.save().then(async () => { + // Create embed object + const embed = { + title: ':hammer: Settings - User [Appearance]', + description: 'Following settings is set!', + color: config.colors.success as any, + fields: [ + { + name: '🏳️‍🌈 Language', + value: `${userDB.language}`, + inline: true, + }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${interaction?.user?.id} has changed appearance settings.` + ); + }); +}; diff --git a/src/commands/settings/user/addons/index.js b/src/commands/settings/user/addons/index.js deleted file mode 100644 index 1892e7a..0000000 --- a/src/commands/settings/user/addons/index.js +++ /dev/null @@ -1,3 +0,0 @@ -const appearance = require('./appearance'); - -module.exports = { appearance }; diff --git a/src/commands/settings/user/addons/index.ts b/src/commands/settings/user/addons/index.ts new file mode 100644 index 0000000..5362aba --- /dev/null +++ b/src/commands/settings/user/addons/index.ts @@ -0,0 +1,3 @@ +import appearance from './appearance'; + +export default { appearance }; diff --git a/src/commands/settings/user/index.js b/src/commands/settings/user/index.ts similarity index 51% rename from src/commands/settings/user/index.js rename to src/commands/settings/user/index.ts index 038e5e6..ba69eae 100644 --- a/src/commands/settings/user/index.js +++ b/src/commands/settings/user/index.ts @@ -1,23 +1,24 @@ -const { Permissions } = require('discord.js'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { appearance } = require('./addons'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // If subcommand is appearance - if (interaction.options.getSubcommand() === 'appearance') { - // Execute appearance addon - await appearance(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` - ); -}; +import { Permissions, CommandInteraction } from 'discord.js'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import appearance from './addons/appearance'; + +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // If subcommand is appearance + if (interaction.options.getSubcommand() === 'appearance') { + // Execute appearance addon + await appearance(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } executed /${ + interaction.commandName + } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` + ); +}; diff --git a/src/commands/shop/addons/pterodactyl.js b/src/commands/shop/addons/pterodactyl.ts similarity index 70% rename from src/commands/shop/addons/pterodactyl.js rename to src/commands/shop/addons/pterodactyl.ts index ca7f3aa..7d0c7ea 100644 --- a/src/commands/shop/addons/pterodactyl.js +++ b/src/commands/shop/addons/pterodactyl.ts @@ -1,175 +1,177 @@ -const { v4: uuidv4 } = require('uuid'); -const axios = require('axios'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { credits, apis } = require('../../../helpers/database/models'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - const { member } = interaction; - const { guild } = member; - - // Get options - const amount = await interaction.options.getInteger('amount'); - - // Get user object - const userDB = await users.findOne({ - userId: member.id, - guildId: guild.id, - }); - - // Get DM user object - const dmUser = interaction.client.users.cache.get(member.id); - - // Stop if amount or user credits is below 100 - if ((amount || userDB.credits) < 100) { - const embed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: `You **can't** withdraw for __Pterodactyl__ below **100**.`, - color: config.colors.error, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Stop if amount or user credits is above 1.000.000 - if ((amount || userDB.credits) > 1000000) { - const embed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: `You **can't** withdraw for __Pterodactyl__ above **1.000.000**.`, - color: config.colors.error, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Stop if user credits is below amount - if (userDB.credits < amount) { - const embed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: `You have **insufficient** credits.`, - color: config.colors.error, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ embeds: [embed], ephemeral: true }); - } - - // Generate a unique voucher for the user - const code = uuidv4(); - - // Get api object - const apiCredentials = await apis.findOne({ - guildId: guild.id, - }); - - // Create a api instance - const api = axios.create({ - baseURL: apiCredentials.url, - headers: { Authorization: `Bearer ${apiCredentials.token}` }, - }); - - // Get shop URL - const shopUrl = apiCredentials.url.replace('/api', '/store'); - - // Make API request - await api - - // Make a post request to the API - .post('vouchers', { - uses: 1, - code, - credits: amount || userDB.credits, - memo: `${interaction.createdTimestamp} - ${member.id}`, - }) - - // If successful - .then(async () => { - // Create DM embed object - const dmEmbed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: `Redeem this voucher [here](${shopUrl})!`, - fields: [ - { name: 'Code', value: `${code}`, inline: true }, - { - name: 'Credits', - value: `${amount || userDB.credits}`, - inline: true, - }, - ], - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Create interaction embed object - const interactionEmbed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: 'I have sent you the code in DM!', - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Withdraw amount from user credits - userDB.credits -= amount || userDB.credits; - - // Save new credits - await userDB - .save() - // If successful - .then(async () => { - // Send debug message - await logger.debug( - `User: ${member.username} redeemed: ${creditNoun(amount)}` - ); - - // Send DM message - await dmUser.send({ embeds: [dmEmbed] }); - - // Send interaction reply - await interaction.editReply({ - embeds: [interactionEmbed], - ephemeral: true, - }); - }) - - // If error occurs - .catch(async (e) => { - await logger.error(e); - const embed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: 'Something went wrong, please try again later.', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ embeds: [embed], ephemeral: true }); - }); - }) - - // If error occurs - .catch(async (e) => { - await logger.error(e); - const embed = { - title: ':shopping_cart: Shop - Pterodactyl', - description: 'Something went wrong, please try again later.', - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ embeds: [embed], ephemeral: true }); - }); -}; +import { v4 as uuidv4 } from 'uuid'; +import axios from 'axios'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import apis from '../../../helpers/database/models/apiSchema'; +import users from '../../../helpers/database/models/userSchema'; +import creditNoun from '../../../helpers/creditNoun'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + const { member } = interaction; + + // Get options + const amount = await interaction.options.getInteger('amount'); + + if (amount === null) return; + + // Get user object + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + // Get DM user object + const dmUser = interaction.client.users.cache.get(interaction?.user?.id); + + // Stop if amount or user credits is below 100 + if ((amount || userDB.credits) < 100) { + const embed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: `You **can't** withdraw for __Pterodactyl__ below **100**.`, + color: config.colors.error as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ embeds: [embed] }); + } + + // Stop if amount or user credits is above 1.000.000 + if ((amount || userDB.credits) > 1000000) { + const embed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: `You **can't** withdraw for __Pterodactyl__ above **1.000.000**.`, + color: config.colors.error as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ embeds: [embed] }); + } + + // Stop if user credits is below amount + if (userDB.credits < amount) { + const embed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: `You have **insufficient** credits.`, + color: config.colors.error as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ embeds: [embed] }); + } + + // Generate a unique voucher for the user + const code = uuidv4(); + + // Get api object + const apiCredentials = await apis.findOne({ + guildId: interaction?.guild?.id, + }); + + // Create a api instance + const api = axios.create({ + baseURL: apiCredentials.url, + headers: { Authorization: `Bearer ${apiCredentials.token}` }, + }); + + // Get shop URL + const shopUrl = apiCredentials.url.replace('/api', '/store'); + + // Make API request + await api + + // Make a post request to the API + .post('vouchers', { + uses: 1, + code, + credits: amount || userDB.credits, + memo: `${interaction.createdTimestamp} - ${interaction?.user?.id}`, + }) + + // If successful + .then(async () => { + // Create DM embed object + const dmEmbed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: `Redeem this voucher [here](${shopUrl})!`, + fields: [ + { name: 'Code', value: `${code}`, inline: true }, + { + name: 'Credits', + value: `${amount || userDB.credits}`, + inline: true, + }, + ], + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Create interaction embed object + const interactionEmbed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: 'I have sent you the code in DM!', + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Withdraw amount from user credits + userDB.credits -= amount || userDB.credits; + + // Save new credits + await userDB + .save() + // If successful + .then(async () => { + // Send debug message + await logger.debug( + `User: ${interaction?.user?.username} redeemed: ${creditNoun( + amount + )}` + ); + + // Send DM message + await dmUser?.send({ embeds: [dmEmbed] }); + + // Send interaction reply + await interaction.editReply({ + embeds: [interactionEmbed], + }); + }) + + // If error occurs + .catch(async (e: any) => { + await logger.error(e); + const embed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: 'Something went wrong, please try again later.', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ embeds: [embed] }); + }); + }) + + // If error occurs + .catch(async (e) => { + await logger.error(e); + const embed = { + title: ':shopping_cart: Shop - Pterodactyl', + description: 'Something went wrong, please try again later.', + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ embeds: [embed] }); + }); +}; diff --git a/src/commands/shop/addons/roles.js b/src/commands/shop/addons/roles.js deleted file mode 100644 index ac03f91..0000000 --- a/src/commands/shop/addons/roles.js +++ /dev/null @@ -1,47 +0,0 @@ -const { v4: uuidv4 } = require('uuid'); -const axios = require('axios'); -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -const { guilds, users } = require('../../../helpers/database/models'); -const creditNoun = require('../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - const name = interaction.options.getString('name'); - - const { member } = interaction; - const { guild } = member; - - const guildDB = await guilds.findOne({ guildId: guild.id }); - const userDB = await users.findOne({ userId: member.id, guildId: guild.id }); - - guild.roles - .create({ - data: { - name, - color: 'BLUE', - }, - reason: `${interaction.member.id} bought from shop`, - }) - .then(async (role) => { - console.log(role); - userDB.credits -= guildDB.shop.roles.pricePerHour; - await userDB.save().then(async () => { - const embed = { - title: ':shopping_cart: Shop - Roles', - description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`, - color: config.colors.error, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ - embeds: [embed], - ephemeral: true, - }); - }); - }) - .catch(console.error); -}; diff --git a/src/commands/shop/addons/roles.ts b/src/commands/shop/addons/roles.ts new file mode 100644 index 0000000..08d1873 --- /dev/null +++ b/src/commands/shop/addons/roles.ts @@ -0,0 +1,48 @@ +import { v4 as uuidv4 } from 'uuid'; +import axios from 'axios'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import guilds from '../../../helpers/database/models/guildSchema'; +import users from '../../../helpers/database/models/userSchema'; +import creditNoun from '../../../helpers/creditNoun'; +import { CommandInteraction, RoleManager } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + const name = interaction.options.getString('name'); + + const { member } = interaction; + + const guildDB = await guilds.findOne({ guildId: interaction?.guild?.id }); + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + if (name === null) return; + + (interaction?.guild?.roles as RoleManager) + .create({ + name, + color: 'BLUE', + reason: `${interaction?.user?.id} bought from shop`, + }) + .then(async (role) => { + console.log(role); + userDB.credits -= guildDB.shop.roles.pricePerHour; + await userDB.save().then(async () => { + const embed = { + title: ':shopping_cart: Shop - Roles', + description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`, + color: config.colors.error as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ + embeds: [embed], + }); + }); + }) + .catch(console.error); +}; diff --git a/src/commands/shop/index.js b/src/commands/shop/index.ts similarity index 79% rename from src/commands/shop/index.js rename to src/commands/shop/index.ts index aa939d8..74a870e 100644 --- a/src/commands/shop/index.js +++ b/src/commands/shop/index.ts @@ -1,61 +1,59 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { Permissions } = require('discord.js'); - -const guilds = require('../../helpers/database/models/guildSchema'); - -const pterodactyl = require('./addons/pterodactyl'); -const roles = require('./roles'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('shop') - .setDescription('Open our shop.') - .addSubcommand((subcommand) => - subcommand - .setName('pterodactyl') - .setDescription('Buy pterodactyl power.') - .addIntegerOption((option) => - option - .setName('amount') - .setDescription('How much credits you want to withdraw.') - ) - ) - .addSubcommandGroup((group) => - group - .setName('roles') - .setDescription('Manage custom roles.') - .addSubcommand((command) => - command - .setName('buy') - .setDescription('Buy a custom role') - .addStringOption((option) => - option - .setName('name') - .setDescription('Name of the role you wish to purchase.') - ) - ) - .addSubcommand((command) => - command - .setName('cancel') - .setDescription('Cancel a custom role') - .addRoleOption((option) => - option - .setName('role') - .setDescription('Name of the role you wish to cancel.') - ) - ) - ), - async execute(interaction) { - // If subcommand is pterodactyl - if (interaction.options.getSubcommand() === 'pterodactyl') { - // Execute pterodactyl addon - await pterodactyl(interaction); - } - - // If subcommand group is roles - else if (interaction.options.getSubcommandGroup() === 'roles') { - // Execute roles addon - await roles(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import { Permissions, CommandInteraction } from 'discord.js'; +import guilds from '../../helpers/database/models/guildSchema'; +import pterodactyl from './addons/pterodactyl'; +import roles from './roles'; + +export default { + data: new SlashCommandBuilder() + .setName('shop') + .setDescription('Open our shop.') + .addSubcommand((subcommand) => + subcommand + .setName('pterodactyl') + .setDescription('Buy pterodactyl power.') + .addIntegerOption((option) => + option + .setName('amount') + .setDescription('How much credits you want to withdraw.') + ) + ) + .addSubcommandGroup((group) => + group + .setName('roles') + .setDescription('Manage custom roles.') + .addSubcommand((command) => + command + .setName('buy') + .setDescription('Buy a custom role') + .addStringOption((option) => + option + .setName('name') + .setDescription('Name of the role you wish to purchase.') + ) + ) + .addSubcommand((command) => + command + .setName('cancel') + .setDescription('Cancel a custom role') + .addRoleOption((option) => + option + .setName('role') + .setDescription('Name of the role you wish to cancel.') + ) + ) + ), + async execute(interaction: CommandInteraction) { + // If subcommand is pterodactyl + if (interaction.options.getSubcommand() === 'pterodactyl') { + // Execute pterodactyl addon + await pterodactyl(interaction); + } + + // If subcommand group is roles + else if (interaction.options.getSubcommandGroup() === 'roles') { + // Execute roles addon + await roles(interaction); + } + }, +}; diff --git a/src/commands/shop/roles/addons/buy.js b/src/commands/shop/roles/addons/buy.js deleted file mode 100644 index 6295585..0000000 --- a/src/commands/shop/roles/addons/buy.js +++ /dev/null @@ -1,68 +0,0 @@ -const { v4: uuidv4 } = require('uuid'); -const axios = require('axios'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -const { - users, - shopRoles, - guilds, -} = require('../../../../helpers/database/models'); -const creditNoun = require('../../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - const { member } = interaction; - const { guild } = member; - - const name = await interaction.options.getString('name'); - - await interaction.guild.roles - .create({ - name, - color: 'RED', - reason: `${interaction.member.id} bought from shop`, - }) - .then(async (role) => { - // Get guild object - const guildDB = await guilds.findOne({ - guildId: interaction.member.guild.id, - }); - - const userDB = await users.findOne({ - userId: member.id, - guildId: guild.id, - }); - const { pricePerHour } = guildDB.shop.roles; - - userDB.credits -= pricePerHour; - - await userDB.save(); - - await shopRoles.create({ - roleId: role.id, - userId: member.id, - guildId: guild.id, - pricePerHour, - lastPayed: new Date(), - }); - - member.roles.add(role.id); - await shopRoles.find().then((role) => console.log(role)); - - const embed = { - title: ':shopping_cart: Shop - Roles [Buy]', - description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`, - color: config.colors.success, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ - embeds: [embed], - ephemeral: true, - }); - }) - .catch(console.error); -}; diff --git a/src/commands/shop/roles/addons/buy.ts b/src/commands/shop/roles/addons/buy.ts new file mode 100644 index 0000000..eeca6c4 --- /dev/null +++ b/src/commands/shop/roles/addons/buy.ts @@ -0,0 +1,66 @@ +import { v4 as uuidv4 } from 'uuid'; +import axios from 'axios'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; +import users from '../../../../helpers/database/models/userSchema'; +import shopRoles from '../../../../helpers/database/models/shopRolesSchema'; +import guilds from '../../../../helpers/database/models/guildSchema'; +import creditNoun from '../../../../helpers/creditNoun'; +import { CommandInteraction, GuildMemberRoleManager } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + const { member } = interaction; + + const name = await interaction.options.getString('name'); + + if (name === null) return; + + await interaction?.guild?.roles + .create({ + name, + color: 'RED', + reason: `${interaction?.user?.id} bought from shop`, + }) + .then(async (role) => { + // Get guild object + const guildDB = await guilds.findOne({ + guildId: interaction?.guild?.id, + }); + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + const { pricePerHour } = guildDB.shop.roles; + + userDB.credits -= pricePerHour; + + await userDB.save(); + + await shopRoles.create({ + roleId: role?.id, + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + pricePerHour, + lastPayed: new Date(), + }); + + await (interaction?.member?.roles as GuildMemberRoleManager)?.add( + role?.id + ); + await shopRoles.find().then((role: any) => console.log(role)); + + const embed = { + title: ':shopping_cart: Shop - Roles [Buy]', + description: `You have bought ${role.name} for ${guildDB.shop.roles.pricePerHour} per hour.`, + color: config.colors.success as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ + embeds: [embed], + }); + }) + .catch(console.error); +}; diff --git a/src/commands/shop/roles/addons/cancel.js b/src/commands/shop/roles/addons/cancel.js deleted file mode 100644 index 37c6f0f..0000000 --- a/src/commands/shop/roles/addons/cancel.js +++ /dev/null @@ -1,64 +0,0 @@ -const { v4: uuidv4 } = require('uuid'); -const axios = require('axios'); -const config = require('../../../../../config.json'); -const logger = require('../../../../handlers/logger'); - -const { - users, - shopRoles, - guilds, -} = require('../../../../helpers/database/models'); -const creditNoun = require('../../../../helpers/creditNoun'); - -module.exports = async (interaction) => { - const { member } = interaction; - const { guild } = member; - - const role = await interaction.options.getRole('role'); - - const roleExist = await shopRoles.find({ - guildId: guild.id, - userId: member.id, - roleId: role.id, - }); - - if (roleExist) { - await member.roles.remove(role.id); - - await interaction.guild.roles - .delete(role.id, `${interaction.member.id} canceled from shop`) - .then(async () => { - // Get guild object - const guildDB = await guilds.findOne({ - guildId: interaction.member.guild.id, - }); - - const userDB = await users.findOne({ - userId: member.id, - guildId: guild.id, - }); - - await shopRoles.deleteOne({ - roleId: role.id, - userId: member.id, - guildId: guild.id, - }); - - const embed = { - title: ':shopping_cart: Shop - Roles [Buy]', - description: `You have canceled ${role.name}.`, - color: config.colors.success, - fields: [ - { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, - ], - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - return interaction.editReply({ - embeds: [embed], - ephemeral: true, - }); - }) - .catch(console.error); - } -}; diff --git a/src/commands/shop/roles/addons/cancel.ts b/src/commands/shop/roles/addons/cancel.ts new file mode 100644 index 0000000..5b9d90c --- /dev/null +++ b/src/commands/shop/roles/addons/cancel.ts @@ -0,0 +1,63 @@ +import { v4 as uuidv4 } from 'uuid'; +import axios from 'axios'; +import config from '../../../../../config.json'; +import logger from '../../../../handlers/logger'; +import users from '../../../../helpers/database/models/userSchema'; +import shopRoles from '../../../../helpers/database/models/shopRolesSchema'; +import guilds from '../../../../helpers/database/models/guildSchema'; +import creditNoun from '../../../../helpers/creditNoun'; +import { CommandInteraction, GuildMemberRoleManager } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + const { member } = interaction; + + const role = await interaction.options.getRole('role'); + + if (role === null) return; + + const roleExist = await shopRoles.find({ + guildId: interaction?.guild?.id, + userId: interaction?.user?.id, + roleId: role?.id, + }); + + if (roleExist) { + await (interaction?.member?.roles as GuildMemberRoleManager).remove( + role?.id + ); + + await interaction?.guild?.roles + .delete(role?.id, `${interaction?.user?.id} canceled from shop`) + .then(async () => { + // Get guild object + const guildDB = await guilds.findOne({ + guildId: interaction?.guild?.id, + }); + + const userDB = await users.findOne({ + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + await shopRoles.deleteOne({ + roleId: role?.id, + userId: interaction?.user?.id, + guildId: interaction?.guild?.id, + }); + + const embed = { + title: ':shopping_cart: Shop - Roles [Buy]', + description: `You have canceled ${role.name}.`, + color: config.colors.success as any, + fields: [ + { name: 'Your balance', value: `${creditNoun(userDB.credits)}` }, + ], + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + return interaction.editReply({ + embeds: [embed], + }); + }) + .catch(console.error); + } +}; diff --git a/src/commands/shop/roles/addons/index.js b/src/commands/shop/roles/addons/index.js deleted file mode 100644 index 61e5b68..0000000 --- a/src/commands/shop/roles/addons/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const buy = require('./buy'); -const cancel = require('./cancel'); - -module.exports = { buy, cancel }; diff --git a/src/commands/shop/roles/addons/index.ts b/src/commands/shop/roles/addons/index.ts new file mode 100644 index 0000000..12e3413 --- /dev/null +++ b/src/commands/shop/roles/addons/index.ts @@ -0,0 +1,4 @@ +import buy from './buy'; +import cancel from './cancel'; + +export default { buy, cancel }; diff --git a/src/commands/shop/roles/index.js b/src/commands/shop/roles/index.ts similarity index 59% rename from src/commands/shop/roles/index.js rename to src/commands/shop/roles/index.ts index b92f604..67f136d 100644 --- a/src/commands/shop/roles/index.js +++ b/src/commands/shop/roles/index.ts @@ -1,27 +1,29 @@ -const logger = require('../../../handlers/logger'); - -const { buy, cancel } = require('./addons'); - -module.exports = async (interaction) => { - // Destructure member - const { member } = interaction; - - // If subcommand is buy - if (interaction.options.getSubcommand() === 'buy') { - // Execute buy addon - await buy(interaction); - } - - // If subcommand is cancel - if (interaction.options.getSubcommand() === 'cancel') { - // Execute cancel addon - await cancel(interaction); - } - - // Send debug message - await logger.debug( - `Guild: ${member.guild.id} User: ${member.id} executed /${ - interaction.commandName - } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` - ); -}; +import logger from '../../../handlers/logger'; +import buy from './addons/buy'; +import cancel from './addons/cancel'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + // Destructure member + const { member } = interaction; + + // If subcommand is buy + if (interaction.options.getSubcommand() === 'buy') { + // Execute buy addon + await buy(interaction); + } + + // If subcommand is cancel + if (interaction.options.getSubcommand() === 'cancel') { + // Execute cancel addon + await cancel(interaction); + } + + // Send debug message + await logger.debug( + `Guild: ${interaction?.guild?.id} User: ${ + interaction?.user?.id + } executed /${ + interaction.commandName + } ${interaction.options.getSubcommandGroup()} ${interaction.options.getSubcommand()}` + ); +}; diff --git a/src/commands/utilities/addons/about.js b/src/commands/utilities/addons/about.ts similarity index 66% rename from src/commands/utilities/addons/about.js rename to src/commands/utilities/addons/about.ts index f408fb1..d0d4d48 100644 --- a/src/commands/utilities/addons/about.js +++ b/src/commands/utilities/addons/about.ts @@ -1,18 +1,18 @@ -const config = require('../../../../config.json'); - -module.exports = async (interaction) => { - const interactionEmbed = { - title: ':hammer: Utilities - About', - description: `This bot is hosted by ${ - config.hoster.url - ? `[${config.hoster.name}](${config.hoster.url})` - : `${config.hoster.name}` - }, the bot is developed by [Zyner](https://github.com/ZynerOrg)! - - If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`, - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - interaction.editReply({ embeds: [interactionEmbed], ephemeral: true }); -}; +import config from '../../../../config.json'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + const interactionEmbed = { + title: ':hammer: Utilities - About', + description: `This bot is hosted by ${ + config.hoster.url + ? `[${config.hoster.name}](${config.hoster.url})` + : `${config.hoster.name}` + }, the bot is developed by [Zyner](https://github.com/ZynerOrg)! + + If you are interested in contributing, then just [fork it](https://github.com/ZynerOrg/xyter) yourself, we :heart: Open Source.`, + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + interaction.editReply({ embeds: [interactionEmbed] }); +}; diff --git a/src/commands/utilities/addons/index.js b/src/commands/utilities/addons/index.js deleted file mode 100644 index 905b5af..0000000 --- a/src/commands/utilities/addons/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const lookup = require('./lookup'); -const about = require('./about'); -const stats = require('./stats'); - -module.exports = { lookup, about, stats }; diff --git a/src/commands/utilities/addons/index.ts b/src/commands/utilities/addons/index.ts new file mode 100644 index 0000000..1eb5b45 --- /dev/null +++ b/src/commands/utilities/addons/index.ts @@ -0,0 +1,5 @@ +import lookup from './lookup'; +import about from './about'; +import stats from './stats'; + +export default { lookup, about, stats }; diff --git a/src/commands/utilities/addons/lookup.js b/src/commands/utilities/addons/lookup.ts similarity index 86% rename from src/commands/utilities/addons/lookup.js rename to src/commands/utilities/addons/lookup.ts index 767193f..4183509 100644 --- a/src/commands/utilities/addons/lookup.js +++ b/src/commands/utilities/addons/lookup.ts @@ -1,88 +1,87 @@ -const axios = require('axios'); - -const config = require('../../../../config.json'); -const logger = require('../../../handlers/logger'); - -module.exports = async (interaction) => { - try { - // Get lookup query - const query = await interaction.options.getString('query'); - - // Make API request - await axios - // Make a get request - .get(`http://ip-api.com/json/${query}`) - - // If successful - .then(async (res) => { - // If query failed - if (res.data.status === 'fail') { - // Create embed object - const embed = { - title: ':hammer: Utilities - Lookup', - description: `${res.data.message}: ${res.data.query}`, - color: config.colors.error, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed] }); - } - - // If query is successful - else if (res.data.status === 'success') { - // Create embed object - const embed = { - title: ':hammer: Utilities - Lookup', - fields: [ - { name: 'AS', value: `${res.data.as || 'Not available'}` }, - { - name: 'Country', - value: `${res.data.country || 'Not available'}`, - }, - { - name: 'Country Code', - value: `${res.data.countryCode || 'Not available'}`, - }, - { - name: 'Region', - value: `${res.data.region || 'Not available'}`, - }, - { - name: 'Region Name', - value: `${res.data.regionName || 'Not available'}`, - }, - { name: 'City', value: `${res.data.city || 'Not available'}` }, - { name: 'ZIP Code', value: `${res.data.zip || 'Not available'}` }, - { name: 'Latitude', value: `${res.data.lat || 'Not available'}` }, - { - name: 'Longitude', - value: `${res.data.lon || 'Not available'}`, - }, - { - name: 'Timezone', - value: `${res.data.timezone || 'Not available'}`, - }, - { name: 'ISP', value: `${res.data.isp || 'Not available'}` }, - { - name: 'Organization', - value: `${res.data.org || 'Not available'}`, - }, - ], - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - - // Send interaction reply - await interaction.editReply({ embeds: [embed] }); - } - }) - .catch(async (e) => { - await logger.error(e); - }); - } catch (e) { - await logger.error(e); - } -}; +import axios from 'axios'; +import config from '../../../../config.json'; +import logger from '../../../handlers/logger'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + try { + // Get lookup query + const query = await interaction.options.getString('query'); + + // Make API request + await axios + // Make a get request + .get(`http://ip-api.com/json/${query}`) + + // If successful + .then(async (res) => { + // If query failed + if (res.data.status === 'fail') { + // Create embed object + const embed = { + title: ':hammer: Utilities - Lookup', + description: `${res.data.message}: ${res.data.query}`, + color: config.colors.error as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + } + + // If query is successful + else if (res.data.status === 'success') { + // Create embed object + const embed = { + title: ':hammer: Utilities - Lookup', + fields: [ + { name: 'AS', value: `${res.data.as || 'Not available'}` }, + { + name: 'Country', + value: `${res.data.country || 'Not available'}`, + }, + { + name: 'Country Code', + value: `${res.data.countryCode || 'Not available'}`, + }, + { + name: 'Region', + value: `${res.data.region || 'Not available'}`, + }, + { + name: 'Region Name', + value: `${res.data.regionName || 'Not available'}`, + }, + { name: 'City', value: `${res.data.city || 'Not available'}` }, + { name: 'ZIP Code', value: `${res.data.zip || 'Not available'}` }, + { name: 'Latitude', value: `${res.data.lat || 'Not available'}` }, + { + name: 'Longitude', + value: `${res.data.lon || 'Not available'}`, + }, + { + name: 'Timezone', + value: `${res.data.timezone || 'Not available'}`, + }, + { name: 'ISP', value: `${res.data.isp || 'Not available'}` }, + { + name: 'Organization', + value: `${res.data.org || 'Not available'}`, + }, + ], + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + + // Send interaction reply + await interaction.editReply({ embeds: [embed] }); + } + }) + .catch(async (e) => { + await logger.error(e); + }); + } catch (e) { + await logger.error(e); + } +}; diff --git a/src/commands/utilities/addons/stats.js b/src/commands/utilities/addons/stats.ts similarity index 76% rename from src/commands/utilities/addons/stats.js rename to src/commands/utilities/addons/stats.ts index 83ea150..d73139f 100644 --- a/src/commands/utilities/addons/stats.js +++ b/src/commands/utilities/addons/stats.ts @@ -1,52 +1,53 @@ -const config = require('../../../../config.json'); - -module.exports = async (interaction) => { - let totalSeconds = interaction.client.uptime / 1000; - const days = Math.floor(totalSeconds / 86400); - totalSeconds %= 86400; - const hours = Math.floor(totalSeconds / 3600); - totalSeconds %= 3600; - const minutes = Math.floor(totalSeconds / 60); - const seconds = Math.floor(totalSeconds % 60); - - const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`; - - const interactionEmbed = { - title: ':hammer: Utilities - Stats', - description: 'Below you can see a list of statistics about the bot.', - fields: [ - { - name: '⏰ Latency', - value: `${Date.now() - interaction.createdTimestamp} ms`, - inline: true, - }, - { - name: '⏰ API Latency', - value: `${Math.round(interaction.client.ws.ping)} ms`, - inline: true, - }, - { - name: '⏰ Uptime', - value: `${uptime}`, - inline: false, - }, - { - name: '📈 Guilds', - value: `${interaction.client.guilds.cache.size}`, - inline: true, - }, - { - name: '📈 Users (non-unique)', - value: `${interaction.client.guilds.cache.reduce( - (acc, guild) => acc + guild.memberCount, - 0 - )}`, - inline: true, - }, - ], - color: config.colors.success, - timestamp: new Date(), - footer: { iconURL: config.footer.icon, text: config.footer.text }, - }; - interaction.editReply({ embeds: [interactionEmbed], ephemeral: true }); -}; +import config from '../../../../config.json'; +import { CommandInteraction } from 'discord.js'; +export default async (interaction: CommandInteraction) => { + if (interaction?.client?.uptime === null) return; + let totalSeconds = interaction?.client?.uptime / 1000; + const days = Math.floor(totalSeconds / 86400); + totalSeconds %= 86400; + const hours = Math.floor(totalSeconds / 3600); + totalSeconds %= 3600; + const minutes = Math.floor(totalSeconds / 60); + const seconds = Math.floor(totalSeconds % 60); + + const uptime = `${days} days, ${hours} hours, ${minutes} minutes and ${seconds} seconds`; + + const interactionEmbed = { + title: ':hammer: Utilities - Stats', + description: 'Below you can see a list of statistics about the bot.', + fields: [ + { + name: '⏰ Latency', + value: `${Date.now() - interaction.createdTimestamp} ms`, + inline: true, + }, + { + name: '⏰ API Latency', + value: `${Math.round(interaction.client.ws.ping)} ms`, + inline: true, + }, + { + name: '⏰ Uptime', + value: `${uptime}`, + inline: false, + }, + { + name: '📈 Guilds', + value: `${interaction.client.guilds.cache.size}`, + inline: true, + }, + { + name: '📈 Users (non-unique)', + value: `${interaction.client.guilds.cache.reduce( + (acc, guild) => acc + guild.memberCount, + 0 + )}`, + inline: true, + }, + ], + color: config.colors.success as any, + timestamp: new Date(), + footer: { iconURL: config.footer.icon, text: config.footer.text }, + }; + interaction.editReply({ embeds: [interactionEmbed] }); +}; diff --git a/src/commands/utilities/index.js b/src/commands/utilities/index.ts similarity index 78% rename from src/commands/utilities/index.js rename to src/commands/utilities/index.ts index bb407ed..cbb3723 100644 --- a/src/commands/utilities/index.js +++ b/src/commands/utilities/index.ts @@ -1,45 +1,46 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); - -const { lookup, about, stats } = require('./addons'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('utilities') - .setDescription('Common utilities.') - .addSubcommand((subcommand) => - subcommand - .setName('lookup') - .setDescription( - 'Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)' - ) - .addStringOption((option) => - option - .setName('query') - .setDescription('The query you want to look up.') - .setRequired(true) - ) - ) - .addSubcommand((subcommand) => - subcommand.setName('about').setDescription('About this bot!)') - ) - .addSubcommand((subcommand) => - subcommand.setName('stats').setDescription('Check bot statistics!)') - ), - async execute(interaction) { - // If subcommand is lookup - if (interaction.options.getSubcommand() === 'lookup') { - // Execute lookup addon - await lookup(interaction); - } - // If subcommand is about - else if (interaction.options.getSubcommand() === 'about') { - // Execute about addon - await about(interaction); - } - // If subcommand is stats - else if (interaction.options.getSubcommand() === 'stats') { - // Execute stats addon - await stats(interaction); - } - }, -}; +import { SlashCommandBuilder } from '@discordjs/builders'; +import lookup from './addons/lookup'; +import about from './addons/about'; +import stats from './addons/stats'; +import { CommandInteraction } from 'discord.js'; +export default { + data: new SlashCommandBuilder() + .setName('utilities') + .setDescription('Common utilities.') + .addSubcommand((subcommand) => + subcommand + .setName('lookup') + .setDescription( + 'Lookup a domain or ip. (Request sent over HTTP, proceed with caution!)' + ) + .addStringOption((option) => + option + .setName('query') + .setDescription('The query you want to look up.') + .setRequired(true) + ) + ) + .addSubcommand((subcommand) => + subcommand.setName('about').setDescription('About this bot!)') + ) + .addSubcommand((subcommand) => + subcommand.setName('stats').setDescription('Check bot statistics!)') + ), + async execute(interaction: CommandInteraction) { + // If subcommand is lookup + if (interaction.options.getSubcommand() === 'lookup') { + // Execute lookup addon + await lookup(interaction); + } + // If subcommand is about + else if (interaction.options.getSubcommand() === 'about') { + // Execute about addon + await about(interaction); + } + // If subcommand is stats + else if (interaction.options.getSubcommand() === 'stats') { + // Execute stats addon + await stats(interaction); + } + }, +}; diff --git a/src/configs/general.ts b/src/configs/general.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/events/guildCreate.js b/src/events/guildCreate.ts similarity index 50% rename from src/events/guildCreate.js rename to src/events/guildCreate.ts index 914511d..7cdd1d9 100644 --- a/src/events/guildCreate.js +++ b/src/events/guildCreate.ts @@ -1,23 +1,26 @@ -const { dbGuildFix, dbMemberFix } = require('../helpers'); +import { Guild } from 'discord.js'; +import dbGuildFix from '../helpers/dbGuildFix'; +import dbMemberFix from '../helpers/dbMemberFix'; -module.exports = { +export default { name: 'guildCreate', - async execute(guild) { + async execute(guild: Guild) { // Destructure client const { client } = guild; await guild.members.fetch().then(async (members) => { - await members.forEach(async (member) => { + members.forEach(async (member) => { const { user } = member; + dbMemberFix(user, guild); }); }); await dbGuildFix(guild); // Set client status - await client.user.setPresence({ + client?.user?.setPresence({ activities: [ - { type: 'WATCHING', name: `${client.guilds.cache.size} guilds` }, + { type: 'WATCHING', name: `${client?.guilds?.cache?.size} guilds` }, ], status: 'online', }); diff --git a/src/events/guildDelete.js b/src/events/guildDelete.js deleted file mode 100644 index 767d44b..0000000 --- a/src/events/guildDelete.js +++ /dev/null @@ -1,87 +0,0 @@ -const { - guilds, - users, - apis, - counters, - shopRoles, - timeouts, -} = require('../helpers/database/models'); - -const logger = require('../handlers/logger'); - -module.exports = { - name: 'guildDelete', - async execute(guild) { - // Destructure client - const { client } = guild; - - guilds - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug(`Successfully deleted guild: ${guild.id}`); - }) - .catch(async (e) => { - await logger.error(`Failed to delete guild: ${guild.id} ${e}`); - }); - users - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug(`Successfully deleted guild: ${guild.id}'s users`); - }) - .catch(async (e) => { - await logger.error(`Failed to delete guild: ${guild.id}'s users ${e}`); - }); - apis - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug(`Successfully deleted guild: ${guild.id}'s apis`); - }) - .catch(async (e) => { - await logger.error(`Failed to delete guild: ${guild.id}'s apis ${e}`); - }); - counters - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug( - `Successfully deleted guild: ${guild.id}'s counters` - ); - }) - .catch(async (e) => { - await logger.error( - `Failed to delete guild: ${guild.id}'s counters ${e}` - ); - }); - shopRoles - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug( - `Successfully deleted guild: ${guild.id}'s shop roles` - ); - }) - .catch(async (e) => { - await logger.error( - `Failed to delete guild: ${guild.id}'s shop roles ${e}` - ); - }); - timeouts - .deleteMany({ guildId: guild.id }) - .then(async () => { - await logger.debug( - `Successfully deleted guild: ${guild.id}'s timeouts` - ); - }) - .catch(async (e) => { - await logger.error( - `Failed to delete guild: ${guild.id}'s timeouts ${e}` - ); - }); - - // Set client status - await client.user.setPresence({ - activities: [ - { type: 'WATCHING', name: `${client.guilds.cache.size} guilds` }, - ], - status: 'online', - }); - }, -}; diff --git a/src/events/guildDelete.ts b/src/events/guildDelete.ts new file mode 100644 index 0000000..3ea009d --- /dev/null +++ b/src/events/guildDelete.ts @@ -0,0 +1,75 @@ +import guilds from '../helpers/database/models/guildSchema'; +import users from '../helpers/database/models/userSchema'; +import apis from '../helpers/database/models/apiSchema'; +import counters from '../helpers/database/models/counterSchema'; +import shopRoles from '../helpers/database/models/shopRolesSchema'; +import timeouts from '../helpers/database/models/timeoutSchema'; + +import logger from '../handlers/logger'; + +import { Guild } from 'discord.js'; + +export default { + name: 'guildDelete', + async execute(guild: Guild) { + // Destructure client + const { client } = guild; + + guilds + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id} ${e}`); + }); + users + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}'s users`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id}'s users ${e}`); + }); + apis + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}'s apis`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id}'s apis ${e}`); + }); + counters + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}'s counters`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id}'s counters ${e}`); + }); + shopRoles + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}'s shop roles`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id}'s shop roles ${e}`); + }); + timeouts + .deleteMany({ guildId: guild.id }) + .then(async () => { + logger.debug(`Successfully deleted guild: ${guild.id}'s timeouts`); + }) + .catch(async (e) => { + logger.error(`Failed to delete guild: ${guild.id}'s timeouts ${e}`); + }); + + // Set client status + await client?.user?.setPresence({ + activities: [ + { type: 'WATCHING', name: `${client.guilds.cache.size} guilds` }, + ], + status: 'online', + }); + }, +}; diff --git a/src/events/guildMemberAdd.js b/src/events/guildMemberAdd.js deleted file mode 100644 index d3958b1..0000000 --- a/src/events/guildMemberAdd.js +++ /dev/null @@ -1,15 +0,0 @@ -const { users } = require('../helpers/database/models'); -const logger = require('../handlers/logger'); - -module.exports = { - name: 'guildMemberAdd', - async execute(member) { - await users - .create({ userId: member.id, guildId: member.guild.id }) - .then( - logger.debug( - `Guild: ${member.guild.id} User: ${member.id} created successfully` - ) - ); - }, -}; diff --git a/src/events/guildMemberAdd.ts b/src/events/guildMemberAdd.ts new file mode 100644 index 0000000..a1375c0 --- /dev/null +++ b/src/events/guildMemberAdd.ts @@ -0,0 +1,17 @@ +import users from '../helpers/database/models/userSchema'; +import logger from '../handlers/logger'; + +import { GuildMember } from 'discord.js'; + +export default { + name: 'guildMemberAdd', + async execute(member: GuildMember) { + await users + .create({ userId: member?.id, guildId: member?.guild?.id }) + .then(async () => + logger.debug( + `Guild: ${member?.guild?.id} User: ${member?.id} created successfully` + ) + ); + }, +}; diff --git a/src/events/guildMemberRemove.js b/src/events/guildMemberRemove.js deleted file mode 100644 index bc5c319..0000000 --- a/src/events/guildMemberRemove.js +++ /dev/null @@ -1,15 +0,0 @@ -const { users } = require('../helpers/database/models'); -const logger = require('../handlers/logger'); - -module.exports = { - name: 'guildMemberRemove', - async execute(member) { - await users - .deleteOne({ userId: member.id, guildId: member.guild.id }) - .then( - logger.debug( - `Guild: ${member.guild.id} User: ${member.id} deleted successfully` - ) - ); - }, -}; diff --git a/src/events/guildMemberRemove.ts b/src/events/guildMemberRemove.ts new file mode 100644 index 0000000..c785189 --- /dev/null +++ b/src/events/guildMemberRemove.ts @@ -0,0 +1,17 @@ +import users from '../helpers/database/models/userSchema'; +import logger from '../handlers/logger'; + +import { GuildMember } from 'discord.js'; + +export default { + name: 'guildMemberRemove', + async execute(member: GuildMember) { + await users + .deleteOne({ userId: member?.id, guildId: member?.guild?.id }) + .then(async () => + logger.debug( + `Guild: ${member?.guild?.id} User: ${member?.id} deleted successfully` + ) + ); + }, +}; diff --git a/src/events/interactionCreate.js b/src/events/interactionCreate.js deleted file mode 100644 index d26be70..0000000 --- a/src/events/interactionCreate.js +++ /dev/null @@ -1,74 +0,0 @@ -const config = require('../../config.json'); -const logger = require('../handlers/logger'); - -const { guilds } = require('../helpers/database/models'); - -module.exports = { - name: 'interactionCreate', - async execute(interaction) { - // Destructure member, client - const { member, client } = interaction; - - // If interaction is command - if (interaction.isCommand()) { - // Get command from collection - const command = client.commands.get(interaction.commandName); - - // If command do not exist - if (!command) return; - - // Create guild if it does not exist already - await guilds.findOne( - { guildId: member.guild.id }, - { new: true, upsert: true } - ); - - try { - // Defer reply - await interaction.deferReply({ - embeds: [ - { - author: { - name: client.user.username, - icon_url: client.user.displayAvatarURL(), - url: 'https://bot.zyner.org/', - }, - title: 'Check', - description: 'Please wait...', - color: config.colors.wait, - timestamp: new Date(), - }, - ], - ephemeral: true, - }); - - // Execute command - await command.execute(interaction); - - // Send debug message - await logger.debug(`Executing command: ${interaction.commandName}`); - } catch (err) { - // Send debug message - await logger.error(err); - - // Send interaction reply - await interaction.reply({ - embeds: [ - { - author: { - name: client.user.username, - icon_url: client.user.displayAvatarURL(), - url: 'https://bot.zyner.org/', - }, - title: 'Error', - description: 'There was an error while executing this command!', - color: config.colors.error, - timestamp: new Date(), - }, - ], - ephemeral: true, - }); - } - } - }, -}; diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts new file mode 100644 index 0000000..bdb47f6 --- /dev/null +++ b/src/events/interactionCreate.ts @@ -0,0 +1,57 @@ +import config from '../../config.json'; +import logger from '../handlers/logger'; +import guilds from '../helpers/database/models/guildSchema'; + +import { Interaction, ColorResolvable } from 'discord.js'; + +export default { + name: 'interactionCreate', + async execute(interaction: Interaction) { + // Destructure member, client + const { client, guild } = interaction; + + // If interaction is command + if (interaction.isCommand()) { + // Get command from collection + const command = client.commands.get(interaction.commandName); + + // If command do not exist + if (!command) return; + + // Create guild if it does not exist already + await guilds.findOne({ guildId: guild?.id }, { new: true, upsert: true }); + + try { + // Defer reply + await interaction.deferReply(); + + // Execute command + await command.execute(interaction); + + // Send debug message + logger.debug(`Executing command: ${interaction.commandName}`); + } catch (e) { + // Send debug message + logger.error(e); + + // Send interaction reply + await interaction.reply({ + embeds: [ + { + author: { + name: client?.user?.username, + icon_url: client?.user?.displayAvatarURL(), + url: 'https://bot.zyner.org/', + }, + title: 'Error', + description: 'There was an error while executing this command!', + color: config.colors.error as ColorResolvable, + timestamp: new Date(), + }, + ], + ephemeral: true, + }); + } + } + }, +}; diff --git a/src/events/messageCreate/index.js b/src/events/messageCreate/index.js deleted file mode 100644 index fc016b2..0000000 --- a/src/events/messageCreate/index.js +++ /dev/null @@ -1,32 +0,0 @@ -const { guilds, users } = require('../../helpers/database/models'); - -const { points, credits, counter } = require('./modules'); - -module.exports = { - name: 'messageCreate', - async execute(message) { - const { guild, author } = message; - - // If message author is bot - if (author.bot) return; - - // Get guild object - const guildDB = await guilds.findOne({ guildId: guild.id }); - - // Get guild object - const userDB = await users.findOne({ - guildId: guild.id, - userId: author.id, - }); - - // Manage credits - - await credits(guildDB, userDB, message); - - // Manage points - await points(guildDB, userDB, message); - - // Manage counter - await counter(guildDB, userDB, message); - }, -}; diff --git a/src/events/messageCreate/index.ts b/src/events/messageCreate/index.ts new file mode 100644 index 0000000..017554e --- /dev/null +++ b/src/events/messageCreate/index.ts @@ -0,0 +1,35 @@ +import guilds from '../../helpers/database/models/guildSchema'; +import users from '../../helpers/database/models/userSchema'; +import points from './modules/points'; +import credits from './modules/credits'; +import counter from './modules/counter'; + +import { Message } from 'discord.js'; +export default { + name: 'messageCreate', + async execute(message: Message) { + const { guild, author } = message; + + // If message author is bot + if (author.bot) return; + + // Get guild object + const guildDB = await guilds.findOne({ guildId: guild?.id }); + + // Get guild object + const userDB = await users.findOne({ + guildId: guild?.id, + userId: author?.id, + }); + + // Manage credits + + await credits(guildDB, userDB, message); + + // Manage points + await points(guildDB, userDB, message); + + // Manage counter + await counter(guildDB, userDB, message); + }, +}; diff --git a/src/events/messageCreate/modules/counter.js b/src/events/messageCreate/modules/counter.ts similarity index 64% rename from src/events/messageCreate/modules/counter.js rename to src/events/messageCreate/modules/counter.ts index d65309d..9a350f4 100644 --- a/src/events/messageCreate/modules/counter.js +++ b/src/events/messageCreate/modules/counter.ts @@ -1,38 +1,32 @@ -const logger = require('../../../handlers/logger'); - -const { - users, - guilds, - experiences, - credits, - counters, - timeouts, -} = require('../../../helpers/database/models'); - -module.exports = async (guildDB, userDB, message) => { - const { guild, channel, content } = message; - - // Get counter object - const counter = await counters.findOne({ - guildId: guild.id, - channelId: channel.id, - }); - - // If counter for the message channel - if (counter) { - // If message content is not strictly the same as counter word - if (content !== counter.word) { - // Delete the message - await message.delete(); - } else { - // Add 1 to the counter object - await counters.findOneAndUpdate( - { - guildId: guild.id, - channelId: channel.id, - }, - { $inc: { counter: 1 } } - ); - } - } -}; +import logger from '../../../handlers/logger'; +import counters from '../../../helpers/database/models/counterSchema'; + +import { Message } from 'discord.js'; + +export default async (guildDB: any, userDB: any, message: Message) => { + const { guild, channel, content } = message; + + // Get counter object + const counter = await counters.findOne({ + guildId: guild?.id, + channelId: channel.id, + }); + + // If counter for the message channel + if (counter) { + // If message content is not strictly the same as counter word + if (content !== counter.word) { + // Delete the message + await message.delete(); + } else { + // Add 1 to the counter object + await counters.findOneAndUpdate( + { + guildId: guild?.id, + channelId: channel.id, + }, + { $inc: { counter: 1 } } + ); + } + } +}; diff --git a/src/events/messageCreate/modules/credits.js b/src/events/messageCreate/modules/credits.ts similarity index 68% rename from src/events/messageCreate/modules/credits.js rename to src/events/messageCreate/modules/credits.ts index d016983..52232be 100644 --- a/src/events/messageCreate/modules/credits.js +++ b/src/events/messageCreate/modules/credits.ts @@ -1,78 +1,70 @@ -const logger = require('../../../handlers/logger'); - -const { - users, - guilds, - experiences, - credits, - counters, - timeouts, -} = require('../../../helpers/database/models'); - -module.exports = async (guildDB, userDB, message) => { - const { guild, author, channel, content } = message; - - // If message length is below guild minimum length - if (content.length < guildDB.credits.minimumLength) return; - - // Check if user has a timeout - const isTimeout = await timeouts.findOne({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-42', - }); - - // If user is not on timeout - if (!isTimeout) { - // Add credits to user - - userDB.credits += guildDB.credits.rate; - - await userDB - .save() - .then(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${channel.id} credits add ${guildDB.credits.rate} balance: ${userDB.credits}` - ); - }) - .catch(async (e) => { - // Send error message - await logger.error(e); - }); - - // Create a timeout for the user - await timeouts.create({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-42', - }); - - setTimeout(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${ - channel.id - } has not talked within last ${ - guildDB.credits.timeout / 1000 - } seconds, credits can be given` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-42', - }); - }, guildDB.credits.timeout); - } else { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${ - channel.id - } has talked within last ${ - guildDB.credits.timeout / 1000 - } seconds, no credits given` - ); - } -}; +import logger from '../../../handlers/logger'; +import timeouts from '../../../helpers/database/models/timeoutSchema'; +import { Message } from 'discord.js'; +export default async (guildDB: any, userDB: any, message: Message) => { + const { guild, author, channel, content } = message; + + // If message length is below guild minimum length + if (content.length < guildDB.credits.minimumLength) return; + + // Check if user has a timeout + const isTimeout = await timeouts.findOne({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-42', + }); + + // If user is not on timeout + if (!isTimeout) { + // Add credits to user + + userDB.credits += guildDB.credits.rate; + + await userDB + .save() + .then(async () => { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${channel.id} credits add ${guildDB.credits.rate} balance: ${userDB.credits}` + ); + }) + .catch(async (e: any) => { + // Send error message + await logger.error(e); + }); + + // Create a timeout for the user + await timeouts.create({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-42', + }); + + setTimeout(async () => { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${ + channel.id + } has not talked within last ${ + guildDB.credits.timeout / 1000 + } seconds, credits can be given` + ); + + // When timeout is out, remove it from the database + await timeouts.deleteOne({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-42', + }); + }, guildDB.credits.timeout); + } else { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${ + channel.id + } has talked within last ${ + guildDB.credits.timeout / 1000 + } seconds, no credits given` + ); + } +}; diff --git a/src/events/messageCreate/modules/index.js b/src/events/messageCreate/modules/index.js deleted file mode 100644 index 1f045c4..0000000 --- a/src/events/messageCreate/modules/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const points = require('./points'); -const credits = require('./credits'); -const counter = require('./counter'); - -module.exports = { points, credits, counter }; diff --git a/src/events/messageCreate/modules/index.ts b/src/events/messageCreate/modules/index.ts new file mode 100644 index 0000000..599442a --- /dev/null +++ b/src/events/messageCreate/modules/index.ts @@ -0,0 +1,5 @@ +import points from './points'; +import credits from './credits'; +import counter from './counter'; + +export default { points, credits, counter }; diff --git a/src/events/messageCreate/modules/points.js b/src/events/messageCreate/modules/points.ts similarity index 68% rename from src/events/messageCreate/modules/points.js rename to src/events/messageCreate/modules/points.ts index 4dbc757..9a00971 100644 --- a/src/events/messageCreate/modules/points.js +++ b/src/events/messageCreate/modules/points.ts @@ -1,70 +1,70 @@ -const logger = require('../../../handlers/logger'); - -const { timeouts } = require('../../../helpers/database/models'); - -module.exports = async (guildDB, userDB, message) => { - const { author, guild, channel, content } = message; - - // If message length is below guild minimum length - if (content.length < guildDB.points.minimumLength) return; - - // Check if user has a timeout - const isTimeout = await timeouts.findOne({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-41', - }); - - // If user is not on timeout - if (!isTimeout) { - // Add points to user - userDB.points += guildDB.points.rate; - - await userDB - .save() - .then(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${channel.id} points add: ${guildDB.points.rate} balance: ${userDB.points}` - ); - }) - .catch(async (e) => { - // Send error message - await logger.error(e); - }); - - // Create a timeout for the user - await timeouts.create({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-41', - }); - - setTimeout(async () => { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${ - channel.id - } has not talked within last ${ - guildDB.points.timeout / 1000 - } seconds, points can be given` - ); - - // When timeout is out, remove it from the database - await timeouts.deleteOne({ - guildId: guild.id, - userId: author.id, - timeoutId: '2022-03-15-17-41', - }); - }, guildDB.points.timeout); - } else { - // Send debug message - await logger.debug( - `Guild: ${guild.id} User: ${author.id} Channel: ${ - channel.id - } has talked within last ${ - guildDB.points.timeout / 1000 - } seconds, no points given` - ); - } -}; +import logger from '../../../handlers/logger'; +import timeouts from '../../../helpers/database/models/timeoutSchema'; + +import { Message } from 'discord.js'; +export default async (guildDB: any, userDB: any, message: Message) => { + const { author, guild, channel, content } = message; + + // If message length is below guild minimum length + if (content.length < guildDB.points.minimumLength) return; + + // Check if user has a timeout + const isTimeout = await timeouts.findOne({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-41', + }); + + // If user is not on timeout + if (!isTimeout) { + // Add points to user + userDB.points += guildDB.points.rate; + + await userDB + .save() + .then(async () => { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${channel.id} points add: ${guildDB.points.rate} balance: ${userDB.points}` + ); + }) + .catch(async (e: any) => { + // Send error message + await logger.error(e); + }); + + // Create a timeout for the user + await timeouts.create({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-41', + }); + + setTimeout(async () => { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${ + channel.id + } has not talked within last ${ + guildDB.points.timeout / 1000 + } seconds, points can be given` + ); + + // When timeout is out, remove it from the database + await timeouts.deleteOne({ + guildId: guild?.id, + userId: author.id, + timeoutId: '2022-03-15-17-41', + }); + }, guildDB.points.timeout); + } else { + // Send debug message + await logger.debug( + `Guild: ${guild?.id} User: ${author.id} Channel: ${ + channel.id + } has talked within last ${ + guildDB.points.timeout / 1000 + } seconds, no points given` + ); + } +}; diff --git a/src/events/messageUpdate.js b/src/events/messageUpdate.ts similarity index 70% rename from src/events/messageUpdate.js rename to src/events/messageUpdate.ts index 49f7bc5..4c08256 100644 --- a/src/events/messageUpdate.js +++ b/src/events/messageUpdate.ts @@ -1,27 +1,27 @@ -const { counters } = require('../helpers/database/models'); - -module.exports = { - name: 'messageUpdate', - async execute(oldMessage, newMessage) { - // If message author is bot - if (newMessage.author.bot) return; - - // Get counter object - const counter = await counters.findOne({ - guildId: newMessage.guild.id, - channelId: newMessage.channel.id, - }); - - // If counter for the message channel - if (counter) { - // If message content is not strictly the same as counter word - if (newMessage.content !== counter.word) { - // Delete the message - await newMessage.delete(); - await newMessage.channel.send( - `${newMessage.author} said **${counter.word}**.` - ); - } - } - }, -}; +import counters from '../helpers/database/models/counterSchema'; +import { Message } from 'discord.js'; +export default { + name: 'messageUpdate', + async execute(oldMessage: Message, newMessage: Message) { + // If message author is bot + if (newMessage.author.bot) return; + + // Get counter object + const counter = await counters.findOne({ + guildId: newMessage.guild?.id, + channelId: newMessage.channel.id, + }); + + // If counter for the message channel + if (counter) { + // If message content is not strictly the same as counter word + if (newMessage.content !== counter.word) { + // Delete the message + await newMessage.delete(); + await newMessage.channel.send( + `${newMessage.author} said **${counter.word}**.` + ); + } + } + }, +}; diff --git a/src/events/ready.js b/src/events/ready.ts similarity index 50% rename from src/events/ready.js rename to src/events/ready.ts index f018e84..0712472 100644 --- a/src/events/ready.js +++ b/src/events/ready.ts @@ -1,36 +1,39 @@ -const logger = require('../handlers/logger'); -const config = require('../../config.json'); - -const { deployCommands, dbGuildFix, dbMemberFix } = require('../helpers'); - -module.exports = { - name: 'ready', - once: true, - async execute(client) { - // Send info message - await logger.info(`Ready! Logged in as ${client.user.tag}`); - - // Set client status - await client.user.setPresence({ - activities: [ - { type: 'WATCHING', name: `${client.guilds.cache.size} guilds` }, - ], - status: 'online', - }); - - if (config.importToDB) { - const guilds = client.guilds.cache; - await guilds.map(async (guild) => { - await guild.members.fetch().then(async (members) => { - await members.forEach(async (member) => { - const { user } = member; - dbMemberFix(user, guild); - }); - }); - await dbGuildFix(guild); - }); - } - - await deployCommands(); - }, -}; +import logger from '../handlers/logger'; +import config from '../../config.json'; +import deployCommands from '../helpers/deployCommands'; +import dbGuildFix from '../helpers/dbGuildFix'; +import dbMemberFix from '../helpers/dbMemberFix'; + +import { Client } from 'discord.js'; +export default { + name: 'ready', + once: true, + async execute(client: Client) { + console.log('Test'); + // Send info message + await logger.info(`Ready! Logged in as ${client?.user?.tag}`); + + // Set client status + await client?.user?.setPresence({ + activities: [ + { type: 'WATCHING', name: `${client.guilds.cache.size} guilds` }, + ], + status: 'online', + }); + + if (config.importToDB) { + const guilds = client.guilds.cache; + await guilds.map(async (guild) => { + await guild?.members.fetch().then(async (members) => { + await members.forEach(async (member) => { + const { user } = member; + dbMemberFix(user, guild); + }); + }); + await dbGuildFix(guild); + }); + } + + await deployCommands(); + }, +}; diff --git a/src/handlers/commands.js b/src/handlers/commands.js deleted file mode 100644 index 2f91cee..0000000 --- a/src/handlers/commands.js +++ /dev/null @@ -1,13 +0,0 @@ -const fs = require('fs'); // fs -const { Collection } = require('discord.js'); // discord.js - -module.exports = async (client) => { - client.commands = new Collection(); - const commandFiles = fs.readdirSync('./src/commands'); - - for (const file of commandFiles) { - // eslint-disable-next-line import/no-dynamic-require, global-require - const command = require(`../commands/${file}`); - client.commands.set(command.data.name, command); - } -}; diff --git a/src/handlers/commands.ts b/src/handlers/commands.ts new file mode 100644 index 0000000..483f048 --- /dev/null +++ b/src/handlers/commands.ts @@ -0,0 +1,12 @@ +import fs from 'fs'; // fs +import { Collection } from 'discord.js'; // discord.js +import { Client } from '../types/common/discord'; +export default async (client: Client) => { + client.commands = new Collection(); + const commandFiles = fs.readdirSync('./src/commands'); + + for (const file of commandFiles) { + const command = require(`../commands/${file}`); + client.commands.set(command.default.data.name, command.default); + } +}; diff --git a/src/handlers/events.js b/src/handlers/events.js deleted file mode 100644 index 9b9d8cc..0000000 --- a/src/handlers/events.js +++ /dev/null @@ -1,14 +0,0 @@ -const fs = require('fs'); // fs - -module.exports = async (client) => { - const eventFiles = fs.readdirSync('./src/events'); - - for (const file of eventFiles) { - const event = require(`../events/${file}`); - if (event.once) { - client.once(event.name, (...args) => event.execute(...args)); - } else { - client.on(event.name, (...args) => event.execute(...args)); - } - } -}; diff --git a/src/handlers/events.ts b/src/handlers/events.ts new file mode 100644 index 0000000..8f6aa3a --- /dev/null +++ b/src/handlers/events.ts @@ -0,0 +1,19 @@ +import fs from 'fs'; // fs +import { Client } from 'discord.js'; // discord.js + +export default async (client: Client) => { + const eventFiles = fs.readdirSync('./src/events'); + + for (const file of eventFiles) { + const event = require(`../events/${file}`); + if (event.once) { + client.once(event.default.name, (...args) => + event.default.execute(...args) + ); + } else { + client.on(event.default.name, (...args) => + event.default.execute(...args) + ); + } + } +}; diff --git a/src/handlers/index.js b/src/handlers/index.js deleted file mode 100644 index 318fa71..0000000 --- a/src/handlers/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const events = require('./events'); -const commands = require('./commands'); -const locale = require('./locale'); -const schedules = require('./schedules'); - -module.exports = { events, commands, locale, schedules }; diff --git a/src/handlers/index.ts b/src/handlers/index.ts new file mode 100644 index 0000000..8d71967 --- /dev/null +++ b/src/handlers/index.ts @@ -0,0 +1,6 @@ +import events from './events'; +import commands from './commands'; +import locale from './locale'; +import schedules from './schedules'; + +export default { events, commands, locale, schedules }; diff --git a/src/handlers/locale.js b/src/handlers/locale.ts similarity index 95% rename from src/handlers/locale.js rename to src/handlers/locale.ts index 9bcf7d7..d31f779 100644 --- a/src/handlers/locale.js +++ b/src/handlers/locale.ts @@ -1,135 +1,135 @@ -const i18next = require('i18next'); - -module.exports = async () => { - await i18next.init({ - lng: 'en', // if you're using a language detector, do not define the lng option - // debug: true, - fallbackLng: 'en', - resources: { - en: { - general: { not_available: 'Not Available' }, - commands: { - credits: { - general: { - credits_one: '{{count}} credit', - credits_other: '{{count}} credits', - }, - addons: { - balance: { embed: { title: 'Credits' } }, - gift: { embed: { title: 'Gift' } }, - }, - }, - reputation: { - addons: { - give: { - version01: { - embed: { - title: ':medal: Reputation', - description: - 'You have given reputation within the last day, you can not repute now!', - }, - }, - version02: { - embed: { - title: ':medal: Reputation', - description: - 'You have given {{user}} a {{type}} reputation!', - }, - }, - version03: { - embed: { - title: ':medal: Reputation', - description: 'You can not repute yourself.', - }, - }, - }, - }, - }, - profile: { - addons: { - view: { - embed: { - title: 'Profile', - reputation: 'Reputation (Global)', - level: 'Level (Guild)', - points: 'Points (Guild)', - credits: 'Credits (Guild)', - language_code: 'Language Code (Global)', - }, - }, - settings: { - embed: { - title: 'Profile', - description: 'Following settings is set', - fields: { language: 'Language' }, - }, - }, - }, - }, - }, - }, - sv: { - general: { not_available: 'Otillgänglig' }, - commands: { - credits: { - general: { - credits_one: '{{count}} krona', - credits_other: '{{count}} kronor', - }, - addons: { - balance: { embed: { title: 'Krediter' } }, - gift: { embed: { title: 'Gåva' } }, - }, - }, - reputation: { - addons: { - give: { - version01: { - embed: { - title: ':medal: Omdöme', - description: - 'Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!', - }, - }, - version02: { - embed: { - title: ':medal: Omdöme', - description: 'Du har gett {{user}} ett {{type}} omdöme!', - }, - }, - version03: { - embed: { - title: ':medal: Omdöme', - description: 'Du kan inte ge dig själv ett omdöme.', - }, - }, - }, - }, - }, - - profile: { - addons: { - view: { - embed: { - title: 'Profil', - reputation: 'Omdöme (Globalt)', - level: 'Nivå (Server)', - points: 'Poäng (Server)', - credits: 'Krediter (Server)', - language_code: 'Språkkod (Globalt)', - }, - }, - settings: { - embed: { - title: 'Profil', - description: 'Följande inställningar är satta', - fields: { language: 'Språk' }, - }, - }, - }, - }, - }, - }, - }, - }); -}; +import i18next from 'i18next'; + +export default async () => { + await i18next.init({ + lng: 'en', // if you're using a language detector, do not define the lng option + // debug: true, + fallbackLng: 'en', + resources: { + en: { + general: { not_available: 'Not Available' }, + commands: { + credits: { + general: { + credits_one: '{{count}} credit', + credits_other: '{{count}} credits', + }, + addons: { + balance: { embed: { title: 'Credits' } }, + gift: { embed: { title: 'Gift' } }, + }, + }, + reputation: { + addons: { + give: { + version01: { + embed: { + title: ':medal: Reputation', + description: + 'You have given reputation within the last day, you can not repute now!', + }, + }, + version02: { + embed: { + title: ':medal: Reputation', + description: + 'You have given {{user}} a {{type}} reputation!', + }, + }, + version03: { + embed: { + title: ':medal: Reputation', + description: 'You can not repute yourself.', + }, + }, + }, + }, + }, + profile: { + addons: { + view: { + embed: { + title: 'Profile', + reputation: 'Reputation (Global)', + level: 'Level (Guild)', + points: 'Points (Guild)', + credits: 'Credits (Guild)', + language_code: 'Language Code (Global)', + }, + }, + settings: { + embed: { + title: 'Profile', + description: 'Following settings is set', + fields: { language: 'Language' }, + }, + }, + }, + }, + }, + }, + sv: { + general: { not_available: 'Otillgänglig' }, + commands: { + credits: { + general: { + credits_one: '{{count}} krona', + credits_other: '{{count}} kronor', + }, + addons: { + balance: { embed: { title: 'Krediter' } }, + gift: { embed: { title: 'Gåva' } }, + }, + }, + reputation: { + addons: { + give: { + version01: { + embed: { + title: ':medal: Omdöme', + description: + 'Du har redan gett omdöme inom den senaste dagen, du kan inte ge ett omdöme just nu!', + }, + }, + version02: { + embed: { + title: ':medal: Omdöme', + description: 'Du har gett {{user}} ett {{type}} omdöme!', + }, + }, + version03: { + embed: { + title: ':medal: Omdöme', + description: 'Du kan inte ge dig själv ett omdöme.', + }, + }, + }, + }, + }, + + profile: { + addons: { + view: { + embed: { + title: 'Profil', + reputation: 'Omdöme (Globalt)', + level: 'Nivå (Server)', + points: 'Poäng (Server)', + credits: 'Krediter (Server)', + language_code: 'Språkkod (Globalt)', + }, + }, + settings: { + embed: { + title: 'Profil', + description: 'Följande inställningar är satta', + fields: { language: 'Språk' }, + }, + }, + }, + }, + }, + }, + }, + }); +}; diff --git a/src/handlers/logger.js b/src/handlers/logger.js deleted file mode 100644 index fb2c351..0000000 --- a/src/handlers/logger.js +++ /dev/null @@ -1,6 +0,0 @@ -const pino = require('pino'); - -const config = require('../../config.json'); - -const logger = pino({ level: config.debug ? 'debug' : 'info' }); -module.exports = logger; diff --git a/src/handlers/logger.ts b/src/handlers/logger.ts new file mode 100644 index 0000000..8ffbf17 --- /dev/null +++ b/src/handlers/logger.ts @@ -0,0 +1,4 @@ +import pino from 'pino'; +import * as config from '../../config.json'; + +export default pino({ level: config.debug ? 'debug' : 'info' }); diff --git a/src/handlers/schedules.js b/src/handlers/schedules.ts similarity index 61% rename from src/handlers/schedules.js rename to src/handlers/schedules.ts index e549bde..7119d25 100644 --- a/src/handlers/schedules.js +++ b/src/handlers/schedules.ts @@ -1,48 +1,50 @@ -const schedule = require('node-schedule'); -const { shopRoles, users, guilds } = require('../helpers/database/models'); -const logger = require('./logger'); - -module.exports = async (client) => { - schedule.scheduleJob('*/30 * * * *', async () => { - shopRoles.find().then(async (shopRoles) => { - shopRoles.map(async (shopRole) => { - const payed = new Date(shopRole.lastPayed); - - oneHourAfterPayed = payed.setHours(payed.getHours() + 1); - - if (new Date() > oneHourAfterPayed) { - // Get guild object - const guild = await guilds.findOne({ - guildId: shopRole.guildId, - }); - - const userDB = await users.findOne({ - userId: shopRole.userId, - guildId: shopRole.guildId, - }); - const { pricePerHour } = guild.shop.roles; - - if (userDB.credits < pricePerHour) { - const rGuild = await client.guilds.cache.get(`${shopRole.guildId}`); - const rMember = await rGuild.members.fetch(`${shopRole.userId}`); - - await rMember.roles - .remove(`${shopRole.roleId}`) - .then(console.log) - .catch(console.error); // Removes all roles - } - - shopRole.lastPayed = new Date(); - shopRole.save(); - userDB.credits -= pricePerHour; - userDB.save(); - await logger.debug( - `${shopRole.roleId} was payed one hour later. BEFORE: ${payed} AFTER: ${oneHourAfterPayed} UPDATED: ${shopRole.updatedAt} CREATED: ${shopRole.createdAt}` - ); - } - }); - }); - - await logger.debug('Checking schedules! (Every 30 minutes)'); - }); -}; +import schedule from 'node-schedule'; +import users from '../helpers/database/models/userSchema'; +import shopRoles from '../helpers/database/models/shopRolesSchema'; +import guilds from '../helpers/database/models/guildSchema'; +import logger from './logger'; +import { Client } from 'discord.js'; +export default async (client: Client) => { + schedule.scheduleJob('*/30 * * * *', async () => { + shopRoles.find().then(async (shopRoles: any) => { + shopRoles.map(async (shopRole: any) => { + const payed = new Date(shopRole.lastPayed); + + const oneHourAfterPayed = payed.setHours(payed.getHours() + 1); + + if (new Date() > new Date(oneHourAfterPayed)) { + // Get guild object + const guild = await guilds.findOne({ + guildId: shopRole.guildId, + }); + + const userDB = await users.findOne({ + userId: shopRole.userId, + guildId: shopRole.guildId, + }); + const { pricePerHour } = guild.shop.roles; + + if (userDB.credits < pricePerHour) { + const rGuild = await client.guilds.cache.get(`${shopRole.guildId}`); + const rMember = await rGuild?.members.fetch(`${shopRole.userId}`); + + await rMember?.roles + .remove(`${shopRole.roleId}`) + .then(console.log) + .catch(console.error); // Removes all roles + } + + shopRole.lastPayed = new Date(); + shopRole.save(); + userDB.credits -= pricePerHour; + userDB.save(); + await logger.debug( + `${shopRole.roleId} was payed one hour later. BEFORE: ${payed} AFTER: ${oneHourAfterPayed} UPDATED: ${shopRole.updatedAt} CREATED: ${shopRole.createdAt}` + ); + } + }); + }); + + await logger.debug('Checking schedules! (Every 30 minutes)'); + }); +}; diff --git a/src/helpers/creditNoun.js b/src/helpers/creditNoun.ts similarity index 64% rename from src/helpers/creditNoun.js rename to src/helpers/creditNoun.ts index 34276c5..19ef8d9 100644 --- a/src/helpers/creditNoun.js +++ b/src/helpers/creditNoun.ts @@ -1,2 +1,2 @@ -module.exports = (amount) => +export default (amount: number) => `${amount <= 1 ? `${amount} credit` : `${amount} credits`}`; diff --git a/src/helpers/database/index.js b/src/helpers/database/index.js deleted file mode 100644 index 0b1d63e..0000000 --- a/src/helpers/database/index.js +++ /dev/null @@ -1,13 +0,0 @@ -const mongoose = require('mongoose'); - -const config = require('../../../config.json'); -const logger = require('../../handlers/logger'); - -module.exports = async () => { - try { - await mongoose.connect(config.mongodb.url); - await logger.info('Connected to the database'); - } catch (err) { - await logger.error(err); - } -}; diff --git a/src/helpers/database/index.ts b/src/helpers/database/index.ts new file mode 100644 index 0000000..b958372 --- /dev/null +++ b/src/helpers/database/index.ts @@ -0,0 +1,10 @@ +import mongoose from 'mongoose'; + +import * as config from '../../../config.json'; +import logger from '../../handlers/logger'; + +export default async () => +{ + await mongoose.connect(config.mongodb.url); + logger.info('Connected to the database'); +}; diff --git a/src/helpers/database/models/apiSchema.js b/src/helpers/database/models/apiSchema.ts similarity index 82% rename from src/helpers/database/models/apiSchema.js rename to src/helpers/database/models/apiSchema.ts index f05b156..978ecb3 100644 --- a/src/helpers/database/models/apiSchema.js +++ b/src/helpers/database/models/apiSchema.ts @@ -1,29 +1,29 @@ -const mongoose = require('mongoose'); - -const apiSchema = new mongoose.Schema( - { - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - url: { - type: mongoose.SchemaTypes.String, - required: true, - unique: false, - index: true, - default: 'https://localhost/api/', - }, - token: { - type: mongoose.SchemaTypes.String, - required: true, - unique: false, - index: true, - default: 'token', - }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('api', apiSchema); +import mongoose from 'mongoose'; + +const apiSchema = new mongoose.Schema( + { + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + url: { + type: mongoose.SchemaTypes.String, + required: true, + unique: false, + index: true, + default: 'https://localhost/api/', + }, + token: { + type: mongoose.SchemaTypes.String, + required: true, + unique: false, + index: true, + default: 'token', + }, + }, + { timestamps: true } +); + +export default mongoose.model('api', apiSchema); diff --git a/src/helpers/database/models/counterSchema.js b/src/helpers/database/models/counterSchema.ts similarity index 82% rename from src/helpers/database/models/counterSchema.js rename to src/helpers/database/models/counterSchema.ts index 9ebef31..8c49b9a 100644 --- a/src/helpers/database/models/counterSchema.js +++ b/src/helpers/database/models/counterSchema.ts @@ -1,34 +1,34 @@ -const mongoose = require('mongoose'); - -const counterSchema = new mongoose.Schema( - { - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - channelId: { - type: mongoose.SchemaTypes.String, - required: true, - unique: true, - index: true, - }, - word: { - type: mongoose.SchemaTypes.String, - required: true, - unique: false, - index: true, - }, - counter: { - type: mongoose.SchemaTypes.Number, - required: true, - unique: false, - index: true, - default: 0, - }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('counter', counterSchema); +import mongoose from 'mongoose'; + +const counterSchema = new mongoose.Schema( + { + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + channelId: { + type: mongoose.SchemaTypes.String, + required: true, + unique: true, + index: true, + }, + word: { + type: mongoose.SchemaTypes.String, + required: true, + unique: false, + index: true, + }, + counter: { + type: mongoose.SchemaTypes.Number, + required: true, + unique: false, + index: true, + default: 0, + }, + }, + { timestamps: true } +); + +export default mongoose.model('counter', counterSchema); diff --git a/src/helpers/database/models/guildSchema.js b/src/helpers/database/models/guildSchema.ts similarity index 90% rename from src/helpers/database/models/guildSchema.js rename to src/helpers/database/models/guildSchema.ts index fe50568..247ddd8 100644 --- a/src/helpers/database/models/guildSchema.js +++ b/src/helpers/database/models/guildSchema.ts @@ -1,71 +1,71 @@ -const mongoose = require('mongoose'); - -const guildSchema = new mongoose.Schema( - { - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: true, - index: true, - }, - credits: { - status: { - type: mongoose.SchemaTypes.Boolean, - default: true, - }, - rate: { - type: mongoose.SchemaTypes.Number, - default: 1, - }, - minimumLength: { - type: mongoose.SchemaTypes.Number, - default: 5, - }, - timeout: { - type: mongoose.SchemaTypes.Number, - default: 5000, - }, - workRate: { - type: mongoose.SchemaTypes.Number, - default: 15, - }, - workTimeout: { - type: mongoose.SchemaTypes.Number, - default: 900000, - }, - }, - shop: { - roles: { - status: { - type: mongoose.SchemaTypes.Boolean, - default: true, - }, - pricePerHour: { - type: mongoose.SchemaTypes.Number, - default: 5, - }, - }, - }, - points: { - status: { - type: mongoose.SchemaTypes.Boolean, - default: false, - }, - rate: { - type: mongoose.SchemaTypes.Number, - default: 1, - }, - minimumLength: { - type: mongoose.SchemaTypes.Number, - default: 5, - }, - timeout: { - type: mongoose.SchemaTypes.Number, - default: 5000, - }, - }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('guild', guildSchema); +import mongoose from 'mongoose'; + +const guildSchema = new mongoose.Schema( + { + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: true, + index: true, + }, + credits: { + status: { + type: mongoose.SchemaTypes.Boolean, + default: true, + }, + rate: { + type: mongoose.SchemaTypes.Number, + default: 1, + }, + minimumLength: { + type: mongoose.SchemaTypes.Number, + default: 5, + }, + timeout: { + type: mongoose.SchemaTypes.Number, + default: 5000, + }, + workRate: { + type: mongoose.SchemaTypes.Number, + default: 15, + }, + workTimeout: { + type: mongoose.SchemaTypes.Number, + default: 900000, + }, + }, + shop: { + roles: { + status: { + type: mongoose.SchemaTypes.Boolean, + default: true, + }, + pricePerHour: { + type: mongoose.SchemaTypes.Number, + default: 5, + }, + }, + }, + points: { + status: { + type: mongoose.SchemaTypes.Boolean, + default: false, + }, + rate: { + type: mongoose.SchemaTypes.Number, + default: 1, + }, + minimumLength: { + type: mongoose.SchemaTypes.Number, + default: 5, + }, + timeout: { + type: mongoose.SchemaTypes.Number, + default: 5000, + }, + }, + }, + { timestamps: true } +); + +export default mongoose.model('guild', guildSchema); diff --git a/src/helpers/database/models/index.js b/src/helpers/database/models/index.js deleted file mode 100644 index f459440..0000000 --- a/src/helpers/database/models/index.js +++ /dev/null @@ -1,15 +0,0 @@ -const users = require('./userSchema'); -const guilds = require('./guildSchema'); -const apis = require('./apiSchema'); -const timeouts = require('./timeoutSchema'); -const counters = require('./counterSchema'); -const shopRoles = require('./shopRolesSchema'); - -module.exports = { - users, - guilds, - apis, - timeouts, - counters, - shopRoles, -}; diff --git a/src/helpers/database/models/index.ts b/src/helpers/database/models/index.ts new file mode 100644 index 0000000..36a9f6d --- /dev/null +++ b/src/helpers/database/models/index.ts @@ -0,0 +1,15 @@ +import users from './userSchema'; +import guilds from './guildSchema'; +import apis from './apiSchema'; +import timeouts from './timeoutSchema'; +import counters from './counterSchema'; +import shopRoles from './shopRolesSchema'; + +export default { + users, + guilds, + apis, + timeouts, + counters, + shopRoles, +}; diff --git a/src/helpers/database/models/shopRolesSchema.js b/src/helpers/database/models/shopRolesSchema.ts similarity index 84% rename from src/helpers/database/models/shopRolesSchema.js rename to src/helpers/database/models/shopRolesSchema.ts index 6a8ff36..4a570c4 100644 --- a/src/helpers/database/models/shopRolesSchema.js +++ b/src/helpers/database/models/shopRolesSchema.ts @@ -1,39 +1,39 @@ -const mongoose = require('mongoose'); - -const shopRoleSchema = new mongoose.Schema( - { - roleId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - userId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - pricePerHour: { - type: mongoose.SchemaTypes.Number, - required: true, - unique: false, - index: true, - default: 5, - }, - lastPayed: { - type: mongoose.SchemaTypes.Date, - unique: false, - index: true, - }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('shopRole', shopRoleSchema); +import mongoose from 'mongoose'; + +const shopRoleSchema = new mongoose.Schema( + { + roleId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + userId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + pricePerHour: { + type: mongoose.SchemaTypes.Number, + required: true, + unique: false, + index: true, + default: 5, + }, + lastPayed: { + type: mongoose.SchemaTypes.Date, + unique: false, + index: true, + }, + }, + { timestamps: true } +); + +export default mongoose.model('shopRole', shopRoleSchema); diff --git a/src/helpers/database/models/timeoutSchema.js b/src/helpers/database/models/timeoutSchema.ts similarity index 77% rename from src/helpers/database/models/timeoutSchema.js rename to src/helpers/database/models/timeoutSchema.ts index 6dd0e96..125ffeb 100644 --- a/src/helpers/database/models/timeoutSchema.js +++ b/src/helpers/database/models/timeoutSchema.ts @@ -1,22 +1,22 @@ -const mongoose = require('mongoose'); - -const timeoutSchema = new mongoose.Schema( - { - userId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - timeoutId: { type: mongoose.SchemaTypes.String }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('timeout', timeoutSchema); +import mongoose from 'mongoose'; + +const timeoutSchema = new mongoose.Schema( + { + userId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + timeoutId: { type: mongoose.SchemaTypes.String }, + }, + { timestamps: true } +); + +export default mongoose.model('timeout', timeoutSchema); diff --git a/src/helpers/database/models/userSchema.js b/src/helpers/database/models/userSchema.ts similarity index 85% rename from src/helpers/database/models/userSchema.js rename to src/helpers/database/models/userSchema.ts index b1e530d..ea14a27 100644 --- a/src/helpers/database/models/userSchema.js +++ b/src/helpers/database/models/userSchema.ts @@ -1,29 +1,29 @@ -const mongoose = require('mongoose'); - -const userSchema = new mongoose.Schema( - { - guildId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - userId: { - type: mongoose.SchemaTypes.Decimal128, - required: true, - unique: false, - index: true, - }, - language: { - type: mongoose.SchemaTypes.String, - default: 'en', - }, - reputation: { type: mongoose.SchemaTypes.Number, default: 0 }, - credits: { type: mongoose.SchemaTypes.Number, default: 0 }, - levels: { type: mongoose.SchemaTypes.Number, default: 0 }, - points: { type: mongoose.SchemaTypes.Number, default: 0 }, - }, - { timestamps: true } -); - -module.exports = mongoose.model('user', userSchema); +import mongoose from 'mongoose'; + +const userSchema = new mongoose.Schema( + { + guildId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + userId: { + type: mongoose.SchemaTypes.Decimal128, + required: true, + unique: false, + index: true, + }, + language: { + type: mongoose.SchemaTypes.String, + default: 'en', + }, + reputation: { type: mongoose.SchemaTypes.Number, default: 0 }, + credits: { type: mongoose.SchemaTypes.Number, default: 0 }, + levels: { type: mongoose.SchemaTypes.Number, default: 0 }, + points: { type: mongoose.SchemaTypes.Number, default: 0 }, + }, + { timestamps: true } +); + +export default mongoose.model('user', userSchema); diff --git a/src/helpers/dbGuildFix.js b/src/helpers/dbGuildFix.ts similarity index 67% rename from src/helpers/dbGuildFix.js rename to src/helpers/dbGuildFix.ts index 0ba83dd..ee2ad4e 100644 --- a/src/helpers/dbGuildFix.js +++ b/src/helpers/dbGuildFix.ts @@ -1,21 +1,31 @@ // TODO This file will make sure that all guilds always has at least one entry in all collections with "guildId" -const { apis, guilds } = require('./database/models'); -const logger = require('../handlers/logger'); +import apis from "./database/models/apiSchema" +import guilds from "./database/models/guildSchema" -module.exports = async (guild) => { +import logger from '../handlers/logger'; +import { Guild } from 'discord.js'; + +export default async (guild: Guild) => +{ const api = await apis.findOne({ guildId: guild.id }); const guildData = await guilds.findOne({ guildId: guild.id }); - if (!api) { + if (!api) +{ apis.create({ guildId: guild.id }); logger.debug(`Guild: ${guild.id} added api collection`); - } else { + } + else +{ logger.debug(`Guild: ${guild.id} already in api collection`); } - if (!guildData) { + if (!guildData) +{ guilds.create({ guildId: guild.id }); logger.debug(`Guild: ${guild.id} added guild collection`); - } else { + } + else +{ logger.debug(`Guild: ${guild.id} already in guild collection`); } }; diff --git a/src/helpers/dbMemberFix.js b/src/helpers/dbMemberFix.ts similarity index 73% rename from src/helpers/dbMemberFix.js rename to src/helpers/dbMemberFix.ts index 320e719..121f875 100644 --- a/src/helpers/dbMemberFix.js +++ b/src/helpers/dbMemberFix.ts @@ -1,20 +1,27 @@ -const { users } = require('./database/models'); -const logger = require('../handlers/logger'); +import users from './database/models/userSchema'; +import logger from '../handlers/logger'; +import { Guild, User } from 'discord.js'; -module.exports = async (user, guild) => { +export default async (user: User, guild: Guild) => +{ const userData = await users.findOne({ userId: user.id, guildId: guild.id }); - if (!userData) { + if (!userData) +{ users .create({ userId: user.id, guildId: guild.id }) - .then(async () => { + .then(async () => +{ await logger.debug(`User: ${user.id} added user collection`); }) - .catch(async (e) => { + .catch(async (e) => +{ await logger.error( `User: ${user.id} failed to added user collection ${e}` ); }); - } else { + } + else +{ logger.debug(`User: ${user.id} already in user collection`); } diff --git a/src/helpers/deployCommands.js b/src/helpers/deployCommands.ts similarity index 71% rename from src/helpers/deployCommands.js rename to src/helpers/deployCommands.ts index d488470..827b637 100644 --- a/src/helpers/deployCommands.js +++ b/src/helpers/deployCommands.ts @@ -1,17 +1,17 @@ -const config = require('../../config.json'); -const logger = require('../handlers/logger'); -const fs = require('fs'); -const { REST } = require('@discordjs/rest'); -const { Routes } = require('discord-api-types/v9'); +import config from '../../config.json'; +import logger from '../handlers/logger'; +import fs from 'fs'; +import { REST } from '@discordjs/rest'; +import { Routes } from 'discord-api-types/v9'; -module.exports = async () => { +export default async () => { const commands = []; const commandFiles = fs.readdirSync('./src/commands'); for (const file of commandFiles) { // eslint-disable-next-line import/no-dynamic-require, global-require const command = require(`../commands/${file}`); - commands.push(command.data.toJSON()); + commands.push(command.default.data.toJSON()); } const rest = new REST({ version: '9' }).setToken(config.bot.token); diff --git a/src/helpers/index.js b/src/helpers/index.js deleted file mode 100644 index 9f4532f..0000000 --- a/src/helpers/index.js +++ /dev/null @@ -1,6 +0,0 @@ -const database = require('./database'); -const deployCommands = require('./deployCommands'); -const dbGuildFix = require('./dbGuildFix'); -const dbMemberFix = require('./dbMemberFix'); - -module.exports = { database, deployCommands, dbGuildFix, dbMemberFix }; diff --git a/src/helpers/index.ts b/src/helpers/index.ts new file mode 100644 index 0000000..1f68476 --- /dev/null +++ b/src/helpers/index.ts @@ -0,0 +1,6 @@ +import database from "./database.ts'; +import deployCommands from './deployCommands'; +import dbGuildFix from './dbGuildFix'; +import dbMemberFix from './dbMemberFix'; + +export default { database, deployCommands, dbGuildFix, dbMemberFix }; diff --git a/src/helpers/saveUser.js b/src/helpers/saveUser.ts similarity index 77% rename from src/helpers/saveUser.js rename to src/helpers/saveUser.ts index 1933987..d3bf640 100644 --- a/src/helpers/saveUser.js +++ b/src/helpers/saveUser.ts @@ -1,12 +1,11 @@ -const sleep = require('./sleep'); +import sleep from './sleep'; +import logger from '../handlers/logger'; -const logger = require('../handlers/logger'); - -module.exports = async function saveUser(data, data2) { +export default async function saveUser(data: any, data2: any) { process.nextTick( async () => { await sleep(Math.floor(Math.random() * 10 + 1) * 100); // 100 - 1000 random Number generator - data.save((_) => + data.save((_: any) => _ ? logger.error( `ERROR Occurred while saving data (saveUser) \n${'='.repeat( @@ -16,7 +15,7 @@ module.exports = async function saveUser(data, data2) { : 'No Error' ); if (data2) { - data2.save((_) => + data2.save((_: any) => _ ? logger.error( `ERROR Occurred while saving data (saveUser) \n${'='.repeat( @@ -30,4 +29,4 @@ module.exports = async function saveUser(data, data2) { data, data2 ); -}; +} diff --git a/src/helpers/sleep.js b/src/helpers/sleep.ts similarity index 60% rename from src/helpers/sleep.js rename to src/helpers/sleep.ts index f91ffc5..ced6bf6 100644 --- a/src/helpers/sleep.js +++ b/src/helpers/sleep.ts @@ -1,5 +1,5 @@ -module.exports = function sleep(milliseconds) { +export default function sleep(milliseconds: any) { return new Promise((resolve) => { setTimeout(resolve, milliseconds); }); -}; +} diff --git a/src/index.js b/src/index.ts similarity index 53% rename from src/index.js rename to src/index.ts index a0d8ce5..919d72a 100644 --- a/src/index.js +++ b/src/index.ts @@ -1,10 +1,13 @@ // Dependencies -const { Client, Intents } = require('discord.js'); // discord.js +import { Client, Intents } from 'discord.js'; // discord.js -const { database } = require('./helpers'); // helpers -const { events, commands, locale, schedules } = require('./handlers'); // handlers +import database from './helpers/database/index'; +import events from './handlers/events'; +import commands from './handlers/commands'; +import locale from './handlers/locale'; +import schedules from './handlers/schedules'; -const config = require('../config.json'); // config.json +import config from '../config.json'; // config.json (async () => { // Initialize discord.js client @@ -21,6 +24,5 @@ const config = require('../config.json'); // config.json await events(client); await commands(client); await schedules(client); - await client.login(config.bot.token); })(); diff --git a/src/types/common/discord.d.ts b/src/types/common/discord.d.ts new file mode 100644 index 0000000..30bae32 --- /dev/null +++ b/src/types/common/discord.d.ts @@ -0,0 +1,8 @@ +import { Collection, Client as DJSClient } from 'discord.js'; +declare module 'discord.js' { + export interface Client extends DJSClient { + commands: Collection; + } +} + +export { Client }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..565e6a7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es2019", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "commonjs", + "resolveJsonModule": true, + "isolatedModules": true, + // "removeComments": true, + "outDir": "./build", + "paths": { + "@interface/*": ["./src/Interfaces/*"] + }, + "typeRoots": ["./src/types/common", "./node_modules/@types"] + }, + "exclude": ["./node_modules", "./test"], + "include": ["./src"] +}