diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..f837930 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,19 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + plugins: ['@typescript-eslint'], + ignorePatterns: ['*.cjs'], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2022 + }, + env: { + node: true + }, + rules: { + 'indent': ['error', 2], + 'quotes': ['error', 'single'], + 'semi': ['error', 'always'], + } +}; diff --git a/.gitignore b/.gitignore index 5808694..3bc9717 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ survey-responses/* config.json next.json -node_modules \ No newline at end of file +node_modules +tsconfig.tsbuildinfo \ No newline at end of file diff --git a/built/commands/change.js b/built/commands/change.js new file mode 100644 index 0000000..7b62cfc --- /dev/null +++ b/built/commands/change.js @@ -0,0 +1,89 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const builders_1 = require("@discordjs/builders"); +const discord_js_1 = require("discord.js"); +const rand = [ + 'This change has no significance.', + 'You do not know what this can do.', + 'Nothing has changed.', + 'Nothing of value has been changed.', + 'You\'ll want to find something of value to change next time.' +]; +const names = [ + 'Fire\'s Pit', + 'Flaming Pit', + 'Pit of Fire', + 'Pit Fire', + 'Pire Fit', + 'White Space', + 'The void', + 'Fire pit', + 'fire pit' +]; +const channels = [ + 'toyota', + 'ъ', + 'deadlocked', + 'stereo-madness', + 'basketball', + 'send-help' +]; +const nicknames = [ + 'напиток безалкогольный сильногаз', + 'forg', + 'foggy', + 'frog', + 'fog' +]; +module.exports = { + data: new builders_1.SlashCommandBuilder() + .setName('change') + .setDescription('Change') + .addStringOption((option) => option.setName('what').setDescription('Change what? Examples include: "environment", "perspective", etc...').setRequired(true)), + execute: async (interaction, member) => { + let what = interaction.options.getString('what'); + let title = `**${member.displayName}** changed the **${what}**`; + let response; + switch (what.toLowerCase()) { + case 'environment': + case 'surroundings': + const name = names[Math.floor(Math.random() * names.length)]; + response = `You feel as if you're in a new space entirely. You find yourself in **${name}**.`; + await interaction.guild.setName(name, 'environment change'); + break; + case 'perspective': + case 'vision': + const channel = channels[Math.floor(Math.random() * channels.length)]; + response = `You've decided you want to change your perspective on the place you find yourself in. You are now in **#${channel}**.`; + await interaction.channel.setName(channel); + break; + case 'persona': + case 'self': + title = 'I\'m afraid I can\'t do that.'; + response = `You're locked in as is, **${member.user.username}**. Noone but you can change this.`; + break; + case 'identity': + response = `I've changed my nickname in accordance. I hope this identity pleases you.`; + await interaction.guild.me.setNickname(nicknames[Math.floor(Math.random() * nicknames.length)]); + break; + case 'location': + case 'position': + response = `You do not feel like your surroundings have changed, but rather where you are relative to your surroundings has changed.`; + const categories = Array(...interaction.guild.channels.cache.filter(v => v.type === 'GUILD_CATEGORY').values()); + const category = categories[Math.floor(Math.random() * categories.length)]; + await interaction.channel.setParent(category); + await interaction.channel.setPosition(Math.floor(Math.random() * category.children.size)); + break; + default: + response = rand[Math.floor(Math.random() * rand.length)]; + } + const embed = new discord_js_1.MessageEmbed() + .setTitle(title) + .setDescription(response) + .setTimestamp(); + await interaction.reply({ + embeds: [embed], + ephemeral: false, + }); + } +}; diff --git a/built/commands/investigate.js b/built/commands/investigate.js new file mode 100644 index 0000000..9db4363 --- /dev/null +++ b/built/commands/investigate.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const builders_1 = require("@discordjs/builders"); +const discord_js_1 = require("discord.js"); +const rand = require('random-seed').create(); +const results = [ + ['Vigilante', 'Veteran', 'Mafioso', 'Ambusher'], + ['Medium', 'Janitor', 'Retributionist'], + ['Survivor', 'Vampire Hunter', 'Amnesiac'], + ['Spy', 'Blackmailer', 'Jailor'], + ['Sheriff', 'Executioner', 'Werewolf'], + ['Framer', 'Vampire', 'Jester'], + ['Lookout', 'Forger', 'Witch'], + ['Escort', 'Transporter', 'Consort', 'Hypnotist'], + ['Doctor', 'Disguiser', 'Serial Killer'], + ['Investigator', 'Consigliere', 'Mayor'], + ['Bodyguard', 'Godfather', 'Arsonist'] +]; +function seperate(l) { + return l.slice(0, -1).join(', ') + ' or ' + l.slice(-1); +} +module.exports = { + data: new builders_1.SlashCommandBuilder() + .setName('investigate') + .setDescription('Investigate someone.') + .addUserOption((option) => option.setName('who').setDescription('Investigate who?').setRequired(true)) + .addBooleanOption((option) => option.setName('sheriff').setDescription('Switch to Sheriff-style investigation').setRequired(false)), + execute: async (interaction, member) => { + let who = interaction.options.getUser('who'); + let sheriff = interaction.options.getBoolean('sheriff'); + let response; + let color; + if (who.id === member.id) { + response = `You decided to investigate yourself tonight. The only thing you've found out this night is that this is a waste of time.`; + color = 0x333333; + } + else { + if (sheriff) { + rand.seed(who.id); + const good = rand.random() > 0.4; + if (good) { + response = `You decided to investigate **${who.username}** tonight.\n_You cannot find evidence of wrongdoing. Your target seems innocent._`; + color = 0x55ff55; + } + else { + response = `You decided to investigate **${who.username}** tonight.\n_Your target is suspicious!_`; + color = 0xff3333; + } + } + else { + rand.seed(who.id); + let result = results[rand.range(results.length)]; + response = `You decided to investigate **${who.username}** tonight.\nYour target could be a ${seperate(result.map(r => '**' + r + '**'))}.`; + color = 0x444444; + } + } + const embed = new discord_js_1.MessageEmbed() + .setDescription(response) + .setAuthor({ + name: `${member.displayName} the ${sheriff ? 'Sheriff' : 'Investigator'}`, + iconURL: member.displayAvatarURL() + }) + .setColor(color); + await interaction.reply({ + embeds: [embed], + ephemeral: true, + }); + } +}; diff --git a/built/commands/monitor.js b/built/commands/monitor.js new file mode 100644 index 0000000..d1548f4 --- /dev/null +++ b/built/commands/monitor.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const builders_1 = require("@discordjs/builders"); +const discord_js_1 = require("discord.js"); +const rand = require('random-seed').create(); +const images = [ + 'img1', + 'img2', + 'img3', + 'img4', + 'img5', + 'img7', + 'img8', + 'img9', + 'img10', + 'img11', + 'img12', + 'img14', + 'img15', + 'img16', + 'img17', + 'img19', + 'img20' +]; +module.exports = { + data: new builders_1.SlashCommandBuilder() + .setName('monitor') + .setDescription('Monitor') + .addStringOption((option) => option.setName('what').setDescription('Monitor what? Examples include: "lobby", "bedroom", "park", "playground", etc...').setRequired(true)), + execute: async (interaction, member) => { + let img; + let what = interaction.options.getString('what'); + if (what.startsWith('the ')) + what = what.slice(4); + switch (what.toLowerCase().trim()) { + case 'home': + img = 'img12'; + break; + case 'hell': + img = 'img4'; + break; + case 'fire pit': + img = 'img4'; + break; + case 'party': + img = 'img23'; + break; + case 'lobby': + img = 'img22'; + break; + case 'rollercoaster': + case 'park': + case 'amusement park': + img = 'img13'; + break; + case 'pit': + case 'hole': + img = 'img21'; + break; + case 'forest': + img = 'img18'; + break; + case 'slide': + case 'metal slide': + case 'playground': + img = 'img6'; + break; + case 'staircase': + img = 'img3'; + break; + case 'security': + case 'security footage': + case 'camera': + img = 'img12'; + break; + case 'lobby': + img = 'img19'; + break; + case 'bedroom': + img = 'img20'; + break; + case 'bathroom': + img = 'img10'; + break; + case 'living room': + case 'livingroom': + img = 'img15'; + break; + case 'store': + case 'shop': + img = 'img11'; + break; + case 'void': + case 'darkness': + case 'emptiness': + img = 'img16'; + break; + default: + rand.seed(what.toLowerCase().trim()); + img = images[rand.range(images.length)]; + break; + } + const embed = new discord_js_1.MessageEmbed() + .setTitle(what) + .setImage(`https://oat.zone/f/monitor-images/${img}.png`) + .setFooter('Image may not always be accurate.') + .setTimestamp(); + await interaction.reply({ + embeds: [embed], + ephemeral: false, + }); + } +}; diff --git a/built/commands/survey.js b/built/commands/survey.js new file mode 100644 index 0000000..65468c0 --- /dev/null +++ b/built/commands/survey.js @@ -0,0 +1,713 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const builders_1 = require("@discordjs/builders"); +const discord_js_1 = require("discord.js"); +const fs = __importStar(require("fs/promises")); +const SURVEY_CHANNEL = '983479509376434216'; +const RESPONSES_CHANNEL = '983762973858361364'; +const GENERAL_CHANNEL = '587108210683412493'; +const ephemeral = true; +function extendOptions(opt) { + return opt.map(t => ({ label: t, value: t.toLowerCase().replace(/[^a-z0-9-]/g, '-') })); +} +function makeid(length) { + let result = ''; + let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + const charactersLength = characters.length; + for (var i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} +const survey = [ + {}, + { + text: 'What is your name?', + textResponse: true, + id: 'survey-name' + }, + { + text: 'Your pronouns?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-pronouns') + .setOptions([ + { + label: 'he/him', + value: 'he-him' + }, + { + label: 'she/her', + value: 'she-her' + }, + { + label: 'they/them', + value: 'they-them' + }, + { + label: 'it/it', + value: 'it-it' + }, + { + label: 'Other', + value: 'other', + description: 'You\'ll be able to specify later.' + } + ]) + .setMinValues(1) + .setMaxValues(5) + ] + }, + { + text: 'What are your interests/hobbies?', + textResponse: true, + id: 'survey-interests', + style: 'PARAGRAPH' + }, + { + text: 'What do you see in this image?\nhttps://cdn.discordapp.com/attachments/789023763396165633/983471779060281364/unknown.png', + textResponse: true, + id: 'survey-image', + style: 'PARAGRAPH' + }, + { + text: 'Which of the following game genres are you currently interested in?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-genre') + .setOptions([ + { + label: 'FPS', + value: 'fps' + }, + { + label: 'Strategy', + value: 'strategy' + }, + { + label: 'Platformer', + value: 'platformer' + }, + { + label: 'Rhythm Game', + value: 'rhythm-game' + }, + { + label: 'Puzzle', + value: 'puzzle' + }, + { + label: 'Shoot-em-up', + value: 'shmup' + } + ]) + .setMinValues(1) + .setMaxValues(6) + ] + }, + { + text: 'Favorite color?', + textResponse: true, + id: 'survey-color1', + placeholder: 'Red, orange, etc...' + }, + { + text: 'Which of these music artists do you listen to?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-artist') + .setOptions([ + { + label: 'Mr. Bill', + value: 'mr-bill' + }, + { + label: 'Virtual Riot', + value: 'virtual-riot' + }, + { + label: 'Mr. Beast', + value: 'mr-beast' + } + ]) + .setMinValues(1) + .setMaxValues(3) + ] + }, + { + text: 'What time is it currently?', + textResponse: true, + id: 'survey-time' + }, + { + text: 'Did you provide the correct time?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-time-correct-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-time-correct-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Favorite color?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-color2') + .setOptions([ + { + label: 'Chair', + value: 'chair' + }, + { + label: 'Lithium', + value: 'lithium' + }, + { + label: 'Read a => String -> a', + value: 'read-signature' + }, + { + label: 'Option 3', + value: 'option3' + } + ]) + .setMinValues(1) + .setMaxValues(4) + ] + }, + { + text: 'How many amperes have you had pushed into your heart at once in your lifetime?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-heart') + .setOptions([ + { + label: '1', + value: 'one' + }, + { + label: '2', + value: 'two' + }, + { + label: '3', + value: 'three' + }, + { + label: '4', + value: 'four' + }, + { + label: '5', + value: 'five' + } + ]) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Are you afraid of the dark?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-dark-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-dark-no').setLabel('No').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-dark-maybe').setLabel('Maybe').setStyle('PRIMARY') + ] + }, + { + text: `Which of these statements on morality do you most resonate with?\nA. Morality is a science which can be understood. There are inherent moral truths in the world.\nB. There does not exist a moral reality, but only perceptions on what is good or bad.`, + components: [ + new discord_js_1.MessageButton().setCustomId('survey-morality-a').setLabel('A').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-morality-b').setLabel('B').setStyle('PRIMARY') + ] + }, + { + text: 'How long ago did you last go on a bridge?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-bridge') + .setOptions(extendOptions(['A day ago', 'A week ago', 'A month ago', 'Several months ago', 'A year ago', 'Don\'t remember/Earlier'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Are you afraid of death?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-death') + .setOptions(extendOptions(['Yes', 'No', 'Maybe', 'Death is just a step to a different world'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'What is your current heartrate?', + textResponse: true, + id: 'survey-heartrate', + placeholder: '90BPM, 120BPM, etc...' + }, + { + text: 'You are operating a railroad track.\nA train is rapidly coming towards a track with 5 people strapped to the rails, unable to move. You are able to redirect the train onto another track, which has one person strapped to it. Do you make the switch and kill the one person, or do nothing and let the 5 people die?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-railroad1-switch').setLabel('Switch').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-railroad1-no').setLabel('Do not').setStyle('PRIMARY') + ] + }, + { + text: 'Which region do you live in?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-region') + .setOptions(extendOptions(['Europe', 'Asia', 'North America', 'South America', 'Moscow River', 'Africa', 'Oceania'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Select the character you resonate with the most.', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-character') + .setOptions([ + { + label: '⯧', + value: 'a' + }, + { + label: '▩', + value: 'b' + }, + { + label: '⍺', + value: 'c' + }, + { + label: '∵', + value: 'd' + }, + { + label: '⨆', + value: 'e' + } + ]) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Which of these statements describe you the best?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-statement') + .setOptions(extendOptions(['Is that a cut on your face, or part of your eye?', 'The gash weaves down as if you cry', 'The pain itself is reason why'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'When was the last time you experienced a power surge?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-power-surge') + .setOptions(extendOptions(['A day ago', 'A week ago', 'A month ago', 'Several months ago', 'A year ago', 'Don\'t remember/Earlier'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Have you ever shown any interest in automobiles and cars?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-cars1-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-cars1-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'You are operating a railroad track.\nA person is strapped to the rails unable to move, however there is a fork right before that splits off to a different track with no people. Do you switch to save the person?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-railroad2') + .setOptions([ + { + label: 'Yes', + value: 'yes' + }, + { + label: 'Bloodshed', + value: 'bloodshed', + description: 'The correct choice' + } + ]) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Have you been here before?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-been-here-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-been-here-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Please provide your social media accounts.', + textResponse: true, + id: 'survey-socialmedia', + style: 'PARAGRAPH', + placeholder: 'Twitter, YouTube, etc. Please provide as many as possible.' + }, + { + text: 'Is your refrigerator running?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-fridge-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-fridge-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Do you generally feel unsafe in your life?', + noNumber: true, + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-unsafe') + .setOptions(extendOptions(['Yes', 'No', 'Sometimes'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'train', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-train') + .setOptions(extendOptions(['Option 1', 'Option 2'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Do you live on planet Earth?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-earth-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-earth-no').setLabel('No').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-earth-maybe').setLabel('Maybe~ ;3').setStyle('PRIMARY') + ] + }, + { + text: 'Do you own a credit or debit card?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-credit-card-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-credit-card-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'You are operating a railroad track.\nYou will be alone on your shift this night, with no one to watch, leaving you with a perfect opportunity to strap an explosive on one of the tracks. Do you cause a horrible accident resulting in the deaths of thousands?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-railroad3-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-railroad3-option-2').setLabel('Option 2').setStyle('PRIMARY') + ] + }, + { + text: 'Please click on the button when you\'re finished watching the video.\nhttps://www.youtube.com/watch?v=FsTCet79i2k', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-finished').setLabel('Done').setStyle('PRIMARY') + ] + }, + { + text: 'Which of these natural landmarks is your favorite?', + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-landmark') + .setOptions(extendOptions(['Darvaza Gas Crater', 'Nazca Lines', 'Bermuda Triangle', 'The Hole'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'Have you ever shown any interest in automobiles and cars?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-cars2-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-cars2-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Are you operating a railroad track?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-railroad4-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-railroad4-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Please explain why/why not.', + textResponse: true, + id: 'survey-railroad4-why', + style: 'PARAGRAPH' + }, + { + text: 'Were you telling the truth in your previous 2 anwsers?', + components: [ + new discord_js_1.MessageButton().setCustomId('survey-railroad4-truth-yes').setLabel('Yes').setStyle('PRIMARY'), + new discord_js_1.MessageButton().setCustomId('survey-railroad4-truth-no').setLabel('No').setStyle('PRIMARY') + ] + }, + { + text: 'Please rate your experience with this survey.', + noNumber: true, + components: [ + new discord_js_1.MessageSelectMenu() + .setCustomId('survey-rating') + .setOptions(extendOptions(['1 ⭐', '2 ⭐⭐', '3 ⭐⭐⭐', '4 ⭐⭐⭐⭐', '5 ⭐⭐⭐⭐⭐'])) + .setMinValues(1) + .setMaxValues(1) + ] + }, + { + text: 'What is your opinion on mycology?', + noNumber: true, + textResponse: true, + id: 'survey-mycology', + style: 'PARAGRAPH' + }, + { + text: 'Do you like mushrooms as a concept?', + noNumber: true, + components: [ + new discord_js_1.MessageButton().setCustomId('survey-closer6').setLabel('Yes.').setStyle('SUCCESS') + ] + }, + { + text: 'Do you like how mushrooms grow and expand?', + noNumber: true, + components: [ + new discord_js_1.MessageButton().setCustomId('survey-closer7').setLabel('Yes.').setStyle('SUCCESS') + ] + }, + { + text: 'Would you become a stepping stone for mushrooms to grow and expand?', + noNumber: true, + components: [ + new discord_js_1.MessageButton().setCustomId('survey-closer8').setLabel('YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES YES').setStyle('SUCCESS') + ] + } +]; +const surveyProgress = new discord_js_1.Collection(); +const surveyInteractions = new discord_js_1.Collection(); +const surveyAnwsered = new discord_js_1.Collection(); +const surveyAnwsers = new discord_js_1.Collection(); +const surveyCurrentMessage = new discord_js_1.Collection(); +function pushResponse(resp, userId) { + const i = surveyProgress.get(userId); + const question = survey[i || 0]; + if (question) { + resp.questionIndex = i; + resp.questionText = question.text; + if (resp.values && question.components) { + const components = question.components; + resp.questionOptions = components[0].options.map(o => o.label); + resp.values = resp.values.map(v => components[0].options.find(opt => opt.value === v)?.label || ''); + if (components[0].maxValues === 1) { + resp.value = resp.values[0]; + resp.values = undefined; + } + } + if (resp.type === 'BUTTON' && question.components) { + const components = question.components; + resp.value = components.find(opt => opt.customId === resp.id)?.label; + resp.questionOptions = components.map(o => o?.label); + } + } + // for ordering purposes + let res = { + id: resp.id, + type: resp.type, + questionIndex: resp.questionIndex, + questionText: resp.questionText, + questionOptions: resp.questionOptions || null, + value: resp.value || resp.values || null + }; + if (!surveyAnwsers.get(userId)) { + surveyAnwsers.set(userId, []); + } + if (res.questionIndex) { + surveyAnwsers.get(userId).push(res); + } +} +function resetProgress(userId) { + surveyAnwsered.set(userId, new discord_js_1.Collection()); + surveyProgress.set(userId, 0); + surveyAnwsers.set(userId, []); + surveyCurrentMessage.delete(userId); +} +async function advanceSurvey(userId, dontAdvanceProgress = false) { + if (!dontAdvanceProgress) + surveyProgress.set(userId, (surveyProgress.get(userId) || 0) + 1); + const interaction = surveyInteractions.get(userId); + const i = surveyProgress.get(userId); + const question = survey[i]; + if (!question) { + const anwsers = surveyAnwsers.get(userId); + const filename = `survey-response-${userId}.json`; + const stringified = JSON.stringify(anwsers, undefined, 2); + await fs.writeFile(filename, stringified, { encoding: 'utf8' }); + (await interaction.client.channels.fetch(RESPONSES_CHANNEL)).send({ + content: `Recieved a response from <@${userId}>`, + files: [filename], + components: [new discord_js_1.MessageActionRow().addComponents(new discord_js_1.MessageButton().setLabel('Approve').setStyle('SUCCESS').setCustomId('survey-reply-approve'), new discord_js_1.MessageButton().setLabel('Deny').setStyle('DANGER').setCustomId('survey-reply-deny')) + ] + }); + await interaction.deferReply({ + ephemeral: ephemeral + }); + await interaction.followUp({ + content: `**Thank you for your participation!** Your responses have been recorded and you will soon become a member of the Fire Pit based on your anwsers.`, + ephemeral: ephemeral + }); + resetProgress(userId); + } + else { + let components = []; + if (question.components) + components = question.components; + if (question.textResponse) + components.push(new discord_js_1.MessageButton().setCustomId(question.id + '-modal').setLabel('Anwser').setStyle('PRIMARY')); + const msg = await interaction.reply({ + content: `${question.noNumber ? '' : `${i}. `}${question.text.split('\n')[0] === '' ? '' : `**${question.text.split('\n')[0]}**`}\n${question.text.split('\n').slice(1).join('\n')}`, + components: components ? ([new discord_js_1.MessageActionRow().addComponents(...components)]) : undefined, + ephemeral: ephemeral, + fetchReply: true + }); + surveyCurrentMessage.set(userId, msg.id); + } +} +module.exports = { + data: new builders_1.SlashCommandBuilder() + .setName('createsurvey') + .setDescription('Re-create the survey button'), + execute: async (interaction, member) => { + const row = new discord_js_1.MessageActionRow().addComponents(new discord_js_1.MessageButton().setCustomId('survey-take').setLabel('Take Survey').setStyle('SECONDARY')); + await interaction.channel.send({ + content: '**Hello!**\n\nIt would be great to know more about you and your interests before you\'re accepted into the Discord server, so please answer some simple questions for us!', + components: [row] + }); + await interaction.reply({ + content: 'done', + ephemeral: true + }); + }, + onClientReady: (bot) => { + bot.on('interactionCreate', interaction => { + if (!interaction.isMessageComponent()) + return; + if (interaction.isModalSubmit()) + return; + if (!interaction.customId.startsWith('survey-')) + return; + if (!interaction.member) + return; + const member = interaction.member; + if (interaction.customId === 'survey-reply-approve' || interaction.customId === 'survey-reply-deny') { + const approve = interaction.customId === 'survey-reply-approve'; + } + surveyInteractions.set(member.id, interaction); + if (interaction.customId === 'survey-take') { + const index = surveyProgress.get(member.id); + if (index && index > 0) { + const currentMessage = surveyCurrentMessage.get(member.id); + if (currentMessage) { + surveyAnwsered.get(member.id).set(currentMessage, true); + } + advanceSurvey(member.id, true); + return; + } + else { + resetProgress(member.id); + } + } + else { + if (!surveyAnwsered.get(member.id)) { + interaction.deferUpdate(); + return; + } + } + if (surveyAnwsered.get(member.id).get(interaction.message.id)) { + interaction.deferUpdate(); + return; + } + if (interaction.customId.endsWith('-modal')) { + const modal = new discord_js_1.Modal() + .setCustomId(interaction.customId) + .setTitle('Fire Pit Survey'); + const i = surveyProgress.get(member.id); + const question = survey[i]; + const input = new discord_js_1.TextInputComponent() + .setCustomId(question.id) + .setLabel(question.text.trim().split('\n')[0].slice(0, 44)) + .setStyle(question.style || 'SHORT') + .setPlaceholder(question.placeholder || '') + .setRequired(true); + // @ts-ignore + const row = new discord_js_1.MessageActionRow().addComponents(input); + // @ts-ignore + modal.addComponents(row); + interaction.showModal(modal); + } + else { + surveyAnwsered.get(member.id).set(interaction.message.id, true); + let resp = { + id: interaction.customId, + type: interaction.componentType, + values: interaction.isSelectMenu() ? interaction.values : undefined + }; + pushResponse(resp, member.id); + advanceSurvey(member.id); + } + }); + bot.on('interactionCreate', interaction => { + if (!interaction.isModalSubmit()) + return; + if (!interaction.member) + return; + const member = interaction.member; + // @ts-ignore + surveyInteractions.set(member.id, interaction); + surveyAnwsered.get(member.id).set(interaction.message.id, true); + const i = surveyProgress.get(member.id); + const question = survey[i]; + const field = interaction.fields.getField(question.id); + let resp = { + id: field.customId, + type: field.type, + value: field.value + }; + pushResponse(resp, member.id); + advanceSurvey(member.id); + }); + bot.on('messageCreate', msg => { + if (msg.channel.id !== SURVEY_CHANNEL) + return; + if (msg.author.id === msg.client.user.id) + return; + msg.delete(); + }); + } +}; diff --git a/built/index.js b/built/index.js new file mode 100644 index 0000000..7695756 --- /dev/null +++ b/built/index.js @@ -0,0 +1,144 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const Discord = __importStar(require("discord.js")); +const fs = __importStar(require("fs")); +const { token, disableDaytimeAnnouncements } = JSON.parse(fs.readFileSync('./config.json', 'utf8')); +const path = __importStar(require("path")); +const morningHour = 8; +const eveningHour = 21; +function getNextMorning() { + let now = new Date(); + let next = new Date(); + if (now.getUTCHours() >= morningHour) { + next.setTime(next.getTime() + 1000 * 60 * 60 * 24); + } + next.setUTCHours(morningHour); + next.setUTCMinutes(Math.floor(Math.random() * 60)); + next.setUTCSeconds(Math.floor(Math.random() * 60)); + console.log('next morning set to ' + next); + return next.getTime(); +} +function getNextNight() { + let now = new Date(); + let next = new Date(); + if (now.getUTCHours() >= eveningHour) { + next.setTime(next.getTime() + 1000 * 60 * 60 * 24); + } + next.setUTCHours(eveningHour); + next.setUTCMinutes(Math.floor(Math.random() * 60)); + next.setUTCSeconds(Math.floor(Math.random() * 60)); + console.log('next night set to ' + next); + return next.getTime(); +} +let next; +function save() { + fs.writeFileSync('./next.json', JSON.stringify(next)); +} +if (fs.existsSync('./next.json')) { + next = JSON.parse(fs.readFileSync('./next.json', 'utf8')); +} +else { + next = { + morning: getNextMorning(), + night: getNextNight() + }; + save(); +} +const bot = new Discord.Client({ + intents: [ + Discord.Intents.FLAGS.GUILDS, + Discord.Intents.FLAGS.GUILD_MESSAGES, + Discord.Intents.FLAGS.GUILD_VOICE_STATES, + Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS, + ], +}); +const channels = [ + '587108210683412493' +]; +const morning = [ + 'goob morning', + 'gm besties', + 'morning !!!', + 'it is Morning', + 'gm', + 'goom morbning' +]; +const night = [ + 'good night!!!!!!', + 'nini all', + 'goob night', + 'goo night .....', + 'sleep well everyone!!!!!', + 'good night !! dont let the bugs bite' +]; +bot.on('ready', async () => { + setInterval(() => { + let current = new Date().getTime(); + // console.log(current, next.morning, next.night); + if (current > next.morning && !disableDaytimeAnnouncements) { + next.morning = getNextMorning(); + channels.forEach(c => { + bot.channels.fetch(c) + .then(channel => channel.send(morning[Math.floor(Math.random() * morning.length)])) + .catch(err => console.log('couldnt find channel ' + c + ': ' + err)); + }); + save(); + } + if (current > next.night && !disableDaytimeAnnouncements) { + next.night = getNextNight(); + channels.forEach(c => { + bot.channels.fetch(c) + .then(channel => channel.send(night[Math.floor(Math.random() * night.length)])) + .catch(err => console.log('couldnt find channel ' + c + ': ' + err)); + }); + save(); + } + }, 1000); + bot.commands = new Discord.Collection(); + const cmdFiles = fs.readdirSync(path.join(__dirname, "./commands")).filter((file) => file.endsWith(".js")); + for (const file of cmdFiles) { + const cmd = (await Promise.resolve().then(() => __importStar(require(`./commands/${file}`)))); + bot.commands.set(cmd.data.name, cmd); + if (cmd.onClientReady) + cmd.onClientReady(bot); + } + console.log('foggy online'); +}); +bot.on('interactionCreate', async (interaction) => { + if (!interaction.isCommand()) + return; + const command = interaction.client.commands.get(interaction.commandName); + if (!command) + return; + try { + await command.execute(interaction, interaction.member); + } + catch (error) { + interaction.reply({ content: "`ERROR`", ephemeral: true }); + console.error(error); + } +}); +bot.login(token); diff --git a/delete-commands.js b/delete-commands.cjs similarity index 100% rename from delete-commands.js rename to delete-commands.cjs diff --git a/deploy-commands.cjs b/deploy-commands.cjs new file mode 100644 index 0000000..45c5ac8 --- /dev/null +++ b/deploy-commands.cjs @@ -0,0 +1,27 @@ +const fs = require("node:fs"); +const { REST } = require("@discordjs/rest"); +const { Routes } = require("discord-api-types/v9"); +const { token } = require('./config.json'); +const { exec } = require('child_process'); + +const rest = new REST({ version: "9" }).setToken(token); + +console.log('building...'); +exec('pnpm tsc', (err, stdout, stderr) => { + if (err) throw err; + + console.log(stdout); + + const commands = []; + const commandFiles = fs.readdirSync("./built/commands").filter((file) => file.endsWith(".js") && !file.startsWith('.')); + + for (const file of commandFiles) { + const command = require(`./built/commands/${file}`); + commands.push(command.data.toJSON()); + } + + rest + .put(Routes.applicationGuildCommands('898850107892596776', '587108210121506816'), { body: commands }) + .then(() => console.log(`${commands.length} commands added`)) + .catch(console.error); +}); \ No newline at end of file diff --git a/deploy-commands.js b/deploy-commands.js deleted file mode 100644 index 213523b..0000000 --- a/deploy-commands.js +++ /dev/null @@ -1,19 +0,0 @@ -const fs = require("node:fs"); -const { REST } = require("@discordjs/rest"); -const { Routes } = require("discord-api-types/v9"); -const {token} = require('./config.json'); - -const rest = new REST({ version: "9" }).setToken(token); - -const commands = []; -const commandFiles = fs.readdirSync("./commands").filter((file) => file.endsWith(".js") && !file.startsWith('.')); - -for (const file of commandFiles) { - const command = require(`./commands/${file}`); - commands.push(command.data.toJSON()); -} - -rest - .put(Routes.applicationGuildCommands('898850107892596776', '587108210121506816'), { body: commands }) - .then(() => console.log(`${commands.length} commands added`)) - .catch(console.error); diff --git a/package.json b/package.json index 1595afb..4c93390 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node built/index.js", + "build": "tsc", + "quickrun": "tsc && node built/index.js" }, "author": "oatmealine", "license": "AGPL-3.0", @@ -13,5 +16,11 @@ "@discordjs/rest": "^0.4.1", "discord.js": "^13.8.0", "random-seed": "^0.3.0" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^5.27.1", + "@typescript-eslint/parser": "^5.27.1", + "eslint": "^8.17.0", + "typescript": "4.8.0-dev.20220606" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec53a1b..0097b64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,10 +1,14 @@ -lockfileVersion: 5.3 +lockfileVersion: 5.4 specifiers: '@discordjs/builders': ^0.13.0 '@discordjs/rest': ^0.4.1 + '@typescript-eslint/eslint-plugin': ^5.27.1 + '@typescript-eslint/parser': ^5.27.1 discord.js: ^13.8.0 + eslint: ^8.17.0 random-seed: ^0.3.0 + typescript: 4.8.0-dev.20220606 dependencies: '@discordjs/builders': 0.13.0 @@ -12,6 +16,12 @@ dependencies: discord.js: 13.8.0 random-seed: 0.3.0 +devDependencies: + '@typescript-eslint/eslint-plugin': 5.27.1_555veff7pbs3zkovuk7bd6t3v4 + '@typescript-eslint/parser': 5.27.1_tk6tc2atvak5hdwmpl7y3anzei + eslint: 8.17.0 + typescript: 4.8.0-dev.20220606 + packages: /@discordjs/builders/0.13.0: @@ -64,6 +74,59 @@ packages: - encoding dev: false + /@eslint/eslintrc/1.3.0: + resolution: {integrity: sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.3.2 + globals: 13.15.0 + ignore: 5.2.0 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/config-array/0.9.5: + resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + /@sapphire/async-queue/1.3.1: resolution: {integrity: sha512-FFTlPOWZX1kDj9xCAsRzH5xEJfawg1lNoYAA+ecOWJMHOfiZYb1uXOI3ne9U4UILSEPwfE68p3T9wUHwIQfR0g==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} @@ -89,6 +152,10 @@ packages: engines: {node: '>=10'} dev: false + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + /@types/node-fetch/2.6.1: resolution: {integrity: sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==} dependencies: @@ -106,10 +173,222 @@ packages: '@types/node': 17.0.23 dev: false + /@typescript-eslint/eslint-plugin/5.27.1_555veff7pbs3zkovuk7bd6t3v4: + resolution: {integrity: sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.27.1_tk6tc2atvak5hdwmpl7y3anzei + '@typescript-eslint/scope-manager': 5.27.1 + '@typescript-eslint/type-utils': 5.27.1_tk6tc2atvak5hdwmpl7y3anzei + '@typescript-eslint/utils': 5.27.1_tk6tc2atvak5hdwmpl7y3anzei + debug: 4.3.4 + eslint: 8.17.0 + functional-red-black-tree: 1.0.1 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.7 + tsutils: 3.21.0_bkjn35j2qbw4mhe45y6bfcgoye + typescript: 4.8.0-dev.20220606 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser/5.27.1_tk6tc2atvak5hdwmpl7y3anzei: + resolution: {integrity: sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.27.1 + '@typescript-eslint/types': 5.27.1 + '@typescript-eslint/typescript-estree': 5.27.1_bkjn35j2qbw4mhe45y6bfcgoye + debug: 4.3.4 + eslint: 8.17.0 + typescript: 4.8.0-dev.20220606 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.27.1: + resolution: {integrity: sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.27.1 + '@typescript-eslint/visitor-keys': 5.27.1 + dev: true + + /@typescript-eslint/type-utils/5.27.1_tk6tc2atvak5hdwmpl7y3anzei: + resolution: {integrity: sha512-+UC1vVUWaDHRnC2cQrCJ4QtVjpjjCgjNFpg8b03nERmkHv9JV9X5M19D7UFMd+/G7T/sgFwX2pGmWK38rqyvXw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/utils': 5.27.1_tk6tc2atvak5hdwmpl7y3anzei + debug: 4.3.4 + eslint: 8.17.0 + tsutils: 3.21.0_bkjn35j2qbw4mhe45y6bfcgoye + typescript: 4.8.0-dev.20220606 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.27.1: + resolution: {integrity: sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.27.1_bkjn35j2qbw4mhe45y6bfcgoye: + resolution: {integrity: sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.27.1 + '@typescript-eslint/visitor-keys': 5.27.1 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.7 + tsutils: 3.21.0_bkjn35j2qbw4mhe45y6bfcgoye + typescript: 4.8.0-dev.20220606 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.27.1_tk6tc2atvak5hdwmpl7y3anzei: + resolution: {integrity: sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.27.1 + '@typescript-eslint/types': 5.27.1 + '@typescript-eslint/typescript-estree': 5.27.1_bkjn35j2qbw4mhe45y6bfcgoye + eslint: 8.17.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.17.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys/5.27.1: + resolution: {integrity: sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.27.1 + eslint-visitor-keys: 3.3.0 + dev: true + + /acorn-jsx/5.3.2_acorn@8.7.1: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.7.1 + dev: true + + /acorn/8.7.1: + resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-union/2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + /asynckit/0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} dev: false + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + /combined-stream/1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -117,11 +396,47 @@ packages: delayed-stream: 1.0.0 dev: false + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-is/0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + /delayed-stream/1.0.0: resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} engines: {node: '>=0.4.0'} dev: false + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + /discord-api-types/0.29.0: resolution: {integrity: sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg==} dev: false @@ -153,9 +468,189 @@ packages: - utf-8-validate dev: false + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils/3.0.0_eslint@8.17.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.17.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys/2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.17.0: + resolution: {integrity: sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.3.0 + '@humanwhocodes/config-array': 0.9.5 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-utils: 3.0.0_eslint@8.17.0 + eslint-visitor-keys: 3.3.0 + espree: 9.3.2 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 6.0.2 + globals: 13.15.0 + ignore: 5.2.0 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.1 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree/9.3.2: + resolution: {integrity: sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.7.1 + acorn-jsx: 5.3.2_acorn@8.7.1 + eslint-visitor-keys: 3.3.0 + dev: true + + /esquery/1.4.0: + resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: false + + /fast-glob/3.2.11: + resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.5 + rimraf: 3.0.2 + dev: true + + /flatted/3.2.5: + resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} + dev: true /form-data/3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} @@ -175,10 +670,164 @@ packages: mime-types: 2.1.35 dev: false + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /functional-red-black-tree/1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals/13.15.0: + resolution: {integrity: sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globby/11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.11 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash/0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /isexe/2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + /json-stringify-safe/5.0.1: resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} dev: false + /levn/0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + /mime-db/1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -191,6 +840,20 @@ packages: mime-db: 1.52.0 dev: false + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -203,6 +866,65 @@ packages: whatwg-url: 5.0.0 dev: false + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /optionator/0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /prelude-ls/1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + /random-seed/0.3.0: resolution: {integrity: sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0=} engines: {node: '>= 0.6.0'} @@ -210,6 +932,89 @@ packages: json-stringify-safe: 5.0.1 dev: false + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /semver/7.3.7: + resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-json-comments/3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /text-table/0.2.0: + resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + /tr46/0.0.3: resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=} dev: false @@ -218,6 +1023,10 @@ packages: resolution: {integrity: sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==} dev: false + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + /tslib/2.3.1: resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} dev: false @@ -226,6 +1035,44 @@ packages: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: false + /tsutils/3.21.0_bkjn35j2qbw4mhe45y6bfcgoye: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.8.0-dev.20220606 + dev: true + + /type-check/0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /typescript/4.8.0-dev.20220606: + resolution: {integrity: sha512-51kwMaA0PjNQbVecA2dFXesmFff80WseziNC1cTcL7s930ApGJMCDbM5K5tzKX9o5Bf3j56KiLo3tJmg87uZJw==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /v8-compile-cache/2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + dev: true + /webidl-conversions/3.0.1: resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} dev: false @@ -237,6 +1084,23 @@ packages: webidl-conversions: 3.0.1 dev: false + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + dev: true + /ws/8.7.0: resolution: {integrity: sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==} engines: {node: '>=10.0.0'} @@ -249,3 +1113,7 @@ packages: utf-8-validate: optional: true dev: false + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true diff --git a/commands/change.js b/src/commands/change.ts similarity index 72% rename from commands/change.js rename to src/commands/change.ts index cbd0617..e466103 100644 --- a/commands/change.js +++ b/src/commands/change.ts @@ -1,5 +1,5 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { CommandInteraction, GuildMember, MessageActionRow, MessageEmbed } = require('discord.js'); +import { SlashCommandBuilder } from '@discordjs/builders'; +import { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageEmbed, TextChannel } from 'discord.js'; const rand = [ 'This change has no significance.', @@ -44,13 +44,8 @@ module.exports = { .setDescription('Change') .addStringOption((option) => option.setName('what').setDescription('Change what? Examples include: "environment", "perspective", etc...').setRequired(true)), - /** - * - * @param {CommandInteraction} interaction - * @param {GuildMember} member - */ - execute: async (interaction, member) => { - let what = interaction.options.getString('what'); + execute: async (interaction: CommandInteraction, member: GuildMember) => { + let what = interaction.options.getString('what')!; let title = `**${member.displayName}** changed the **${what}**`; let response; @@ -59,13 +54,13 @@ module.exports = { case 'surroundings': const name = names[Math.floor(Math.random() * names.length)]; response = `You feel as if you're in a new space entirely. You find yourself in **${name}**.`; - await interaction.guild.setName(name, 'environment change'); + await interaction.guild!.setName(name, 'environment change'); break; case 'perspective': case 'vision': const channel = channels[Math.floor(Math.random() * channels.length)]; response = `You've decided you want to change your perspective on the place you find yourself in. You are now in **#${channel}**.`; - await interaction.channel.setName(channel); + await (interaction.channel as TextChannel).setName(channel); break; case 'persona': case 'self': @@ -74,15 +69,15 @@ module.exports = { break; case 'identity': response = `I've changed my nickname in accordance. I hope this identity pleases you.`; - await interaction.guild.me.setNickname(nicknames[Math.floor(Math.random() * nicknames.length)]); + await interaction.guild!.me!.setNickname(nicknames[Math.floor(Math.random() * nicknames.length)]); break; case 'location': case 'position': response = `You do not feel like your surroundings have changed, but rather where you are relative to your surroundings has changed.`; - const categories = Array(...interaction.guild.channels.cache.filter(v => v.type === 'GUILD_CATEGORY').values()); - const category = categories[Math.floor(Math.random() * categories.length)]; - await interaction.channel.setParent(category); - await interaction.channel.setPosition(Math.floor(Math.random() * category.children.size)); + const categories = Array(...interaction.guild!.channels.cache.filter(v => v.type === 'GUILD_CATEGORY').values()); + const category = categories[Math.floor(Math.random() * categories.length)] as CategoryChannel; + await (interaction.channel as TextChannel).setParent(category); + await (interaction.channel as TextChannel).setPosition(Math.floor(Math.random() * category.children.size)); break; default: response = rand[Math.floor(Math.random() * rand.length)]; diff --git a/commands/investigate.js b/src/commands/investigate.ts similarity index 86% rename from commands/investigate.js rename to src/commands/investigate.ts index ac88b29..9dfa511 100644 --- a/commands/investigate.js +++ b/src/commands/investigate.ts @@ -1,5 +1,5 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { CommandInteraction, GuildMember, MessageActionRow, MessageEmbed } = require('discord.js'); +import { SlashCommandBuilder } from '@discordjs/builders'; +import { CommandInteraction, GuildMember, MessageEmbed } from 'discord.js'; const rand = require('random-seed').create(); const results = [ @@ -16,7 +16,7 @@ const results = [ ['Bodyguard', 'Godfather', 'Arsonist'] ]; -function seperate(l) { +function seperate(l: string[]): string { return l.slice(0, -1).join(', ') + ' or ' + l.slice(-1); } @@ -27,13 +27,8 @@ module.exports = { .addUserOption((option) => option.setName('who').setDescription('Investigate who?').setRequired(true)) .addBooleanOption((option) => option.setName('sheriff').setDescription('Switch to Sheriff-style investigation').setRequired(false)), - /** - * - * @param {CommandInteraction} interaction - * @param {GuildMember} member - */ - execute: async (interaction, member) => { - let who = interaction.options.getUser('who'); + execute: async (interaction: CommandInteraction, member: GuildMember) => { + let who = interaction.options.getUser('who')!; let sheriff = interaction.options.getBoolean('sheriff'); let response; let color; diff --git a/commands/monitor.js b/src/commands/monitor.ts similarity index 86% rename from commands/monitor.js rename to src/commands/monitor.ts index 5e7a7cd..d299291 100644 --- a/commands/monitor.js +++ b/src/commands/monitor.ts @@ -1,5 +1,6 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { CommandInteraction, GuildMember, MessageActionRow, MessageEmbed } = require('discord.js'); +import { SlashCommandBuilder } from '@discordjs/builders'; +import type { GuildMember } from 'discord.js'; +import { CommandInteraction, MessageEmbed } from 'discord.js'; const rand = require('random-seed').create(); const images = [ @@ -28,14 +29,9 @@ module.exports = { .setDescription('Monitor') .addStringOption((option) => option.setName('what').setDescription('Monitor what? Examples include: "lobby", "bedroom", "park", "playground", etc...').setRequired(true)), - /** - * - * @param {CommandInteraction} interaction - * @param {GuildMember} member - */ - execute: async (interaction, member) => { + execute: async (interaction: CommandInteraction, member: GuildMember) => { let img; - let what = interaction.options.getString('what'); + let what = interaction.options.getString('what')!; if (what.startsWith('the ')) what = what.slice(4); switch (what.toLowerCase().trim()) { diff --git a/commands/survey.js b/src/commands/survey.ts similarity index 83% rename from commands/survey.js rename to src/commands/survey.ts index c2dc388..55c6c9d 100644 --- a/commands/survey.js +++ b/src/commands/survey.ts @@ -1,7 +1,7 @@ -const { SlashCommandBuilder } = require('@discordjs/builders'); -const { CommandInteraction, GuildMember, MessageActionRow, MessageEmbed, MessageButton, Client, Collection, MessageComponentInteraction, MessageSelectMenu, Modal, TextInputComponent } = require('discord.js'); -const fs = require('fs/promises'); -const { inspect } = require('util'); +import { SlashCommandBuilder } from '@discordjs/builders'; +import { CommandInteraction, GuildMember, MessageActionRow, MessageEmbed, MessageButton, Client, Collection, MessageComponentInteraction, MessageSelectMenu, Modal, TextInputComponent, MessageSelectOptionData, MessageInteraction, MessageComponentType, TextChannel, TextInputStyleResolvable } from 'discord.js'; +import * as fs from 'fs/promises'; +import { inspect } from 'util'; const SURVEY_CHANNEL = '983479509376434216'; const RESPONSES_CHANNEL = '983762973858361364'; @@ -9,16 +9,16 @@ const GENERAL_CHANNEL = '587108210683412493'; const ephemeral = true; -function extendOptions(opt) { +function extendOptions(opt: string[]): MessageSelectOptionData[] { return opt.map(t => ({label: t, value: t.toLowerCase().replace(/[^a-z0-9-]/g, '-')})); } -function makeid(length) { - let result = ''; - let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; +function makeid(length: number) { + let result = ''; + let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength = characters.length; for ( var i = 0; i < length; i++ ) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); + result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } @@ -491,32 +491,44 @@ const survey = [ } ] -const surveyProgress = new Collection(); -const surveyInteractions = new Collection(); -const surveyAnwsered = new Collection(); -const surveyAnwsers = new Collection(); -const surveyCurrentMessage = new Collection(); +interface SurveyResponse { + id: string, + type: MessageComponentType, + value: string | string[] | null, + values: string[] | null, + questionIndex: number, + questionText: string, + questionOptions: string[] | null, +} -function pushResponse(resp, userId) { +const surveyProgress: Collection = new Collection(); +const surveyInteractions: Collection = new Collection(); +const surveyAnwsered: Collection> = new Collection(); +const surveyAnwsers: Collection[]> = new Collection(); +const surveyCurrentMessage: Collection = new Collection(); + +function pushResponse(resp: Partial, userId: string) { const i = surveyProgress.get(userId); - const question = survey[i]; + const question = survey[i || 0]; if (question) { resp.questionIndex = i; resp.questionText = question.text; if (resp.values && question.components) { - resp.questionOptions = question.components[0].options.map(o => o.label); - resp.values = resp.values.map(v => question.components[0].options.find(opt => opt.value === v)?.label); + const components = question.components as MessageSelectMenu[]; + resp.questionOptions = components[0].options.map(o => o.label); + resp.values = resp.values.map(v => components[0].options.find(opt => opt.value === v)?.label || ''); - if (question.components[0].maxValues === 1) { + if (components[0].maxValues === 1) { resp.value = resp.values[0]; resp.values = undefined; } } if (resp.type === 'BUTTON' && question.components) { - resp.value = question.components.find(opt => opt.customId === resp.id)?.label; - resp.questionOptions = question.components.map(o => o.label); + const components = question.components as MessageButton[]; + resp.value = components.find(opt => opt.customId === resp.id)?.label; + resp.questionOptions = components.map(o => o?.label!); } } @@ -534,22 +546,22 @@ function pushResponse(resp, userId) { surveyAnwsers.set(userId, []); } if (res.questionIndex) { - surveyAnwsers.get(userId).push(res); + surveyAnwsers.get(userId)!.push(res); } } -function resetProgress(userId) { +function resetProgress(userId: string) { surveyAnwsered.set(userId, new Collection()); surveyProgress.set(userId, 0); surveyAnwsers.set(userId, []); - surveyCurrentMessage.set(userId, undefined); + surveyCurrentMessage.delete(userId); } -async function advanceSurvey(userId, dontAdvanceProgress) { +async function advanceSurvey(userId: string, dontAdvanceProgress = false) { if (!dontAdvanceProgress) surveyProgress.set(userId, (surveyProgress.get(userId) || 0) + 1); - const interaction = surveyInteractions.get(userId); + const interaction = surveyInteractions.get(userId)!; - const i = surveyProgress.get(userId); + const i = surveyProgress.get(userId)!; const question = survey[i]; if (!question) { @@ -558,7 +570,7 @@ async function advanceSurvey(userId, dontAdvanceProgress) { const stringified = JSON.stringify(anwsers, undefined, 2); await fs.writeFile(filename, stringified, {encoding: 'utf8'}); - (await interaction.client.channels.fetch(RESPONSES_CHANNEL)).send({ + (await interaction.client.channels.fetch(RESPONSES_CHANNEL) as TextChannel).send({ content: `Recieved a response from <@${userId}>`, files: [filename], components: [new MessageActionRow().addComponents( @@ -576,14 +588,14 @@ async function advanceSurvey(userId, dontAdvanceProgress) { resetProgress(userId); } else { - let components = []; + let components: (MessageSelectMenu | MessageButton)[] = []; if (question.components) components = question.components; if (question.textResponse) components.push( new MessageButton().setCustomId(question.id + '-modal').setLabel('Anwser').setStyle('PRIMARY') ) const msg = await interaction.reply({ - content: `${question.noNumber ? '' : `${i}. `}${question.text.split('\n')[0] === '' ? '' : `**${question.text.split('\n')[0]}**`}\n${question.text.split('\n').slice(1).join('\n')}`, + content: `${question.noNumber ? '' : `${i}. `}${question.text!.split('\n')[0] === '' ? '' : `**${question.text!.split('\n')[0]}**`}\n${question.text!.split('\n').slice(1).join('\n')}`, components: components ? ([new MessageActionRow().addComponents(...components)]) : undefined, ephemeral: ephemeral, fetchReply: true @@ -598,17 +610,12 @@ module.exports = { .setName('createsurvey') .setDescription('Re-create the survey button'), - /** - * - * @param {CommandInteraction} interaction - * @param {GuildMember} member - */ - execute: async (interaction, member) => { + execute: async (interaction: CommandInteraction, member: GuildMember) => { const row = new MessageActionRow().addComponents( new MessageButton().setCustomId('survey-take').setLabel('Take Survey').setStyle('SECONDARY') ); - await interaction.channel.send({ + await interaction.channel!.send({ content: '**Hello!**\n\nIt would be great to know more about you and your interests before you\'re accepted into the Discord server, so please answer some simple questions for us!', components: [row] }); @@ -618,17 +625,14 @@ module.exports = { }); }, - /** - * - * @param {Client} client - */ - onClientReady: (bot) => { + onClientReady: (bot: Client) => { bot.on('interactionCreate', interaction => { if (!interaction.isMessageComponent()) return; if (interaction.isModalSubmit()) return; if (!interaction.customId.startsWith('survey-')) return; + if (!interaction.member) return; - const member = interaction.member; + const member = interaction.member as GuildMember; if (interaction.customId === 'survey-reply-approve' || interaction.customId === 'survey-reply-deny') { const approve = interaction.customId === 'survey-reply-approve'; @@ -642,7 +646,7 @@ module.exports = { if (index && index > 0) { const currentMessage = surveyCurrentMessage.get(member.id); if (currentMessage) { - surveyAnwsered.get(member.id).set(currentMessage, true); + surveyAnwsered.get(member.id)!.set(currentMessage, true); } advanceSurvey(member.id, true); return; @@ -656,7 +660,7 @@ module.exports = { } } - if (surveyAnwsered.get(member.id).get(interaction.message.id)) { + if (surveyAnwsered.get(member.id)!.get(interaction.message.id)) { interaction.deferUpdate(); return; } @@ -666,29 +670,29 @@ module.exports = { .setCustomId(interaction.customId) .setTitle('Fire Pit Survey'); - const i = surveyProgress.get(member.id); + const i = surveyProgress.get(member.id)!; const question = survey[i]; const input = new TextInputComponent() - .setCustomId(question.id) - .setLabel(question.text.trim().split('\n')[0].slice(0, 44)) - .setStyle(question.style || 'SHORT') + .setCustomId(question.id!) + .setLabel(question.text!.trim().split('\n')[0].slice(0, 44)) + .setStyle((question.style as TextInputStyleResolvable) || 'SHORT') .setPlaceholder(question.placeholder || '') .setRequired(true); + // @ts-ignore const row = new MessageActionRow().addComponents(input); + // @ts-ignore modal.addComponents(row); interaction.showModal(modal); } else { - surveyAnwsered.get(member.id).set(interaction.message.id, true); + surveyAnwsered.get(member.id)!.set(interaction.message.id, true); - let resp = {}; - - resp.id = interaction.customId; - resp.type = interaction.componentType; - if (interaction.values) { - resp.values = interaction.values; - } + let resp = { + id: interaction.customId, + type: interaction.componentType, + values: interaction.isSelectMenu() ? interaction.values : undefined + }; pushResponse(resp, member.id); @@ -697,21 +701,25 @@ module.exports = { }); bot.on('interactionCreate', interaction => { if (!interaction.isModalSubmit()) return; - const member = interaction.member; + if (!interaction.member) return; + const member = interaction.member as GuildMember; + + // @ts-ignore surveyInteractions.set(member.id, interaction); - surveyAnwsered.get(member.id).set(interaction.message.id, true); + surveyAnwsered.get(member.id)!.set(interaction.message!.id, true); - const i = surveyProgress.get(member.id); + const i = surveyProgress.get(member.id)!; const question = survey[i]; - const field = interaction.fields.getField(question.id); + const field = interaction.fields.getField(question.id!); - let resp = {}; - resp.id = field.customId; - resp.type = field.type; - resp.value = field.value; + let resp = { + id: field.customId, + type: field.type, + value: field.value + }; pushResponse(resp, member.id); @@ -719,7 +727,7 @@ module.exports = { }) bot.on('messageCreate', msg => { if (msg.channel.id !== SURVEY_CHANNEL) return; - if (msg.author.id === msg.client.user.id) return; + if (msg.author.id === msg.client.user!.id) return; msg.delete(); }); diff --git a/index.js b/src/index.ts similarity index 82% rename from index.js rename to src/index.ts index d512889..b8b7890 100644 --- a/index.js +++ b/src/index.ts @@ -1,7 +1,7 @@ -const Discord = require('discord.js'); -const { token, disableDaytimeAnnouncements } = require('./config.json'); -const fs = require('fs'); -const path = require('path'); +import * as Discord from 'discord.js'; +import * as fs from 'fs'; +const { token, disableDaytimeAnnouncements } = JSON.parse(fs.readFileSync('./config.json', 'utf8')); +import * as path from 'path'; const morningHour = 8; const eveningHour = 21; @@ -35,7 +35,12 @@ function getNextNight() { return next.getTime(); } -let next; +interface DaytimeSchedule { + morning: number; + night: number; +} + +let next: DaytimeSchedule; function save() { fs.writeFileSync('./next.json', JSON.stringify(next)); @@ -82,7 +87,7 @@ const night = [ 'good night !! dont let the bugs bite' ]; -bot.on('ready', () => { +bot.on('ready', async () => { setInterval(() => { let current = new Date().getTime(); @@ -92,7 +97,7 @@ bot.on('ready', () => { next.morning = getNextMorning(); channels.forEach(c => { bot.channels.fetch(c) - .then(channel => channel.send(morning[Math.floor(Math.random() * morning.length)])) + .then(channel => (channel as Discord.TextBasedChannel).send(morning[Math.floor(Math.random() * morning.length)])) .catch(err => console.log('couldnt find channel ' + c + ': ' + err)); }); save(); @@ -101,7 +106,7 @@ bot.on('ready', () => { next.night = getNextNight(); channels.forEach(c => { bot.channels.fetch(c) - .then(channel => channel.send(night[Math.floor(Math.random() * night.length)])) + .then(channel => (channel as Discord.TextBasedChannel).send(night[Math.floor(Math.random() * night.length)])) .catch(err => console.log('couldnt find channel ' + c + ': ' + err)); }); save(); @@ -111,7 +116,7 @@ bot.on('ready', () => { bot.commands = new Discord.Collection(); const cmdFiles = fs.readdirSync(path.join(__dirname, "./commands")).filter((file) => file.endsWith(".js")); for (const file of cmdFiles) { - const cmd = require(`./commands/${file}`); + const cmd = (await import(`./commands/${file}`)); bot.commands.set(cmd.data.name, cmd); if (cmd.onClientReady) cmd.onClientReady(bot); } diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..79ef120 --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,7 @@ +import { Collection } from 'discord.js'; + +declare module 'discord.js' { + export interface Client { + commands: Collection; + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4fb676e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "outDir": "./built/", + "rootDir": "./src/", + "allowJs": true, + "strict": true, + "target": "esnext", + "module": "nodenext", + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "skipLibCheck": true + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "built"] +} \ No newline at end of file