diff --git a/oxlint.config.ts b/oxlint.config.ts index 7d5c909..3dab7b8 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -11,6 +11,14 @@ export default defineConfig({ 'prefer-template': 'warn', 'typescript/no-explicit-any': 'error', 'prefer-const': 'error', + 'id-length': [ + 'error', + { + min: 2, + checkGeneric: false, + exceptions: ['_', 'i', 'j', 'x', 'y', 'z'], + }, + ], }, ignorePatterns: ['node_modules', 'dist', 'build', 'coverage', '.git'], }); diff --git a/src/env.ts b/src/env.ts index ba2d53b..9edf730 100644 --- a/src/env.ts +++ b/src/env.ts @@ -1,3 +1,4 @@ +// oxlint-disable id-length import '@/loadEnvFile.js'; function optionalEnv(key: string): string | undefined { diff --git a/src/features/showcase/edit-showcase.ts b/src/features/showcase/edit-showcase.ts index f053049..a9f0bf8 100644 --- a/src/features/showcase/edit-showcase.ts +++ b/src/features/showcase/edit-showcase.ts @@ -223,8 +223,8 @@ const modalHandler: ModalSubmitInteraction = { if (prevTagIds.length !== newProjectTags.length) { return false; } - const s = new Set(prevTagIds); - return newProjectTags.every((t) => s.has(t)); + const previousTagIdsSet = new Set(prevTagIds); + return newProjectTags.every((tag) => previousTagIdsSet.has(tag)); }; if (!tagsEqual()) { changes.push({ diff --git a/src/features/showcase/util.ts b/src/features/showcase/util.ts index 1d7daf6..69ef530 100644 --- a/src/features/showcase/util.ts +++ b/src/features/showcase/util.ts @@ -160,7 +160,9 @@ export const resolveTagNames = ( tagIds: readonly string[], availableTags: GuildForumTag[] ): string[] => { - return tagIds.map((id) => availableTags.find((t) => t.id === id)?.name ?? id); + return tagIds.map( + (id) => availableTags.find((tag) => tag.id === id)?.name ?? id + ); }; export const getShowcaseLogChannel = (guild: Guild | null) => { diff --git a/src/features/tags/create-tag.ts b/src/features/tags/create-tag.ts index 8cb9f69..c6e3711 100644 --- a/src/features/tags/create-tag.ts +++ b/src/features/tags/create-tag.ts @@ -129,7 +129,7 @@ const submissionHandler: ModalSubmitInteraction = { await interaction.reply({ components: [ ErrorMessages.Tags.TagAlreadyExists( - existingTags.map((t) => t.name).join(', ') + existingTags.map((tag) => tag.name).join(', ') ), ], flags: MessageFlags.Ephemeral | MessageFlags.IsComponentsV2, diff --git a/src/features/tags/edit-tag.ts b/src/features/tags/edit-tag.ts index 1c20835..4450d97 100644 --- a/src/features/tags/edit-tag.ts +++ b/src/features/tags/edit-tag.ts @@ -63,7 +63,7 @@ export const editTagCommandHandler = async ( .setCustomId('aliases') .setStyle(TextInputStyle.Short) .setRequired(true) - .setValue(tag.aliases.map((a) => a.name).join(', ')) + .setValue(tag.aliases.map((alias) => alias.name).join(', ')) ), new LabelBuilder() .setLabel('Short Description') @@ -142,7 +142,7 @@ const modalHandler: ModalSubmitInteraction = { await interaction.reply({ components: [ ErrorMessages.Tags.TagAlreadyExists( - existingTags.map((t) => t.name).join(', ') + existingTags.map((tag) => tag.name).join(', ') ), ], flags: MessageFlags.Ephemeral | MessageFlags.IsComponentsV2, diff --git a/src/util/advent-scheduler.test.ts b/src/util/advent-scheduler.test.ts index 1ef0166..dcd4391 100644 --- a/src/util/advent-scheduler.test.ts +++ b/src/util/advent-scheduler.test.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import { promises as fs } from 'node:fs'; -import test from 'node:test'; +import test, { it } from 'node:test'; import { config } from '@/env.js'; const { loadTracker, saveTracker } = await import('./advent-scheduler.js'); @@ -13,17 +13,14 @@ async function cleanupTestTracker() { } } -void test('advent scheduler: tracker file operations', async (t) => { - await t.test( - 'should create empty tracker if file does not exist', - async () => { - await cleanupTestTracker(); - const tracker = await loadTracker(); - assert.deepEqual(tracker, {}); - } - ); +void test('advent scheduler: tracker file operations', async () => { + await it('should create empty tracker if file does not exist', async () => { + await cleanupTestTracker(); + const tracker = await loadTracker(); + assert.deepEqual(tracker, {}); + }); - await t.test('should save and load tracker data correctly', async () => { + await it('should save and load tracker data correctly', async () => { const testData = { '2025': [1, 2, 3], '2026': [1], @@ -33,7 +30,7 @@ void test('advent scheduler: tracker file operations', async (t) => { assert.deepEqual(loaded, testData); }); - await t.test('should track multiple days per year', async () => { + await it('should track multiple days per year', async () => { const tracker = { '2025': [1, 5, 10, 15, 20, 25], }; diff --git a/src/util/advent-scheduler.ts b/src/util/advent-scheduler.ts index bbbbd82..aa942ad 100644 --- a/src/util/advent-scheduler.ts +++ b/src/util/advent-scheduler.ts @@ -39,7 +39,7 @@ async function markDayAsPosted(year: number, day: number): Promise { if (!tracker[yearKey].includes(day)) { tracker[yearKey].push(day); - tracker[yearKey].sort((a, b) => a - b); + tracker[yearKey].sort((firstDay, secondDay) => firstDay - secondDay); await saveTracker(tracker); } } diff --git a/src/util/fuzzy-search.ts b/src/util/fuzzy-search.ts index 4f3e20b..fe12df0 100644 --- a/src/util/fuzzy-search.ts +++ b/src/util/fuzzy-search.ts @@ -1,18 +1,18 @@ -export const levenshtein = (a: string, b: string) => { - const dp = Array.from({ length: a.length + 1 }, () => - Array(b.length + 1).fill(0) +export const levenshtein = (originalString: string, targetString: string) => { + const dp = Array.from({ length: originalString.length + 1 }, () => + Array(targetString.length + 1).fill(0) ); - for (let i = 0; i <= a.length; i++) { + for (let i = 0; i <= originalString.length; i++) { dp[i][0] = i; } - for (let j = 0; j <= b.length; j++) { + for (let j = 0; j <= targetString.length; j++) { dp[0][j] = j; } - for (let i = 1; i <= a.length; i++) { - for (let j = 1; j <= b.length; j++) { - const cost = a[i - 1] === b[j - 1] ? 0 : 1; + for (let i = 1; i <= originalString.length; i++) { + for (let j = 1; j <= targetString.length; j++) { + const cost = originalString[i - 1] === targetString[j - 1] ? 0 : 1; dp[i][j] = Math.min( dp[i - 1][j] + 1, // deletion dp[i][j - 1] + 1, // insertion @@ -21,7 +21,7 @@ export const levenshtein = (a: string, b: string) => { } } - return dp[a.length][b.length]; + return dp[originalString.length][targetString.length]; }; const bestSubstringDistance = (query: string, text: string): number => { @@ -71,7 +71,7 @@ export function fuzzySearch({ query = query.trim().toLowerCase(); const queryLen = query.length; - const scored = items.map((item) => { + const scoringArray = items.map((item) => { let maxFuzzyScore = 0; let titleMatchScore = 0; @@ -110,11 +110,11 @@ export function fuzzySearch({ }); return ( - scored + scoringArray // Filter by the original fuzzy score threshold (optional, you could use a lower threshold) - .filter((s) => s.score >= threshold) - .sort((a, b) => b.score - a.score) + .filter((result) => result.score >= threshold) + .sort((first, second) => second.score - first.score) .slice(0, limit) - .map((s) => s.item) + .map((result) => result.item) ); }