diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d6dfd85 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,12 @@ +# Directories +dist/ +node_modules/ + +# Files +.dockerignore +.env +.env.sample +.gitattributes +.gitignore +.npmrc +Dockerfile diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..97f63fc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,10 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "tabWidth": 2, + "useTabs": false, + "printWidth": 128, + "bracketSpacing": true, + "arrowParens": "always", +} diff --git a/src/commands/admin/init.ts b/src/commands/admin/init.ts index ceaad68..81e102e 100644 --- a/src/commands/admin/init.ts +++ b/src/commands/admin/init.ts @@ -1,5 +1,5 @@ -import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime"; -import config from "../../config"; +import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime'; +import config from '../../config'; // ---------- @@ -8,12 +8,12 @@ import config from "../../config"; .setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall) .setContexts(Constants.InteractionContextType.Guild) .setCommandType(Constants.ApplicationCommandType.ChatInput) - .setMemberPermission(Constants.PermissionFlagsBits.Administrator) + .setMemberPermission(Constants.PermissionFlagsBits.Administrator), ) class InitCommand extends Command { users = [ '1363132678022631428', // nxbat - '454653142500507649' // bitdash + '454653142500507649', // bitdash ]; async #createInformationMessage(context: CommandClient, interaction: CommandInteraction) { @@ -37,9 +37,9 @@ class InitCommand extends Command { footer: { text: `Made by nxbat @ Archwing`, - icon_url: 'https://femboytrain.ing/nxbat-archwing' - } - } + icon_url: 'https://femboytrain.ing/nxbat-archwing', + }, + }, }); } diff --git a/src/commands/index.ts b/src/commands/index.ts index c3b29f9..da29c40 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -1,8 +1,8 @@ -import init from "./admin/init"; -import leaderboard from "./leaderboard"; -import optin from "./privacy/optin"; -import optout from "./privacy/optout"; -import profile from "./profile"; +import init from './admin/init'; +import leaderboard from './leaderboard'; +import optin from './privacy/optin'; +import optout from './privacy/optout'; +import profile from './profile'; // ---------- diff --git a/src/commands/leaderboard.ts b/src/commands/leaderboard.ts index 2e80748..bd74876 100644 --- a/src/commands/leaderboard.ts +++ b/src/commands/leaderboard.ts @@ -1,5 +1,5 @@ -import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime"; -import { getHighestPets, getUser } from "../utils"; +import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime'; +import { getHighestPets } from '../utils'; // ---------- @@ -7,7 +7,7 @@ import { getHighestPets, getUser } from "../utils"; new CommandBuilder('leaderboard', 'Get the petting leaderboard.') .setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall) .setContexts(Constants.InteractionContextType.Guild) - .setCommandType(Constants.ApplicationCommandType.ChatInput) + .setCommandType(Constants.ApplicationCommandType.ChatInput), ) class LeaderboardCommand extends Command { cooldown = 15; @@ -18,29 +18,29 @@ class LeaderboardCommand extends Command { const _data = await getHighestPets(); const description = _data.length ? _data - .map((entry, index) => - `**${index + 1}.** <@${entry.userId}> — **${entry.pets.toLocaleString()}** pets!` - ) + .map((entry, index) => `**${index + 1}.** <@${entry.userId}> — **${entry.pets.toLocaleString()}** pets!`) .join('\n') : 'Nobody has any pets yet!'; await interaction.createMessage({ - embeds: [{ - author: { - name: interaction.user.username, - icon_url: interaction.user.avatarURL + embeds: [ + { + author: { + name: interaction.user.username, + icon_url: interaction.user.avatarURL, + }, + + color: 0xe77ed1, + + title: "Pond's Petting Leaderboard", + description: description, + + footer: { + text: `Made by nxbat @ Archwing`, + icon_url: 'https://femboytrain.ing/nxbat-archwing', + }, }, - - color: 0xe77ed1, - - title: "Pond's Petting Leaderboard", - description: description, - - footer: { - text: `Made by nxbat @ Archwing`, - icon_url: 'https://femboytrain.ing/nxbat-archwing' - } - }] + ], }); } } diff --git a/src/commands/privacy/optin.ts b/src/commands/privacy/optin.ts index 678ca10..1b21161 100644 --- a/src/commands/privacy/optin.ts +++ b/src/commands/privacy/optin.ts @@ -1,5 +1,5 @@ -import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime"; -import { getUser, updateUserSettings } from "../../utils"; +import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime'; +import { updateUserSettings } from '../../utils'; // ---------- @@ -7,7 +7,7 @@ import { getUser, updateUserSettings } from "../../utils"; new CommandBuilder('optin', 'Stop counting your pet interactions.') .setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall) .setContexts(Constants.InteractionContextType.Guild) - .setCommandType(Constants.ApplicationCommandType.ChatInput) + .setCommandType(Constants.ApplicationCommandType.ChatInput), ) class OptInCommand extends Command { cooldown = 5; diff --git a/src/commands/privacy/optout.ts b/src/commands/privacy/optout.ts index 6839849..c242a94 100644 --- a/src/commands/privacy/optout.ts +++ b/src/commands/privacy/optout.ts @@ -1,5 +1,5 @@ -import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime"; -import { getUser, updateUserSettings } from "../../utils"; +import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime'; +import { updateUserSettings } from '../../utils'; // ---------- @@ -7,7 +7,7 @@ import { getUser, updateUserSettings } from "../../utils"; new CommandBuilder('optout', 'Stop counting your pet interactions.') .setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall) .setContexts(Constants.InteractionContextType.Guild) - .setCommandType(Constants.ApplicationCommandType.ChatInput) + .setCommandType(Constants.ApplicationCommandType.ChatInput), ) class OptOutCommand extends Command { cooldown = 5; @@ -18,7 +18,7 @@ class OptOutCommand extends Command { await updateUserSettings(interaction.user.id, { participating: false }); await interaction.createMessage({ - content: "Successfully opted out. You won't receive any points for petting :<" + content: "Successfully opted out. You won't receive any points for petting :<", }); } } diff --git a/src/commands/profile.ts b/src/commands/profile.ts index c3d8e3d..1cb8dc1 100644 --- a/src/commands/profile.ts +++ b/src/commands/profile.ts @@ -1,5 +1,5 @@ -import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from "athena-prime"; -import { getPetPosition, getUser } from "../utils"; +import { Command, CommandBuilder, CommandClient, CommandInteraction, Constants, SlashCommand } from 'athena-prime'; +import { getPetPosition, getUser } from '../utils'; // ---------- @@ -7,7 +7,7 @@ import { getPetPosition, getUser } from "../utils"; new CommandBuilder('profile', 'View your profile.') .setIntegrationTypes(Constants.ApplicationIntegrationType.GuildInstall) .setContexts(Constants.InteractionContextType.Guild) - .setCommandType(Constants.ApplicationCommandType.ChatInput) + .setCommandType(Constants.ApplicationCommandType.ChatInput), ) class ProfileCommand extends Command { cooldown = 15; @@ -19,38 +19,40 @@ class ProfileCommand extends Command { const position = await getPetPosition(interaction.user.id); await interaction.createMessage({ - embeds: [{ - author: { - name: interaction.user.username, - icon_url: interaction.user.avatarURL + embeds: [ + { + author: { + name: interaction.user.username, + icon_url: interaction.user.avatarURL, + }, + + color: 0xe77ed1, + + title: `Your Profile | Pet the Pond`, + fields: [ + { + name: 'Pets', + value: `${_user.statistics.pets}`, + inline: true, + }, + { + name: 'Rank', + value: position ? `#${position}` : 'N/A', + inline: true, + }, + { + name: 'Participating', + value: _user.settings.participating ? 'Yes' : 'No', + inline: false, + }, + ], + + footer: { + text: `Made by nxbat @ Archwing`, + icon_url: 'https://femboytrain.ing/nxbat-archwing', + }, }, - - color: 0xe77ed1, - - title: `Your Profile | Pet the Pond`, - fields: [ - { - name: 'Pets', - value: `${_user.statistics.pets}`, - inline: true - }, - { - name: 'Rank', - value: position ? `#${position}` : 'N/A', - inline: true - }, - { - name: 'Participating', - value: _user.settings.participating ? 'Yes' : 'No', - inline: false - } - ], - - footer: { - text: `Made by nxbat @ Archwing`, - icon_url: 'https://femboytrain.ing/nxbat-archwing' - } - }] + ], }); } } diff --git a/src/config.ts b/src/config.ts index a623dd1..ebe26f2 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ export default { identifiers: { - emojiId: "448912932340891670", - targetId: "1363132678022631428" - } -} + emojiId: '448912932340891670', + targetId: '1363132678022631428', + }, +}; diff --git a/src/events/client/ready.ts b/src/events/client/ready.ts index 8f55416..9687170 100644 --- a/src/events/client/ready.ts +++ b/src/events/client/ready.ts @@ -1,4 +1,4 @@ -import { CommandClient, Event } from "athena-prime"; +import { CommandClient, Event } from 'athena-prime'; // ---------- @@ -7,7 +7,7 @@ class ReadyEvent extends Event { async handle(context: CommandClient) { await context.deployCommands(); - context.setCustomActivity("Petting the Pond!"); + context.setCustomActivity('Petting the Pond!'); } } diff --git a/src/events/index.ts b/src/events/index.ts index b34af39..a9f5f8f 100644 --- a/src/events/index.ts +++ b/src/events/index.ts @@ -1,6 +1,6 @@ -import messageReactionAdd from "./message/messageReactionAdd"; -import messageReactionRemove from "./message/messageReactionRemove"; -import ready from "./client/ready"; +import messageReactionAdd from './message/messageReactionAdd'; +import messageReactionRemove from './message/messageReactionRemove'; +import ready from './client/ready'; // ---------- diff --git a/src/events/message/messageReactionAdd.ts b/src/events/message/messageReactionAdd.ts index 085a5de..77deb8a 100644 --- a/src/events/message/messageReactionAdd.ts +++ b/src/events/message/messageReactionAdd.ts @@ -1,6 +1,6 @@ -import { CommandClient, Constants, Event, Member, Message } from "athena-prime"; +import { CommandClient, Constants, Event, Member, Message } from 'athena-prime'; import config from '../../config'; -import { getUser, updateUserStatistics } from "../../utils"; +import { getUser, updateUserStatistics } from '../../utils'; // ---------- @@ -12,9 +12,8 @@ class MessageReactionAddEvent extends Event { if (msg.author.id !== config.identifiers.targetId || emoji.id !== config.identifiers.emojiId) return; const _user = await getUser(member.id); - if (_user.flags.blacklisted || !_user.settings.participating) return; + if (!_user.settings.participating) return; - // Update Statistics. await updateUserStatistics(member.id, { pets: _user.statistics.pets + 1 }); } } diff --git a/src/events/message/messageReactionRemove.ts b/src/events/message/messageReactionRemove.ts index 656748b..921e9a3 100644 --- a/src/events/message/messageReactionRemove.ts +++ b/src/events/message/messageReactionRemove.ts @@ -1,20 +1,24 @@ -import { CommandClient, Constants, Event, Member, Message } from "athena-prime"; +import { CommandClient, Constants, Event } from 'athena-prime'; import config from '../../config'; -import { getUser, updateUserStatistics } from "../../utils"; +import { getUser, updateUserStatistics } from '../../utils'; // ---------- class MessageReactionRemoveEvent extends Event { event: string = 'messageReactionRemove' as const; - async handle(context: CommandClient, message: { id: string, channel: { id: string }}, emoji: Constants.APIEmoji, userId: string) { + async handle( + context: CommandClient, + message: { id: string; channel: { id: string } }, + emoji: Constants.APIEmoji, + userId: string, + ) { const msg = await context.getMessage(message.channel.id, message.id); if (msg.author.id !== config.identifiers.targetId || emoji.id !== config.identifiers.emojiId) return; const _user = await getUser(userId); - if (_user.flags.blacklisted || !_user.settings.participating) return; + if (!_user.settings.participating) return; - // Update Statistics. if (_user.statistics.pets >= 0) return; await updateUserStatistics(userId, { pets: _user.statistics.pets - 1 }); } diff --git a/src/index.ts b/src/index.ts index 24a3e3b..05260dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,7 @@ const client: CommandClient = new CommandClient({ intents: [ Constants.GatewayIntentBits.Guilds, Constants.GatewayIntentBits.GuildMessages, - Constants.GatewayIntentBits.GuildMessageReactions + Constants.GatewayIntentBits.GuildMessageReactions, ], largeBotOptimizations: true, @@ -22,13 +22,13 @@ const client: CommandClient = new CommandClient({ users: () => new NullCollection(User), members: () => new NullCollection(Member), messages: () => new NullCollection(Message), - guilds: () => new NullCollection(Guild) + guilds: () => new NullCollection(Guild), }, }, }); -commands.forEach(command => client.registerCommand(command, true)); -events.forEach(event => client.registerEvent(event, true)); +commands.forEach((command) => client.registerCommand(command, true)); +events.forEach((event) => client.registerEvent(event, true)); // ---------- diff --git a/src/types/database.d.ts b/src/types/database.d.ts index 74923ae..95952bd 100644 --- a/src/types/database.d.ts +++ b/src/types/database.d.ts @@ -19,4 +19,4 @@ export type User = { * User statistics. */ statistics: UserStatistics; -} +}; diff --git a/src/utils/database.ts b/src/utils/database.ts index 45504c4..86afec4 100644 --- a/src/utils/database.ts +++ b/src/utils/database.ts @@ -1,20 +1,16 @@ -import postgres from "postgres"; -import { User } from "../types"; +import postgres from 'postgres'; +import { User } from '../types'; const client = postgres(process.env.DATABASE_URL); const getDefaultUser = (userId: string): User => ({ - flags: { - blacklisted: false - }, - settings: { participating: true, }, statistics: { - pets: 0 - } + pets: 0, + }, }); export async function getUser(userId: string): Promise { @@ -50,7 +46,7 @@ export async function deleteUser(userId: string): Promise { `; } -export async function updateUserSettings(userId: string, settings: Partial): Promise { +export async function updateUserSettings(userId: string, settings: Partial): Promise { await client` UPDATE users SET data = jsonb_set( @@ -62,7 +58,7 @@ export async function updateUserSettings(userId: string, settings: Partial): Promise { +export async function updateUserStatistics(userId: string, statistics: Partial): Promise { await client` UPDATE users SET data = jsonb_set( @@ -76,7 +72,7 @@ export async function updateUserStatistics(userId: string, statistics: Partial { +export async function getHighestPets(limit = 10): Promise<{ userId: string; pets: number }[]> { const users = await client<{ user_id: string; pets: number }[]>` SELECT user_id, (data->'statistics'->>'pets')::integer AS pets FROM users @@ -87,9 +83,9 @@ export async function getHighestPets(limit = 10): Promise<{ userId: string, pets LIMIT ${limit} `; - return users.map(user => ({ + return users.map((user) => ({ userId: user.user_id, - pets: user.pets + pets: user.pets, })); }