Fix a bunch of linter errors
diff --git a/src/utils/calculate.ts b/src/utils/calculate.ts
index 9bdef3b..6d0c55f 100644
--- a/src/utils/calculate.ts
+++ b/src/utils/calculate.ts
@@ -36,7 +36,7 @@
}
let int = 0n;
- for(const perm of permissions) {
+ for (const perm of permissions) {
int += BigInt(2 ** array.indexOf(perm));
}
return int.toString(16);
@@ -47,7 +47,10 @@
array = logs;
}
const permissions = [];
- const int = (BigInt("0x" + permissionsHex)).toString(2).split("").reverse();
+ const int = BigInt("0x" + permissionsHex)
+ .toString(2)
+ .split("")
+ .reverse();
for (const index in int) {
if (int[index] === "1" && array.length > index) {
permissions.push(array[index]);
@@ -56,9 +59,4 @@
return permissions;
};
-export {
- toHexInteger,
- toHexArray,
- tickets,
- logs
-};
\ No newline at end of file
+export { toHexInteger, toHexArray, tickets, logs };
diff --git a/src/utils/client.ts b/src/utils/client.ts
index a343bcb..0ce61f1 100644
--- a/src/utils/client.ts
+++ b/src/utils/client.ts
@@ -1,9 +1,12 @@
import { HaikuClient } from "jshaiku";
import { Intents } from "discord.js";
-import config from "../config/main.json" assert {type: "json"};
+import config from "../config/main.json" assert { type: "json" };
-const client = new HaikuClient({
- intents: new Intents(32767).bitfield // This is a way of specifying all intents w/o having to type them out
-}, config);
+const client = new HaikuClient(
+ {
+ intents: new Intents(32767).bitfield // This is a way of specifying all intents w/o having to type them out
+ },
+ config
+);
-export default client;
\ No newline at end of file
+export default client;
diff --git a/src/utils/confirmationMessage.ts b/src/utils/confirmationMessage.ts
index fd58d12..728cc52 100644
--- a/src/utils/confirmationMessage.ts
+++ b/src/utils/confirmationMessage.ts
@@ -1,9 +1,14 @@
-import Discord, { CommandInteraction, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import Discord, {
+ CommandInteraction,
+ Message,
+ MessageActionRow,
+ MessageButton,
+ TextInputComponent
+} from "discord.js";
import { modalInteractionCollector } from "./dualCollector.js";
import EmojiEmbed from "./generateEmojiEmbed.js";
import getEmojiByName from "./getEmojiByName.js";
-
interface CustomBoolean<T> {
title: string;
disabled: boolean;
@@ -19,8 +24,8 @@
title = "";
emoji = "";
description = "";
- color = "";
- customButtons: {[index:string]: CustomBoolean<unknown>} = {};
+ color: "Danger" | "Warning" | "Success" = "Success";
+ customButtons: Record<string, CustomBoolean<unknown>> = {};
inverted = false;
reason: string | null = null;
@@ -28,21 +33,45 @@
this.interaction = interaction;
}
- setTitle(title: string) { this.title = title; return this; }
- setEmoji(emoji: string) { this.emoji = emoji; return this; }
- setDescription(description: string) { this.description = description; return this; }
- setColor(color: string) { this.color = color; return this; }
- setInverted(inverted: boolean) { this.inverted = inverted; return this; }
- addCustomBoolean(customId: string, title: string, disabled: boolean, callback: () => Promise<unknown> | null, callbackClicked: string | null, emoji?: string, initial?: boolean) { this.customButtons[customId] = {
- title: title,
- disabled: disabled,
- value: callbackClicked,
- emoji: emoji,
- active: initial ?? false,
- onClick: callback ?? (() => null),
- response: null
- };
- return this;
+ setTitle(title: string) {
+ this.title = title;
+ return this;
+ }
+ setEmoji(emoji: string) {
+ this.emoji = emoji;
+ return this;
+ }
+ setDescription(description: string) {
+ this.description = description;
+ return this;
+ }
+ setColor(color: "Danger" | "Warning" | "Success") {
+ this.color = color;
+ return this;
+ }
+ setInverted(inverted: boolean) {
+ this.inverted = inverted;
+ return this;
+ }
+ addCustomBoolean(
+ customId: string,
+ title: string,
+ disabled: boolean,
+ callback: () => Promise<unknown> = async () => null,
+ callbackClicked: string | null,
+ emoji?: string,
+ initial?: boolean
+ ) {
+ this.customButtons[customId] = {
+ title: title,
+ disabled: disabled,
+ value: callbackClicked,
+ emoji: emoji,
+ active: initial ?? false,
+ onClick: callback,
+ response: null
+ };
+ return this;
}
addReasonButton(reason: string) {
this.reason = reason;
@@ -63,50 +92,71 @@
.setEmoji(getEmojiByName("CONTROL.CROSS", "id"))
];
Object.entries(this.customButtons).forEach(([k, v]) => {
- fullComponents.push(new Discord.MessageButton()
+ const button = new Discord.MessageButton()
.setCustomId(k)
.setLabel(v.title)
.setStyle(v.active ? "SUCCESS" : "PRIMARY")
- .setEmoji(getEmojiByName(v.emoji, "id"))
- .setDisabled(v.disabled));
+ .setDisabled(v.disabled);
+ if (v.emoji !== undefined)
+ button.setEmoji(getEmojiByName(v.emoji, "id"));
+ fullComponents.push(button);
});
- if (this.reason !== null) fullComponents.push(new Discord.MessageButton()
- .setCustomId("reason")
- .setLabel("Edit Reason")
- .setStyle("PRIMARY")
- .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
- .setDisabled(false)
- );
+ if (this.reason !== null)
+ fullComponents.push(
+ new Discord.MessageButton()
+ .setCustomId("reason")
+ .setLabel("Edit Reason")
+ .setStyle("PRIMARY")
+ .setEmoji(getEmojiByName("ICONS.EDIT", "id"))
+ .setDisabled(false)
+ );
const components = [];
for (let i = 0; i < fullComponents.length; i += 5) {
- components.push(new MessageActionRow().addComponents(fullComponents.slice(i, i + 5)));
+ components.push(
+ new MessageActionRow().addComponents(
+ fullComponents.slice(i, i + 5)
+ )
+ );
}
const object = {
embeds: [
new EmojiEmbed()
.setEmoji(this.emoji)
.setTitle(this.title)
- .setDescription(this.description + "\n\n" + Object.values(this.customButtons).map(v => {
- if (v.value === null) return "";
- return v.active ? `*${v.value}*\n` : "";
- }).join(""))
+ .setDescription(
+ this.description +
+ "\n\n" +
+ Object.values(this.customButtons)
+ .map((v) => {
+ if (v.value === null) return "";
+ return v.active ? `*${v.value}*\n` : "";
+ })
+ .join("")
+ )
.setStatus(this.color)
],
components: components,
ephemeral: true,
fetchReply: true
};
- let m;
+ let m: Message;
try {
- if ( editOnly ) {
- m = await this.interaction.editReply(object);
+ if (editOnly) {
+ m = (await this.interaction.editReply(object)) as Message;
} else {
- m = await this.interaction.reply(object);
+ m = (await this.interaction.reply(
+ object
+ )) as unknown as Message;
}
- } catch { return { cancelled: true }; }
+ } catch {
+ return { cancelled: true };
+ }
let component;
try {
- component = await m.awaitMessageComponent({filter: (m) => m.user.id === this.interaction.user.id, time: 300000});
+ component = await m.awaitMessageComponent({
+ filter: (m) => m.user.id === this.interaction.user.id,
+ time: 300000
+ });
} catch (e) {
return { success: false, components: this.customButtons };
}
@@ -114,47 +164,75 @@
component.deferUpdate();
for (const v of Object.values(this.customButtons)) {
if (!v.active) continue;
- try { v.response = await v.onClick(); }
- catch (e) { console.log(e); }
+ try {
+ v.response = await v.onClick();
+ } catch (e) {
+ console.log(e);
+ }
}
return { success: true, components: this.customButtons };
} else if (component.customId === "no") {
component.deferUpdate();
return { success: false, components: this.customButtons };
} else if (component.customId === "reason") {
- await component.showModal(new Discord.Modal().setCustomId("modal").setTitle("Editing reason").addComponents(
- new MessageActionRow<TextInputComponent>().addComponents(new TextInputComponent()
- .setCustomId("reason")
- .setLabel("Reason")
- .setMaxLength(2000)
- .setRequired(false)
- .setStyle("PARAGRAPH")
- .setPlaceholder("Spammed in #general")
- .setValue(this.reason ? this.reason : "")
- )
- ));
+ await component.showModal(
+ new Discord.Modal()
+ .setCustomId("modal")
+ .setTitle("Editing reason")
+ .addComponents(
+ new MessageActionRow<TextInputComponent>().addComponents(
+ new TextInputComponent()
+ .setCustomId("reason")
+ .setLabel("Reason")
+ .setMaxLength(2000)
+ .setRequired(false)
+ .setStyle("PARAGRAPH")
+ .setPlaceholder("Spammed in #general")
+ .setValue(this.reason ? this.reason : "")
+ )
+ )
+ );
await this.interaction.editReply({
- embeds: [new EmojiEmbed()
- .setTitle(this.title)
- .setDescription("Modal opened. If you can't see it, click back and try again.")
- .setStatus(this.color)
- .setEmoji(this.emoji)
- ], components: [new MessageActionRow().addComponents([new MessageButton()
- .setLabel("Back")
- .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
- .setStyle("PRIMARY")
- .setCustomId("back")
- ])]
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(this.title)
+ .setDescription(
+ "Modal opened. If you can't see it, click back and try again."
+ )
+ .setStatus(this.color)
+ .setEmoji(this.emoji)
+ ],
+ components: [
+ new MessageActionRow().addComponents([
+ new MessageButton()
+ .setLabel("Back")
+ .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+ .setStyle("PRIMARY")
+ .setCustomId("back")
+ ])
+ ]
});
let out;
try {
- out = await modalInteractionCollector(m, (m) => m.channel.id === this.interaction.channel.id, (m) => m.customId === "reason");
- } catch (e) { return {}; }
- if (out.fields) { return { newReason: out.fields.getTextInputValue("reason") ?? "" }; }
- else { return { newReason: this.reason }; }
+ out = await modalInteractionCollector(
+ m,
+ (m) => m.channel.id === this.interaction.channel.id,
+ (m) => m.customId === "reason"
+ );
+ } catch (e) {
+ return {};
+ }
+ if (out.fields) {
+ return {
+ newReason: out.fields.getTextInputValue("reason") ?? ""
+ };
+ } else {
+ return { newReason: this.reason };
+ }
} else {
component.deferUpdate();
- this.customButtons[component.customId].active = !this.customButtons[component.customId].active;
+ this.customButtons[component.customId].active =
+ !this.customButtons[component.customId].active;
return { components: this.customButtons };
}
}
diff --git a/src/utils/convertCurlyBracketString.ts b/src/utils/convertCurlyBracketString.ts
index f05076e..49a4418 100644
--- a/src/utils/convertCurlyBracketString.ts
+++ b/src/utils/convertCurlyBracketString.ts
@@ -1,13 +1,33 @@
-async function convertCurlyBracketString(str, memberID, memberName, serverName, members): Promise<string> {
+async function convertCurlyBracketString(
+ str,
+ memberID,
+ memberName,
+ serverName,
+ members
+): Promise<string> {
const memberCount = (await members.fetch()).size;
- const bots = (await members.fetch()).filter(m => m.user.bot).size;
+ const bots = (await members.fetch()).filter((m) => m.user.bot).size;
str = str
- .replace("{member:mention}", memberID ? `<@${memberID}>` : "{member:mention}")
- .replace("{member:name}", memberName ? `${memberName}` : "{member:name}")
+ .replace(
+ "{member:mention}",
+ memberID ? `<@${memberID}>` : "{member:mention}"
+ )
+ .replace(
+ "{member:name}",
+ memberName ? `${memberName}` : "{member:name}"
+ )
.replace("{serverName}", serverName ? `${serverName}` : "{serverName}")
- .replace("{memberCount}", memberCount ? `${memberCount}` : "{memberCount}")
+ .replace(
+ "{memberCount}",
+ memberCount ? `${memberCount}` : "{memberCount}"
+ )
.replace("{memberCount:bots}", bots ? `${bots}` : "{memberCount:bots}")
- .replace("{memberCount:humans}", (memberCount && bots) ? `${memberCount - bots}` : "{memberCount:humans}");
+ .replace(
+ "{memberCount:humans}",
+ memberCount && bots
+ ? `${memberCount - bots}`
+ : "{memberCount:humans}"
+ );
return str;
}
diff --git a/src/utils/createLogException.ts b/src/utils/createLogException.ts
index c62a824..7a6c492 100644
--- a/src/utils/createLogException.ts
+++ b/src/utils/createLogException.ts
@@ -3,6 +3,8 @@
export default function (guild: string, channel: string, message: string) {
client.noLog.push(`${guild}/${channel}/${message}`);
setTimeout(() => {
- client.noLog = client.noLog.filter((i) => {return i !== `${guild}/${channel}/${message}`;});
+ client.noLog = client.noLog.filter((i) => {
+ return i !== `${guild}/${channel}/${message}`;
+ });
}, 500);
-}
\ No newline at end of file
+}
diff --git a/src/utils/createPageIndicator.ts b/src/utils/createPageIndicator.ts
index fa203dc..ccf18e2 100644
--- a/src/utils/createPageIndicator.ts
+++ b/src/utils/createPageIndicator.ts
@@ -1,15 +1,23 @@
import getEmojiByName from "./getEmojiByName.js";
-function pageIndicator(amount: number, selected: number, showDetails?: boolean | true) {
+function pageIndicator(
+ amount: number,
+ selected: number,
+ showDetails?: boolean | true
+) {
let out = "";
if (amount === 1) {
- out += getEmojiByName("TRACKS.SINGLE." + (selected === 0 ? "ACTIVE" : "INACTIVE"));
+ out += getEmojiByName(
+ "TRACKS.SINGLE." + (selected === 0 ? "ACTIVE" : "INACTIVE")
+ );
} else {
for (let i = 0; i < amount; i++) {
- out += getEmojiByName("TRACKS.HORIZONTAL." +
- (i === 0 ? "LEFT" : (i === amount - 1 ? "RIGHT" : "MIDDLE")) + "." +
- (i === selected ? "ACTIVE" : "INACTIVE")
+ out += getEmojiByName(
+ "TRACKS.HORIZONTAL." +
+ (i === 0 ? "LEFT" : i === amount - 1 ? "RIGHT" : "MIDDLE") +
+ "." +
+ (i === selected ? "ACTIVE" : "INACTIVE")
);
}
}
@@ -19,4 +27,4 @@
return out;
}
-export default pageIndicator;
\ No newline at end of file
+export default pageIndicator;
diff --git a/src/utils/database.ts b/src/utils/database.ts
index cffdf04..3592c95 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -1,10 +1,9 @@
import type Discord from "discord.js";
import { Collection, MongoClient } from "mongodb";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
+// @ts-expect-error
import structuredClone from "@ungap/structured-clone";
-import config from "../config/main.json" assert {type: "json"};
-
+import config from "../config/main.json" assert { type: "json" };
const mongoClient = new MongoClient(config.mongoUrl);
await mongoClient.connect();
@@ -19,17 +18,21 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get(target: Record<string, any>, prop: string, receiver: any) {
let dataToReturn = data[prop];
- if (dataToReturn === null ) return Reflect.get(target, prop, receiver);
- if (typeof dataToReturn === "object" && !Array.isArray(dataToReturn)) dataToReturn = new Proxy(
- Reflect.get(target, prop, receiver),
- Entry(dataToReturn)
- );
+ if (dataToReturn === null)
+ return Reflect.get(target, prop, receiver);
+ if (
+ typeof dataToReturn === "object" &&
+ !Array.isArray(dataToReturn)
+ )
+ dataToReturn = new Proxy(
+ Reflect.get(target, prop, receiver),
+ Entry(dataToReturn)
+ );
return dataToReturn ?? Reflect.get(target, prop, receiver);
}
};
};
-
export class Guilds {
guilds: Collection<GuildConfig>;
defaultData: GuildConfig | null;
@@ -41,55 +44,89 @@
}
async setup() {
- this.defaultData = (await import("../config/default.json", { assert: { type: "json" }})).default as unknown as GuildConfig;
+ this.defaultData = (
+ await import("../config/default.json", { assert: { type: "json" } })
+ ).default as unknown as GuildConfig;
}
async read(guild: string) {
const entry = await this.guilds.findOne({ id: guild });
- return new Proxy(structuredClone(this.defaultData), Entry(entry)) as unknown as GuildConfig;
+ return new Proxy(
+ structuredClone(this.defaultData),
+ Entry(entry)
+ ) as unknown as GuildConfig;
}
- async write(guild: string, set: object | null, unset: string[] | string = []) {
+ async write(
+ guild: string,
+ set: object | null,
+ unset: string[] | string = []
+ ) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const uo: Record<string, any> = {};
if (!Array.isArray(unset)) unset = [unset];
for (const key of unset) {
uo[key] = null;
}
- const out = {$set: {}, $unset: {}};
- if (set) out["$set"] = set;
- if (unset.length) out["$unset"] = uo;
+ const out = { $set: {}, $unset: {} };
+ if (set) out.$set = set;
+ if (unset.length) out.$unset = uo;
await this.guilds.updateOne({ id: guild }, out, { upsert: true });
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async append(guild: string, key: string, value: any) {
if (Array.isArray(value)) {
- await this.guilds.updateOne({ id: guild }, {
- $addToSet: { [key]: { $each: value } }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $addToSet: { [key]: { $each: value } }
+ },
+ { upsert: true }
+ );
} else {
- await this.guilds.updateOne({ id: guild }, {
- $addToSet: { [key]: value }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $addToSet: { [key]: value }
+ },
+ { upsert: true }
+ );
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- async remove(guild: string, key: string, value: any, innerKey?: string | null) {
+ async remove(
+ guild: string,
+ key: string,
+ value: any,
+ innerKey?: string | null
+ ) {
console.log(Array.isArray(value));
if (innerKey) {
- await this.guilds.updateOne({ id: guild }, {
- $pull: { [key]: { [innerKey]: { $eq: value } } }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pull: { [key]: { [innerKey]: { $eq: value } } }
+ },
+ { upsert: true }
+ );
} else if (Array.isArray(value)) {
- await this.guilds.updateOne({ id: guild }, {
- $pullAll: { [key]: value }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pullAll: { [key]: value }
+ },
+ { upsert: true }
+ );
} else {
- await this.guilds.updateOne({ id: guild }, {
- $pullAll: { [key]: [value] }
- }, { upsert: true });
+ await this.guilds.updateOne(
+ { id: guild },
+ {
+ $pullAll: { [key]: [value] }
+ },
+ { upsert: true }
+ );
}
}
@@ -98,7 +135,6 @@
}
}
-
export class History {
histories: Collection<HistorySchema>;
defaultData: GuildConfig;
@@ -108,7 +144,16 @@
return this;
}
- async create(type: string, guild: string, user: Discord.User, moderator: Discord.User | null, reason: string | null, before?: null, after?: null, amount?: null) {
+ async create(
+ type: string,
+ guild: string,
+ user: Discord.User,
+ moderator: Discord.User | null,
+ reason: string | null,
+ before?: null,
+ after?: null,
+ amount?: null
+ ) {
await this.histories.insertOne({
type: type,
guild: guild,
@@ -123,14 +168,16 @@
}
async read(guild: string, user: string, year: number) {
- const entry = (await this.histories.find({
- guild: guild,
- user: user,
- occurredAt: {
- $gte: new Date(year - 1, 11, 31, 23, 59, 59),
- $lt: new Date(year + 1, 0, 1, 0, 0, 0)
- }
- }).toArray()) as HistorySchema[];
+ const entry = (await this.histories
+ .find({
+ guild: guild,
+ user: user,
+ occurredAt: {
+ $gte: new Date(year - 1, 11, 31, 23, 59, 59),
+ $lt: new Date(year + 1, 0, 1, 0, 0, 0)
+ }
+ })
+ .toArray()) as HistorySchema[];
return entry;
}
@@ -149,7 +196,11 @@
}
async create(guild: string, user: string, note: string | null) {
- await this.modNotes.updateOne({ guild: guild, user: user }, { $set: { note: note }}, { upsert: true });
+ await this.modNotes.updateOne(
+ { guild: guild, user: user },
+ { $set: { note: note } },
+ { upsert: true }
+ );
}
async read(guild: string, user: string) {
@@ -167,163 +218,165 @@
}
async hasPremium(guild: string) {
- const entry = await this.premium.findOne({ appliesTo: { $in: [guild] } });
+ const entry = await this.premium.findOne({
+ appliesTo: { $in: [guild] }
+ });
return entry !== null;
}
}
export interface GuildConfig {
- id: string,
- version: number,
+ id: string;
+ version: number;
singleEventNotifications: {
- statsChannelDeleted: boolean
- }
+ statsChannelDeleted: boolean;
+ };
filters: {
images: {
- NSFW: boolean,
- size: boolean
- },
- malware: boolean,
+ NSFW: boolean;
+ size: boolean;
+ };
+ malware: boolean;
wordFilter: {
- enabled: boolean,
+ enabled: boolean;
words: {
- strict: string[],
- loose: string[]
- },
+ strict: string[];
+ loose: string[];
+ };
allowed: {
- users: string[],
- roles: string[],
- channels: string[]
- }
- },
+ users: string[];
+ roles: string[];
+ channels: string[];
+ };
+ };
invite: {
- enabled: boolean,
- channels: string[]
- },
+ enabled: boolean;
+ channels: string[];
+ };
pings: {
- mass: number,
- everyone: boolean,
- roles: boolean,
+ mass: number;
+ everyone: boolean;
+ roles: boolean;
allowed: {
- roles: string[],
- rolesToMention: string[],
- users: string[],
- channels: string[]
- }
- }
- }
+ roles: string[];
+ rolesToMention: string[];
+ users: string[];
+ channels: string[];
+ };
+ };
+ };
welcome: {
- enabled: boolean,
+ enabled: boolean;
verificationRequired: {
- message: boolean,
- role: string | null
- },
- role: string | null,
- ping: string | null,
- channel: string | null,
- message: string | null,
- }
- stats: Record<string, {name: string, enabled: boolean}>
+ message: boolean;
+ role: string | null;
+ };
+ role: string | null;
+ ping: string | null;
+ channel: string | null;
+ message: string | null;
+ };
+ stats: Record<string, { name: string; enabled: boolean }>;
logging: {
logs: {
- enabled: boolean,
- channel: string | null,
- toLog: string | null,
- },
+ enabled: boolean;
+ channel: string | null;
+ toLog: string | null;
+ };
staff: {
- channel: string | null,
- },
+ channel: string | null;
+ };
attachments: {
- channel: string | null,
- saved: Record<string, string>
- }
- }
+ channel: string | null;
+ saved: Record<string, string>;
+ };
+ };
verify: {
- enabled: boolean,
- role: string | null,
- }
+ enabled: boolean;
+ role: string | null;
+ };
tickets: {
- enabled: boolean,
- category: string | null,
- types: string | null,
- customTypes: string[],
- useCustom: boolean,
- supportRole: string | null,
- maxTickets: number
- }
+ enabled: boolean;
+ category: string | null;
+ types: string | null;
+ customTypes: string[];
+ useCustom: boolean;
+ supportRole: string | null;
+ maxTickets: number;
+ };
moderation: {
mute: {
- timeout: boolean,
- role: string | null,
- text: string | null,
- link: string | null
- },
+ timeout: boolean;
+ role: string | null;
+ text: string | null;
+ link: string | null;
+ };
kick: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
ban: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
softban: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
warn: {
- text: string | null,
- link: string | null
- },
+ text: string | null;
+ link: string | null;
+ };
role: {
- role: string | null,
- }
- }
+ role: string | null;
+ };
+ };
tracks: {
- name: string,
- retainPrevious: boolean,
- nullable: boolean,
- track: string[],
- manageableBy: string[]
- }[]
+ name: string;
+ retainPrevious: boolean;
+ nullable: boolean;
+ track: string[];
+ manageableBy: string[];
+ }[];
roleMenu: {
- enabled: boolean,
- allowWebUI: boolean,
+ enabled: boolean;
+ allowWebUI: boolean;
options: {
- name: string,
- description: string,
- min: number,
- max: number,
+ name: string;
+ description: string;
+ min: number;
+ max: number;
options: {
- name: string,
- description: string | null,
- role: string
- }[]
- }[]
- }
- tags: Record<string, string>
+ name: string;
+ description: string | null;
+ role: string;
+ }[];
+ }[];
+ };
+ tags: Record<string, string>;
}
export interface HistorySchema {
- type: string,
- guild: string,
- user: string,
- moderator: string | null,
- reason: string,
- occurredAt: Date,
- before: string | null,
- after: string | null,
- amount: string | null
+ type: string;
+ guild: string;
+ user: string;
+ moderator: string | null;
+ reason: string;
+ occurredAt: Date;
+ before: string | null;
+ after: string | null;
+ amount: string | null;
}
export interface ModNoteSchema {
- guild: string,
- user: string,
- note: string
+ guild: string;
+ user: string;
+ note: string;
}
export interface PremiumSchema {
- user: string,
- level: number,
- expires: Date,
- appliesTo: string[]
-}
\ No newline at end of file
+ user: string;
+ level: number;
+ expires: Date;
+ appliesTo: string[];
+}
diff --git a/src/utils/defaultEmbeds.ts b/src/utils/defaultEmbeds.ts
index ce6edc1..68d8013 100644
--- a/src/utils/defaultEmbeds.ts
+++ b/src/utils/defaultEmbeds.ts
@@ -1,9 +1,9 @@
import EmojiEmbed from "./generateEmojiEmbed.js";
-export const LoadingEmbed = [new EmojiEmbed()
- .setTitle("Loading")
- .setDescription("One moment...")
- .setStatus("Danger")
- .setEmoji("NUCLEUS.LOADING")
+export const LoadingEmbed = [
+ new EmojiEmbed()
+ .setTitle("Loading")
+ .setDescription("One moment...")
+ .setStatus("Danger")
+ .setEmoji("NUCLEUS.LOADING")
];
-
diff --git a/src/utils/dualCollector.ts b/src/utils/dualCollector.ts
index 11df0ce..8c6e55c 100644
--- a/src/utils/dualCollector.ts
+++ b/src/utils/dualCollector.ts
@@ -1,18 +1,49 @@
-import Discord, { Interaction } from "discord.js";
+import Discord, {
+ Interaction,
+ Message,
+ MessageComponentInteraction
+} from "discord.js";
import client from "./client.js";
-export default async function (m, interactionFilter, messageFilter) {
+export default async function (
+ m: Message,
+ interactionFilter: (
+ i: MessageComponentInteraction
+ ) => boolean | Promise<boolean>,
+ messageFilter: (m: Message) => boolean | Promise<boolean>
+) {
let out;
try {
out = await new Promise((resolve, _reject) => {
- const mes = m.createMessageComponentCollector({filter: (m) => interactionFilter(m), time: 300000})
- .on("collect", (m) => { resolve(m); });
- const int = m.channel.createMessageCollector({filter: (m) => messageFilter(m), time: 300000})
- .then("collect", (m) => { try {m.delete();} catch (e) { client._error(e); } resolve(m); });
- mes.on("end", () => { int.stop(); });
- int.on("end", () => { mes.stop(); });
+ const mes = m
+ .createMessageComponentCollector({
+ filter: (m) => interactionFilter(m),
+ time: 300000
+ })
+ .on("collect", (m) => {
+ resolve(m);
+ });
+ const int = m.channel
+ .createMessageCollector({
+ filter: (m) => messageFilter(m),
+ time: 300000
+ })
+ .on("collect", (m) => {
+ try {
+ m.delete();
+ } catch (e) {
+ client._error(e);
+ }
+ resolve(m);
+ });
+ mes.on("end", () => {
+ int.stop();
+ });
+ int.on("end", () => {
+ mes.stop();
+ });
});
- } catch(e) {
+ } catch (e) {
console.log(e);
return null;
}
@@ -20,27 +51,43 @@
return out;
}
-export async function modalInteractionCollector(m, modalFilter, interactionFilter) {
+export async function modalInteractionCollector(
+ m: Message,
+ modalFilter: (i: Interaction) => boolean | Promise<boolean>,
+ interactionFilter: (
+ i: MessageComponentInteraction
+ ) => boolean | Promise<boolean>
+) {
let out;
try {
out = await new Promise((resolve, _reject) => {
- const int = m.createMessageComponentCollector({filter: (m: Interaction) => interactionFilter(m), time: 300000})
- .on("collect", (m: Interaction) => { resolve(m); });
- const mod = new Discord.InteractionCollector(
- client, {
- filter: (m: Interaction) => modalFilter(m),
+ const int = m
+ .createMessageComponentCollector({
+ filter: (i: MessageComponentInteraction) =>
+ interactionFilter(i),
time: 300000
})
- .on("collect", async (m: Interaction) => {
- int.stop();
- (m as Discord.ModalSubmitInteraction).deferUpdate();
- resolve((m as Discord.ModalSubmitInteraction)); });
- int.on("end", () => { mod.stop(); });
- mod.on("end", () => { int.stop(); });
+ .on("collect", (i: Interaction) => {
+ resolve(i);
+ });
+ const mod = new Discord.InteractionCollector(client, {
+ filter: (i: Interaction) => modalFilter(i),
+ time: 300000
+ }).on("collect", async (i: Interaction) => {
+ int.stop();
+ (i as Discord.ModalSubmitInteraction).deferUpdate();
+ resolve(i as Discord.ModalSubmitInteraction);
+ });
+ int.on("end", () => {
+ mod.stop();
+ });
+ mod.on("end", () => {
+ int.stop();
+ });
});
- } catch(e) {
+ } catch (e) {
console.log(e);
return null;
}
return out;
-}
\ No newline at end of file
+}
diff --git a/src/utils/eventScheduler.ts b/src/utils/eventScheduler.ts
index df46ca8..6923ede 100644
--- a/src/utils/eventScheduler.ts
+++ b/src/utils/eventScheduler.ts
@@ -2,13 +2,18 @@
import client from "./client.js";
import * as fs from "fs";
import * as path from "path";
-import config from "../config/main.json" assert {type: "json"};
+import config from "../config/main.json" assert { type: "json" };
class EventScheduler {
private agenda: Agenda;
constructor() {
- this.agenda = new Agenda({db: {address: config.mongoUrl + "Nucleus", collection: "eventScheduler"}});
+ this.agenda = new Agenda({
+ db: {
+ address: config.mongoUrl + "Nucleus",
+ collection: "eventScheduler"
+ }
+ });
this.agenda.define("unmuteRole", async (job) => {
const guild = await client.guilds.fetch(job.attrs.data.guild);
@@ -18,17 +23,31 @@
await job.remove();
});
this.agenda.define("deleteFile", async (job) => {
- fs.rm(path.resolve("dist/utils/temp", job.attrs.data.fileName), client._error);
+ fs.rm(
+ path.resolve("dist/utils/temp", job.attrs.data.fileName),
+ client._error
+ );
await job.remove();
});
this.agenda.define("naturalUnmute", async (job) => {
- const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
+ const { log, NucleusColors, entry, renderUser, renderDelta } =
+ client.logger;
const guild = await client.guilds.fetch(job.attrs.data.guild);
const user = await guild.members.fetch(job.attrs.data.user);
if (user.communicationDisabledUntil === null) return;
- try { await client.database.history.create(
- "unmute", user.guild.id, user.user, null, null, null, null
- );} catch (e) { client._error(e); }
+ try {
+ await client.database.history.create(
+ "unmute",
+ user.guild.id,
+ user.user,
+ null,
+ null,
+ null,
+ null
+ );
+ } catch (e) {
+ client._error(e);
+ }
const data = {
meta: {
type: "memberUnmute",
@@ -41,7 +60,10 @@
list: {
memberId: entry(user.user.id, `\`${user.user.id}\``),
name: entry(user.user.id, renderUser(user.user)),
- unmuted: entry(new Date().getTime(), renderDelta(new Date().getTime())),
+ unmuted: entry(
+ new Date().getTime(),
+ renderDelta(new Date().getTime())
+ ),
unmutedBy: entry(null, "*Time out ended*")
},
hidden: {
@@ -53,7 +75,7 @@
}
async start() {
- await new Promise(resolve => this.agenda.once("ready", resolve));
+ await new Promise((resolve) => this.agenda.once("ready", resolve));
this.agenda.start();
return this;
}
@@ -65,8 +87,8 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cancel(name: string, data: any) {
- this.agenda.cancel({name, data});
+ this.agenda.cancel({ name, data });
}
}
-export default EventScheduler;
\ No newline at end of file
+export default EventScheduler;
diff --git a/src/utils/generateEmojiEmbed.ts b/src/utils/generateEmojiEmbed.ts
index 65e11fa..c1de60f 100644
--- a/src/utils/generateEmojiEmbed.ts
+++ b/src/utils/generateEmojiEmbed.ts
@@ -2,9 +2,9 @@
import getEmojiByName from "./getEmojiByName.js";
const colors = {
- "Danger": 0xF27878,
- "Warning": 0xF2D478,
- "Success": 0x68D49E
+ Danger: 0xf27878,
+ Warning: 0xf2d478,
+ Success: 0x68d49e
};
class EmojiEmbed extends MessageEmbed {
@@ -12,7 +12,7 @@
_emoji: string | null = null;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
+ // @ts-expect-error
// This *is* meant to be an accessor rather than a property
override get title() {
if (!this._emoji) return this._title;
@@ -23,9 +23,18 @@
this._title = title;
}
- override setTitle(title: string) { this._title = title; return this; }
- setEmoji(emoji: string) { this._emoji = emoji; return this; }
- setStatus(color: "Danger" | "Warning" | "Success") { this.setColor(colors[color]); return this; }
+ override setTitle(title: string) {
+ this._title = title;
+ return this;
+ }
+ setEmoji(emoji: string) {
+ this._emoji = emoji;
+ return this;
+ }
+ setStatus(color: "Danger" | "Warning" | "Success") {
+ this.setColor(colors[color]);
+ return this;
+ }
}
-export default EmojiEmbed;
\ No newline at end of file
+export default EmojiEmbed;
diff --git a/src/utils/generateKeyValueList.ts b/src/utils/generateKeyValueList.ts
index a093ab7..a158391 100644
--- a/src/utils/generateKeyValueList.ts
+++ b/src/utils/generateKeyValueList.ts
@@ -1,22 +1,21 @@
-const forceCaps = [
- "ID",
- "NSFW",
- "URL"
-];
+const forceCaps = ["ID", "NSFW", "URL"];
export function capitalize(s: string) {
s = s.replace(/([A-Z])/g, " $1");
- s = s.split(" ").map(word => {
- return forceCaps.includes(word.toUpperCase()) ? word.toUpperCase() : (word[0] ?? "")
- .toUpperCase() + word.slice(1)
- .toLowerCase()
- .replace("discord", "Discord");
- }).join(" ");
+ s = s
+ .split(" ")
+ .map((word) => {
+ return forceCaps.includes(word.toUpperCase())
+ ? word.toUpperCase()
+ : (word[0] ?? "").toUpperCase() +
+ word.slice(1).toLowerCase().replace("discord", "Discord");
+ })
+ .join(" ");
return s;
}
export function toCapitals(s: string) {
- if (s[0] === undefined) return "";
+ if (s.startsWith(undefined)) return "";
return s[0].toUpperCase() + s.slice(1).toLowerCase();
}
@@ -28,4 +27,4 @@
return out;
}
-export default keyValueList;
\ No newline at end of file
+export default keyValueList;
diff --git a/src/utils/getEmojiByName.ts b/src/utils/getEmojiByName.ts
index c0a43cb..f953a4f 100644
--- a/src/utils/getEmojiByName.ts
+++ b/src/utils/getEmojiByName.ts
@@ -1,13 +1,13 @@
-import emojis from "../config/emojis.json" assert {type: "json"};
+import emojis from "../config/emojis.json" assert { type: "json" };
interface EmojisIndex {
[key: string]: string | EmojisIndex | EmojisIndex[];
}
function getEmojiByName(name: string, format?: string): string {
- const split = name.split(".");
+ const parts = name.split(".");
let id: string | EmojisIndex | EmojisIndex[] | undefined = emojis;
- split.forEach(part => {
+ for (const part of parts) {
if (typeof id === "string" || id === undefined) {
throw new Error(`Emoji ${name} not found`);
}
@@ -16,8 +16,11 @@
} else {
id = id[part];
}
- });
- if ( format === "id" ) {
+ }
+ if (typeof id !== "string" && id !== undefined) {
+ throw new Error(`Emoji ${name} not found`);
+ }
+ if (format === "id") {
if (id === undefined) return "0";
return id.toString();
}
diff --git a/src/utils/log.ts b/src/utils/log.ts
index f9f751e..6baa0a5 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -7,18 +7,17 @@
const wait = promisify(setTimeout);
-
export class Logger {
renderUser(user: Discord.User | string) {
if (typeof user === "string") return `${user} [<@${user}>]`;
return `${user.username} [<@${user.id}>]`;
}
renderTime(t: number) {
- t = Math.floor(t /= 1000);
+ t = Math.floor((t /= 1000));
return `<t:${t}:D> at <t:${t}:T>`;
}
renderDelta(t: number) {
- t = Math.floor(t /= 1000);
+ t = Math.floor((t /= 1000));
return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
}
renderNumberDelta(num1: number, num2: number) {
@@ -35,19 +34,23 @@
return `${role.name} [<@&${role.id}>]`;
}
renderEmoji(emoji: Discord.GuildEmoji) {
- return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${emoji.name}:\`]`;
+ return `<${emoji.animated ? "a" : ""}:${emoji.name}:${emoji.id}> [\`:${
+ emoji.name
+ }:\`]`;
}
public readonly NucleusColors = {
- red: 0xF27878,
- yellow: 0xF2D478,
- green: 0x68D49E
-
+ red: 0xf27878,
+ yellow: 0xf2d478,
+ green: 0x68d49e
};
- async getAuditLog(guild: Discord.Guild, event: Discord.GuildAuditLogsResolvable): Promise<Discord.GuildAuditLogsEntry[]>{
+ async getAuditLog(
+ guild: Discord.Guild,
+ event: Discord.GuildAuditLogsResolvable
+ ): Promise<Discord.GuildAuditLogsEntry[]> {
await wait(250);
- const auditLog = await guild.fetchAuditLogs({type: event});
+ const auditLog = await guild.fetchAuditLogs({ type: event });
return auditLog as unknown as Discord.GuildAuditLogsEntry[];
}
@@ -56,16 +59,23 @@
const config = await client.database.guilds.read(log.hidden.guild);
if (!config.logging.logs.enabled) return;
if (!(log.meta.calculateType === true)) {
- if(!toHexArray(config.logging.logs.toLog).includes(log.meta.calculateType)) return console.log("Not logging this type of event");
+ if (
+ !toHexArray(config.logging.logs.toLog).includes(
+ log.meta.calculateType
+ )
+ )
+ return console.log("Not logging this type of event");
}
if (config.logging.logs.channel) {
- const channel = await client.channels.fetch(config.logging.logs.channel) as Discord.TextChannel;
+ const channel = (await client.channels.fetch(
+ config.logging.logs.channel
+ )) as Discord.TextChannel | null;
const description: Record<string, string> = {};
- Object.entries(log.list).map(entry => {
+ Object.entries(log.list).map((entry) => {
const key: string = entry[0];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const value: any = entry[1];
- if(value.displayValue) {
+ if (value.displayValue) {
description[key] = value.displayValue;
} else {
description[key] = value;
@@ -74,19 +84,22 @@
if (channel) {
log.separate = log.separate || {};
const embed = new Discord.MessageEmbed()
- .setTitle(`${getEmojiByName(log.meta.emoji)} ${log.meta.displayName}`)
+ .setTitle(
+ `${getEmojiByName(log.meta.emoji)} ${
+ log.meta.displayName
+ }`
+ )
.setDescription(
(log.separate.start ? log.separate.start + "\n" : "") +
- generateKeyValueList(description) +
- (log.separate.end ? "\n" + log.separate.end : "")
+ generateKeyValueList(description) +
+ (log.separate.end ? "\n" + log.separate.end : "")
)
.setTimestamp(log.meta.timestamp)
.setColor(log.meta.color);
- channel.send({embeds: [embed]});
+ channel.send({ embeds: [embed] });
}
}
}
}
-
export default {};
diff --git a/src/utils/memory.ts b/src/utils/memory.ts
index 070bd7f..a397d09 100644
--- a/src/utils/memory.ts
+++ b/src/utils/memory.ts
@@ -1,31 +1,38 @@
import client from "./client.js";
+import type { GuildConfig } from "./database.js";
+
+interface GuildData {
+ lastUpdated: number;
+ filters: GuildConfig["filters"];
+ logging: GuildConfig["logging"];
+ tickets: GuildConfig["tickets"];
+}
class Memory {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- memory: Record<string, any>;
+ memory: Map<string, GuildData>;
constructor() {
- this.memory = {};
+ this.memory = new Map<string, GuildData>();
setInterval(() => {
- for (const guild in this.memory) {
- if (this.memory[guild].updated + 15 * 60 * 1000 < Date.now()) {
- delete this.memory[guild];
+ for (const [guild, guildData] of this.memory.entries()) {
+ if (guildData.lastUpdated + 15 * 60 * 1000 < Date.now()) {
+ this.memory.delete(guild);
}
}
}, 1000 * 60 * 30);
}
- async readGuildInfo(guild: string): Promise<object> {
- if (!this.memory[guild]) {
+ async readGuildInfo(guild: string): Promise<GuildData> {
+ if (!this.memory.has(guild)) {
const guildData = await client.database.guilds.read(guild);
- this.memory[guild] = {
+ this.memory.set(guild, {
lastUpdated: Date.now(),
filters: guildData.filters,
logging: guildData.logging,
tickets: guildData.tickets
- };
+ });
}
- return this.memory[guild];
+ return this.memory.get(guild)!;
}
}
diff --git a/src/utils/plurals.ts b/src/utils/plurals.ts
index 619ced2..9cb16a0 100644
--- a/src/utils/plurals.ts
+++ b/src/utils/plurals.ts
@@ -4,4 +4,4 @@
return `${amount} ${unit}s`;
}
-export default addPlural;
\ No newline at end of file
+export default addPlural;
diff --git a/src/utils/singleNotify.ts b/src/utils/singleNotify.ts
index 7339129..8f011e3 100644
--- a/src/utils/singleNotify.ts
+++ b/src/utils/singleNotify.ts
@@ -3,28 +3,40 @@
import { Record as ImmutableRecord } from "immutable";
const severitiesType = ImmutableRecord({
- "Critical": "Danger",
- "Warning": "Warning",
- "Info": "Success"
+ Critical: "Danger",
+ Warning: "Warning",
+ Info: "Success"
} as Record<string, "Danger" | "Warning" | "Success">);
const severities = severitiesType();
-export default async function(type: string, guild: string, message: string | true, severity: "Critical" | "Warning" | "Info" = "Info") {
+export default async function (
+ type: string,
+ guild: string,
+ message: string | true,
+ severity: "Critical" | "Warning" | "Info" = "Info"
+) {
const data = await client.database.guilds.read(guild);
if (message === true) {
- return await client.database.guilds.write(guild, {[`singleEventNotifications.${type}`]: false});
+ return await client.database.guilds.write(guild, {
+ [`singleEventNotifications.${type}`]: false
+ });
}
if (data.singleEventNotifications[type]) return;
- await client.database.guilds.write(guild, {[`singleEventNotifications.${type}`]: true});
+ await client.database.guilds.write(guild, {
+ [`singleEventNotifications.${type}`]: true
+ });
try {
const channel = await client.channels.fetch(data.logging.staff.channel);
if (!channel) return;
- await channel.send({embeds: [new EmojiEmbed()
- .setTitle(`${severity} notification`)
- .setDescription(message)
- .setStatus(severities.get(severity))
- .setEmoji("CONTROL.BLOCKCROSS")
- ]});
+ await channel.send({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle(`${severity} notification`)
+ .setDescription(message)
+ .setStatus(severities.get(severity))
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
} catch (err) {
console.error(err);
}
diff --git a/src/utils/temp/generateFileName.ts b/src/utils/temp/generateFileName.ts
index 8a219b7..956f1d7 100644
--- a/src/utils/temp/generateFileName.ts
+++ b/src/utils/temp/generateFileName.ts
@@ -2,7 +2,7 @@
import * as crypto from "crypto";
import client from "../client.js";
import * as path from "path";
-import {fileURLToPath} from "url";
+import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -12,6 +12,10 @@
if (fs.existsSync(`./${fileName}`)) {
fileName = generateFileName(ending);
}
- client.database.eventScheduler.schedule("deleteFile", new Date().getTime() + (60 * 1000), {fileName: `${fileName}.${ending}`});
+ client.database.eventScheduler.schedule(
+ "deleteFile",
+ new Date().getTime() + 60 * 1000,
+ { fileName: `${fileName}.${ending}` }
+ );
return path.join(__dirname, fileName + "." + ending);
}