From f3bcee81849f8e874d29de98c17155630c29fb49 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 9 Dec 2025 00:25:53 +0100 Subject: [PATCH 01/15] feat(CI): upgrade versions --- .github/workflows/release-package.yml | 6 +++--- .github/workflows/update-dependencies.yml | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml index 3de4370..e90a357 100644 --- a/.github/workflows/release-package.yml +++ b/.github/workflows/release-package.yml @@ -6,10 +6,10 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 with: - node-version: "22.x" + node-version: "24.x" registry-url: "https://registry.npmjs.org" - name: Install pnpm diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 2950730..88bdef1 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -9,13 +9,11 @@ jobs: update-deps: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 - - uses: pnpm/action-setup@v3 + - uses: actions/checkout@v6 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v6 with: - version: 10.17.1 - - uses: actions/setup-node@v5 - with: - node-version: 22 + node-version: "24.x" - name: Update dependencies run: | pnpm install From db6aa583614d937e2616004f719362c9dbc6cb00 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:09:12 +0200 Subject: [PATCH 02/15] refactor(managers): use generic type --- src/managers/AutoCompleteManager.ts | 18 ++++++++---------- src/managers/BaseManager.ts | 8 ++++---- src/managers/ButtonManager.ts | 18 ++++++++---------- src/managers/CommandManager.ts | 18 ++++++++---------- src/managers/ContextMenuManager.ts | 18 ++++++++---------- src/managers/EventManager.ts | 24 ++++++++++-------------- src/managers/ModalManager.ts | 18 ++++++++---------- src/managers/SelectMenuManager.ts | 18 ++++++++---------- 8 files changed, 62 insertions(+), 78 deletions(-) diff --git a/src/managers/AutoCompleteManager.ts b/src/managers/AutoCompleteManager.ts index f1e71c0..b1170be 100644 --- a/src/managers/AutoCompleteManager.ts +++ b/src/managers/AutoCompleteManager.ts @@ -5,7 +5,7 @@ import { type AutoCompleteStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class AutoCompleteManager extends BaseManager { +export class AutoCompleteManager extends BaseManager { private interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class AutoCompleteManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): AutoCompleteStructure | null { - const autoComplete = (this.interactions.get(id) as AutoCompleteStructure) ?? null; - return autoComplete; + public getByCustomId(id: InteractionCustomId): AutoCompleteStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): AutoCompleteStructure | null { - let autoComplete = null; + public getByRegex(id: InteractionCustomId): AutoCompleteStructure | null { + let autoComplete: AutoCompleteStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - autoComplete = action as AutoCompleteStructure; + autoComplete = action; break; } } @@ -42,8 +41,7 @@ export class AutoCompleteManager extends BaseManager { return autoComplete; } - public getAll(): Collection { - const autoCompletes = this.interactions as Collection; - return autoCompletes; + public getAll(): Collection { + return this.interactions; } } diff --git a/src/managers/BaseManager.ts b/src/managers/BaseManager.ts index 595f161..59b3082 100644 --- a/src/managers/BaseManager.ts +++ b/src/managers/BaseManager.ts @@ -7,7 +7,7 @@ export interface ManagerOptions { directoryPath: string; } -export abstract class BaseManager { +export abstract class BaseManager { public readonly client: StelliaClient; public readonly directoryPath: string; private isLoaded = false; @@ -26,7 +26,7 @@ export abstract class BaseManager { } public abstract loadData(): Promise; - public abstract getByCustomId(id: InteractionCustomId): InteractionStructure | null; - public abstract getByRegex(id: InteractionCustomId): InteractionStructure | null; - public abstract getAll(): Collection; + public abstract getByCustomId(id: InteractionCustomId): TStructure | null; + public abstract getByRegex(id: InteractionCustomId): TStructure | null; + public abstract getAll(): Collection; } diff --git a/src/managers/ButtonManager.ts b/src/managers/ButtonManager.ts index a61a7e8..f3ca408 100644 --- a/src/managers/ButtonManager.ts +++ b/src/managers/ButtonManager.ts @@ -5,7 +5,7 @@ import { type ButtonStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class ButtonManager extends BaseManager { +export class ButtonManager extends BaseManager { public interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class ButtonManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): ButtonStructure | null { - const button = (this.interactions.get(id) as ButtonStructure) ?? null; - return button; + public getByCustomId(id: InteractionCustomId): ButtonStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): ButtonStructure | null { - let button = null; + public getByRegex(id: InteractionCustomId): ButtonStructure | null { + let button: ButtonStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - button = action as ButtonStructure; + button = action; break; } } @@ -42,8 +41,7 @@ export class ButtonManager extends BaseManager { return button; } - public getAll(): Collection { - const buttons = this.interactions as Collection; - return buttons; + public getAll(): Collection { + return this.interactions; } } diff --git a/src/managers/CommandManager.ts b/src/managers/CommandManager.ts index eaf62dd..9cf28a8 100644 --- a/src/managers/CommandManager.ts +++ b/src/managers/CommandManager.ts @@ -5,7 +5,7 @@ import { type CommandStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class CommandManager extends BaseManager { +export class CommandManager extends BaseManager { private interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class CommandManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): CommandStructure | null { - const command = (this.interactions.get(id) as CommandStructure) ?? null; - return command; + public getByCustomId(id: InteractionCustomId): CommandStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): CommandStructure | null { - let command = null; + public getByRegex(id: InteractionCustomId): CommandStructure | null { + let command: CommandStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - command = action as CommandStructure; + command = action; break; } } @@ -42,8 +41,7 @@ export class CommandManager extends BaseManager { return command; } - public getAll(): Collection { - const commands = this.interactions as Collection; - return commands; + public getAll(): Collection { + return this.interactions; } } diff --git a/src/managers/ContextMenuManager.ts b/src/managers/ContextMenuManager.ts index aae1222..29c4231 100644 --- a/src/managers/ContextMenuManager.ts +++ b/src/managers/ContextMenuManager.ts @@ -5,7 +5,7 @@ import { type ContextMenuStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class ContextMenuManager extends BaseManager { +export class ContextMenuManager extends BaseManager { private interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class ContextMenuManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): ContextMenuStructure | null { - const contextMenu = (this.interactions.get(id) as ContextMenuStructure) ?? null; - return contextMenu; + public getByCustomId(id: InteractionCustomId): ContextMenuStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): ContextMenuStructure | null { - let contextMenu = null; + public getByRegex(id: InteractionCustomId): ContextMenuStructure | null { + let contextMenu: ContextMenuStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - contextMenu = action as ContextMenuStructure; + contextMenu = action; break; } } @@ -42,8 +41,7 @@ export class ContextMenuManager extends BaseManager { return contextMenu; } - public getAll(): Collection { - const contextMenus = this.interactions as Collection; - return contextMenus; + public getAll(): Collection { + return this.interactions; } } diff --git a/src/managers/EventManager.ts b/src/managers/EventManager.ts index de410f0..b44a3ce 100644 --- a/src/managers/EventManager.ts +++ b/src/managers/EventManager.ts @@ -18,7 +18,7 @@ import { import { requiredFiles } from "@utils/index.js"; import { logger } from "@utils/logger.js"; -export class EventManager extends BaseManager { +export class EventManager extends BaseManager { private interactions: Collection = new Collection(); private guildsConfiguration: GuildsConfiguration; @@ -35,8 +35,7 @@ export class EventManager extends BaseManager { } public async loadData(): Promise { - const events = await requiredFiles(this.directoryPath); - this.interactions = events; + this.interactions = await requiredFiles(this.directoryPath); for (const eventStructure of this.interactions.values()) { if (this.client.environment?.areGuildsConfigurationEnabled) { @@ -49,16 +48,15 @@ export class EventManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): EventStructure | null { - const event = (this.interactions.get(id) as EventStructure) ?? null; - return event; + public getByCustomId(id: InteractionCustomId): EventStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): EventStructure | null { - let event = null; + public getByRegex(id: InteractionCustomId): EventStructure | null { + let event: EventStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - event = action as EventStructure; + event = action; break; } } @@ -66,9 +64,8 @@ export class EventManager extends BaseManager { return event; } - public getAll(): Collection { - const events = this.interactions as Collection; - return events; + public getAll(): Collection { + return this.interactions; } private async loadEventWithGuildConfiguration(eventStructure: EventStructure) { @@ -113,8 +110,7 @@ export class EventManager extends BaseManager { if ("guild" in mainArgument && mainArgument.guild) { return this.client.getGuildConfiguration(mainArgument.guild.id); } - if (mainArgument && typeof mainArgument === "object" && - "message" in mainArgument && mainArgument.message && + if ("message" in mainArgument && mainArgument.message && typeof mainArgument.message === "object" && "guild" in mainArgument.message && mainArgument.message.guild && "id" in mainArgument.message.guild ) { diff --git a/src/managers/ModalManager.ts b/src/managers/ModalManager.ts index b84fd28..8904971 100644 --- a/src/managers/ModalManager.ts +++ b/src/managers/ModalManager.ts @@ -5,7 +5,7 @@ import { type ModalStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class ModalManager extends BaseManager { +export class ModalManager extends BaseManager { private interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class ModalManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): ModalStructure | null { - const modal = (this.interactions.get(id) as ModalStructure) ?? null; - return modal; + public getByCustomId(id: InteractionCustomId): ModalStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): ModalStructure | null { - let modal = null; + public getByRegex(id: InteractionCustomId): ModalStructure | null { + let modal: ModalStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - modal = action as ModalStructure; + modal = action; break; } } @@ -42,8 +41,7 @@ export class ModalManager extends BaseManager { return modal; } - public getAll(): Collection { - const modals = this.interactions as Collection; - return modals; + public getAll(): Collection { + return this.interactions; } } diff --git a/src/managers/SelectMenuManager.ts b/src/managers/SelectMenuManager.ts index b0cf4b7..b258522 100644 --- a/src/managers/SelectMenuManager.ts +++ b/src/managers/SelectMenuManager.ts @@ -5,7 +5,7 @@ import { type SelectMenuStructure } from "@structures/index.js"; import { type InteractionCustomId, type StructureCustomId } from "@typescript/index.js"; import { requiredFiles } from "@utils/index.js"; -export class SelectMenuManager extends BaseManager { +export class SelectMenuManager extends BaseManager { private interactions: Collection = new Collection(); private constructor(client: StelliaClient, directoryPath: string) { @@ -25,16 +25,15 @@ export class SelectMenuManager extends BaseManager { this.setManagerLoaded(); } - public getByCustomId(id: InteractionCustomId): SelectMenuStructure | null { - const selectMenu = (this.interactions.get(id) as SelectMenuStructure) ?? null; - return selectMenu; + public getByCustomId(id: InteractionCustomId): SelectMenuStructure | null { + return this.interactions.get(id) ?? null; } - public getByRegex(id: InteractionCustomId): SelectMenuStructure | null { - let selectMenu = null; + public getByRegex(id: InteractionCustomId): SelectMenuStructure | null { + let selectMenu: SelectMenuStructure | null = null; for (const [customId, action] of this.interactions.entries()) { if (customId instanceof RegExp && customId.test(id)) { - selectMenu = action as SelectMenuStructure; + selectMenu = action; break; } } @@ -42,8 +41,7 @@ export class SelectMenuManager extends BaseManager { return selectMenu; } - public getAll(): Collection { - const selectMenus = this.interactions as Collection; - return selectMenus; + public getAll(): Collection { + return this.interactions; } } From 9619e431766ba6a42340fbfd9b05b8b786833350 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:09:38 +0200 Subject: [PATCH 03/15] refactor(date): remove deprecated TimestampStyles --- src/utils/dateFormatters.ts | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/utils/dateFormatters.ts b/src/utils/dateFormatters.ts index 69e9d3e..3b5281e 100644 --- a/src/utils/dateFormatters.ts +++ b/src/utils/dateFormatters.ts @@ -1,29 +1,39 @@ import { time, TimestampStyles } from "discord.js"; -export const formatTimestampToShortDateTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateTime); -}; - export const formatTimestampToShortTime = (timestamp: number): string => { return time(Math.round(timestamp / 1000), TimestampStyles.ShortTime); }; +export const formatTimestampToMediumTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.MediumTime); +}; + export const formatTimestampToShortDate = (timestamp: number): string => { return time(Math.round(timestamp / 1000), TimestampStyles.ShortDate); }; -export const formatTimestampToLongDateTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.LongDateTime); +export const formatTimestampToLongDate = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.LongDate); }; -export const formatTimestampToLongTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.LongTime); +export const formatTimestampToLongDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.LongDateShortTime); }; -export const formatTimestampToLongDate = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.LongDate); +export const formatTimestampToFullDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.FullDateShortTime); +}; + +export const formatTimestampToShortDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateShortTime); }; +export const formatTimestampToShortDateMediumTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateMediumTime); +}; + + export const formatTimestampToRelativeTime = (timestamp: number): string => { return time(Math.round(timestamp / 1000), TimestampStyles.RelativeTime); }; + From 7ae81b04cfc20859704517c9165a51671dac9633 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:10:37 +0200 Subject: [PATCH 04/15] bump(deps): latest Djs version + new tsconfig for TS 6 --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- tsconfig.json | 19 ++++++++++--------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index bcc4291..0bbe4bc 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "framework" ], "dependencies": { - "discord.js": "^14.26.0", + "discord.js": "^14.26.2", "i18next": "^26.0.3", "log-symbols": "^7.0.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 244624f..83d4d1c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: discord.js: - specifier: ^14.26.0 - version: 14.26.0 + specifier: ^14.26.2 + version: 14.26.2 i18next: specifier: ^26.0.3 version: 26.0.3(typescript@6.0.2) @@ -529,8 +529,8 @@ packages: discord-api-types@0.38.43: resolution: {integrity: sha512-sSoBf/nK6m7BGtw65mi+QBuvEWaHE8MMziFLqWL+gT6ME/BLg34dRSVKS3Husx40uU06bvxUc3/X+D9Y6/zAbw==} - discord.js@14.26.0: - resolution: {integrity: sha512-I+5dmdg7WnjIOEXspX6mJ4jLgblhZV6QpQcC3U2JjrFWnHCKDpoLkhV46SBP8k9QePs3YWJOvndVutUARRO0AQ==} + discord.js@14.26.2: + resolution: {integrity: sha512-feShi+gULJ6R2MAA4/KkCFnkJcuVrROJrKk4czplzq8gE1oqhqgOy9K0Scu44B8oGeWKe04egquzf+ia6VtXAw==} engines: {node: '>=18'} doctrine@2.1.0: @@ -1917,7 +1917,7 @@ snapshots: discord-api-types@0.38.43: {} - discord.js@14.26.0: + discord.js@14.26.2: dependencies: '@discordjs/builders': 1.14.1 '@discordjs/collection': 1.5.3 diff --git a/tsconfig.json b/tsconfig.json index 44e8637..4f9cfc2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,7 @@ { "compilerOptions": { - "baseUrl": "./src", "strictPropertyInitialization": false, - "target": "ES2024", + "target": "ES2025", "module": "NodeNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, @@ -11,12 +10,14 @@ "outDir": "./dist", "declaration": true, "paths": { - "@client/*": ["client/*"], - "@constants/*": ["constants/*"], - "@managers/*": ["managers/*"], - "@structures/*": ["structures/*"], - "@typescript/*": ["typescript/*"], - "@utils/*": ["utils/*"] - } + "@client/*": ["./src/client/*"], + "@constants/*": ["./src/constants/*"], + "@managers/*": ["./src/managers/*"], + "@structures/*": ["./src/structures/*"], + "@typescript/*": ["./src/typescript/*"], + "@utils/*": ["./src/utils/*"], + "*": ["./src/*"] + }, + "rootDir": "./src" } } From eb6a692fcc77e063145a949ce262537ae0e3cd23 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:10:45 +0200 Subject: [PATCH 05/15] fix: sonar --- src/typescript/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/typescript/types.ts b/src/typescript/types.ts index e3d53b3..80ef8d6 100644 --- a/src/typescript/types.ts +++ b/src/typescript/types.ts @@ -11,7 +11,7 @@ import { export type StructureCustomId = string | RegExp; -// sonarjs/no-duplicate-string: off +// NOSONAR export type InteractionCustomId = string; export enum InteractionType { From f5ebb8f2eaafbfcfc7588daba17d927cbe243165 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:11:41 +0200 Subject: [PATCH 06/15] fix(file): more generic file path --- src/utils/files.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/utils/files.ts b/src/utils/files.ts index 33a9425..b65d8da 100644 --- a/src/utils/files.ts +++ b/src/utils/files.ts @@ -1,5 +1,6 @@ import { readdirSync, statSync } from "node:fs"; import path from "node:path"; +import { pathToFileURL } from "node:url"; import { Collection } from "discord.js"; import { type AnyInteractionStructure } from "@structures/index.js"; import { type StructureCustomId } from "@typescript/index.js"; @@ -17,20 +18,20 @@ export const requiredFiles = async (filePath: string): Promise => { - const module = await import(`file://${filePath}`); - const data: InteractionStructure = module.default; + const moduleUrl = pathToFileURL(filePath).href; + const module = await import(moduleUrl); - return data; + return module.default as InteractionStructure; }; const getAllFilesPath = (dirPath: string, arrayOfFiles: string[] = []): string[] => { const files = readdirSync(dirPath); for (const file of files) { - if (statSync(dirPath + "/" + file).isDirectory()) { - arrayOfFiles = getAllFilesPath(dirPath + "/" + file, arrayOfFiles); + const fullPath = path.join(dirPath, file); + if (statSync(fullPath).isDirectory()) { + arrayOfFiles = getAllFilesPath(fullPath, arrayOfFiles); } else { - const __dirname = path.resolve(); - arrayOfFiles.push(path.join(__dirname, dirPath, "/", file)); + arrayOfFiles.push(path.resolve(fullPath)); } } From cd1326264b01d5f8043b1e1d107eb2d7e3ea1796 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Mon, 6 Apr 2026 20:14:23 +0200 Subject: [PATCH 07/15] fix(managers): remove types --- src/client/StelliaUtils.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/client/StelliaUtils.ts b/src/client/StelliaUtils.ts index c185ebf..966796c 100644 --- a/src/client/StelliaUtils.ts +++ b/src/client/StelliaUtils.ts @@ -63,8 +63,8 @@ export class StelliaUtils { } public initializeCommands = async (): Promise => { - const commands = this.client.managers.commands?.getAll().values(); - const contextMenus = this.client.managers.contextMenus?.getAll().values(); + const commands = this.client.managers.commands?.getAll().values(); + const contextMenus = this.client.managers.contextMenus?.getAll().values(); const applicationCommands = [...(commands || []), ...(contextMenus || [])].map((item) => item.data.command); if (this.client.isReady()) { @@ -126,7 +126,7 @@ export class StelliaUtils { const autoCompleteManager = this.client.managers.autoCompletes; if (!autoCompleteManager) return; - const autoComplete = autoCompleteManager.getByCustomId(autoCompleteInteraction.commandName); + const autoComplete = autoCompleteManager.getByCustomId(autoCompleteInteraction.commandName); if (!autoComplete) return; if (this.client.environment?.areGuildsConfigurationEnabled) { @@ -149,8 +149,8 @@ export class StelliaUtils { if (!buttonManager) return; const button = - buttonManager.getByCustomId(buttonInteraction.customId) || - buttonManager.getByRegex(buttonInteraction.customId); + buttonManager.getByCustomId(buttonInteraction.customId) || + buttonManager.getByRegex(buttonInteraction.customId); if (!button) return; if (button.data.reply.autoDefer && !buttonInteraction.deferred) { @@ -176,7 +176,7 @@ export class StelliaUtils { const commandManager = this.client.managers.commands; if (!commandManager) return; - const command = commandManager.getByCustomId(commandInteraction.commandName); + const command = commandManager.getByCustomId(commandInteraction.commandName); if (!command) return; if (command.data.reply.autoDefer && !commandInteraction.deferred) { @@ -218,8 +218,8 @@ export class StelliaUtils { if (!modalManager) return; const modal = - modalManager.getByCustomId(modalInteraction.customId) || - modalManager.getByRegex(modalInteraction.customId); + modalManager.getByCustomId(modalInteraction.customId) || + modalManager.getByRegex(modalInteraction.customId); if (!modal) return; if (modal.data.reply.autoDefer && !modalInteraction.deferred) { @@ -246,8 +246,8 @@ export class StelliaUtils { if (!selectMenuManager) return; const selectMenu = - selectMenuManager.getByCustomId(selectMenuInteraction.customId) || - selectMenuManager.getByRegex(selectMenuInteraction.customId); + selectMenuManager.getByCustomId(selectMenuInteraction.customId) || + selectMenuManager.getByRegex(selectMenuInteraction.customId); if (!selectMenu) return; if (selectMenu.data.reply.autoDefer && !selectMenuInteraction.deferred) { @@ -272,7 +272,7 @@ export class StelliaUtils { const contextMenuManager = this.client.managers.contextMenus; if (!contextMenuManager) return; - const messageContextMenu = contextMenuManager.getByCustomId(interaction.commandName); + const messageContextMenu = contextMenuManager.getByCustomId(interaction.commandName); if (!messageContextMenu) return; if (messageContextMenu.data.reply.autoDefer && !interaction.deferred) { @@ -297,7 +297,7 @@ export class StelliaUtils { const contextMenuManager = this.client.managers.contextMenus; if (!contextMenuManager) return; - const userContextMenu = contextMenuManager.getByCustomId(interaction.commandName); + const userContextMenu = contextMenuManager.getByCustomId(interaction.commandName); if (!userContextMenu) return; if (userContextMenu.data.reply.autoDefer && !interaction.deferred) { From d7e6ba592b48b82ec6b3dbe8c802f5760ca4b20e Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 16:41:54 +0200 Subject: [PATCH 08/15] refactor: remove unused imports --- src/client/StelliaUtils.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/client/StelliaUtils.ts b/src/client/StelliaUtils.ts index 966796c..6aa369e 100644 --- a/src/client/StelliaUtils.ts +++ b/src/client/StelliaUtils.ts @@ -16,22 +16,16 @@ import { import { type StelliaClient } from "@client/index.js"; import { DISCORD_API_VERSION } from "@constants/index.js"; import { - type AutoCompleteStructure, type AutoCompleteStructureWithGuildConfiguration, type AutoCompleteStructureWithoutGuildConfiguration, - type ButtonStructure, type ButtonStructureWithGuildConfiguration, type ButtonStructureWithoutGuildConfiguration, - type CommandStructure, type CommandStructureWithGuildConfiguration, type CommandStructureWithoutGuildConfiguration, - type ContextMenuStructure, type ContextMenuStructureWithGuildConfiguration, type ContextMenuStructureWithoutGuildConfiguration, - type ModalStructure, type ModalStructureWithGuildConfiguration, type ModalStructureWithoutGuildConfiguration, - type SelectMenuStructure, type SelectMenuStructureWithGuildConfiguration, type SelectMenuStructureWithoutGuildConfiguration } from "@structures/index.js"; @@ -111,8 +105,7 @@ export class StelliaUtils { private async initializeGuildsConfiguration(): Promise { if (this.client.environment?.areGuildsConfigurationEnabled) { try { - const guildsConfiguration = await this.client.getGuildsConfiguration(); - this.guildsConfiguration = guildsConfiguration; + this.guildsConfiguration = await this.client.getGuildsConfiguration(); logger.success("Guilds configuration loaded successfully for interactions"); } catch (error: any) { logger.errorWithInformation("Error while loading guilds configuration", error); From 4b5f39b3fec052de6e5da48c5600ce42b738812e Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 16:50:16 +0200 Subject: [PATCH 09/15] refactor(translation): improve typing --- src/utils/translation.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/utils/translation.ts b/src/utils/translation.ts index ff9d19c..2b48787 100644 --- a/src/utils/translation.ts +++ b/src/utils/translation.ts @@ -1,11 +1,9 @@ import { type Locale } from "discord.js"; import { changeLanguage, t } from "i18next"; -interface TranslateArgs { - [key: string]: any; -} +type TranslateArgs = Record; -export const translateToLocale = async (locale: Locale, key: string, args?: TranslateArgs): Promise => { +export const translateToLocale = async (locale: Locale, key: string, args?: TranslateArgs): Promise => { await changeLanguage(locale); - return t(key, { interpolation: { escapeValue: false }, returnObjects: true, ...args }); + return t(key, { interpolation: { escapeValue: false }, returnObjects: true, ...args }) as T; }; From dcd3d0d10e6ba58c5763a18f5b5eee0f95e85c7e Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:08:42 +0200 Subject: [PATCH 10/15] fix(event): ...args on guildsConfiguration --- src/managers/EventManager.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/managers/EventManager.ts b/src/managers/EventManager.ts index b44a3ce..7f3098b 100644 --- a/src/managers/EventManager.ts +++ b/src/managers/EventManager.ts @@ -88,7 +88,7 @@ export class EventManager extends BaseManager { } const eventStructure = event as EventStructureWithAllGuildsConfiguration; - return eventStructure.execute(this.client, this.guildsConfiguration); + return eventStructure.execute(this.client, this.guildsConfiguration, ...args); }; private async loadEventWithoutGuildConfiguration(eventStructure: EventStructure): Promise { @@ -124,8 +124,7 @@ export class EventManager extends BaseManager { private async initializeGuildsConfiguration(): Promise { if (this.client.environment?.areGuildsConfigurationEnabled) { try { - const guildsConfiguration = await this.client.getGuildsConfiguration(); - this.guildsConfiguration = guildsConfiguration; + this.guildsConfiguration = await this.client.getGuildsConfiguration(); logger.success("Guilds configuration loaded successfully for events"); } catch (error: any) { logger.errorWithInformation("Error while loading guilds configuration", error); From 7788a853b44ca4145101fd07ed2a218f0492592a Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:21:03 +0200 Subject: [PATCH 11/15] feat(ci): add tag workflow --- .github/workflows/tag.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/tag.yml diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 0000000..5361da0 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,26 @@ +name: Tag on version bump +on: + push: + branches: + - main + paths: + - 'package.json' + +jobs: + tag: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 2 + + - name: Check & tag new version + run: | + PREV=$(git show HEAD~1:package.json | jq -r '.version') + CURR=$(jq -r '.version' package.json) + if [ "$PREV" != "$CURR" ]; then + git tag "v$CURR" + git push origin "v$CURR" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 6fece03c728b1f489d22837efb08fa819d7d2e83 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:21:40 +0200 Subject: [PATCH 12/15] release: 1.6.0-dev-2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0bbe4bc..6b45646 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@stelliajs/framework", - "version": "1.6.0-dev-1", + "version": "1.6.0-dev-2", "main": "./dist/index.js", "types": "./dist/index.d.ts", "scripts": { From 8115d4339d4ca3773c59b4dcdd9c52b8b31e7bb9 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:32:24 +0200 Subject: [PATCH 13/15] feat(ci): add permissions write --- .github/workflows/tag.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index 5361da0..f6680be 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -9,6 +9,8 @@ on: jobs: tag: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@v6 with: From c9789d4231a787dbc0bfcea598f439694baa270b Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:32:37 +0200 Subject: [PATCH 14/15] feat(ci): add permissions write --- .github/workflows/tag.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index f6680be..dafb562 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -4,7 +4,7 @@ on: branches: - main paths: - - 'package.json' + - "package.json" jobs: tag: From 3515817bdae5cd124b2b050e36ecd022feda2407 Mon Sep 17 00:00:00 2001 From: Tweenty Date: Tue, 7 Apr 2026 17:48:28 +0200 Subject: [PATCH 15/15] refactor(ci): manually create new dev version --- .github/workflows/tag.yml | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index dafb562..178707c 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -1,10 +1,6 @@ -name: Tag on version bump +name: Tag dev version on: - push: - branches: - - main - paths: - - "package.json" + workflow_dispatch: jobs: tag: @@ -12,17 +8,12 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 2 + - uses: actions/checkout@v5 - - name: Check & tag new version + - name: Create dev tag run: | - PREV=$(git show HEAD~1:package.json | jq -r '.version') - CURR=$(jq -r '.version' package.json) - if [ "$PREV" != "$CURR" ]; then - git tag "v$CURR" - git push origin "v$CURR" - fi - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + SHA=$(git rev-parse --short HEAD) + VERSION=$(jq -r '.version' package.json) + TAG="v${VERSION}-dev-${SHA}" + git tag "$TAG" + git push origin "$TAG" \ No newline at end of file