From 79a3c50a19cea1ae7df95d778c87a129dbfb7316 Mon Sep 17 00:00:00 2001 From: Okami Date: Mon, 4 Mar 2024 17:19:20 -0600 Subject: [PATCH] Tests & Linting fixes (#20) --- .eslintrc.json | 51 ++++----------- .github/workflows/lint.yml | 49 +++++++++++++++ .github/workflows/npm-publish.yml | 48 +++++++------- __tests__/Client.test.ts | 25 +++++++- .../commands/chat/builders/ping.ts | 8 +-- .../commands/chat/execution/ping.ts | 2 +- .../commands/chat/execution/ping.ts | 2 +- .../valid/commands/chat/builders/ping.ts | 6 +- .../valid/commands/chat/execution/ping.ts | 2 +- __tests__/valid/events/ready.ts | 4 +- jest.config.ts | 26 ++++---- package.json | 11 ++-- .../{BaseComand.ts => BaseCommand.ts} | 10 ++- src/Classes/Commands/ChatInputCommand.ts | 7 +-- src/Classes/Commands/ContextMenuCommand.ts | 8 +-- src/Classes/Commands/index.ts | 3 +- src/Classes/Commands/interfaces.ts | 37 ++++++----- src/Classes/Commands/types.ts | 5 +- src/Classes/ExtendedClient.ts | 62 +++++++++++++------ src/Classes/Handlers/CommandHandler.ts | 5 +- src/Classes/HelpInfo/BaseHelper.ts | 7 +-- src/Classes/HelpInfo/ChatInputHelper.ts | 6 +- src/Classes/HelpInfo/SubcommandHelper.ts | 6 +- src/Classes/Interaction.ts | 2 +- src/Classes/index.ts | 1 - src/events/interactionCreate.ts | 4 +- src/{types => typings}/index.d.ts | 2 +- src/util/types.ts | 1 - tsconfig.json | 20 +++--- yarn.lock | 13 ++-- 30 files changed, 231 insertions(+), 202 deletions(-) create mode 100644 .github/workflows/lint.yml rename src/Classes/Commands/{BaseComand.ts => BaseCommand.ts} (92%) rename src/{types => typings}/index.d.ts (99%) diff --git a/.eslintrc.json b/.eslintrc.json index 873b119..2aaf3d3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,22 +4,14 @@ "es2020": true, "browser": true }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "airbnb-base", - "prettier" - ], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "airbnb-base"], "ignorePatterns": ["**/dist/*"], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 8, "requireConfigFile": false }, - "plugins": [ - "@typescript-eslint", - "@stylistic/eslint-plugin" - ], + "plugins": ["@typescript-eslint", "@stylistic/eslint-plugin"], "root": true, "rules": { "@typescript-eslint/no-non-null-assertion": "off", @@ -38,23 +30,12 @@ } ], "block-spacing": "error", - "brace-style": [ - "error", - "stroustrup" - ], + "brace-style": ["error", "stroustrup"], "class-methods-use-this": 0, - "comma-dangle": [ - "error", - "never" - ], - "curly": [ - "error", - "multi-line" - ], + "comma-dangle": ["error", "never"], + "curly": ["error", "multi-line"], "global-require": "off", - "indent": [ - "error", "tab" - ], + "indent": ["error", "tab"], "import/extensions": "off", "import/prefer-default-export": "off", "import/no-dynamic-require": "off", @@ -74,10 +55,7 @@ "mode": "strict" } ], - "linebreak-style": [ - "error", - "unix" - ], + "linebreak-style": ["error", "unix"], "max-classes-per-file": "off", "max-len": [ "error", @@ -110,10 +88,11 @@ "prev": "*", "next": "function" }, - { + { "blankLine": "always", "prev": "*", - "next": "export" } + "next": "export" + } ], "object-curly-newline": [ "error", @@ -135,14 +114,8 @@ } } ], - "object-curly-spacing": [ - "error", - "always" - ], - "semi": [ - "error", - "always" - ], + "object-curly-spacing": ["error", "always"], + "semi": ["error", "always"], "space-before-function-paren": [ "error", { diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d90c0c8 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,49 @@ +name: Lint + +on: + pull_request: + branches: [main] + push: + branches: [main] + +jobs: + linting: + name: Linting + runs-on: ubuntu-latest + + strategy: + matrix: + NODE_VERSION: [20.x] + + steps: + - name: Install NodeJS + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.NODE_VERSION }} + + - name: Code Checkout + uses: actions/checkout@v3 + + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - name: Cache Node.js modules + id: yarn-cache + uses: actions/cache@v3 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install Dependencies + run: yarn install --frozen-lockfile --silent + env: + CI: true + + - name: Build the project + run: yarn build + + - name: Lint the project with Yarn + run: yarn lint diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 7c2a809..bfe6baa 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,30 +1,30 @@ name: Node.js Package on: - release: - types: [created] + release: + types: [created] jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 20 - - run: yarn install --frozen-lockfile - - run: yarn test + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + - run: yarn install --frozen-lockfile + - run: yarn test - publish-npm: - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 20 - registry-url: https://registry.npmjs.org/ - - run: yarn install --frozen-lockfile - - run: yarn publish - env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + publish-npm: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 20 + registry-url: https://registry.npmjs.org/ + - run: yarn install --frozen-lockfile + - run: yarn publish + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/__tests__/Client.test.ts b/__tests__/Client.test.ts index 148a80e..1cdfc98 100644 --- a/__tests__/Client.test.ts +++ b/__tests__/Client.test.ts @@ -1,8 +1,7 @@ import { - describe, - expect, - it + describe, expect, it } from '@jest/globals'; +import { readdir } from 'fs/promises'; import { join } from 'path'; import { ExtendedClient as Client } from '../src/Classes/ExtendedClient'; @@ -65,6 +64,26 @@ describe('Client', () => { await expect(init()).resolves.not.toThrow(); }); + it('Should load with the correct number of events', async () => { + let client: Client | null = null; + const eventPath = join(__dirname, 'valid', 'events'); + + const init = async () => { + client = new Client({ intents: [] }); + await client.init({ + commandPath: join(__dirname, 'valid', 'commands'), + eventPath + }); + }; + + await expect(init()).resolves.not.toThrow(); + + const eventFiles = await readdir(eventPath); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((client as any)!._eventHandler.size).toBe(eventFiles.length + 1); // "interactionCreate" event is always added + }); + it('Should throw if command builder doesn\'t come with an execute handler', async () => { const init = async () => { const client = new Client({ intents: [] }); diff --git a/__tests__/invalid-command/commands/chat/builders/ping.ts b/__tests__/invalid-command/commands/chat/builders/ping.ts index e621a9b..61ad711 100644 --- a/__tests__/invalid-command/commands/chat/builders/ping.ts +++ b/__tests__/invalid-command/commands/chat/builders/ping.ts @@ -2,10 +2,4 @@ import { ChatInputCommand } from '../../../../../src'; export const ns = 'sme'; -export default new ChatInputCommand() - .setBuilder((builder) => - builder - .setName('ping') - .setDescription('Ping Pong Command') - ) - .setGlobal(true); +export default new ChatInputCommand().setBuilder((builder) => builder.setName('ping').setDescription('Ping Pong Command')).setGlobal(true); diff --git a/__tests__/invalid-command/commands/chat/execution/ping.ts b/__tests__/invalid-command/commands/chat/execution/ping.ts index 4bf2802..64afa00 100644 --- a/__tests__/invalid-command/commands/chat/execution/ping.ts +++ b/__tests__/invalid-command/commands/chat/execution/ping.ts @@ -1,5 +1,5 @@ import { ChatInputCommandInteraction } from 'discord.js'; export default async function ping(interaction: ChatInputCommandInteraction) { - return interaction.reply('Pong!') + return interaction.reply('Pong!'); } diff --git a/__tests__/invalid-event/commands/chat/execution/ping.ts b/__tests__/invalid-event/commands/chat/execution/ping.ts index 4bf2802..64afa00 100644 --- a/__tests__/invalid-event/commands/chat/execution/ping.ts +++ b/__tests__/invalid-event/commands/chat/execution/ping.ts @@ -1,5 +1,5 @@ import { ChatInputCommandInteraction } from 'discord.js'; export default async function ping(interaction: ChatInputCommandInteraction) { - return interaction.reply('Pong!') + return interaction.reply('Pong!'); } diff --git a/__tests__/valid/commands/chat/builders/ping.ts b/__tests__/valid/commands/chat/builders/ping.ts index eaacb56..fd57b42 100644 --- a/__tests__/valid/commands/chat/builders/ping.ts +++ b/__tests__/valid/commands/chat/builders/ping.ts @@ -4,10 +4,6 @@ import handler from '../execution/ping'; export const ns = 'sme'; export default new ChatInputCommand() - .setBuilder((builder) => - builder - .setName('ping') - .setDescription('Ping Pong Command') - ) + .setBuilder((builder) => builder.setName('ping').setDescription('Ping Pong Command')) .setGlobal(true) .setExecute(handler); diff --git a/__tests__/valid/commands/chat/execution/ping.ts b/__tests__/valid/commands/chat/execution/ping.ts index 4bf2802..64afa00 100644 --- a/__tests__/valid/commands/chat/execution/ping.ts +++ b/__tests__/valid/commands/chat/execution/ping.ts @@ -1,5 +1,5 @@ import { ChatInputCommandInteraction } from 'discord.js'; export default async function ping(interaction: ChatInputCommandInteraction) { - return interaction.reply('Pong!') + return interaction.reply('Pong!'); } diff --git a/__tests__/valid/events/ready.ts b/__tests__/valid/events/ready.ts index 7ef9c5d..dea8608 100644 --- a/__tests__/valid/events/ready.ts +++ b/__tests__/valid/events/ready.ts @@ -1,7 +1,7 @@ import { Events } from 'discord.js'; -import { Client, Event } from '../../../src'; +import { Event } from '../../../src'; -async function onReady(client: Client) { +async function onReady() { // Noop } diff --git a/jest.config.ts b/jest.config.ts index 70c87bf..50c669b 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -51,9 +51,7 @@ export default { // errorOnDeprecated: false, // The default configuration for fake timers - // fakeTimers: { - // "enableGlobally": false - // }, + fakeTimers: { enableGlobally: true }, // Force coverage collection from ignored files using an array of glob patterns // forceCoverageMatch: [], @@ -88,9 +86,7 @@ export default { // ], // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - moduleNameMapper: { - '^@/(.*)$': '/src/$1' - }, + moduleNameMapper: { '^@/(.*)$': '/src/$1' }, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader // modulePathIgnorePatterns: [], @@ -155,13 +151,10 @@ export default { // testLocationInResults: false, // The glob patterns Jest uses to detect test files - testMatch: ["**/*.test.ts"], + testMatch: ['**/*.test.ts'], // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - testPathIgnorePatterns: [ - '/node_modules/', - '/dist/' - ], + testPathIgnorePatterns: ['/node_modules/', '/dist/'], // The regexp pattern or array of patterns that Jest uses to detect test files // testRegex: [], @@ -174,10 +167,13 @@ export default { // A map from regular expressions to paths to transformers transform: { - '^.+\\.ts?$': ['ts-jest', { - isolatedModules: true, - tsconfig: 'tsconfig.json' - }] + '^.+\\.ts?$': [ + 'ts-jest', + { + isolatedModules: true, + tsconfig: 'tsconfig.json' + } + ] }, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation diff --git a/package.json b/package.json index 09127da..e757e47 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "@progressive-victory/client", - "version": "0.3.3", + "version": "0.3.4", "description": "Modified Discord.js client for discord bots", "main": "dist/index.js", - "types": "dist/index.d.ts", + "types": "typings/index.d.ts", "files": [ "dist" ], @@ -15,8 +15,8 @@ "license": "MIT", "private": false, "scripts": { - "lint": "prettier --check . && eslint . --ext .ts", - "format": "prettier --write . && eslint --fix --format=pretty src __tests__", + "lint": "eslint . --ext .ts", + "format": "prettier --write . && eslint --fix src __tests__", "build": "swc ./src --out-dir dist && tsc --emitDeclarationOnly", "start": "node ./dist/index.js", "prepublish": "yarn build", @@ -39,10 +39,9 @@ "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.56.0", "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "jest": "^29.7.0", - "prettier": "^3.2.4", + "prettier": "^3.2.5", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "typescript": "^5.3.3" diff --git a/src/Classes/Commands/BaseComand.ts b/src/Classes/Commands/BaseCommand.ts similarity index 92% rename from src/Classes/Commands/BaseComand.ts rename to src/Classes/Commands/BaseCommand.ts index 055ee0e..bfa73f4 100644 --- a/src/Classes/Commands/BaseComand.ts +++ b/src/Classes/Commands/BaseCommand.ts @@ -1,7 +1,5 @@ import { - ChatInputCommandInteraction, - ContextMenuCommandBuilder, - ContextMenuCommandInteraction + ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction } from 'discord.js'; import { ChatInputCommandBuilders, ReturnableInteraction } from './types'; @@ -47,7 +45,7 @@ export class Command< /** * Set the isGlobal Value - * @param isGlobal boolean vaule to be set + * @param isGlobal boolean value to be set * @returns The modified object */ setGlobal(isGlobal: boolean): this { @@ -70,8 +68,8 @@ export class Command< } /** - * - * @param options + * + * @param options */ constructor(options: Partial> = {}) { if (options.isGlobal) this.isGlobal = options.isGlobal; diff --git a/src/Classes/Commands/ChatInputCommand.ts b/src/Classes/Commands/ChatInputCommand.ts index 1b141bc..380bc68 100644 --- a/src/Classes/Commands/ChatInputCommand.ts +++ b/src/Classes/Commands/ChatInputCommand.ts @@ -1,10 +1,8 @@ import { - AutocompleteInteraction, - ChatInputCommandInteraction, - SlashCommandBuilder + AutocompleteInteraction, ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; import { ChatInputHelper } from '../HelpInfo/ChatInputHelper'; -import { Command } from './BaseComand'; +import { Command } from './BaseCommand'; import { Command as ICommand } from './interfaces'; import { ChatInputCommandBuilders } from './types'; @@ -12,7 +10,6 @@ import { ChatInputCommandBuilders } from './types'; * Slash command */ export class ChatInputCommand extends Command implements ICommand { - // Help Info data structure private _helpInfo: ChatInputHelper; diff --git a/src/Classes/Commands/ContextMenuCommand.ts b/src/Classes/Commands/ContextMenuCommand.ts index d00309e..d563727 100644 --- a/src/Classes/Commands/ContextMenuCommand.ts +++ b/src/Classes/Commands/ContextMenuCommand.ts @@ -1,10 +1,9 @@ import { ContextMenuCommandBuilder, ContextMenuCommandInteraction } from 'discord.js'; import { BaseHelper } from '../HelpInfo/BaseHelper'; -import { Command } from './BaseComand'; +import { Command } from './BaseCommand'; import { Command as ICommand } from './interfaces'; export class ContextMenuCommand extends Command implements ICommand { - private _helpInfo: BaseHelper; get helpInfo() { @@ -20,9 +19,7 @@ export class ContextMenuCommand extends Command ContextMenuCommandBuilder) - ): this { + setBuilder(input: ContextMenuCommandBuilder | ((subcommandBuilder: ContextMenuCommandBuilder) => ContextMenuCommandBuilder)): this { if (typeof input === 'function') { this._builder = input(new ContextMenuCommandBuilder()); } @@ -41,5 +38,4 @@ export class ContextMenuCommand extends Command Promise | ReturnableInteraction; - execute: (interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) => Promise | ReturnableInteraction - - helpInfo: BaseHelper | ChatInputHelper + helpInfo: BaseHelper | ChatInputHelper; /** * Set the isGlobal Value * @param isGlobal boolean vaule to be set * @returns The modified object */ - setGlobal(isGlobal: boolean): this + setGlobal(isGlobal: boolean): this; /** * Set the command builder method * @param input The command Builder or a callback function * @returns The modified object */ - setBuilder(input: SlashCommandBuilder | ContextMenuCommandBuilder - | ((subcommandBuilder: SlashCommandBuilder) => ChatInputCommandBuilders) - | ((subcommandBuilder: ContextMenuCommandBuilder) => ContextMenuCommandBuilder)): this - - setExecute(execute: (interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) => - Promise | ReturnableInteraction): this + setBuilder( + input: + | SlashCommandBuilder + | ContextMenuCommandBuilder + | ((subcommandBuilder: SlashCommandBuilder) => ChatInputCommandBuilders) + | ((subcommandBuilder: ContextMenuCommandBuilder) => ContextMenuCommandBuilder) + ): this; + + setExecute( + execute: (interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction) => Promise | ReturnableInteraction + ): this; /** * Set Help Info * @param input help info object * @returns The updated object */ - setHelpInfo(input: ChatInputHelper - | BaseHelper - | ((helpInfo: ChatInputHelper) => ChatInputHelper) - | ((helpInfo: BaseHelper) => BaseHelper) - ): this + setHelpInfo(input: ChatInputHelper | BaseHelper | ((helpInfo: ChatInputHelper) => ChatInputHelper) | ((helpInfo: BaseHelper) => BaseHelper)): this; } diff --git a/src/Classes/Commands/types.ts b/src/Classes/Commands/types.ts index 7abd4a0..0d0de12 100644 --- a/src/Classes/Commands/types.ts +++ b/src/Classes/Commands/types.ts @@ -2,12 +2,13 @@ import { ChatInputCommandInteraction, CommandInteraction, ContextMenuCommandBuilder, - ContextMenuCommandInteraction, InteractionResponse, + ContextMenuCommandInteraction, + InteractionResponse, Message, SharedSlashCommandOptions, SlashCommandBuilder } from 'discord.js'; -import { Command } from './BaseComand'; +import { Command } from './BaseCommand'; /** * Possible command return types diff --git a/src/Classes/ExtendedClient.ts b/src/Classes/ExtendedClient.ts index e1950b3..dee6717 100644 --- a/src/Classes/ExtendedClient.ts +++ b/src/Classes/ExtendedClient.ts @@ -20,7 +20,6 @@ import { InteractionHandler } from './Handlers/InteractionHandler'; * @see {@link https://discord.js.org/#/docs/main/stable/class/Client} */ export class ExtendedClient extends Client { - private _eventHandler = new EventHandler(this); private _commandHandler = new CommandHandler(this); @@ -60,7 +59,7 @@ export class ExtendedClient extends Client { } get commandHandler() { - return this._commandHandler as Omit; + return this._commandHandler as Omit; } get interactionHandler() { @@ -79,13 +78,7 @@ export class ExtendedClient extends Client { // Paths const { - receiveMessageComponents, - receiveModals, - receiveAutocomplete, - replyOnError, - splitCustomID, - splitCustomIDOn, - useGuildCommands + receiveMessageComponents, receiveModals, receiveAutocomplete, replyOnError, splitCustomID, splitCustomIDOn, useGuildCommands } = options; // Misc configuration @@ -96,7 +89,7 @@ export class ExtendedClient extends Client { this.splitCustomID = splitCustomID === undefined ? false : splitCustomID; this.useGuildCommands = useGuildCommands === undefined ? false : useGuildCommands; this.splitCustomIDOn = splitCustomIDOn || '_'; - + // Add interaction event listener for built in interaction handler this._eventHandler.add(interactionCreate); } @@ -109,9 +102,8 @@ export class ExtendedClient extends Client { public async init(options: initOptions) { this.emit('debug', 'Client initializing...'); - // load in dependate event, command and interaction files + // load in dependant event, command and interaction files await Promise.all([ - this.loadEvents(options.eventPath), this.loadCommands(options.commandPath), this.loadContextMenus(options.contextMenuPath), this.loadButtons(options.buttonPath), @@ -119,6 +111,8 @@ export class ExtendedClient extends Client { this.loadModals(options.modalPath) ]); + await this.loadEvents(options.eventPath); + // update private init flag this._hasInitRun = true; @@ -215,9 +209,8 @@ export class ExtendedClient extends Client { const resp: { default: Type } = await import(join(dirPath, file.name)); // Get name of file - const name = - ('builder' in resp.default !== undefined && (resp.default as TypeCommand).builder?.name) || - (resp.default as Interaction)?.name; + const name = ('builder' in resp.default && resp.default.builder?.name) + || (resp.default as Interaction)?.name; if (!name) { throw new Error(`[ERROR] ${file.name} is missing a name`); @@ -231,7 +224,7 @@ export class ExtendedClient extends Client { for (const dir of dirents.filter((dirent) => dirent.isDirectory())) { // Get the complete filepath const directoryPath = join(dirPath, dir.name); - // Get subfolder contects + // Get subfolder contents const dirFiles = await readdir(directoryPath); // For Each file in the Array of Directory entities where the file ends in ts or js based on the environment @@ -240,8 +233,7 @@ export class ExtendedClient extends Client { const resp: { default: Type } = await import(join(directoryPath, file)); // Get name of file - const name = - 'builder' in resp.default !== undefined ? (resp.default as TypeCommand).builder.name : (resp.default as Interaction).name; + const name = 'builder' in resp.default ? resp.default.builder.name : resp.default.name; // Add object to the collection collection.set(name, resp.default); @@ -271,3 +263,37 @@ export class ExtendedClient extends Client { return error instanceof Error; } } + +declare module 'discord.js' { + interface BaseInteraction { + client: ExtendedClient; + } + + interface Component { + client: ExtendedClient; + } + + interface Message { + client: ExtendedClient; + } + + interface BaseChannel { + client: ExtendedClient; + } + + interface Role { + client: ExtendedClient; + } + + interface Guild { + client: ExtendedClient; + } + + interface User { + client: ExtendedClient; + } + + interface GuildMember { + client: ExtendedClient; + } +} diff --git a/src/Classes/Handlers/CommandHandler.ts b/src/Classes/Handlers/CommandHandler.ts index 3682e3b..0ac6806 100644 --- a/src/Classes/Handlers/CommandHandler.ts +++ b/src/Classes/Handlers/CommandHandler.ts @@ -5,7 +5,6 @@ import assert from 'node:assert/strict'; import { ChatInputCommand, ContextMenuCommand } from '../Commands'; import { ExtendedClient } from '../ExtendedClient'; - export class CommandHandler { protected readonly client: ExtendedClient; @@ -60,7 +59,9 @@ export class CommandHandler { this.client.emit('debug', 'Deploying commands...'); - const commandData = this.chatCommands.filter((f) => f.isGlobal === true).map((m) => m.toJSON()) + const commandData = this.chatCommands + .filter((f) => f.isGlobal === true) + .map((m) => m.toJSON()) .concat(this.contextCommands.filter((f) => f.isGlobal === true).map((m) => m.toJSON())); const sentCommands = await this.client.application.commands.set(commandData); diff --git a/src/Classes/HelpInfo/BaseHelper.ts b/src/Classes/HelpInfo/BaseHelper.ts index ef4c54f..c95f87c 100644 --- a/src/Classes/HelpInfo/BaseHelper.ts +++ b/src/Classes/HelpInfo/BaseHelper.ts @@ -4,7 +4,6 @@ import { import { LocalizedHelpInfo, helpInfo } from './types'; export class BaseHelper { - private _name: string; private _title: string; @@ -72,7 +71,7 @@ export class BaseHelper { } setName(name: string) { - this.name=name; + this.name = name; return this; } @@ -112,7 +111,6 @@ export class BaseHelper { } getInfo(locale: Locale): helpInfo { - const obj: helpInfo = { title: this.titleLocalizations[locale], description: this.descriptionLocalizations[locale] @@ -123,7 +121,4 @@ export class BaseHelper { return obj; } - - // constructor(options: Partial) { - // } } diff --git a/src/Classes/HelpInfo/ChatInputHelper.ts b/src/Classes/HelpInfo/ChatInputHelper.ts index 41be186..b510ae1 100644 --- a/src/Classes/HelpInfo/ChatInputHelper.ts +++ b/src/Classes/HelpInfo/ChatInputHelper.ts @@ -1,11 +1,11 @@ import { SubcommandHelper } from './SubcommandHelper'; export class ChatInputHelper extends SubcommandHelper { - subcomandGroups: SubcommandHelper[]; - addSubcomandGroup(helpInfo: SubcommandHelper) { - this.subcomandGroups.push(helpInfo); + addSubcomandGroup(helpInfo: SubcommandHelper | ((subcommandHelper: SubcommandHelper) => SubcommandHelper)) { + if (typeof helpInfo === 'function') this.subcomandGroups.push(helpInfo(new SubcommandHelper())); + else this.subcomandGroups.push(helpInfo); return this; } } diff --git a/src/Classes/HelpInfo/SubcommandHelper.ts b/src/Classes/HelpInfo/SubcommandHelper.ts index 9dc387e..b29be80 100644 --- a/src/Classes/HelpInfo/SubcommandHelper.ts +++ b/src/Classes/HelpInfo/SubcommandHelper.ts @@ -1,11 +1,11 @@ import { BaseHelper } from './BaseHelper'; export class SubcommandHelper extends BaseHelper { - subcomands: BaseHelper[]; - addSubcommand(helpInfo: BaseHelper) { - this.subcomands.push(helpInfo); + addSubcommand(helpInfo: BaseHelper| ((subcommandHelper: BaseHelper) => BaseHelper)) { + if (typeof helpInfo === 'function') this.subcomands.push(helpInfo(new BaseHelper())); + else this.subcomands.push(helpInfo); return this; } } diff --git a/src/Classes/Interaction.ts b/src/Classes/Interaction.ts index 3f0c145..5b827fa 100644 --- a/src/Classes/Interaction.ts +++ b/src/Classes/Interaction.ts @@ -10,7 +10,7 @@ export class Interaction { // Method that to run when interaction happens private _execute: (interaction: E) => Promise; - get name(){ + get name() { return this._name; } diff --git a/src/Classes/index.ts b/src/Classes/index.ts index 6f50374..494263f 100644 --- a/src/Classes/index.ts +++ b/src/Classes/index.ts @@ -9,4 +9,3 @@ export { ExtendedClient } from './ExtendedClient'; export type { LocalizedHelpInfo, helpInfo } from './HelpInfo'; export { BaseHelper, ChatInputHelper, SubcommandHelper } from './HelpInfo'; - diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index f4adacf..a412418 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -68,6 +68,4 @@ async function onInteractionCreate(interaction: Interaction) { } } -export default new Event() - .setName(Events.InteractionCreate) - .setExecute(onInteractionCreate); +export default new Event().setName(Events.InteractionCreate).setExecute(onInteractionCreate); diff --git a/src/types/index.d.ts b/src/typings/index.d.ts similarity index 99% rename from src/types/index.d.ts rename to src/typings/index.d.ts index 3d80c5d..fd71f0f 100644 --- a/src/types/index.d.ts +++ b/src/typings/index.d.ts @@ -28,7 +28,7 @@ declare module 'discord.js' { interface User { client: ExtendedClient; } - + interface GuildMember { client: ExtendedClient; } diff --git a/src/util/types.ts b/src/util/types.ts index 013608f..6db9bbc 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -1,4 +1,3 @@ - /** * Color values that can be referenced */ diff --git a/tsconfig.json b/tsconfig.json index 0d721d4..59c56a7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,12 @@ { - "compilerOptions": { - "outDir": "dist", - "target": "ES2022", - "module": "CommonJS", - "noImplicitAny": true, - "declaration": true, - "esModuleInterop": true - }, - "include": ["src"], - "exclude": ["node_modules"] + "compilerOptions": { + "outDir": "dist", + "target": "ES2022", + "module": "CommonJS", + "noImplicitAny": true, + "declaration": true, + "esModuleInterop": true + }, + "include": ["src"], + "exclude": ["node_modules"] } diff --git a/yarn.lock b/yarn.lock index dea2c70..915fa55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1973,11 +1973,6 @@ eslint-config-airbnb-base@^15.0.0: object.entries "^1.1.5" semver "^6.3.0" -eslint-config-prettier@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== - eslint-import-resolver-node@^0.3.9: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" @@ -3683,10 +3678,10 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.4.tgz#4723cadeac2ce7c9227de758e5ff9b14e075f283" - integrity sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ== +prettier@^3.2.5: + version "3.2.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0"