From b0763f752445d74e307a6db6c8a994b50ff96d29 Mon Sep 17 00:00:00 2001 From: Piyush Acharya Date: Thu, 12 Jan 2023 19:58:57 -0800 Subject: [PATCH] Adhere to TS and Markdown Style Guidelines (#46) * Update package.json * Adhere to Markdown and TS Style Guidelines * Adhere to ESLint * Some more edits to adhere to the ESLint standard * style: modify slightly to adhere to ESLint spec Co-authored-by: Piyush Acharya Co-authored-by: Abheek --- .eslintrc.json | 110 ++++++++++++++---- .github/CODE_OF_CONDUCT.md | 2 +- .github/CONTRIBUTING.md | 16 ++- .github/workflows/codeql.yml | 16 +-- .github/workflows/eslint.yml | 10 +- .github/workflows/release.yml | 4 +- README.md | 27 +++-- docker-compose.yml | 26 ++--- package.json | 2 +- src/commands/about.ts | 4 +- src/commands/help.ts | 3 +- src/commands/rounds.ts | 21 ++-- src/commands/score.ts | 7 +- src/commands/settings.ts | 30 ++++- src/commands/top.ts | 6 +- src/commands/train.ts | 43 ++++--- src/deploy-commands.js | 18 +-- src/helpers/db.ts | 14 ++- src/helpers/util/pagination.ts | 21 +++- tsconfig.json | 203 +++++++++++++++++---------------- 20 files changed, 365 insertions(+), 218 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 63fb5d6..67417ac 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,44 +10,110 @@ "node": true, "es6": true }, - "ignorePatterns": ["src/deploy-commands.js"], + "ignorePatterns": [ + "src/deploy-commands.js" + ], "rules": { - "arrow-spacing": ["error", { "before": true, "after": true }], - "brace-style": ["error", "stroustrup", { "allowSingleLine": true }], - "comma-dangle": ["error", "always-multiline"], + "arrow-spacing": [ + "error", + { + "before": true, + "after": true + } + ], + "brace-style": [ + "error", + "stroustrup", + { + "allowSingleLine": true + } + ], + "comma-dangle": [ + "error", + "always-multiline" + ], "comma-spacing": "error", "comma-style": "error", - "curly": ["error", "multi-line", "consistent"], - "dot-location": ["error", "property"], + "curly": [ + "error", + "multi-line", + "consistent" + ], + "dot-location": [ + "error", + "property" + ], "handle-callback-err": "off", - "indent": ["error", "tab"], + "indent": [ + "error", + "tab" + ], "keyword-spacing": "error", - "max-nested-callbacks": ["error", { "max": 4 }], - "max-statements-per-line": ["error", { "max": 2 }], + "max-nested-callbacks": [ + "error", + { + "max": 4 + } + ], + "max-statements-per-line": [ + "error", + { + "max": 2 + } + ], "no-console": "off", "no-empty-function": "error", "no-floating-decimal": "error", "no-lonely-if": "error", "no-multi-spaces": "error", - "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], - "no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }], - "no-trailing-spaces": ["error"], + "no-multiple-empty-lines": [ + "error", + { + "max": 2, + "maxEOF": 1, + "maxBOF": 0 + } + ], + "no-shadow": [ + "error", + { + "allow": [ + "err", + "resolve", + "reject" + ] + } + ], + "no-trailing-spaces": [ + "error" + ], "no-var": "error", - "object-curly-spacing": ["error", "always"], + "object-curly-spacing": [ + "error", + "always" + ], "prefer-const": "error", - "quotes": ["error", "single"], - "semi": ["error", "always"], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], "space-before-blocks": "error", - "space-before-function-paren": ["error", { - "anonymous": "never", - "named": "never", - "asyncArrow": "always" - }], + "space-before-function-paren": [ + "error", + { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + } + ], "space-in-parens": "error", "space-infix-ops": "error", "space-unary-ops": "error", "spaced-comment": "error", "yoda": "error" } -} - +} \ No newline at end of file diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index e9bb389..fcaa8b9 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an +standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9a197fa..8578bac 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,22 +1,32 @@ # Contributing ## Cloning for Contribution -To set up the development environment to make changes to the code, clone the repo, install dependencies, and run it directly with `node` as Docker doesn't expose as much. + +To set up the development environment to make changes to the code, clone the repo, install dependencies, and run it +directly with `node` as Docker doesn't expose as much. ## Making Changes + To edit the code please keep a few things in mind: + 1. Be able to explain changes you make; they should be legible and understandable. 2. Please try to abide by ESLint's rules, setting up ESLint is quite easy to do and not too difficult to follow. ## Testing Your Code + For testing, make sure to set up the prerequisites: + 1. MongoDB: have a MongoDB server set up. 2. Environment Variables: take a look at the `docker-compose.yml` for examples. -Once that's done, you can run `yarn tsc` or `npx tsc` to build to JavaScript in the `built` directory. Here you'll find `deploy-commands.js` which you need to deploy the slash commands, and `index.js` which you can run to start the bot. +Once that's done, you can run `yarn tsc` or `npx tsc` to build to JavaScript in the `built` directory. Here you'll +find `deploy-commands.js` which you need to deploy the slash commands, and `index.js` which you can run to start the +bot. ## Submitting Your Contribution -Creating a PR is easy enough and there are plenty of tutorials to do so. When contributing, please make sure to highlight and explain your change, with any import information additionally included. + +Creating a PR is easy enough and there are plenty of tutorials to do so. When contributing, please make sure to +highlight and explain your change, with any import information additionally included. --- diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7a5f298..a97bf76 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,13 +13,13 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: 'javascript' + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: 'javascript' - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 25a2be6..01bf30d 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -11,8 +11,8 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Install modules - run: yarn - - name: Run ESLint - run: yarn run lint + - uses: actions/checkout@v2 + - name: Install modules + run: yarn + - name: Run ESLint + run: yarn run lint diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 02a2efe..c35d6ea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: uses: docker/metadata-action@v3 with: images: adawesomeguy/awesomescibo - + - name: Build and push uses: docker/build-push-action@v2 with: @@ -51,7 +51,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - + - name: Setup Node.js uses: actions/setup-node@v2 with: diff --git a/README.md b/README.md index 5f0b536..78909f6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - ![logo](https://user-images.githubusercontent.com/67982792/160637166-b8c3a390-e4f9-46d1-8738-dcb2d8b9baa7.png)

AwesomeSciBo

@@ -16,23 +15,35 @@

Open-source Discord bot that aims to aid up-and-coming Scibowlers with randomly generated (non-stock) rounds and training. It has many features, including subject-targeted training, a cross-server leaderboard, and a plethora of slash commands!

## Deployment -Deploying this bot to your Discord server is relatively simple: you can add it to your own server by using [this link](https://adat.link/awesomescibo). + +Deploying this bot to your Discord server is relatively simple: you can add it to your own server by +using [this link](https://adat.link/awesomescibo). ## Contributing -Please see [CONTRIBUTING.md](https://github.com/ADawesomeguy/AwesomeSciBo/blob/master/.github/CONTRIBUTING.md). +Please see [CONTRIBUTING.md](https://github.com/ADawesomeguy/AwesomeSciBo/blob/master/.github/CONTRIBUTING.md). ## Installation + There are basically two ways to install it: -### Method 1 (Node): -After cloning the repository, dependencies can be installed with `yarn` or `npm i`. The bot can then be compile to JavaScript with `yarn tsc` or `npx tsc`, and will be deployed in the `built/` directory. Finally, the bot can be run by entering said directory and running `./index.js` or `node index.js`. +### Method 1 (Node): -### Method 2 (Docker): -This bot has a Dockerfile within the repository which can be built using `docker build . -t [tag]`. Alternatively and preferably, the image can be taken from [DockerHub](https://hub.docker.com/r/adawesomeguy/awesomescibo). +After cloning the repository, dependencies can be installed with `yarn` or `npm i`. The bot can then be compile to +JavaScript with `yarn tsc` or `npx tsc`, and will be deployed in the `built/` directory. Finally, the bot can be run by +entering said directory and running `./index.js` or `node index.js`. + +### Method 2 (Docker): + +This bot has a Dockerfile within the repository which can be built using `docker build . -t [tag]`. Alternatively and +preferably, the image can be taken from [DockerHub](https://hub.docker.com/r/adawesomeguy/awesomescibo). ## Usage + This bot uses slash commands now :). You can just click on the bot icon after typing `/` to see a list of commands. ## Credit -The bot was made by [@ADawesomeguy](https://github.com/ADawesomeguy). However, the API was made by [@CQCumbers](https://github.com/CQCumbers). Go give [his API](https://github.com/CQCumbers/ScibowlDB) a star, he totally deserves it! + +The bot was made by [@ADawesomeguy](https://github.com/ADawesomeguy). However, the API was made +by [@CQCumbers](https://github.com/CQCumbers). Go give [his API](https://github.com/CQCumbers/ScibowlDB) a star, he +totally deserves it! diff --git a/docker-compose.yml b/docker-compose.yml index 8779f30..3ec1540 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,17 @@ # Use root/example as user/password credentials version: '3.1' services: - mongo: - image: mongo:4.4 - restart: always - volumes: - - ./data:/data/db + mongo: + image: mongo:4.4 + restart: always + volumes: + - ./data:/data/db - awesomescibo: - image: docker.io/adawesomeguy/awesomescibo:latest - restart: unless-stopped - environment: - MONGO_URI: "mongodb://mongo:27017/AWESOME" - TOKEN: "" - CLIENT_ID: "" - TESTING_GUILD: "" + awesomescibo: + image: docker.io/adawesomeguy/awesomescibo:latest + restart: unless-stopped + environment: + MONGO_URI: "mongodb://mongo:27017/AWESOME" + TOKEN: "" + CLIENT_ID: "" + TESTING_GUILD: "" diff --git a/package.json b/package.json index 65082ec..77fac1e 100644 --- a/package.json +++ b/package.json @@ -31,4 +31,4 @@ "author": "Abheek Dhawan", "license": "MIT", "description": "A simple Discord bot that automatically generates Science Bowl rounds using the ScibowlDB API!" -} +} \ No newline at end of file diff --git a/src/commands/about.ts b/src/commands/about.ts index 39618ae..cd7c6e6 100644 --- a/src/commands/about.ts +++ b/src/commands/about.ts @@ -11,11 +11,11 @@ export const data = new SlashCommandBuilder() .setName('about') .setDescription('Commands regarding the creation/development of the bot'); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { await interaction.deferReply(); const client = interaction.client; - const embeds : MessageEmbed[] = []; + const embeds: MessageEmbed[] = []; const contributorEmbed = new MessageEmbed().setTitle('Contributors') .addField('Creator', '<@745063586422063214> [ADawesomeguy#3602]', true) diff --git a/src/commands/help.ts b/src/commands/help.ts index 0504860..ae7bb2a 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -5,7 +5,8 @@ export const data = new SlashCommandBuilder() .setName('help') .setDescription('Replies with a help message explaining what the bot can do'); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { + await interaction.deferReply(); await interaction.deferReply(); const helpEmbed = new MessageEmbed() diff --git a/src/commands/rounds.ts b/src/commands/rounds.ts index cb0b653..0d90b14 100644 --- a/src/commands/rounds.ts +++ b/src/commands/rounds.ts @@ -28,20 +28,20 @@ export const data = new SlashCommandBuilder() return subcommand; }); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { const action = interaction.options.getSubcommand(); switch (action) { case 'generate': { interaction.deferReply({ ephemeral: true }); let finalizedHTML = '

ROUND GENERATED BY AWESOMESCIBO USING THE SCIBOWLDB API

'; - let tossup_question : string; - let question_category : string; - let tossup_format : string; - let tossup_answer : string; - let bonus_question : string; - let bonus_format : string; - let bonus_answer : string; + let tossup_question: string; + let question_category: string; + let tossup_format: string; + let tossup_answer: string; + let bonus_question: string; + let bonus_format: string; + let bonus_answer: string; let htmlContent = ''; await axios.post('https://scibowldb.com/api/questions', { categories: ['BIOLOGY', 'PHYSICS', 'CHEMISTRY', 'EARTH AND SPACE', 'ASTRONOMY', 'MATH'] }) .then((response) => { @@ -72,7 +72,10 @@ export async function execute(interaction : CommandInteraction) { log({ logger: 'rounds', content: `Saving round to DB failed: ${err}`, level: 'error' }); return; } - interaction.followUp({ content: `Here's your round: https://api.adawesome.tech/round/${round._id.toString()}`, ephemeral: true }); + interaction.followUp({ + content: `Here's your round: https://api.adawesome.tech/round/${round._id.toString()}`, + ephemeral: true, + }); }); }); break; diff --git a/src/commands/score.ts b/src/commands/score.ts index 06c5c5d..2408e4b 100644 --- a/src/commands/score.ts +++ b/src/commands/score.ts @@ -16,7 +16,7 @@ export const data = new SlashCommandBuilder() return option; }); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { const scoreEmbed = new MessageEmbed() .setColor('#ffffff'); @@ -27,7 +27,10 @@ export async function execute(interaction : CommandInteraction) { } if (!score) { - await interaction.reply({ content: 'Unfortunately, that user does not seem to have used AwesomeSciBo yet.', ephemeral: true }); + await interaction.reply({ + content: 'Unfortunately, that user does not seem to have used AwesomeSciBo yet.', + ephemeral: true, + }); return; } diff --git a/src/commands/settings.ts b/src/commands/settings.ts index d918c4b..a0bc130 100644 --- a/src/commands/settings.ts +++ b/src/commands/settings.ts @@ -26,7 +26,7 @@ export const data = new SlashCommandBuilder() return subcommand; }); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { const action = interaction.options.getSubcommand(); switch (action) { case 'display': { @@ -70,7 +70,11 @@ export async function execute(interaction : CommandInteraction) { const vals = dispChoice.values; const config = await userConfig.findById(interaction.user.id); if (!config) { - await interaction.editReply({ content: 'You don\'t have a configuration!', embeds: [], components: [] }); + await interaction.editReply({ + content: 'You don\'t have a configuration!', + embeds: [], + components: [], + }); } else if (vals.length === 1 && vals.at(0) === 'subjects') { await interaction.editReply({ @@ -138,7 +142,10 @@ export async function execute(interaction : CommandInteraction) { .then(async lvlChoice => { const vals = lvlChoice.values; const levels = new Array(); - await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { gradeLevels: vals }, { upsert: true, new: true }); + await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { gradeLevels: vals }, { + upsert: true, + new: true, + }); await vals.forEach(v => { switch (v) { case 'MS': @@ -148,7 +155,11 @@ export async function execute(interaction : CommandInteraction) { levels.push('High School'); } }); - await interaction.editReply({ content: `Level set to: ${levels.toString().split(',').join(', ')}`, embeds: [], components: [] }); + await interaction.editReply({ + content: `Level set to: ${levels.toString().split(',').join(', ')}`, + embeds: [], + components: [], + }); }); })); break; @@ -219,12 +230,19 @@ export async function execute(interaction : CommandInteraction) { (subjectMsg as Message).awaitMessageComponent({ filter: subjectFilter, componentType: 'SELECT_MENU' }) .then(async subjectChoice => { const vals = subjectChoice.values; - await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { subjects: vals }, { upsert: true, new: true }); + await userConfig.findOneAndUpdate({ _id: interaction.user.id }, { subjects: vals }, { + upsert: true, + new: true, + }); const subjects = new Array(); await vals.forEach(v => { subjects.push(v.toLowerCase().split(' ').map(w => w[0].toUpperCase() + w.substring(1)).join(' ')); }); - await interaction.editReply({ content: `Subjects set to: ${subjects.toString().split(',').join(', ')}`, components: [], embeds: [] }); + await interaction.editReply({ + content: `Subjects set to: ${subjects.toString().split(',').join(', ')}`, + components: [], + embeds: [], + }); }); })); break; diff --git a/src/commands/top.ts b/src/commands/top.ts index 0e7ac6e..28a8127 100644 --- a/src/commands/top.ts +++ b/src/commands/top.ts @@ -8,7 +8,7 @@ export const data = new SlashCommandBuilder() .setName('top') .setDescription('Lists top ten scores across servers (server specific leaderboard WIP)'); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { await interaction.deferReply(); userScore @@ -21,13 +21,13 @@ export async function execute(interaction : CommandInteraction) { } if (obj.length < 10) { - // Need at least 10 scores for top 10 + // Need at least 10 scores for top 10 return interaction.followUp( `There are only ${obj.length} users, we need at least 10!`, ); } - const embeds : MessageEmbed[] = []; + const embeds: MessageEmbed[] = []; let lbMessageContent = ''; for (let i = 0; i < 10; i++) { diff --git a/src/commands/train.ts b/src/commands/train.ts index 1485228..6812c67 100644 --- a/src/commands/train.ts +++ b/src/commands/train.ts @@ -31,7 +31,7 @@ export const data = new SlashCommandBuilder() return option; }); -export async function execute(interaction : CommandInteraction) { +export async function execute(interaction: CommandInteraction) { await interaction.deferReply(); const subject = interaction.options.get('subject') ? interaction.options.get('subject')?.value : null; @@ -44,23 +44,26 @@ export async function execute(interaction : CommandInteraction) { if (!obj) { score = 0; const firstTimeEmbed = new MessageEmbed() - .setAuthor({ name: interaction.client.user?.tag ? interaction.client.user?.tag : '', iconURL: interaction.client.user?.displayAvatarURL() }) + .setAuthor({ + name: interaction.client.user?.tag ? interaction.client.user?.tag : '', + iconURL: interaction.client.user?.displayAvatarURL(), + }) .setDescription('Hey! It seems like it\'s your first time using AwesomeSciBo. Here\'s some information regarding the bot if you need it (for issues, contributions, etc.):') .addField('Creator', '<@745063586422063214> [@abheekd#3602]') .addField('GitHub', '[Link](https://github.com/ADawesomeguy/AwesomeSciBo) (a star couldn\'t hurt...)') .setColor('#ffffff') .setTimestamp(); interaction.user.send({ embeds: [firstTimeEmbed] }); - } + } else if (obj) { score = obj.score; - } + } else { log({ logger: 'train', content: `Getting user score failed: ${err}`, level: 'error' }); } }); - let categoryArray : string[] = []; + let categoryArray: string[] = []; const allCategories = ['BIOLOGY', 'PHYSICS', 'CHEMISTRY', 'EARTH AND SPACE', 'ASTRONOMY', 'MATH']; const configCategories = await userConfig.findById(interaction.user.id); @@ -142,7 +145,7 @@ export async function execute(interaction : CommandInteraction) { let predicted = ''; if (answerMsg?.content.toLowerCase() === tossupAnswer.toLowerCase() || answers.includes(answerMsg?.content.toUpperCase())) { predicted = 'correct'; - } + } else { predicted = 'incorrect'; } @@ -151,10 +154,13 @@ export async function execute(interaction : CommandInteraction) { updateScore(true, score, authorId).then((msgToReply) => answerMsg?.reply(msgToReply), ); - } + } else { const overrideEmbed = new MessageEmbed() - .setAuthor({ name: answerMsg?.author.tag ? answerMsg.author.tag : '', iconURL: answerMsg?.author.displayAvatarURL() }) + .setAuthor({ + name: answerMsg?.author.tag ? answerMsg.author.tag : '', + iconURL: answerMsg?.author.displayAvatarURL(), + }) .addField('Correct answer', `\`${tossupAnswer}\``) .setDescription('It seems your answer was incorrect. Please react with <:override:955265585086857236> to override your answer if you think you got it right.') .setColor('#ffffff') @@ -174,7 +180,7 @@ export async function execute(interaction : CommandInteraction) { const overrideFilter = i => { return ( ['override'].includes(i.customId) && - i.user.id === answerMsg.author.id + i.user.id === answerMsg.author.id ); }; overrideMsg @@ -186,8 +192,16 @@ export async function execute(interaction : CommandInteraction) { await i.reply(msgToReply); overrideMsg.edit({ components: [] }); }); - }).catch(err => log({ logger: 'train', content: `Failed to override score: ${err}`, level: 'error' })); - }).catch(err => log({ logger: 'train', content: `Failed to send override message: ${err}`, level: 'error' })); + }).catch(err => log({ + logger: 'train', + content: `Failed to override score: ${err}`, + level: 'error', + })); + }).catch(err => log({ + logger: 'train', + content: `Failed to send override message: ${err}`, + level: 'error', + })); } interaction.editReply({ components: [sourceButton] }); }).catch(err => log({ logger: 'train', content: `${err}`, level: 'error' })); @@ -221,10 +235,13 @@ export async function execute(interaction : CommandInteraction) { updateScore(true, score, authorId).then((msgToReply) => mcChoice.reply(msgToReply), ); - } + } else { const incorrectEmbed = new MessageEmbed() - .setAuthor({ name: interaction.user.tag, iconURL: interaction.user.displayAvatarURL() }) + .setAuthor({ + name: interaction.user.tag, + iconURL: interaction.user.displayAvatarURL(), + }) .addField('Correct answer', `\`${tossupAnswer}\``) .setDescription(`It seems your answer ${mcChoice.customId.toUpperCase()} was incorrect.`) .setColor('#ffffff') diff --git a/src/deploy-commands.js b/src/deploy-commands.js index e360e6e..a56e0b3 100644 --- a/src/deploy-commands.js +++ b/src/deploy-commands.js @@ -1,20 +1,20 @@ #!/usr/bin/env node const fs = require('node:fs'); -const { REST } = require('@discordjs/rest'); -const { Routes } = require('discord-api-types/v9'); -const { clientId, token } = require('./helpers/env'); +const {REST} = require('@discordjs/rest'); +const {Routes} = require('discord-api-types/v9'); +const {clientId, token} = require('./helpers/env'); const commands = []; const commandFiles = fs.readdirSync(__dirname + '/commands').filter(file => file.endsWith('.js')); for (const file of commandFiles) { - const command = require(`${__dirname}/commands/${file}`); - commands.push(command.data.toJSON()); + const command = require(`${__dirname}/commands/${file}`); + commands.push(command.data.toJSON()); } -const rest = new REST({ version: '9' }).setToken(token); +const rest = new REST({version: '9'}).setToken(token); -rest.put(Routes.applicationCommands(clientId), { body: commands }) - .then(() => console.log('Successfully registered application commands.')) - .catch(console.error); +rest.put(Routes.applicationCommands(clientId), {body: commands}) + .then(() => console.log('Successfully registered application commands.')) + .catch(console.error); diff --git a/src/helpers/db.ts b/src/helpers/db.ts index 8b9f964..26c2a15 100644 --- a/src/helpers/db.ts +++ b/src/helpers/db.ts @@ -3,10 +3,10 @@ import mongoose from 'mongoose'; import log from '../helpers/log'; import userScore from '../models/userScore'; -export async function updateScore(isCorrect : boolean, score : number, authorId : string) { +export async function updateScore(isCorrect: boolean, score: number, authorId: string) { if (!isCorrect) { return `Nice try! Your score is still ${score}.`; - } + } else { // TODO: Error handling const doc = await userScore.findOne({ @@ -20,12 +20,12 @@ export async function updateScore(isCorrect : boolean, score : number, authorId newUserScore.save(err => { if (err) { log({ logger: 'db', content: `Error creating new user ${authorId} for scoring`, level: 'error' }); - } + } else { log({ logger: 'db', content: `Successfully created user ${authorId} for scoring`, level: 'debug' }); } }); - } + } else { doc.score = doc.score + 4; doc.save(); @@ -42,6 +42,10 @@ export async function connect(mongoUri) { useNewUrlParser: true, }) .then(() => log({ logger: 'db', content: `Connected to the database at ${mongoUri}!`, level: 'info' })) - .catch(err => log({ logger: 'db', content: `Failed to connect to the database at ${mongoUri}: ${err}`, level: 'fatal' })); + .catch(err => log({ + logger: 'db', + content: `Failed to connect to the database at ${mongoUri}: ${err}`, + level: 'fatal', + })); } diff --git a/src/helpers/util/pagination.ts b/src/helpers/util/pagination.ts index 187ff91..b296fb5 100644 --- a/src/helpers/util/pagination.ts +++ b/src/helpers/util/pagination.ts @@ -1,6 +1,6 @@ import { CommandInteraction, Message, MessageActionRow, MessageButton, MessageEmbed } from 'discord.js'; -export async function paginateMessage(message : Message, embeds : MessageEmbed[]) { +export async function paginateMessage(message: Message, embeds: MessageEmbed[]) { let index = 0; const row = new MessageActionRow; @@ -19,7 +19,10 @@ export async function paginateMessage(message : Message, embeds : MessageEmbed[] .then(async paginatorMessage => { const filter = m => m.author.id === message.author.id; - const paginatorCollector = paginatorMessage.createMessageComponentCollector({ componentType: 'BUTTON', filter: filter }); + const paginatorCollector = paginatorMessage.createMessageComponentCollector({ + componentType: 'BUTTON', + filter: filter, + }); paginatorCollector.on('collect', async i => { switch (i.customId) { @@ -37,7 +40,7 @@ export async function paginateMessage(message : Message, embeds : MessageEmbed[] }); } -export async function paginateInteraction(interaction : CommandInteraction, embeds : MessageEmbed[]) { +export async function paginateInteraction(interaction: CommandInteraction, embeds: MessageEmbed[]) { let index = 0; const row = new MessageActionRow; @@ -52,12 +55,20 @@ export async function paginateInteraction(interaction : CommandInteraction, embe .setStyle('SECONDARY') ); - await interaction.followUp({ content: `Page 1 of ${embeds.length}:`, embeds: [embeds[index]], components: [row], fetchReply: true }) + await interaction.followUp({ + content: `Page 1 of ${embeds.length}:`, + embeds: [embeds[index]], + components: [row], + fetchReply: true, + }) .then(async p => { const paginatorMessage = p as Message; const filter = i => i.user.id === interaction.user.id; - const paginatorCollector = paginatorMessage.createMessageComponentCollector({ componentType: 'BUTTON', filter: filter }); + const paginatorCollector = paginatorMessage.createMessageComponentCollector({ + componentType: 'BUTTON', + filter: filter, + }); paginatorCollector.on('collect', async i => { switch (i.customId) { diff --git a/tsconfig.json b/tsconfig.json index 63f9120..1e78ad4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,101 +1,104 @@ { - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Projects */ - "incremental": true, /* Enable incremental compilation */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ - // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "resolveJsonModule": true, /* Enable importing .json files */ - // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./built", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": false, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ - // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ - // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + /* Projects */ + "incremental": true, + /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + /* Language and Environment */ + "target": "es2016", + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + /* Modules */ + "module": "commonjs", + /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + "moduleResolution": "node", + /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + /* JavaScript Support */ + "allowJs": true, + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./built", + /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, + /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, + /* Ensure that casing is correct in imports. */ + /* Type Checking */ + "strict": true, + /* Enable all strict type-checking options. */ + "noImplicitAny": false, + /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true + /* Skip type checking all .d.ts files. */ + } +} \ No newline at end of file