Discord-FP
A Beautiful Application Command Framework based on Discord.js
Features
- Type-safe
- Light-weight
- High performance
- Auto-complete & Middlewares
- File-system Based
- Beautiful code with Functional Programming
- Support both ESM and CommonJS
Install
npm install discord-fp
Note
Example below uses commonjs + typescript, you may convert it into normal common js syntax yourself
Slash command in the Best way
Stop writing lots of interaction.options.get("name")
just for getting the value of an option
Let us handle everything!
import { options, slash } from "discord-fp";
export default slash({
description: "Say Hello to you",
options: {
name: options.string({
description: "Your name",
}),
},
execute: async ({ event, options }) => {
await event.reply(`Hello, ${options.name}`);
},
});
Find your Command Instantly
Tired of finding your command all the place? All commands are file-system based!
Search file by name, you are able to find your command instantly
For slash command: test hello
commands/test/_meta.ts
import { group } from "discord-fp";
export default group({
description: "Your Command Group description",
});
commands/test/hello.ts
import { slash } from "discord-fp";
export default slash({
});
Powerful & Beautiful
Not just slash commands, you are able to create context menu commands with few lines of code
commands/Delete Message.ts
import { message } from "discord-fp";
export default message({
async execute(e) {
await e.reply("I don't wanna delete message!");
},
});
Middleware
Wanted to run something before executing a command?
With middleware, you can control how an event handler being fired
commands/_meta.ts
import type { Middleware } from "discord-fp";
export middleware: Middleware = (e, handler) => {
if (something) {
return handler(e)
} else {
}
}
Everything is Type-safe + Null-safe
From config to options values, It's all type-safe!
export default slash({
description: "Say Hello to you",
options: {
enabled: options.boolean({
description: "Enabled",
required: false,
}),
number: options.number({
description: "Example number",
required: true,
}),
},
});
Take a look at options
:
(parameter) options: {
enabled: boolean | null;
number: number;
}
Getting Started
Try our template which includes everything you need
Start Discord-FP after the bot is ready
import { start } from "discord-fp";
import { join } from "path";
client.on("ready", () => {
start(client, {
load: ["./commands"],
});
});
Create Slash command
Create a file inside the folder
Since it's file-system based, command name is same as its file name
commands/hello.ts
import { slash } from "discord-fp";
export default slash({
description: "Say Hello World",
execute: async ({ event, options }) => {
await event.reply(`Hello World`);
},
});
Run your bot
Start your bot, and run the slash command in Discord
hello
Then you should see the bot replied "Hello World"!
Command Group & Sub commands
You may use command group & sub command for grouping tons of commands
-
Create a folder
-
Create a _meta.ts
/ meta.js
file
-
Define information for the command group in the _meta
file
import { group } from "discord-fp";
export default group({
description: "My Command group",
});
-
Create commands inside the folder
Inside the folder, Only slash commands are supported
import { options, slash } from "discord-fp";
export default slash({
description: "Say Hello World",
execute: async ({ event, options }) => {
await event.reply(`Hello World`);
},
});
What is _meta.ts & _meta.js ?
You may create a _meta
file for controling how the folder being loaded
By defining middleware and loader, you can customize almost everything
For example, Command group is just a type of loader
import { Middleware, group } from "discord-fp";
export default group({
description: "My Command group"
})
export middleware: Middleware = (e, handler) => {
return handler(e)
}
Command Options
We provides type-safe options out-of-the-box
import { options } from "discord-fp";
options.string({
description: "Your name",
required: false,
});
Auto-complete
Enable auto-complete easily
options.string({
description: "Your name",
required: false,
autoComplete(e) {
const items = ["hello", "world"];
const v = e.options.getFocused();
e.respond(result);
},
});
Transform
Make your code even better with transform
options.string({
description: "Your name",
require: true,
}).transform((v) => {
return `Mr.${v}`;
}),
ESM Usage
ESM has been supported since v0.2.1
Note
If you have any problems with relative path, you may pass an absolute path instead
Common js
const { start } = require("discord-fp");
start(client, {
load: ["./commands"],
});
ESM
import { start } from "discord-fp";
start(client, {
load: ["./commands"],
});
Any issues?
Feel free to open an issue!
Give this repo a star if you loved this library