Fix various issues pre-switching-to-bun

pull/17/head
Skyler Grey 3 years ago
parent a402d1cb13
commit f21323a0b7
Signed by: Minion3665
GPG Key ID: 1AFD10256B3C714D

@ -4,7 +4,7 @@
"es2020": true, "es2020": true,
"node": true "node": true
}, },
"ignorePatterns": ["dist/"], "ignorePatterns": ["dist/", "src/Unfinished/"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/strict", "prettier"], "extends": ["eslint:recommended", "plugin:@typescript-eslint/strict", "prettier"],
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
@ -23,8 +23,6 @@
"caughtErrorsIgnorePattern": "^_" "caughtErrorsIgnorePattern": "^_"
} }
], ],
"@typescript-eslint/no-explicit-any": "error", "@typescript-eslint/no-explicit-any": "error"
"@typescript-eslint/no-unnecessary-condition": "off", // TODO: remove this rule
"no-constant-condition": "off"
} }
} }

@ -28,11 +28,11 @@
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"start": "node --experimental-json-modules --enable-source-maps dist/index.js", "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", "dev": "rm -rf dist && eslint src --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/index.js", "force-dev": "rm -rf dist && eslint src --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": "echo 'Style checking...'; prettier --check .; echo 'Linting...'; eslint src; 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-fix": "echo 'Fixing eslint issues...'; eslint src --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 src; echo 'To view errors in more detail, please run `yarn lint`'; true",
"setup": "node Installer.js" "setup": "node Installer.js"
}, },
"repository": { "repository": {
@ -56,6 +56,7 @@
"@typescript-eslint/parser": "^5.32.0", "@typescript-eslint/parser": "^5.32.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
"prettier": "^2.7.1", "prettier": "^2.7.1",
"prettier-eslint": "^15.0.1",
"tsc-suppress": "^1.0.7" "tsc-suppress": "^1.0.7"
} }
} }

@ -176,11 +176,12 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
if (all) { if (all) {
members.forEach((member) => { members.forEach((member) => {
let applies = true; let applies = true;
filters.forEach((filter) => { for (const filter of filters) {
if (!filter.check(member)) { if (!filter.check(member)) {
applies = false; applies = false;
break;
} }
}); }
if (applies) { if (applies) {
affected.push(member); affected.push(member);
} }
@ -188,11 +189,12 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
} else { } else {
members.forEach((member) => { members.forEach((member) => {
let applies = false; let applies = false;
filters.forEach((filter) => { for (const filter of filters) {
if (filter.check(member)) { if (filter.check(member)) {
applies = true; applies = true;
break;
} }
}); }
if (applies) { if (applies) {
affected.push(member); affected.push(member);
} }

@ -67,7 +67,7 @@ const callback = async (interaction: CommandInteraction): Promise<unknown> => {
fetchReply: true fetchReply: true
})) as Message; })) as Message;
const options = { const options = {
enabled: interaction.options.getString("enabled") as string | boolean, enabled: interaction.options.getString("enabled") as string | boolean | null,
category: interaction.options.getChannel("category"), category: interaction.options.getChannel("category"),
maxtickets: interaction.options.getNumber("maxticketsperuser"), maxtickets: interaction.options.getNumber("maxticketsperuser"),
supportping: interaction.options.getRole("supportrole") supportping: interaction.options.getRole("supportrole")

@ -82,7 +82,9 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
})) as Message; })) as Message;
let page = 0; let page = 0;
let selectPaneOpen = false; let selectPaneOpen = false;
while (true) { let cancelled = false;
let timedOut = false;
while (!cancelled && !timedOut) {
let selectPane: MessageActionRow[] = []; let selectPane: MessageActionRow[] = [];
if (selectPaneOpen) { if (selectPaneOpen) {
@ -136,7 +138,8 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
try { try {
i = await m.awaitMessageComponent({ time: 300000 }); i = await m.awaitMessageComponent({ time: 300000 });
} catch (e) { } catch (e) {
break; timedOut = true;
continue;
} }
i.deferUpdate(); i.deferUpdate();
if ((i.component as MessageActionRowComponent).customId === "left") { if ((i.component as MessageActionRowComponent).customId === "left") {
@ -151,66 +154,18 @@ const callback = async (interaction: CommandInteraction): Promise<void> => {
page = parseInt((i as SelectMenuInteraction).values[0]!); page = parseInt((i as SelectMenuInteraction).values[0]!);
selectPaneOpen = false; selectPaneOpen = false;
} else { } else {
const em = new Discord.MessageEmbed(pages[page]!.embed); cancelled = true;
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed");
await interaction.editReply({
embeds: [em],
components: [
new MessageActionRow().addComponents([
new MessageButton()
.setCustomId("left")
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("select")
.setEmoji(getEmojiByName("CONTROL.MENU", "id"))
.setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("right")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("close")
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setStyle("DANGER")
.setDisabled(true)
])
]
});
return;
} }
} }
const em = new Discord.MessageEmbed(pages[page]!.embed); const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out"); if (timedOut) {
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
} else {
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message closed");
}
await interaction.editReply({ await interaction.editReply({
embeds: [em], embeds: [em],
components: [ components: []
new MessageActionRow().addComponents([
new MessageButton()
.setCustomId("left")
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("select")
.setEmoji(getEmojiByName("CONTROL.MENU", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("right")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("close")
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
.setStyle("DANGER")
.setDisabled(true)
])
]
}); });
}; };

@ -1,4 +1,4 @@
import type { GuildAuditLogsEntry, GuildBan } from 'discord.js'; import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js"; import { purgeByUser } from "../actions/tickets/delete.js";
import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js"; import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js";
// @ts-expect-error // @ts-expect-error

@ -1,4 +1,4 @@
import type { GuildAuditLogsEntry, GuildBan } from 'discord.js'; import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js"; import { purgeByUser } from "../actions/tickets/delete.js";
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku"; import type { HaikuClient } from "jshaiku";

@ -1,6 +1,6 @@
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku"; import type { HaikuClient } from "jshaiku";
import type { Guild, GuildAuditLogsEntry } from 'discord.js'; import type { Guild, GuildAuditLogsEntry } from "discord.js";
import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js"; import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js";
export const event = "guildUpdate"; export const event = "guildUpdate";
@ -31,8 +31,8 @@ export async function callback(client: HaikuClient, before: Guild, after: Guild)
NONE: "None", NONE: "None",
ELEVATED: "Enabled" ELEVATED: "Enabled"
}; };
const beforeOwner = await before.fetchOwner() const beforeOwner = await before.fetchOwner();
const afterOwner = await after.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) if (before.icon !== after.icon)

@ -11,7 +11,7 @@ import type { HaikuClient } from "jshaiku";
export const event = "interactionCreate"; export const event = "interactionCreate";
function getAutocomplete(typed: string, options: string[]): {name: string, value: string}[] { 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. options = options.filter((option) => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete.
if (!typed) if (!typed)
return options return options
@ -65,8 +65,11 @@ function generateWelcomeMessageAutocomplete(typed: string) {
} }
async function interactionCreate(interaction: Interaction) { async function interactionCreate(interaction: Interaction) {
if (interaction.type === "MESSAGE_COMPONENT" && (interaction as MessageComponentInteraction).componentType === "BUTTON") { if (
const int = (interaction as MessageComponentInteraction) interaction.type === "MESSAGE_COMPONENT" &&
(interaction as MessageComponentInteraction).componentType === "BUTTON"
) {
const int = interaction as MessageComponentInteraction;
switch (int.customId) { switch (int.customId) {
case "rolemenu": { case "rolemenu": {
return await roleMenu(interaction); return await roleMenu(interaction);
@ -85,24 +88,16 @@ async function interactionCreate(interaction: Interaction) {
} }
} }
} else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") { } else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") {
const int = (interaction as AutocompleteInteraction) const int = interaction as AutocompleteInteraction;
switch ( switch (`${int.commandName} ${int.options.getSubcommandGroup(false)} ${int.options.getSubcommand(false)}`) {
`${int.commandName} ${int.options.getSubcommandGroup(
false
)} ${int.options.getSubcommand(false)}`
) {
case "tag null null": { case "tag null null": {
return int.respond( return int.respond(getAutocomplete(int.options.getString("tag") ?? "", await tagAutocomplete(int)));
getAutocomplete(int.options.getString("tag") ?? "", await tagAutocomplete(int))
);
} }
case "settings null stats": { case "settings null stats": {
return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? "")); return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? ""));
} }
case "settings null welcome": { case "settings null welcome": {
return int.respond( return int.respond(generateWelcomeMessageAutocomplete(int.options.getString("message") ?? ""));
generateWelcomeMessageAutocomplete(int.options.getString("message") ?? "")
);
} }
} }
} }

@ -9,7 +9,9 @@ export const event = "inviteCreate";
export async function callback(client: HaikuClient, invite: Invite) { export async function callback(client: HaikuClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE"); const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId).first(); const audit = auditLog.entries
.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId)
.first();
if (audit.executor.id === client.user.id) return; if (audit.executor.id === client.user.id) return;
const data = { const data = {
meta: { meta: {

@ -9,7 +9,9 @@ export const event = "inviteDelete";
export async function callback(client: HaikuClient, invite: Invite) { export async function callback(client: HaikuClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE"); const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId).first(); const audit = auditLog.entries
.filter((entry: GuildAuditLogsEntry) => entry.target!.id === invite.inviterId)
.first();
if (audit.executor.id === client.user.id) return; if (audit.executor.id === client.user.id) return;
const data = { const data = {
meta: { meta: {

@ -10,7 +10,9 @@ export async function callback(client: HaikuClient, message: Message) {
if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return; if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return;
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger; const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(message.guild, "MEMBER_BAN_ADD"); const auditLog = await getAuditLog(message.guild, "MEMBER_BAN_ADD");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => 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) {
if (audit.createdAt - 100 < new Date().getTime()) return; if (audit.createdAt - 100 < new Date().getTime()) return;
} }
@ -54,7 +56,9 @@ export async function callback(client: HaikuClient, message: Message) {
repliedTo: entry( repliedTo: entry(
replyTo, replyTo,
replyTo replyTo
? `[[Jump to message]](https://discord.com/channels/${message.guild!.id}/${message.channel.id}/${replyTo.messageId})` ? `[[Jump to message]](https://discord.com/channels/${message.guild!.id}/${
message.channel.id
}/${replyTo.messageId})`
: "None" : "None"
) )
}, },

@ -1,5 +1,5 @@
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku" import type { HaikuClient } from "jshaiku";
import type { GuildAuditLogsEntry, Sticker } from "discord.js"; import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete"; export const event = "stickerDelete";

@ -1,5 +1,5 @@
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku" import type { HaikuClient } from "jshaiku";
import type { GuildAuditLogsEntry, Sticker } from "discord.js"; import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete"; export const event = "stickerDelete";

@ -1,5 +1,5 @@
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku" import type { HaikuClient } from "jshaiku";
import type { Sticker } from "discord.js"; import type { Sticker } from "discord.js";
export const event = "stickerUpdate"; export const event = "stickerUpdate";

@ -2,7 +2,7 @@ import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error // @ts-expect-error
import humanizeDuration from "humanize-duration"; import humanizeDuration from "humanize-duration";
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku" import type { HaikuClient } from "jshaiku";
export const event = "threadCreate"; export const event = "threadCreate";
export async function callback(client: HaikuClient, thread: ThreadChannel) { export async function callback(client: HaikuClient, thread: ThreadChannel) {
@ -10,10 +10,12 @@ export async function callback(client: HaikuClient, thread: ThreadChannel) {
const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE"); const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => 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; if (audit.executor.id === client.user.id) return;
const category = thread.parent ? entry( const category = thread.parent
thread.parent.parent ? thread.parent.parent.name : "None", ? entry(
thread.parent.parent ? renderChannel(thread.parent.parent) : "None" thread.parent.parent ? thread.parent.parent.name : "None",
) : entry(null, "Uncategorised") thread.parent.parent ? renderChannel(thread.parent.parent) : "None"
)
: entry(null, "Uncategorised");
const data = { const data = {
meta: { meta: {
type: "channelCreate", type: "channelCreate",

@ -2,7 +2,7 @@ import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error // @ts-expect-error
import humanizeDuration from "humanize-duration"; import humanizeDuration from "humanize-duration";
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku" import type { HaikuClient } from "jshaiku";
export const event = "threadDelete"; export const event = "threadDelete";
export async function callback(client: HaikuClient, thread: ThreadChannel) { export async function callback(client: HaikuClient, thread: ThreadChannel) {
@ -10,10 +10,12 @@ export async function callback(client: HaikuClient, thread: ThreadChannel) {
const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE"); const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => 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; if (audit.executor.id === client.user.id) return;
const category = thread.parent ? entry( const category = thread.parent
thread.parent.parent ? thread.parent.parent.name : "None", ? entry(
thread.parent.parent ? renderChannel(thread.parent.parent) : "None" thread.parent.parent ? thread.parent.parent.name : "None",
) : entry(null, "Uncategorised") thread.parent.parent ? renderChannel(thread.parent.parent) : "None"
)
: entry(null, "Uncategorised");
const data = { const data = {
meta: { meta: {
type: "channelDelete", type: "channelDelete",

@ -32,7 +32,9 @@ export async function callback(client: HaikuClient, before: ThreadChannel, after
if (before.rateLimitPerUser !== after.rateLimitPerUser) { if (before.rateLimitPerUser !== after.rateLimitPerUser) {
list["slowmode"] = entry( list["slowmode"] = entry(
[before.rateLimitPerUser, after.rateLimitPerUser], [before.rateLimitPerUser, after.rateLimitPerUser],
`${humanizeDuration((before.rateLimitPerUser ?? 0) * 1000)} -> ${humanizeDuration((after.rateLimitPerUser ?? 0) * 1000)}` `${humanizeDuration((before.rateLimitPerUser ?? 0) * 1000)} -> ${humanizeDuration(
(after.rateLimitPerUser ?? 0) * 1000
)}`
); );
} }
if (!(Object.keys(list).length - 3)) return; if (!(Object.keys(list).length - 3)) return;

@ -15,25 +15,34 @@ export async function callback(client: HaikuClient, channel: Discord.GuildChanne
auditLogUpdate, auditLogUpdate,
auditLogDelete auditLogDelete
]); ]);
const auditCreate = auditLogCreate.entries.filter((entry: GuildAuditLogsEntry | null) => { const auditCreate = auditLogCreate.entries
if (entry === null) return false .filter((entry: GuildAuditLogsEntry | null) => {
return (entry.target! as Webhook).channelId === channel.id} if (entry === null) return false;
).first(); return (entry.target! as Webhook).channelId === channel.id;
const auditUpdate = auditLogUpdate.entries.filter((entry: GuildAuditLogsEntry | null) => { })
if (entry === null) return false .first();
return (entry.target! as Webhook).channelId === channel.id} const auditUpdate = auditLogUpdate.entries
).first(); .filter((entry: GuildAuditLogsEntry | null) => {
const auditDelete = auditLogDelete.entries.filter((entry: GuildAuditLogsEntry | null) => { if (entry === null) return false;
if (entry === null) return false return (entry.target! as Webhook).channelId === channel.id;
return (entry.target! as Webhook).channelId === channel.id} })
).first(); .first();
const auditDelete = auditLogDelete.entries
.filter((entry: GuildAuditLogsEntry | null) => {
if (entry === null) return false;
return (entry.target! as Webhook).channelId === channel.id;
})
.first();
if (!auditCreate && !auditUpdate && !auditDelete) return; if (!auditCreate && !auditUpdate && !auditDelete) return;
let audit = auditCreate; let audit = auditCreate;
let action: "Create" | "Update" | "Delete" = "Create"; let action: "Create" | "Update" | "Delete" = "Create";
let list: Record<string, ReturnType<typeof entry> | string> = {}; let list: Record<string, ReturnType<typeof entry> | string> = {};
if (auditUpdate && auditUpdate.createdTimestamp > audit.createdTimestamp) { if (auditUpdate && auditUpdate.createdTimestamp > audit.createdTimestamp) {
const { before, after } = auditUpdate.changes.reduce( const { before, after } = auditUpdate.changes.reduce(
(acc: {before: Record<string, string>, after: Record<string, string>}, change: {key: string, new: string, old: string}) => { (
acc: { before: Record<string, string>; after: Record<string, string> },
change: { key: string; new: string; old: string }
) => {
acc.before[change.key] = change.old; acc.before[change.key] = change.old;
acc.after[change.key] = change.new; acc.after[change.key] = change.new;
return acc; return acc;
@ -50,14 +59,20 @@ export async function callback(client: HaikuClient, channel: Discord.GuildChanne
renderChannel(await client.channels.fetch(after.channel_id)) renderChannel(await client.channels.fetch(after.channel_id))
); );
if (!Object.keys(list).length) return; if (!Object.keys(list).length) return;
list["created"] = entry(auditUpdate.target.createdTimestamp, renderDelta(auditUpdate.target.createdTimestamp)); list["created"] = entry(
auditUpdate.target.createdTimestamp,
renderDelta(auditUpdate.target.createdTimestamp)
);
list["edited"] = entry(after.editedTimestamp, renderDelta(new Date().getTime())); list["edited"] = entry(after.editedTimestamp, renderDelta(new Date().getTime()));
list["editedBy"] = entry(auditUpdate.executor.id, renderUser(auditUpdate.executor)); list["editedBy"] = entry(auditUpdate.executor.id, renderUser(auditUpdate.executor));
audit = auditUpdate; audit = auditUpdate;
action = "Update"; action = "Update";
} else if (auditDelete && auditDelete.createdTimestamp > audit.createdTimestamp) { } else if (auditDelete && auditDelete.createdTimestamp > audit.createdTimestamp) {
const { before } = auditDelete.changes.reduce( const { before } = auditDelete.changes.reduce(
(acc: {before: Record<string, string>, after: Record<string, string>}, change: {key: string, new: string, old: string}) => { (
acc: { before: Record<string, string>; after: Record<string, string> },
change: { key: string; new: string; old: string }
) => {
acc.before[change.key] = change.old; acc.before[change.key] = change.old;
acc.after[change.key] = change.new; acc.after[change.key] = change.new;
return acc; return acc;
@ -78,7 +93,10 @@ export async function callback(client: HaikuClient, channel: Discord.GuildChanne
action = "Delete"; action = "Delete";
} else { } else {
const { before } = auditDelete.changes.reduce( const { before } = auditDelete.changes.reduce(
(acc: {before: Record<string, string>, after: Record<string, string>}, change: {key: string, new: string, old: string}) => { (
acc: { before: Record<string, string>; after: Record<string, string> },
change: { key: string; new: string; old: string }
) => {
acc.before[change.key] = change.old; acc.before[change.key] = change.old;
acc.after[change.key] = change.new; acc.after[change.key] = change.new;
return acc; return acc;

@ -1,4 +1,12 @@
import { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton, MessageComponentInteraction, TextChannel } from "discord.js"; import {
CommandInteraction,
GuildMember,
Message,
MessageActionRow,
MessageButton,
MessageComponentInteraction,
TextChannel
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js"; import getEmojiByName from "../utils/getEmojiByName.js";
import { PasteClient, Publicity, ExpireDate } from "pastebin-api"; import { PasteClient, Publicity, ExpireDate } from "pastebin-api";

@ -230,7 +230,9 @@ export default async (guild: Guild, interaction?: CommandInteraction) => {
let selectPaneOpen = false; let selectPaneOpen = false;
while (true) { let cancelled = false;
let timedOut = false;
while (!cancelled && !timedOut) {
let selectPane: MessageActionRow[] = []; let selectPane: MessageActionRow[] = [];
if (selectPaneOpen) { if (selectPaneOpen) {
@ -297,7 +299,8 @@ export default async (guild: Guild, interaction?: CommandInteraction) => {
time: 300000 time: 300000
}); });
} catch (e) { } catch (e) {
break; timedOut = true;
continue;
} }
i.deferUpdate(); i.deferUpdate();
if (!("customId" in i.component)) { if (!("customId" in i.component)) {
@ -314,91 +317,40 @@ export default async (guild: Guild, interaction?: CommandInteraction) => {
page = parseInt((i as SelectMenuInteraction).values[0]!); page = parseInt((i as SelectMenuInteraction).values[0]!);
selectPaneOpen = false; selectPaneOpen = false;
} else { } else {
if (interaction) { cancelled = true;
const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
em.setFooter({ text: "Message closed" });
interaction.editReply({
embeds: [em],
components: [
new MessageActionRow().addComponents([
new MessageButton()
.setCustomId("left")
.setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("select")
.setEmoji(getEmojiByName("CONTROL.MENU", "id"))
.setStyle(selectPaneOpen ? "PRIMARY" : "SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("right")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(true)
])
]
});
} else {
m.delete();
}
return;
} }
} }
if (interaction) { if (timedOut) {
const em = new Discord.MessageEmbed(pages[page]!.embed); if (interaction) {
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({ const em = new Discord.MessageEmbed(pages[page]!.embed);
text: "Message timed out" em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
}); text: "Message timed out"
await interaction.editReply({ });
embeds: [em], await interaction.editReply({
components: [ embeds: [em],
new MessageActionRow().addComponents([ components: []
new MessageButton() });
.setCustomId("left") } else {
.setEmoji(getEmojiByName("CONTROL.LEFT", "id")) const em = new Discord.MessageEmbed(pages[page]!.embed);
.setStyle("SECONDARY") em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
.setDisabled(true), text: "Message timed out"
new MessageButton() });
.setCustomId("select") await m.edit({
.setEmoji(getEmojiByName("CONTROL.MENU", "id")) embeds: [em],
.setStyle("SECONDARY") components: []
.setDisabled(true), });
new MessageButton() }
.setCustomId("right")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(true)
])
]
});
} else { } else {
const em = new Discord.MessageEmbed(pages[page]!.embed); if (interaction) {
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({ const em = new Discord.MessageEmbed(pages[page]!.embed);
text: "Message timed out" em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
}); em.setFooter({ text: "Message closed" });
await m.edit({ interaction.editReply({
embeds: [em], embeds: [em],
components: [ components: []
new MessageActionRow().addComponents([ });
new MessageButton() } else {
.setCustomId("left") m.delete();
.setEmoji(getEmojiByName("CONTROL.LEFT", "id")) }
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("select")
.setEmoji(getEmojiByName("CONTROL.MENU", "id"))
.setStyle("SECONDARY")
.setDisabled(true),
new MessageButton()
.setCustomId("right")
.setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
.setStyle("SECONDARY")
.setDisabled(true)
])
]
});
} }
}; };

@ -1,4 +1,4 @@
import type { Guild, User } from 'discord.js'; import type { Guild, User } from "discord.js";
// @ts-expect-error // @ts-expect-error
import type { HaikuClient } from "jshaiku"; import type { HaikuClient } from "jshaiku";
import type { GuildMember } from "discord.js"; import type { GuildMember } from "discord.js";
@ -14,7 +14,7 @@ export async function callback(client: HaikuClient, member?: GuildMember, guild?
if (!member && !guild) return; if (!member && !guild) return;
guild = await client.guilds.fetch(member ? member.guild.id : guild!.id); guild = await client.guilds.fetch(member ? member.guild.id : guild!.id);
if (!guild) return; if (!guild) return;
user = user ?? member!.user user = user ?? member!.user;
const config = await client.database.guilds.read(guild.id); const config = await client.database.guilds.read(guild.id);
Object.entries(config.getKey("stats")).forEach(async ([channel, props]) => { Object.entries(config.getKey("stats")).forEach(async ([channel, props]) => {
if ((props as PropSchema).enabled) { if ((props as PropSchema).enabled) {

@ -1,5 +1,12 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js"; import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
import Discord, { CommandInteraction, GuildMember, Interaction, MessageComponentInteraction, Permissions, Role } from "discord.js"; import Discord, {
CommandInteraction,
GuildMember,
Interaction,
MessageComponentInteraction,
Permissions,
Role
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js"; import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch"; import fetch from "node-fetch";
import { TestString, NSFWCheck } from "./scanners.js"; import { TestString, NSFWCheck } from "./scanners.js";
@ -175,20 +182,17 @@ export default async function (interaction: CommandInteraction | MessageComponen
let length = 5; let length = 5;
let itt = 0; let itt = 0;
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
while (true) { do {
itt += 1; itt += 1;
code = ""; code = "";
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length)); code += chars.charAt(Math.floor(Math.random() * chars.length));
} }
if (code in verify) continue;
if (itt > 1000) { if (itt > 1000) {
itt = 0; itt = 0;
length += 1; length += 1;
continue;
} }
break; } while (code in verify);
}
const role: Role | null = await interaction.guild!.roles.fetch(config.verify.role); const role: Role | null = await interaction.guild!.roles.fetch(config.verify.role);
if (!role) { if (!role) {
await interaction.editReply({ await interaction.editReply({

@ -1,4 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
export type AsyncReturnType<T extends (...args: any[]) => Promise<any>> = T extends (...args: any[]) => Promise<infer X>
? X
: unknown;
Loading…
Cancel
Save