diff --git a/TODO b/TODO index 579b574..d2cd1a2 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ Role all Server rules verificationRequired on welcome +// TODO !IMPORTANT! URL + image hash + file hash database ROLE MENU SETTINGS diff --git a/package.json b/package.json index 09e29b7..f4a8ef3 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "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", + "lint-list": "echo 'Style checking...'; prettier --check .; echo 'Linting...'; eslint .; echo 'To view errors in more detail, please run `yarn lint`'; true", "setup": "node Installer.js" }, "repository": { diff --git a/src/commands/settings/welcome.ts b/src/commands/settings/welcome.ts index d1c2011..188e4b9 100644 --- a/src/commands/settings/welcome.ts +++ b/src/commands/settings/welcome.ts @@ -52,12 +52,13 @@ const callback = async (interaction: CommandInteraction): Promise => { interaction.options.getChannel("channel") || interaction.options.getString("message") ) { - let role: Role; - let ping: Role; - const message = interaction.options.getString("message"); + let role: Role | null; + let ping: Role | null; + let channel: Channel | null; + const message: string | null = interaction.options.getString("message"); try { - role = interaction.options.getRole("role") as Role; - ping = interaction.options.getRole("ping") as Role; + role = interaction.options.getRole("role") as Role | null; + ping = interaction.options.getRole("ping") as Role | null; } catch { return await interaction.editReply({ embeds: [ @@ -69,9 +70,8 @@ const callback = async (interaction: CommandInteraction): Promise => { ] }); } - let channel: Channel; try { - channel = interaction.options.getChannel("channel") as Channel; + channel = interaction.options.getChannel("channel") as Channel | null; } catch { return await interaction.editReply({ embeds: [ @@ -83,7 +83,13 @@ const callback = async (interaction: CommandInteraction): Promise => { ] }); } - const options = {}; + const options: { + role?: string; + ping?: string; + channel?: string; + message?: string; + } = {}; + if (role) options.role = renderRole(role); if (ping) options.ping = renderRole(ping); if (channel) options.channel = renderChannel(channel); @@ -98,13 +104,25 @@ const callback = async (interaction: CommandInteraction): Promise => { if (confirmation.cancelled) return; if (confirmation.success) { try { - const toChange = {}; + const toChange: { + "welcome.role"?: string; + "welcome.ping"?: string; + "welcome.channel"?: string; + "welcome.message"?: string; + } = {}; if (role) toChange["welcome.role"] = role.id; if (ping) toChange["welcome.ping"] = ping.id; if (channel) toChange["welcome.channel"] = channel.id; if (message) toChange["welcome.message"] = message; - await client.database.guilds.write(interaction.guild.id, toChange); - const list = { + await client.database.guilds.write(interaction.guild!.id, toChange); + const list: { + memberId: ReturnType; + changedBy: ReturnType; + role?: ReturnType; + ping?: ReturnType; + channel?: ReturnType; + message?: ReturnType; + } = { memberId: entry(interaction.user.id, `\`${interaction.user.id}\``), changedBy: entry(interaction.user.id, renderUser(interaction.user)) }; @@ -123,7 +141,7 @@ const callback = async (interaction: CommandInteraction): Promise => { }, list: list, hidden: { - guild: interaction.guild.id + guild: interaction.guild!.id } }; log(data); @@ -155,7 +173,7 @@ const callback = async (interaction: CommandInteraction): Promise => { } let lastClicked = null; while (true) { - const config = await client.database.guilds.read(interaction.guild.id); + const config = await client.database.guilds.read(interaction.guild!.id); m = (await interaction.editReply({ embeds: [ new EmojiEmbed() @@ -164,19 +182,19 @@ const callback = async (interaction: CommandInteraction): Promise => { `**Message:** ${config.welcome.message ? `\n> ${config.welcome.message}` : "*None set*"}\n` + `**Role:** ${ config.welcome.role - ? renderRole(await interaction.guild.roles.fetch(config.welcome.role)) + ? renderRole(await interaction.guild!.roles.fetch(config.welcome.role)) : "*None set*" }\n` + `**Ping:** ${ config.welcome.ping - ? renderRole(await interaction.guild.roles.fetch(config.welcome.ping)) + ? renderRole(await interaction.guild!.roles.fetch(config.welcome.ping)) : "*None set*" }\n` + `**Channel:** ${ config.welcome.channel ? config.welcome.channel == "dm" ? "DM" - : renderChannel(await interaction.guild.channels.fetch(config.welcome.channel)) + : renderChannel(await interaction.guild!.channels.fetch(config.welcome.channel)) : "*None set*" }` ) @@ -226,7 +244,7 @@ const callback = async (interaction: CommandInteraction): Promise => { i.deferUpdate(); if (i.customId == "clear-message") { if (lastClicked == "clear-message") { - await client.database.guilds.write(interaction.guild.id, { + await client.database.guilds.write(interaction.guild!.id, { "welcome.message": null }); lastClicked = null; @@ -235,7 +253,7 @@ const callback = async (interaction: CommandInteraction): Promise => { } } else if (i.customId == "clear-role") { if (lastClicked == "clear-role") { - await client.database.guilds.write(interaction.guild.id, { + await client.database.guilds.write(interaction.guild!.id, { "welcome.role": null }); lastClicked = null; @@ -244,7 +262,7 @@ const callback = async (interaction: CommandInteraction): Promise => { } } else if (i.customId == "clear-ping") { if (lastClicked == "clear-ping") { - await client.database.guilds.write(interaction.guild.id, { + await client.database.guilds.write(interaction.guild!.id, { "welcome.ping": null }); lastClicked = null; @@ -253,7 +271,7 @@ const callback = async (interaction: CommandInteraction): Promise => { } } else if (i.customId == "clear-channel") { if (lastClicked == "clear-channel") { - await client.database.guilds.write(interaction.guild.id, { + await client.database.guilds.write(interaction.guild!.id, { "welcome.channel": null }); lastClicked = null; @@ -261,14 +279,14 @@ const callback = async (interaction: CommandInteraction): Promise => { lastClicked = "clear-channel"; } } else if (i.customId == "set-channel-dm") { - await client.database.guilds.write(interaction.guild.id, { + await client.database.guilds.write(interaction.guild!.id, { "welcome.channel": "dm" }); lastClicked = null; } } await interaction.editReply({ - embeds: [m.embeds[0].setFooter({ text: "Message closed" })], + embeds: [m.embeds[0]!.setFooter({ text: "Message closed" })], components: [] }); }; diff --git a/src/events/channelCreate.ts b/src/events/channelCreate.ts index 19f5c9b..2aa8ec7 100644 --- a/src/events/channelCreate.ts +++ b/src/events/channelCreate.ts @@ -1,9 +1,13 @@ +import type { GuildAuditLogsEntry } from "discord.js"; +import type { GuildBasedChannel } from "discord.js"; +// @ts-expect-error +import { HaikuClient } from "jshaiku"; export const event = "channelCreate"; -export async function callback(client, channel) { - const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = channel.client.logger; +export async function callback(client: HaikuClient, channel: GuildBasedChannel) { + const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const auditLog = await getAuditLog(channel.guild, "CHANNEL_CREATE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === channel.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first(); if (audit.executor.id === client.user.id) return; let emoji; let readableType; @@ -27,7 +31,7 @@ export async function callback(client, channel) { displayName = "Voice Channel"; break; } - case "GUILD_STAGE": { + case "GUILD_STAGE_VOICE": { emoji = "CHANNEL.VOICE.CREATE"; readableType = "Stage"; displayName = "Stage Channel"; diff --git a/src/events/channelDelete.ts b/src/events/channelDelete.ts index f39e7ed..d42a12a 100644 --- a/src/events/channelDelete.ts +++ b/src/events/channelDelete.ts @@ -1,7 +1,7 @@ import { BaseGuildTextChannel, - BaseGuildVoiceChannel, - GuildChannel, + GuildAuditLogsEntry, + GuildBasedChannel, StageChannel, ThreadChannel, VoiceChannel @@ -11,10 +11,12 @@ import type { HaikuClient } from "jshaiku"; import getEmojiByName from "../utils/getEmojiByName.js"; export const event = "channelDelete"; + +export async function callback(client: HaikuClient, channel: GuildBasedChannel) { const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger; const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE"); - const audit = auditLog.entries.filter((entry) => entry.target.id === channel.id).first(); + const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === channel.id).first(); if (audit.executor.id === client.user.id) return; let emoji; @@ -46,15 +48,15 @@ export const event = "channelDelete"; } } const list: { - channelId: string; - name: string; - topic?: string | null; - type: any; - category: any; - nsfw?: boolean | null; - created: any; - deleted: any; - deletedBy: any; + channelId: { value: string; displayValue: string }; + name: { value: string; displayValue: string }; + topic?: { value: string; displayValue: string } | null; + type: { value: string; displayValue: string }; + category: { value: string; displayValue: string }; + nsfw?: { value: string; displayValue: string } | null; + created: { value: string; displayValue: string }; + deleted: { value: string; displayValue: string }; + deletedBy: { value: string; displayValue: string }; } = { channelId: entry(channel.id, `\`${channel.id}\``), name: entry(channel.id, `${channel.name}`), diff --git a/src/premium/createTranscript.ts b/src/premium/createTranscript.ts index 5fbb8ad..50bcbcf 100644 --- a/src/premium/createTranscript.ts +++ b/src/premium/createTranscript.ts @@ -4,7 +4,6 @@ import { Message, MessageActionRow, MessageButton, - PartialGroupDMChannel, TextChannel } from "discord.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js"; @@ -17,7 +16,7 @@ const pbClient = new PasteClient(config.pastebinApiKey); export default async function (interaction: CommandInteraction) { if (interaction.channel === null) return; - if (interaction.channel instanceof DMChannel) return; + if (!(interaction.channel instanceof TextChannel)) return; const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger; let messages: Message[] = []; @@ -44,18 +43,19 @@ export default async function (interaction: CommandInteraction) { out += "\n\n"; } }); - const member = interaction.channel.guild.members.cache.get(interaction.channel.topic.split(" ")[0]); + const member = interaction.guild!.members.cache.get(interaction.channel.topic.split(" ")[0]); let m; if (out !== "") { const url = await pbClient.createPaste({ code: out, expireDate: ExpireDate.Never, - name: `Ticket Transcript for ${member.user.username}#${member.user.discriminator} (Created at ${new Date( + name: `Ticket Transcript ${member ? ("for " + member.user.username + "#" + member.user.discriminator + " ") : ""}` + + `(Created at ${new Date( interaction.channel.createdTimestamp ).toDateString()})`, publicity: Publicity.Unlisted }); - const guildConfig = await client.database.guilds.read(interaction.guild.id); + const guildConfig = await client.database.guilds.read(interaction.guild!.id); m = await interaction.reply({ embeds: [ new EmojiEmbed() @@ -121,15 +121,15 @@ export default async function (interaction: CommandInteraction) { timestamp: new Date().getTime() }, list: { - ticketFor: entry( - interaction.channel.topic.split(" ")[0], - renderUser((await interaction.guild.members.fetch(interaction.channel.topic.split(" ")[0])).user) - ), - deletedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)), + ticketFor: member ? entry( + member.id, + renderUser(member.user) + ) : entry(null, "*Unknown*"), + deletedBy: entry(interaction.member!.user.id, renderUser(interaction.member!.user)), deleted: entry(new Date().getTime(), renderDelta(new Date().getTime())) }, hidden: { - guild: interaction.guild.id + guild: interaction.guild!.id } }; log(data); diff --git a/src/utils/log.ts b/src/utils/log.ts index fdf17ef..cd2f3c7 100644 --- a/src/utils/log.ts +++ b/src/utils/log.ts @@ -24,7 +24,7 @@ export class Logger { const delta = num2 - num1; return `${num1} -> ${num2} (${delta > 0 ? "+" : ""}${delta})`; } - entry(value: string, displayValue: string) { + entry(value: string, displayValue: string): { value: string; displayValue: string } { return { value: value, displayValue: displayValue }; } renderChannel(channel: Discord.GuildChannel | Discord.ThreadChannel) {