Yet another Fluxer bot built with TypeScript and Bun

feat!: Module-based command system rewrite #2

merged opened by spring.furrest.net targeting develop from better-command-system

Since our current command system only allows one command at time, but it is better to start rewriting it to allow to be using @Module (similar on how Discord.Net/Fluxer.Net actually handles).

Since we're using decorators in TypeScript, it should be less painless and clean. But for this pull request, I don't think it's going to be easy anyway. But we'll see for now.

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:rqpfcwwpcadmlnqxuncywcif/sh.tangled.repo.pull/3mhqm7nd6m522
+12 -43
Interdiff #0 โ†’ #1
src/args.ts

This file has not been changed.

src/base/ModuleBase.ts

This file has not been changed.

src/bot.ts

This file has not been changed.

src/commands/ban.ts

This file has not been changed.

src/commands/bulkdelete.ts

This file has not been changed.

src/commands/echo.ts

This file has not been changed.

src/commands/kick.ts

This file has not been changed.

+1 -5
src/commands/misc.ts
··· 23 23 description: "Echoes the provided content", 24 24 args: echoArgs, 25 25 }) 26 - async echo( 27 - _ctx: BotContext, 28 - message: Message, 29 - args: ParsedArgs<typeof echoArgs>, 30 - ): Promise<void> { 26 + async echo(_ctx: BotContext, message: Message, args: ParsedArgs<typeof echoArgs>): Promise<void> { 31 27 await message.channel?.send({ content: args.content }); 32 28 } 33 29
+5 -18
src/commands/moderation.ts
··· 3 3 import { db } from "@/db"; 4 4 import { warnsTable } from "@/db/schemas"; 5 5 import { Command } from "@/decorators/command"; 6 - import { 7 - RequireGuild, 8 - RequireNonBot, 9 - RequireUserPermission, 10 - } from "@/decorators/guards"; 6 + import { RequireGuild, RequireNonBot, RequireUserPermission } from "@/decorators/guards"; 11 7 import type { BotContext, ParsedArgs } from "@/types"; 12 8 import { ColorPalette } from "@/utils"; 13 9 import { Client, EmbedBuilder, type Message } from "@fluxerjs/core"; ··· 76 72 }, 77 73 { 78 74 name: "By", 79 - value: 80 - msg.author.globalName || 81 - `${msg.author.username}#${msg.author.discriminator}`, 75 + value: msg.author.globalName || `${msg.author.username}#${msg.author.discriminator}`, 82 76 }, 83 77 ) 84 78 .setColor(this.palette.get("red")) ··· 100 94 content: `Successfully banned **${member.displayName}**`, 101 95 }); 102 96 103 - if (successMessage) 104 - setTimeout(() => successMessage.delete().catch(() => {}), 5000); 97 + if (successMessage) setTimeout(() => successMessage.delete().catch(() => {}), 5000); 105 98 } 106 99 107 100 @Command({ ··· 127 120 }, 128 121 { 129 122 name: "By", 130 - value: 131 - msg.author.globalName || 132 - `${msg.author.username}#${msg.author.discriminator}`, 123 + value: msg.author.globalName || `${msg.author.username}#${msg.author.discriminator}`, 133 124 }, 134 125 ) 135 126 .setColor(this.palette.get("red")) ··· 193 184 description: "Purges a number of messages", 194 185 args: purgeArgs, 195 186 }) 196 - async purge( 197 - ctx: BotContext, 198 - msg: Message, 199 - args: ParsedArgs<typeof purgeArgs>, 200 - ) { 187 + async purge(ctx: BotContext, msg: Message, args: ParsedArgs<typeof purgeArgs>) { 201 188 const { client } = ctx; 202 189 203 190 const messages = await client.rest.get<Array<{ id: string }>>(
src/commands/ping.ts

This file has not been changed.

src/commands/warn.ts

This file has not been changed.

src/decorators/command.ts

This file has not been changed.

src/decorators/guards.ts

This file has not been changed.

src/index.ts

This file has not been changed.

+5 -7
src/registry/commandRegistry.ts
··· 86 86 return; 87 87 } 88 88 89 - const commands: ModuleCommand[] = Reflect.getMetadata(MODULE_COMMANDS_KEY, instance.constructor) ?? []; 89 + const commands: ModuleCommand[] = 90 + Reflect.getMetadata(MODULE_COMMANDS_KEY, instance.constructor) ?? []; 90 91 if (commands.length === 0) { 91 92 this.logger.warn(`Module ${meta.name} has no commands`); 92 93 return; ··· 177 178 } else { 178 179 const method = (entry.instance as Record<string, unknown>)[entry.methodName]; 179 180 if (typeof method === "function") { 180 - await (method as (ctx: BotContext, message: Message, args: unknown) => Promise<void>).call( 181 - entry.instance, 182 - ctx, 183 - message, 184 - parsedArgs, 185 - ); 181 + await ( 182 + method as (ctx: BotContext, message: Message, args: unknown) => Promise<void> 183 + ).call(entry.instance, ctx, message, parsedArgs); 186 184 } 187 185 } 188 186 } catch (err) {
src/registry/loadModules.ts

This file has not been changed.

+1 -13
README.md
··· 9 9 10 10 ## Roadmap 11 11 12 - - [ ] Add basic moderation stuff 12 + - [X] Add basic moderation stuff 13 13 - [ ] Some fun command I guess (?) 14 14 - [ ] Idk what to write here but you can go ahead and write an suggestion 15 - 16 - To install dependencies: 17 - 18 - ```bash 19 - bun install 20 - ``` 21 - 22 - To run: 23 - 24 - ```bash 25 - bun run index.ts 26 - ```

History

2 rounds 1 comment
sign up or login to add to the discussion
4 commits
expand
feat(modules/commands): rewrite to use ModuleBase
chore(modules/commands): migrate commands to ModuleBase
chore: run bun fmt
docs: small cleanup + smol writing and updating roadmap
expand 1 comment

fyi: the new module-based command system were written by AI. I could've disclosed that... :/

pull request successfully merged
2 commits
expand
feat(modules/commands): rewrite to use ModuleBase
chore(modules/commands): migrate commands to ModuleBase
expand 0 comments