From 0f5cc78ff6e1635ac469bc2ad46444f9599fb0ef Mon Sep 17 00:00:00 2001 From: pineafan Date: Fri, 12 Aug 2022 21:55:42 +0100 Subject: [PATCH] Much more typing --- package.json | 2 +- src/events/guildBanAdd.ts | 11 +++++---- src/events/guildBanRemove.ts | 11 +++++---- src/events/guildMemberUpdate.ts | 18 +++++++++------ src/events/guildUpdate.ts | 39 ++++++++++++++++++-------------- src/events/interactionCreate.ts | 37 +++++++++++++++++------------- src/events/inviteCreate.ts | 13 +++++++---- src/events/inviteDelete.ts | 13 +++++++---- src/events/memberJoin.ts | 12 ++++++---- src/events/memberLeave.ts | 12 ++++++---- src/events/messageCreate.ts | 4 ++-- src/events/messageDelete.ts | 25 +++++++++++--------- src/events/messageEdit.ts | 26 ++++++++++++--------- src/events/roleCreate.ts | 10 +++++--- src/events/roleDelete.ts | 9 +++++--- src/events/roleUpdate.ts | 17 ++++++++------ src/events/stickerCreate.ts | 14 ++++++++---- src/events/stickerDelete.ts | 12 ++++++---- src/events/stickerUpdate.ts | 12 ++++++---- src/events/threadCreate.ts | 21 ++++++++++------- src/events/threadDelete.ts | 23 +++++++++++-------- src/premium/createTranscript.ts | 4 ++-- src/reflex/statsChannelUpdate.ts | 18 ++++++++------- src/reflex/verify.ts | 4 ++-- tsconfig.json | 2 +- 25 files changed, 222 insertions(+), 147 deletions(-) diff --git a/package.json b/package.json index cba5c39..6ab482d 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "build": "tsc", "start": "node --experimental-json-modules --enable-source-maps dist/index.js", "dev": "rm -rf dist && eslint . --fix && tsc && node --experimental-json-modules --enable-source-maps dist/index.js", - "force-dev": "rm -rf dist && eslint . --fix; tsc-suppress && node --experimental-json-modules --enable-source-maps dist/src/index.js", + "force-dev": "rm -rf dist && eslint . --fix; tsc-suppress && node --experimental-json-modules --enable-source-maps dist/index.js", "lint": "echo 'Style checking...'; prettier --check .; echo 'Linting...'; eslint .; echo 'To auto-fix everything possible, please run `yarn lint-fix`'; true", "lint-fix": "echo 'Fixing eslint issues...'; eslint . --fix; echo 'Reformatting...'; prettier --write --loglevel warn --cache .; true", "lint-list": "echo 'Style checking...'; prettier --check .; echo 'Linting...'; eslint .; echo 'To view errors in more detail, please run `yarn lint`'; true", diff --git a/src/events/guildBanAdd.ts b/src/events/guildBanAdd.ts index 17c4595..a05389f 100644 --- a/src/events/guildBanAdd.ts +++ b/src/events/guildBanAdd.ts @@ -1,14 +1,17 @@ +import type { GuildAuditLogsEntry, GuildBan } from 'discord.js'; import { purgeByUser } from "../actions/tickets/delete.js"; import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; export const event = "guildBanAdd"; -export async function callback(client, ban) { - await statsChannelRemove(client, ban.user); +export async function callback(client: HaikuClient, ban: GuildBan) { + await statsChannelRemove(client, undefined, ban.guild, ban.user); purgeByUser(ban.user.id, ban.guild); - const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger; + const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger; const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_ADD"); - const audit = auditLog.entries.filter((entry) => entry.target.id === ban.user.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === ban.user.id).first(); if (audit.executor.id === client.user.id) return; await client.database.history.create("ban", ban.guild.id, ban.user, audit.executor, audit.reason); const data = { diff --git a/src/events/guildBanRemove.ts b/src/events/guildBanRemove.ts index 74b7c4e..86d6efe 100644 --- a/src/events/guildBanRemove.ts +++ b/src/events/guildBanRemove.ts @@ -1,14 +1,15 @@ +import type { GuildAuditLogsEntry, GuildBan } from 'discord.js'; import { purgeByUser } from "../actions/tickets/delete.js"; -import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; export const event = "guildBanRemove"; -export async function callback(client, ban) { - await statsChannelRemove(client, ban.user); +export async function callback(client: HaikuClient, ban: GuildBan) { purgeByUser(ban.user.id, ban.guild); - const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = ban.user.client.logger; + const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger; const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_REMOVE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === ban.user.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === ban.user.id).first(); if (audit.executor.id === client.user.id) return; await client.database.history.create("unban", ban.guild.id, ban.user, audit.executor, audit.reason); const data = { diff --git a/src/events/guildMemberUpdate.ts b/src/events/guildMemberUpdate.ts index 08730f2..1f21870 100644 --- a/src/events/guildMemberUpdate.ts +++ b/src/events/guildMemberUpdate.ts @@ -1,10 +1,14 @@ +import type { GuildAuditLogsEntry, GuildMember } from "discord.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; + export const event = "guildMemberUpdate"; -export async function callback(client, before, after) { +export async function callback(client: HaikuClient, before: GuildMember, after: GuildMember) { try { - const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = after.client.logger; + const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger; const auditLog = await getAuditLog(after.guild, "MEMBER_UPDATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === after.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === after.id).first(); if (audit.executor.id === client.user.id) return; if (before.nickname !== after.nickname) { await client.database.history.create( @@ -13,8 +17,8 @@ export async function callback(client, before, after) { after.user, audit.executor, null, - before.nickname || before.user.username, - after.nickname || after.user.username + before.nickname ?? before.user.username, + after.nickname ?? after.user.username ); const data = { meta: { @@ -39,8 +43,8 @@ export async function callback(client, before, after) { }; log(data); } else if ( - before.communicationDisabledUntilTimestamp < new Date().getTime() && - after.communicationDisabledUntil > new Date().getTime() + (before.communicationDisabledUntilTimestamp ?? 0) < new Date().getTime() && + (after.communicationDisabledUntil ?? 0) > new Date().getTime() // TODO: test this ) { await client.database.history.create( "mute", diff --git a/src/events/guildUpdate.ts b/src/events/guildUpdate.ts index a165770..ea9008d 100644 --- a/src/events/guildUpdate.ts +++ b/src/events/guildUpdate.ts @@ -1,14 +1,17 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; +import type { Guild, GuildAuditLogsEntry } from 'discord.js'; import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js"; export const event = "guildUpdate"; -export async function callback(client, before, after) { - await statsChannelUpdate(client, after.me); - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = after.client.logger; +export async function callback(client: HaikuClient, before: Guild, after: Guild) { + await statsChannelUpdate(client, after.me!); + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger; const auditLog = await getAuditLog(after, "GUILD_UPDATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === after.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === after.id).first(); if (audit.executor.id === client.user.id) return; - const list = {}; + const list: Record> = {}; const verificationLevels = { NONE: "Unrestricted", @@ -28,32 +31,34 @@ export async function callback(client, before, after) { NONE: "None", ELEVATED: "Enabled" }; + const beforeOwner = await before.fetchOwner() + const afterOwner = await after.fetchOwner() - if (before.name !== after.name) list.name = entry([before.name, after.name], `${before.name} -> ${after.name}`); + if (before.name !== after.name) list["name"] = entry([before.name, after.name], `${before.name} -> ${after.name}`); if (before.icon !== after.icon) - list.icon = entry([before.icon, after.icon], `[Before](${before.iconURL()}) -> [After](${after.iconURL()})`); + list["icon"] = entry([before.icon, after.icon], `[Before](${before.iconURL()}) -> [After](${after.iconURL()})`); if (before.splash !== after.splash) - list.splash = entry( + list["splash"] = entry( [before.splash, after.splash], `[Before](${before.splashURL()}) -> [After](${after.splashURL()})` ); if (before.banner !== after.banner) - list.banner = entry( + list["banner"] = entry( [before.banner, after.banner], `[Before](${before.bannerURL()}) -> [After](${after.bannerURL()})` ); - if (before.owner !== after.owner) - list.owner = entry( - [before.owner, after.owner], - `${renderUser(before.owner.user)} -> ${renderUser(after.owner.user)}` + if (beforeOwner !== afterOwner) + list["owner"] = entry( + [beforeOwner, afterOwner], + `${renderUser(beforeOwner.user)} -> ${renderUser(afterOwner.user)}` ); if (before.verificationLevel !== after.verificationLevel) - list.verificationLevel = entry( + list["verificationLevel"] = entry( [verificationLevels[before.verificationLevel], verificationLevels[after.verificationLevel]], `${verificationLevels[before.verificationLevel]} -> ${verificationLevels[after.verificationLevel]}` ); if (before.explicitContentFilter !== after.explicitContentFilter) - list.explicitContentFilter = entry( + list["explicitContentFilter"] = entry( [ explicitContentFilterLevels[before.explicitContentFilter], explicitContentFilterLevels[after.explicitContentFilter] @@ -69,8 +74,8 @@ export async function callback(client, before, after) { ); if (!Object.keys(list).length) return; - list.updated = entry(new Date().getTime(), renderDelta(new Date().getTime())); - list.updatedBy = entry(audit.executor.id, renderUser(audit.executor)); + list["updated"] = entry(new Date().getTime(), renderDelta(new Date().getTime())); + list["updatedBy"] = entry(audit.executor.id, renderUser(audit.executor)); const data = { meta: { type: "guildUpdate", diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index 5b0aff1..9ee7bee 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -5,10 +5,13 @@ import close from "../actions/tickets/delete.js"; import createTranscript from "../premium/createTranscript.js"; import Fuse from "fuse.js"; import { autocomplete as tagAutocomplete } from "../commands/tag.js"; +import type { AutocompleteInteraction, Interaction, MessageComponentInteraction } from "discord.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; export const event = "interactionCreate"; -function getAutocomplete(typed: string, options: string[]): object[] { +function getAutocomplete(typed: string, options: string[]): {name: string, value: string}[] { options = options.filter((option) => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete. if (!typed) return options @@ -23,7 +26,7 @@ function getAutocomplete(typed: string, options: string[]): object[] { return fuse.slice(0, 25).map((option) => ({ name: option.item, value: option.item })); } -function generateStatsChannelAutocomplete(typed) { +function generateStatsChannelAutocomplete(typed: string) { const validReplacements = ["serverName", "memberCount", "memberCount:bots", "memberCount:humans"]; const autocompletions = []; const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/); @@ -38,7 +41,7 @@ function generateStatsChannelAutocomplete(typed) { } return getAutocomplete(typed, autocompletions); } -function generateWelcomeMessageAutocomplete(typed) { +function generateWelcomeMessageAutocomplete(typed: string) { const validReplacements = [ "serverName", "memberCount", @@ -61,14 +64,15 @@ function generateWelcomeMessageAutocomplete(typed) { return getAutocomplete(typed, autocompletions); } -async function interactionCreate(interaction) { - if (interaction.componentType === "BUTTON") { - switch (interaction.customId) { +async function interactionCreate(interaction: Interaction) { + if (interaction.type === "MESSAGE_COMPONENT" && (interaction as MessageComponentInteraction).componentType === "BUTTON") { + const int = (interaction as MessageComponentInteraction) + switch (int.customId) { case "rolemenu": { return await roleMenu(interaction); } case "verifybutton": { - return verify(interaction); + return verify(int); } case "createticket": { return create(interaction); @@ -77,32 +81,33 @@ async function interactionCreate(interaction) { return close(interaction); } case "createtranscript": { - return createTranscript(interaction); + return createTranscript(int); } } } else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") { + const int = (interaction as AutocompleteInteraction) switch ( - `${interaction.commandName} ${interaction.options.getSubcommandGroup( + `${int.commandName} ${int.options.getSubcommandGroup( false - )} ${interaction.options.getSubcommand(false)}` + )} ${int.options.getSubcommand(false)}` ) { case "tag null null": { - return interaction.respond( - getAutocomplete(interaction.options.getString("tag"), await tagAutocomplete(interaction)) + return int.respond( + getAutocomplete(int.options.getString("tag") ?? "", await tagAutocomplete(int)) ); } case "settings null stats": { - return interaction.respond(generateStatsChannelAutocomplete(interaction.options.getString("name"))); + return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? "")); } case "settings null welcome": { - return interaction.respond( - generateWelcomeMessageAutocomplete(interaction.options.getString("message")) + return int.respond( + generateWelcomeMessageAutocomplete(int.options.getString("message") ?? "") ); } } } } -export async function callback(client, interaction) { +export async function callback(_client: HaikuClient, interaction: Interaction) { await interactionCreate(interaction); } diff --git a/src/events/inviteCreate.ts b/src/events/inviteCreate.ts index 7b23bb2..fb35b7e 100644 --- a/src/events/inviteCreate.ts +++ b/src/events/inviteCreate.ts @@ -1,10 +1,15 @@ +import type { GuildAuditLogsEntry, Invite } from "discord.js"; +// @ts-expect-error import humanizeDuration from "humanize-duration"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; + export const event = "inviteCreate"; -export async function callback(client, invite) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger; +export async function callback(client: HaikuClient, invite: Invite) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === invite.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { @@ -23,7 +28,7 @@ export async function callback(client, invite) { created: entry(invite.createdTimestamp, renderDelta(invite.createdTimestamp)) }, hidden: { - guild: invite.guild.id + guild: invite.guild!.id } }; log(data); diff --git a/src/events/inviteDelete.ts b/src/events/inviteDelete.ts index 2cd3bc5..b07893a 100644 --- a/src/events/inviteDelete.ts +++ b/src/events/inviteDelete.ts @@ -1,10 +1,15 @@ +import type { GuildAuditLogsEntry, Invite } from "discord.js"; +// @ts-expect-error import humanizeDuration from "humanize-duration"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; + export const event = "inviteDelete"; -export async function callback(client, invite) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = invite.client.logger; +export async function callback(client: HaikuClient, invite: Invite) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === invite.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { @@ -23,7 +28,7 @@ export async function callback(client, invite) { deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())) }, hidden: { - guild: invite.guild.id + guild: invite.guild!.id } }; log(data); diff --git a/src/events/memberJoin.ts b/src/events/memberJoin.ts index ebc2934..786c4ec 100644 --- a/src/events/memberJoin.ts +++ b/src/events/memberJoin.ts @@ -1,13 +1,15 @@ +import type { GuildMember } from "discord.js"; import { callback as statsChannelAdd } from "../reflex/statsChannelUpdate.js"; import { callback as welcome } from "../reflex/welcome.js"; -import client from "../utils/client.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; export const event = "guildMemberAdd"; -export async function callback(_, member) { - welcome(_, member); - statsChannelAdd(_, member); - const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger; +export async function callback(client: HaikuClient, member: GuildMember) { + welcome(client, member); + statsChannelAdd(client, member); + const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger; await client.database.history.create("join", member.guild.id, member.user, null, null); const data = { meta: { diff --git a/src/events/memberLeave.ts b/src/events/memberLeave.ts index 00f6d84..20845d5 100644 --- a/src/events/memberLeave.ts +++ b/src/events/memberLeave.ts @@ -1,14 +1,18 @@ +import type { GuildAuditLogsEntry, GuildMember } from "discord.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; + import { purgeByUser } from "../actions/tickets/delete.js"; import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js"; export const event = "guildMemberRemove"; -export async function callback(client, member) { +export async function callback(client: HaikuClient, member: GuildMember) { purgeByUser(member.id, member.guild); await statsChannelRemove(client, member); - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger; + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger; const auditLog = await getAuditLog(member.guild, "MEMBER_KICK"); - const audit = auditLog.entries.filter((entry) => entry.target.id === member.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === member.id).first(); let type = "leave"; if (audit) { if (audit.executor.id === client.user.id) return; @@ -50,7 +54,7 @@ export async function callback(client, member) { displayName: "Member Left", calculateType: "guildMemberUpdate", color: NucleusColors.red, - emoji: "MEMBER." + (member.bot ? "BOT." : "") + "LEAVE", + emoji: "MEMBER." + (member.user.bot ? "BOT." : "") + "LEAVE", timestamp: new Date().getTime() }, list: { diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts index f690885..d0f059c 100644 --- a/src/events/messageCreate.ts +++ b/src/events/messageCreate.ts @@ -5,7 +5,7 @@ import logAttachment from "../premium/attachmentLogs.js"; import createLogException from "../utils/createLogException.js"; import getEmojiByName from "../utils/getEmojiByName.js"; import client from "../utils/client.js"; -import { callback as a } from "../reflex/statsChannelUpdate.js"; +import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js"; import { Message, ThreadChannel } from "discord.js"; export const event = "messageCreate"; @@ -15,7 +15,7 @@ export async function callback(_client: HaikuClient, message: Message) { if (message.author.bot) return; if (message.channel.type === "DM") return; try { - await a(client, await message.guild.members.fetch(message.author.id)); + await statsChannelUpdate(client, await message.guild.members.fetch(message.author.id)); } catch (e) { console.log(e); } diff --git a/src/events/messageDelete.ts b/src/events/messageDelete.ts index 3a72876..f2301e0 100644 --- a/src/events/messageDelete.ts +++ b/src/events/messageDelete.ts @@ -1,17 +1,20 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; +import type { GuildAuditLogsEntry, Message } from "discord.js"; + export const event = "messageDelete"; -export async function callback(client, message) { +export async function callback(client: HaikuClient, message: Message) { try { if (message.author.id === client.user.id) return; - if (client.noLog.includes(`${message.guild.id}/${message.channel.id}/${message.id}`)) return; - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = - message.channel.client.logger; + if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return; + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(message.guild, "MEMBER_BAN_ADD"); - const audit = auditLog.entries.filter((entry) => entry.target.id === message.author.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === message.author.id).first(); if (audit) { if (audit.createdAt - 100 < new Date().getTime()) return; } - message.reference = message.reference || {}; + const replyTo = message.reference; let content = message.cleanContent; content.replace("`", "\\`"); if (content.length > 256) content = content.substring(0, 253) + "..."; @@ -23,7 +26,7 @@ export async function callback(client, message) { ) ?? [] ).length; let attachmentJump = ""; - const config = (await client.database.guilds.read(message.guild.id)).logging.attachments.saved[ + const config = (await client.database.guilds.read(message.guild!.id)).logging.attachments.saved[ message.channel.id + message.id ]; if (config) { @@ -49,14 +52,14 @@ export async function callback(client, message) { mentions: message.mentions.users.size, attachments: entry(attachments, attachments + attachmentJump), repliedTo: entry( - message.reference.messageId || null, - message.reference.messageId - ? `[[Jump to message]](https://discord.com/channels/${message.guild.id}/${message.channel.id}/${message.reference.messageId})` + replyTo, + replyTo + ? `[[Jump to message]](https://discord.com/channels/${message.guild!.id}/${message.channel.id}/${replyTo.messageId})` : "None" ) }, hidden: { - guild: message.channel.guild.id + guild: message.guild!.id } }; log(data); diff --git a/src/events/messageEdit.ts b/src/events/messageEdit.ts index 1470832..89e69de 100644 --- a/src/events/messageEdit.ts +++ b/src/events/messageEdit.ts @@ -1,10 +1,14 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; +import type { Message, MessageReference } from "discord.js"; + export const event = "messageUpdate"; -export async function callback(client, oldMessage, newMessage) { +export async function callback(client: HaikuClient, oldMessage: Message, newMessage: Message) { if (newMessage.author.id === client.user.id) return; - const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = - newMessage.channel.client.logger; - newMessage.reference = newMessage.reference || {}; + if (!newMessage.guild) return; + const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger; + const replyTo: MessageReference | null = newMessage.reference; let newContent = newMessage.cleanContent.replaceAll("`", "‘"); let oldContent = oldMessage.cleanContent.replaceAll("`", "‘"); let attachmentJump = ""; @@ -37,8 +41,8 @@ export async function callback(client, oldMessage, newMessage) { renderDelta(new Date(newMessage.createdTimestamp)) ), published: entry( - new Date(newMessage.editedTimestamp), - renderDelta(new Date(newMessage.editedTimestamp)) + new Date(newMessage.editedTimestamp!), + renderDelta(new Date(newMessage.editedTimestamp!)) ), mentions: renderNumberDelta(oldMessage.mentions.users.size, newMessage.mentions.users.size), attachments: entry( @@ -47,7 +51,7 @@ export async function callback(client, oldMessage, newMessage) { ) }, hidden: { - guild: newMessage.channel.guild.id + guild: newMessage.guild.id } }; return log(data); @@ -87,14 +91,14 @@ export async function callback(client, oldMessage, newMessage) { renderNumberDelta(oldMessage.attachments.size, newMessage.attachments.size) + attachmentJump ), repliedTo: entry( - newMessage.reference.messageId || null, - newMessage.reference.messageId - ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${newMessage.reference.messageId})` + replyTo, + replyTo + ? `[[Jump to message]](https://discord.com/channels/${newMessage.guild.id}/${newMessage.channel.id}/${replyTo.messageId})` : "None" ) }, hidden: { - guild: newMessage.channel.guild.id + guild: newMessage.guild.id } }; log(data); diff --git a/src/events/roleCreate.ts b/src/events/roleCreate.ts index f1b0a91..e7a0a5c 100644 --- a/src/events/roleCreate.ts +++ b/src/events/roleCreate.ts @@ -1,10 +1,14 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; +import type { GuildAuditLogsEntry, Role } from "discord.js"; + export const event = "roleCreate"; -export async function callback(client, role) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = role.client.logger; +export async function callback(client: HaikuClient, role: Role) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = client.logger; if (role.managed) return; const auditLog = await getAuditLog(role.guild, "ROLE_CREATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === role.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === role.id).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { diff --git a/src/events/roleDelete.ts b/src/events/roleDelete.ts index 4807e7d..348f211 100644 --- a/src/events/roleDelete.ts +++ b/src/events/roleDelete.ts @@ -1,12 +1,15 @@ import getEmojiByName from "../utils/getEmojiByName.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; +import type { GuildAuditLogsEntry, Role } from "discord.js"; export const event = "roleDelete"; -export async function callback(client, role) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = role.client.logger; +export async function callback(client: HaikuClient, role: Role) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger; if (role.managed) return; const auditLog = await getAuditLog(role.guild, "ROLE_DELETE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === role.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === role.id).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { diff --git a/src/events/roleUpdate.ts b/src/events/roleUpdate.ts index 53bbdee..9b75fc0 100644 --- a/src/events/roleUpdate.ts +++ b/src/events/roleUpdate.ts @@ -1,15 +1,18 @@ +import type { Role } from "discord.js"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku"; import getEmojiByName from "../utils/getEmojiByName.js"; export const event = "roleUpdate"; -export async function callback(client, or, nr) { +export async function callback(client: HaikuClient, or: Role, nr: Role) { const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger; const auditLog = await getAuditLog(nr.guild, "ROLE_UPDATE"); const audit = auditLog.entries.first(); if (audit.executor.id === client.user.id) return; - const changes = { + const changes: Record> = { roleId: entry(nr.id, `\`${nr.id}\``), role: entry(nr.id, renderRole(nr)), edited: entry(new Date().getTime(), renderDelta(new Date().getTime())), @@ -21,14 +24,14 @@ export async function callback(client, or, nr) { mentionable[1] = nr.mentionable ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`; hoist[0] = or.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`; hoist[1] = nr.hoist ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`; - if (or.name !== nr.name) changes.name = entry([or.name, nr.name], `${or.name} -> ${nr.name}`); + if (or.name !== nr.name) changes["name"] = entry([or.name, nr.name], `${or.name} -> ${nr.name}`); if (or.position !== nr.position) - changes.position = entry([or.position, nr.position], `${or.position} -> ${nr.position}`); - if (or.hoist !== nr.hoist) changes.showInMemberList = entry([or.hoist, nr.hoist], `${hoist[0]} -> ${hoist[1]}`); + changes["position"] = entry([or.position, nr.position], `${or.position} -> ${nr.position}`); + if (or.hoist !== nr.hoist) changes["showInMemberList"] = entry([or.hoist, nr.hoist], `${hoist[0]} -> ${hoist[1]}`); if (or.mentionable !== nr.mentionable) - changes.mentionable = entry([or.mentionable, nr.mentionable], `${mentionable[0]} -> ${mentionable[1]}`); + changes["mentionable"] = entry([or.mentionable, nr.mentionable], `${mentionable[0]} -> ${mentionable[1]}`); if (or.hexColor !== nr.hexColor) - changes.color = entry([or.hexColor, nr.hexColor], `\`${or.hexColor}\` -> \`${nr.hexColor}\``); + changes["color"] = entry([or.hexColor, nr.hexColor], `\`${or.hexColor}\` -> \`${nr.hexColor}\``); if (Object.keys(changes).length === 4) return; diff --git a/src/events/stickerCreate.ts b/src/events/stickerCreate.ts index c538bde..01d6c2c 100644 --- a/src/events/stickerCreate.ts +++ b/src/events/stickerCreate.ts @@ -1,9 +1,13 @@ -export const event = "stickerCreate"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku" +import type { GuildAuditLogsEntry, Sticker } from "discord.js"; -export async function callback(client, emoji) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger; +export const event = "stickerDelete"; + +export async function callback(client: HaikuClient, emoji: Sticker) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger; const auditLog = await getAuditLog(emoji.guild, "STICKER_CREATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === emoji.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { @@ -21,7 +25,7 @@ export async function callback(client, emoji) { created: entry(emoji.createdTimestamp, renderDelta(emoji.createdTimestamp)) }, hidden: { - guild: emoji.guild.id + guild: emoji.guild!.id } }; log(data); diff --git a/src/events/stickerDelete.ts b/src/events/stickerDelete.ts index 7ac17ce..c9b3fab 100644 --- a/src/events/stickerDelete.ts +++ b/src/events/stickerDelete.ts @@ -1,9 +1,13 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku" +import type { GuildAuditLogsEntry, Sticker } from "discord.js"; + export const event = "stickerDelete"; -export async function callback(client, emoji) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = emoji.client.logger; +export async function callback(client: HaikuClient, emoji: Sticker) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger; const auditLog = await getAuditLog(emoji.guild, "STICKER_DELETE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === emoji.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first(); if (audit.executor.id === client.user.id) return; const data = { meta: { @@ -22,7 +26,7 @@ export async function callback(client, emoji) { deleted: entry(audit.createdTimestamp, renderDelta(audit.createdTimestamp)) }, hidden: { - guild: emoji.guild.id + guild: emoji.guild!.id } }; log(data); diff --git a/src/events/stickerUpdate.ts b/src/events/stickerUpdate.ts index 662f981..c6e3b6e 100644 --- a/src/events/stickerUpdate.ts +++ b/src/events/stickerUpdate.ts @@ -1,17 +1,21 @@ +// @ts-expect-error +import type { HaikuClient } from "jshaiku" +import type { Sticker } from "discord.js"; + export const event = "stickerUpdate"; -export async function callback(client, oe, ne) { +export async function callback(client: HaikuClient, oe: Sticker, ne: Sticker) { const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger; if (oe.name === ne.name) return; - const auditLog = await getAuditLog(ne.guild, "EMOJI_UPDATE"); + const auditLog = await getAuditLog(ne.guild, "STICKER_UPDATE"); const audit = auditLog.entries.first(); if (audit.executor.id === client.user.id) return; const changes = { stickerId: entry(ne.id, `\`${ne.id}\``), edited: entry(ne.createdTimestamp, renderDelta(ne.createdTimestamp)), - editedBy: entry(audit.executor.id, renderUser((await ne.guild.members.fetch(audit.executor.id)).user)), + editedBy: entry(audit.executor.id, renderUser((await ne.guild!.members.fetch(audit.executor.id)).user)), name: entry([oe.name, ne.name], `\`:${oe.name}:\` -> \`:${ne.name}:\``) }; const data = { @@ -25,7 +29,7 @@ export async function callback(client, oe, ne) { }, list: changes, hidden: { - guild: ne.guild.id + guild: ne.guild!.id } }; log(data); diff --git a/src/events/threadCreate.ts b/src/events/threadCreate.ts index da3cbae..e8849c9 100644 --- a/src/events/threadCreate.ts +++ b/src/events/threadCreate.ts @@ -1,11 +1,19 @@ +import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js"; +// @ts-expect-error import humanizeDuration from "humanize-duration"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku" export const event = "threadCreate"; -export async function callback(client, thread) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger; +export async function callback(client: HaikuClient, thread: ThreadChannel) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === thread.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first(); if (audit.executor.id === client.user.id) return; + const category = thread.parent ? entry( + thread.parent.parent ? thread.parent.parent.name : "None", + thread.parent.parent ? renderChannel(thread.parent.parent) : "None" + ) : entry(null, "Uncategorised") const data = { meta: { type: "channelCreate", @@ -19,13 +27,10 @@ export async function callback(client, thread) { threadId: entry(thread.id, `\`${thread.id}\``), name: entry(thread.name, renderChannel(thread)), parentChannel: entry(thread.parentId, renderChannel(thread.parent)), - category: entry( - thread.parent.parent ? thread.parent.parent.name : "None", - thread.parent.parent ? renderChannel(thread.parent.parent) : "None" - ), + category: category, autoArchiveDuration: entry( thread.autoArchiveDuration, - humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { + humanizeDuration((thread.autoArchiveDuration ?? 0) * 60 * 1000, { round: true }) ), diff --git a/src/events/threadDelete.ts b/src/events/threadDelete.ts index bfae11a..1908b7f 100644 --- a/src/events/threadDelete.ts +++ b/src/events/threadDelete.ts @@ -1,11 +1,19 @@ +import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js"; +// @ts-expect-error import humanizeDuration from "humanize-duration"; +// @ts-expect-error +import type { HaikuClient } from "jshaiku" export const event = "threadDelete"; -export async function callback(client, thread) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = thread.client.logger; +export async function callback(client: HaikuClient, thread: ThreadChannel) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === thread.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first(); if (audit.executor.id === client.user.id) return; + const category = thread.parent ? entry( + thread.parent.parent ? thread.parent.parent.name : "None", + thread.parent.parent ? renderChannel(thread.parent.parent) : "None" + ) : entry(null, "Uncategorised") const data = { meta: { type: "channelDelete", @@ -18,14 +26,11 @@ export async function callback(client, thread) { list: { threadId: entry(thread.id, `\`${thread.id}\``), name: entry(thread.name, thread.name), - parentChannel: entry(thread.parentId, renderChannel(thread.parent)), - category: entry( - thread.parent.parent ? thread.parent.parent.name : "None", - thread.parent.parent ? renderChannel(thread.parent.parent) : "None" - ), + parentChannel: entry(thread.parentId, thread.parent ? renderChannel(thread.parent) : "*None*"), + category: category, autoArchiveDuration: entry( thread.autoArchiveDuration, - humanizeDuration(thread.autoArchiveDuration * 60 * 1000, { + humanizeDuration((thread.autoArchiveDuration ?? 0) * 60 * 1000, { round: true }) ), diff --git a/src/premium/createTranscript.ts b/src/premium/createTranscript.ts index c60bf23..57720bf 100644 --- a/src/premium/createTranscript.ts +++ b/src/premium/createTranscript.ts @@ -1,4 +1,4 @@ -import { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton, TextChannel } from "discord.js"; +import { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton, MessageComponentInteraction, TextChannel } from "discord.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import getEmojiByName from "../utils/getEmojiByName.js"; import { PasteClient, Publicity, ExpireDate } from "pastebin-api"; @@ -7,7 +7,7 @@ import client from "../utils/client.js"; const pbClient = new PasteClient(config.pastebinApiKey); -export default async function (interaction: CommandInteraction) { +export default async function (interaction: CommandInteraction | MessageComponentInteraction) { if (interaction.channel === null) return; if (!(interaction.channel instanceof TextChannel)) return; const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger; diff --git a/src/reflex/statsChannelUpdate.ts b/src/reflex/statsChannelUpdate.ts index 644a75f..657e90d 100644 --- a/src/reflex/statsChannelUpdate.ts +++ b/src/reflex/statsChannelUpdate.ts @@ -1,3 +1,4 @@ +import type { Guild, User } from 'discord.js'; // @ts-expect-error import type { HaikuClient } from "jshaiku"; import type { GuildMember } from "discord.js"; @@ -9,28 +10,29 @@ interface PropSchema { name: string; } -export async function callback(client: HaikuClient, member: GuildMember) { - const guild = await client.guilds.fetch(member.guild.id); +export async function callback(client: HaikuClient, member?: GuildMember, guild?: Guild, user?: User) { + if (!member && !guild) return; + guild = await client.guilds.fetch(member ? member.guild.id : guild!.id); + if (!guild) return; + user = user ?? member!.user const config = await client.database.guilds.read(guild.id); Object.entries(config.getKey("stats")).forEach(async ([channel, props]) => { if ((props as PropSchema).enabled) { let string = (props as PropSchema).name; if (!string) return; - string = await convertCurlyBracketString(string, member.id, member.displayName, guild.name, guild.members); + string = await convertCurlyBracketString(string, user!.id, user!.username, guild!.name, guild!.members); let fetchedChannel; try { - fetchedChannel = await guild.channels.fetch(channel); + fetchedChannel = await guild!.channels.fetch(channel); } catch (e) { fetchedChannel = null; } if (!fetchedChannel) { const deleted = config.getKey("stats")[channel]; - console.log(`stats.${channel}`); - console.log(guild.id); - await client.database.guilds.write(guild.id, null, `stats.${channel}`); + await client.database.guilds.write(guild!.id, null, `stats.${channel}`); return singleNotify( "statsChannelDeleted", - guild.id, + guild!.id, "One or more of your stats channels have been deleted. Please use `/settings stats` if you wish to add the channel again.\n" + `The channels name was: ${deleted.name}`, "Critical" diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts index 37f8d6c..f28b291 100644 --- a/src/reflex/verify.ts +++ b/src/reflex/verify.ts @@ -1,5 +1,5 @@ import { LoadingEmbed } from "./../utils/defaultEmbeds.js"; -import Discord, { CommandInteraction, GuildMember, Interaction, Permissions, Role } from "discord.js"; +import Discord, { CommandInteraction, GuildMember, Interaction, MessageComponentInteraction, Permissions, Role } from "discord.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import fetch from "node-fetch"; import { TestString, NSFWCheck } from "./scanners.js"; @@ -21,7 +21,7 @@ function step(i: number) { return "\n\n" + createPageIndicator(5, i); } -export default async function (interaction: CommandInteraction) { +export default async function (interaction: CommandInteraction | MessageComponentInteraction) { const verify = client.verify; await interaction.reply({ embeds: LoadingEmbed, diff --git a/tsconfig.json b/tsconfig.json index df7bcba..27960c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,6 @@ "skipLibCheck": true, "noImplicitReturns": false }, - "include": ["src/**/*", "*.js"], + "include": ["src/**/*"], "exclude": [] }