chore: resolve all eslint errors
All checks were successful
Build / build (push) Successful in 1m4s

This commit is contained in:
Corban-Lee Jones 2025-05-15 21:33:57 +01:00
parent c4247bf2a6
commit 99ebb9a578
14 changed files with 146 additions and 66 deletions

View File

@ -4,22 +4,31 @@ import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default [
{
ignores: [
"./dist/**/*",
"./src/**/generated/**/*",
"./generated/**/*",
"esbuild.mjs",
"jest.config.js",
"postcss.config.js",
"tailwind.config.js",
]
},
...tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
{
files: ["./src/**/*.{ts,js}"]
}
)
ignores: [
"./dist/**/*",
"./src/**/generated/**/*",
"./generated/**/*",
"esbuild.mjs",
"jest.config.js",
"postcss.config.js",
"tailwind.config.js",
]
},
...tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
{
files: ["./src/**/*.{ts,js}"],
rules: {
"@typescript-eslint/no-unused-vars": [
"error", {
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/no-explicit-any": "off"
}
}
)
];

View File

@ -1,4 +1,4 @@
import Prisma, { PrismaClient } from "../generated/prisma";
import { PrismaClient } from "../generated/prisma";
const client = new PrismaClient();

View File

@ -167,4 +167,16 @@ describe("Match: REGEX", () => {
runFilterTest(filter, testCases);
});
describe("Match: FUZZY", () => { });
describe("Match: FUZZY", () => {
const filter: prisma.Filter = {
...templateFilter,
name: "",
value: String.raw``,
matching_algorithm: MatchingAlgorithms.REGEX,
is_insensitive: true
};
const testCases: FilterTestCase[] = [];
runFilterTest(filter, testCases);
});

View File

@ -1,7 +1,6 @@
import { Client, GatewayIntentBits } from "discord.js";
import EventHandler from "@bot/handlers/events";
import InteractionHandler from "@bot/handlers/interactions";
import { triggerTask } from "@bot/task";
export default class DiscordBot extends Client {
constructor() {

View File

@ -1,11 +1,11 @@
import { RESTPostAPIApplicationCommandsJSONBody, SlashCommandBuilder } from "discord.js";
import { RESTPostAPIApplicationCommandsJSONBody, SlashCommandBuilder, ToAPIApplicationCommandOptions } from "discord.js";
import DiscordBot from "@bot/bot";
export default class Interaction {
readonly client: DiscordBot;
name!: string;
description: string = "No description";
options: any[] = [];
options: ToAPIApplicationCommandOptions[] = [];
dmPermission!: boolean;
constructor(client: DiscordBot) {

View File

@ -1,4 +1,4 @@
import fuzz from "fuzzball"; // todo: implement for fuzzy match
import fuzz from "fuzzball";
import { Filter, MatchingAlgorithms } from "../../generated/prisma";
function splitWords(filterValue: string): string[] {
@ -60,7 +60,16 @@ export const regex = (filter: Filter, input: string) => {
};
export const fuzzy = (filter: Filter, input: string) => {
throw new Error("'fuzzy' filter not implemented");
let filterValue = filter.value.replace(/[^\w\s]/g, "");
let inputValue = input.replace(/[^\w\s]/g, "");
if (filter.is_insensitive) {
filterValue = filterValue.toLowerCase();
inputValue = inputValue.toLowerCase();
}
const ratio = fuzz.partial_ratio(filterValue, inputValue);
return ratio > 90;
};
export const mapAlgorithmToFunction = (filter: Filter, input: string) => {

View File

@ -18,7 +18,8 @@ export default class EventHandler extends Collection<string, Event> {
const modules = getAllFiles(eventsDirectory);
for (const module of modules) {
const eventClass = ((r) => r.default || r)(require(module));
const imported = await import(module);
const eventClass = imported.default || imported;
const event: Event = new eventClass(this.client);
this.set(event.name, event);

View File

@ -18,7 +18,8 @@ export default class InteractionHandler extends Collection<string, Interaction>
const modules = getAllFiles(interactionsDirectory);
for (const module of modules) {
const interactionClass = ((r) => r.default || r)(require(module))
const imported = await import(module);
const interactionClass = imported.default || imported;
const interaction: Interaction = new interactionClass(this.client);
this.set(interaction.name, interaction);
}
@ -28,7 +29,7 @@ export default class InteractionHandler extends Collection<string, Interaction>
const interactions = this.map(inter => inter.toJSON())
const rest = new REST({ version: "10" }).setToken(process.env.BOT_TOKEN!);
for (const [_, guild] of this.client.guilds.cache) {
for (const guild of this.client.guilds.cache.values()) {
rest.put(
Routes.applicationGuildCommands(process.env.CLIENT_ID!, guild.id),
{ body: interactions }

View File

@ -29,10 +29,13 @@ const processGuild = async (guild: Guild, client: Client) => {
};
const getParsedUrl = async (url: string) => {
const parser = new RssParser();
try { return parser.parseURL(url) }
catch (error) { return undefined }
try {
return new RssParser().parseURL(url)
}
catch (error) {
console.error(error);
return undefined
}
};
const processFeed = async (feed: ExpandedFeed, client: Client) => {
@ -43,11 +46,11 @@ const processFeed = async (feed: ExpandedFeed, client: Client) => {
for (const channelId of feed.channels.map(channel => channel.channel_id)) {
const channel = client.channels.cache.get(channelId);
if (channel) await processItems(parsed.items, feed, channel, client);
if (channel) await processItems(parsed.items, feed, channel);
}
};
const processItems = async (items: RssParser.Item[], feed: ExpandedFeed, channel: DiscordChannel, client: Client) => {
const processItems = async (items: RssParser.Item[], feed: ExpandedFeed, channel: DiscordChannel) => {
console.log(`Processing ${items.length} items`);
for (let i = items.length; i--;) {

View File

@ -1,22 +1,29 @@
import fs from "fs";
import { join } from "path";
/**
* Recursively gets all .ts or .js files in a directory and its subdirectories.
* @param directoryPath - The directory to start from.
* @param existingResult - Optional array to accumulate results.
* @returns A list of full paths to .ts or .js files.
*/
const getAllFiles = (directoryPath: string, existingResult?: string[]) => {
const fileNames = fs.readdirSync(directoryPath);
let result: string[] = existingResult ?? [];
const result: string[] = existingResult ?? [];
for (const fileName of fileNames) {
if (!(fileName.endsWith(".ts") || fileName.endsWith(".js"))) continue;
const fullPath = join(directoryPath, fileName);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
getAllFiles(fullPath, result);
} else if (fileName.endsWith(".ts") || fileName.endsWith(".js")) {
result.push(fullPath);
}
fs.statSync(fullPath).isDirectory()
? result = getAllFiles(fullPath, result)
: result.push(fullPath);
}
return result
return result;
};
export default getAllFiles;

View File

@ -9,7 +9,7 @@ import "datatables.net-select-dt"
import prisma from "../../../../../generated/prisma";
declare let guildId: string;
declare let channels: Array<any>;
declare let channels: Array<TextChannel>;
// #region DataTable
@ -174,7 +174,7 @@ const columnDefs: ConfigColumnDefs[] = [
orderable: false,
searchable: false,
className: "size-px whitespace-nowrap",
render: (_data: unknown, type: string, row: any) => {
render: (_data: unknown, type: string, row: ExpandedFeed) => {
if (!row.message_style || type !== "display") return null;
const wrapper = $("<div>").addClass("flex px-6 py-4");
@ -284,14 +284,23 @@ const onTableSelectChange = () => {
$(".rows-selected-count-js").text(selectedRowsCount);
const $elem = $(".rows-selected-count-js.zero-empty-js");
selectedRowsCount === 0 ? $elem.hide() : $elem.show();
if (selectedRowsCount === 0) {
$elem.hide();
return;
}
$elem.show();
};
$("#selectAllBox").on("change", function() {
const dt: Api = (table as any).dataTable;
(this as HTMLInputElement).checked
? dt.rows().select()
: dt.rows().deselect();
if ((this as HTMLInputElement).checked) {
dt.rows().select();
return;
}
dt.rows().deselect();
});
$("#deleteRowsBtn").on("click", async () => {
@ -353,9 +362,12 @@ const openEditModal = async (id: number | undefined) => {
$("#editForm").removeClass("submitted");
editModal.open();
id === undefined
? clearEditModalData()
: loadEditModalData(id);
if (id === undefined) {
clearEditModalData();
return;
}
loadEditModalData(id);
};
$(document).on("click", ".open-edit-modal-js", async event => {
@ -380,6 +392,7 @@ window.addEventListener("preline:ready", () => {
interface ExpandedFeed extends prisma.Feed {
channels: prisma.Channel[];
filters: prisma.Feed[];
message_style: prisma.MessageStyle | undefined;
}
const clearEditModalData = () => {
@ -601,7 +614,7 @@ window.addEventListener("preline:ready", () => {
styleSelect = new HSSelect(styleEl, styleSelectOptions);
// Add options to the channel select
channels.forEach((channel: TextChannel) => {
channels.forEach(channel => {
channelSelect.addOption({
title: channel.name,
val: channel.id,

View File

@ -212,16 +212,26 @@ const onTableSelectChange = () => {
$(".rows-selected-count-js").text(selectedRowsCount);
const $elem = $(".rows-selected-count-js.zero-empty-js");
selectedRowsCount === 0 ? $elem.hide() : $elem.show();
if (selectedRowsCount === 0) {
$elem.hide();
return;
}
$elem.show();
};
$("#selectAllBox").on("change", function() {
const dt: Api = (table as any).dataTable;
(this as HTMLInputElement).checked
? dt.rows().select()
: dt.rows().deselect();
if ((this as HTMLInputElement).checked) {
dt.rows().select();
return;
}
dt.rows().deselect();
});
$("#deleteRowsBtn").on("click", async () => {
const dt: Api = (table as any).dataTable;
const rowsData = dt.rows({ selected: true }).data().toArray();
@ -279,9 +289,12 @@ const openEditModal = async (id: number | undefined) => {
$("#editForm").removeClass("submitted");
editModal.open();
id === undefined
? clearEditModalData()
: loadEditModalData(id);
if (id === undefined) {
clearEditModalData();
return;
}
loadEditModalData(id);
};
$(document).on("click", ".open-edit-modal-js", async event => {

View File

@ -304,16 +304,26 @@ const onTableSelectChange = () => {
$(".rows-selected-count-js").text(selectedRowsCount);
const $elem = $(".rows-selected-count-js.zero-empty-js");
selectedRowsCount === 0 ? $elem.hide() : $elem.show();
if (selectedRowsCount === 0) {
$elem.hide();
return;
}
$elem.show();
};
$("#selectAllBox").on("change", function() {
const dt: Api = (table as any).dataTable;
(this as HTMLInputElement).checked
? dt.rows().select()
: dt.rows().deselect();
if ((this as HTMLInputElement).checked) {
dt.rows().select();
return;
}
dt.rows().deselect();
});
$("#deleteRowsBtn").on("click", async () => {
const dt: Api = (table as any).dataTable;
const rowsData = dt.rows({ selected: true }).data().toArray();
@ -373,9 +383,12 @@ const openEditModal = async (id: number | undefined) => {
$("#editForm").removeClass("submitted");
editModal.open();
id === undefined
? clearEditModalData()
: loadEditModalData(id);
if (id === undefined) {
clearEditModalData();
return;
}
loadEditModalData(id);
};
$(document).on("click", ".open-edit-modal-js", async event => {

View File

@ -7,7 +7,7 @@ export const logger = winston.createLogger({
format: combine(
timestamp({ format: timestampFormat }),
json(),
printf(({ timestamp, level, message, ...data }) => {
printf(({ _timestamp, level, message, ...data }) => {
const response = { level, message, data };
return JSON.stringify(response);
})