Merge branch 'main' into development
diff --git a/src/commands/nucleus/stats.ts b/src/commands/nucleus/stats.ts
index 1cbcee8..b7594ba 100644
--- a/src/commands/nucleus/stats.ts
+++ b/src/commands/nucleus/stats.ts
@@ -189,8 +189,8 @@
return;
}
const guild = (await client.guilds.fetch(GuildID)) as Guild | null;
+ await i.deferUpdate();
if (!guild) {
- await i.deferUpdate();
await interaction.editReply({
embeds: [
new EmojiEmbed().setTitle("Admin").setDescription("Not in server").setStatus("Danger")
@@ -200,7 +200,6 @@
return;
}
if (i.customId === "stats") {
- await i.deferUpdate();
await interaction.editReply({
embeds: [
new EmojiEmbed()
@@ -238,7 +237,6 @@
components: []
});
} else if (i.customId === "data") {
- await i.deferUpdate();
// Get all the data and convert to a string
const data = await client.database.guilds.read(guild.id);
const stringified = JSON.stringify(data, null, 2);
@@ -277,7 +275,6 @@
components: []
});
} else if (i.customId === "cache") {
- await i.deferUpdate();
await client.memory.forceUpdate(guild.id);
await interaction.editReply({
embeds: [
diff --git a/src/utils/database.ts b/src/utils/database.ts
index ddee338..abb638f 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -144,12 +144,14 @@
}
async staffChannels(): Promise<string[]> {
- const entries = (await this.guilds
- .find(
- { "logging.staff.channel": { $exists: true } },
- { projection: { "logging.staff.channel": 1, _id: 0 } }
- )
- .toArray()).map((e) => e.logging.staff.channel);
+ const entries = (
+ await this.guilds
+ .find(
+ { "logging.staff.channel": { $exists: true } },
+ { projection: { "logging.staff.channel": 1, _id: 0 } }
+ )
+ .toArray()
+ ).map((e) => e.logging.staff.channel);
const out: string[] = [];
for (const entry of entries) {
if (entry) out.push(entry);
diff --git a/src/utils/getCommandDataByName.ts b/src/utils/getCommandDataByName.ts
index 46f4362..dcf45ca 100644
--- a/src/utils/getCommandDataByName.ts
+++ b/src/utils/getCommandDataByName.ts
@@ -1,22 +1,40 @@
import type Discord from "discord.js";
import client from "./client.js";
+/**
+ * @param name The name of the command, not including a leading slash. This can be space or slash separated e.g. "mod/about" or "mod about"
+ * @returns A string which when put into Discord will mention the command if the command exists or a codeblock with the command name if it does not
+ *
+ * @throws Will throw an error if as empty string is passed
+ **/
export const getCommandMentionByName = (name: string): string => {
const split = name.replaceAll("/", " ").split(" ");
- const commandName: string = split[0]!;
+ const commandName: string | undefined = split[0];
+ if (commandName === undefined) throw new RangeError(`Invalid command ${name} provided to getCommandByName`);
const filterCommand = (command: Discord.ApplicationCommand) => command.name === commandName;
const command = client.fetchedCommands.filter((c) => filterCommand(c));
- if (command.size === 0) return `\`/${name.replaceAll("/", " ")}\``;
- const commandID = command.first()!.id;
+ const commandID = command.first()?.id;
+
+ if (commandID === undefined) return `\`/${name.replaceAll("/", " ")}\``;
+
return `</${split.join(" ")}:${commandID}>`;
};
+/**
+ * @param name The name of the command, not including a leading slash. This can be space or slash separated e.g. "mod/about" or "mod about"
+ * @returns An object containing the command name, the command description and a string which when put into Discord will mention the command
+ *
+ * @throws Will throw an error if the command doesn't exist
+ * @throws Will throw an error if as empty string is passed
+ **/
export const getCommandByName = (name: string): { name: string; description: string; mention: string } => {
const split = name.replaceAll(" ", "/");
- const command = client.commands["commands/" + split]!;
- // console.log(command)
+ const command = client.commands["commands/" + split];
+
+ if (command === undefined) throw new RangeError(`Invalid command ${name} provided to getCommandByName`);
+
const mention = getCommandMentionByName(name);
return {
name: command[1].name,
diff --git a/src/utils/getEmojiByName.ts b/src/utils/getEmojiByName.ts
index ebcb257..56f1444 100644
--- a/src/utils/getEmojiByName.ts
+++ b/src/utils/getEmojiByName.ts
@@ -18,7 +18,7 @@
}
getEmojiPaths(emojis);
-function getEmojiByName(name: (typeof EMOJIPATHS)[number], format?: string): string {
+function getEmojiByName(name: typeof EMOJIPATHS[number], format?: string): string {
const parts = name.split(".");
let id: string | EmojisIndex | EmojisIndex[] | undefined = emojis;
for (const part of parts) {
diff --git a/src/utils/migration/migration.ts b/src/utils/migration/migration.ts
deleted file mode 100644
index 6286465..0000000
--- a/src/utils/migration/migration.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import * as fs from "fs";
-import client from "../client.js";
-import _ from "lodash";
-
-const dir = "./data";
-const files = fs.readdirSync(dir);
-
-for (const file of files) {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- let rsmData: any;
- try {
- rsmData = JSON.parse(fs.readFileSync(`${dir}/${file}`, "utf8"));
- } catch {
- continue;
- }
- if (!rsmData.version || rsmData.version < 3) continue;
- const nucleusData = await client.database.guilds.readOld(rsmData.guild_info.id);
- const rsmToNucleus = {
- id: rsmData.guild_info.id,
- version: 1,
- singleEventNotifications: {},
- filters: {
- images: {
- NSFW: rsmData.images?.nsfw,
- size: rsmData.images?.toosmall
- },
- malware: null,
- wordFilter: {
- enabled: true,
- words: {
- strict: rsmData.wordfilter?.strict,
- loose: rsmData.wordfilter?.soft
- },
- allowed: {
- users: rsmData.wordfilter?.ignore?.members,
- roles: rsmData.wordfilter?.ignore?.roles,
- channels: rsmData.wordfilter?.ignore?.channels
- }
- },
- invite: {
- enabled: rsmData.invite?.enabled,
- allowed: {
- channels: rsmData.invite?.whitelist?.members,
- roles: rsmData.invite?.whitelist?.roles,
- users: rsmData.invite?.whitelist?.channels
- }
- }
- },
- welcome: {
- enabled: true,
- role: rsmData.welcome?.role,
- channel: rsmData.welcome?.message?.channel,
- message: rsmData.welcome?.message?.text ?? null
- },
- logging: {
- logs: {
- enabled: true,
- channel: rsmData.log_info?.log_channel
- },
- staff: {
- channel: rsmData.log_info?.staff
- }
- },
- verify: {
- enabled: true,
- role: rsmData.verify_role
- },
- tickets: {
- enabled: true,
- category: rsmData.modmail?.cat,
- supportRole: rsmData.modmail?.mention,
- maxTickets: rsmData.modmail?.max
- },
- tags: rsmData.tags
- } as Partial<ReturnType<typeof client.database.guilds.read>>;
- // console.log(rsmToNucleus)
- const merged = _.merge(nucleusData, rsmToNucleus);
- // console.log(merged)
- await client.database.guilds.write(merged.id!, merged);
-}
diff --git a/src/utils/types/recursivePartial.d.ts b/src/utils/types/recursivePartial.d.ts
new file mode 100644
index 0000000..a578bb4
--- /dev/null
+++ b/src/utils/types/recursivePartial.d.ts
@@ -0,0 +1,7 @@
+type RecursivePartial<T> = {
+ [P in keyof T]?: T[P] extends (infer U)[]
+ ? RecursivePartial<U>[]
+ : T[P] extends object
+ ? RecursivePartial<T[P]>
+ : T[P];
+};