From 7140a7aef84bf444e5350f49985b9b8d6d5f92ff Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Fri, 1 Jul 2022 19:10:17 -0500 Subject: [PATCH 01/17] feat: adding docs --- guide-en/README.md | 114 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 3 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index 77649dcd5..d55205d57 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -1,7 +1,115 @@ # Introduction -Welcome to the Sern's official guide. This guide will teach you how to use the Sern. +Welcome to the sern's official guide. This guide will go through all the core features of the framework.
+Thank you for choosing sern to be your framework!
+ +**Disclaimers**: +- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements.
+- Sern is only available in ```discord.js@dev``` at the moment. There are plans to roll out a version of Sern in ```discord.js@13.xx.xx``` in the future. ## You will learn -* How to use the Sern with the [Sern CLI](https://github.com/sern-handler/cli) -(TODO) +* sern's goal +* How to use Sern with the [CLI](https://github.com/sern-handler/cli) +* Your first command +* The Context class +* Plugins + - Command Plugins + - Event Plugins +* The SernEmitter class +* Your sern.config.json +* Your first event +* Setting up event listeners + +--- + +# Goal + +sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools +to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. +It should include all the tools for any bot at any scale. + + +# CLI + +Setting up the [CLI](https://github.com/sern-handler/cli) is easy.
+- To start a brand new project, run : +``` +sern init (-y) +``` +Include the `-y` flag if you want to set up defaults. The default langauge is [Typescript](https://www.typescriptlang.org/)
+ +- To install [plugins](todo) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), +``` +sern plugins +``` +This will display a menu selection of all installable plugins.
+**Note**: You must have a [sern.config.json](todo) to use this command. +If you want to view plugins, visit the repository linked above. + +- To install extra utilities into your project +``` +sern extra +``` + +# First Command +We will dissect a basic command. +If you installed a new project via the cli, This is the `ping` command located in src/commands folder. + +Typescript +```typescript +import { commandModule, CommandType } from '@sern/handler'; + +export default commandModule({ + type: CommandType.Both, + plugins: [], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Javascript +```javascript +const { CommandType, commandModule } = require('@sern/handler'); + +exports.default = commandModule({ + type: CommandType.Both, + plugins: [], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply('Pong 🏓'); + }, +}) +``` +### Essential properties of a command + +- **module.type** (Required) + - The type of your module. For example, a command listening to messages would have the type CommandType.Text +- **module.execute** (Required) + - This function is called when the command is triggered. Do your logic here! +- **module.name** (Optional) + - Give your command a name. **(defaults to its filename)** +- **module.description** (Optional) + - Give your command a description. **(defaults to `..`)** +- **module.plugins** (Optional) + - A list of [plugins](todo) that will modify and change the behavior of your command.
+ +### Types of command modules +Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
+All available command types : +``` +CommandType.Text = A Text Command +CommandType.Slash = A Slash Command +CommandType.Both = A Command supporting either / or text or slash +CommandType. + +``` +### How are modules fully typed? +Discriminated unions in Typescript are a fundamental idea. In short, giving objects a property +that differentiates itself from the rest of the union allows typescript to infer the rest of +the properties in the object. This concept is useful when we wanted to add correct typings for all +interaction types, messages, and event modules. + + From 93e3aeccd811d139d66d7b1873aea6c72463deff Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Fri, 1 Jul 2022 20:36:33 -0500 Subject: [PATCH 02/17] feat: add another example of commandModule --- guide-en/README.md | 49 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index d55205d57..cb1fff572 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -9,7 +9,7 @@ Thank you for choosing sern to be your framework!
## You will learn * sern's goal -* How to use Sern with the [CLI](https://github.com/sern-handler/cli) +* How to use sern with the [CLI](https://github.com/sern-handler/cli) * Your first command * The Context class * Plugins @@ -102,14 +102,45 @@ All available command types : ``` CommandType.Text = A Text Command CommandType.Slash = A Slash Command -CommandType.Both = A Command supporting either / or text or slash -CommandType. - +CommandType.Both = A Command supporting either text or slash +CommandType.Modal = A Command listening to Modal interactions +CommandType.MenuSelect = A Command listening to select menu interactions +CommandType.MenuUser = A Command listening to context menu user interactions +CommandType.MenuMsg = A Command listening to context menu message interactions +CommandType.Button = A Command listening to button interactions +``` +So, lets say you want to make a command module that listens to modals.
+**Note**: Keep in mind you'll need to send a modal with a custom id `dm-me`. This example below is the response to a modal being sent.
+ +Typescript: +```typescript +import { commandModule, CommandType } from '@sern/handler'; +export default commandModule({ + name: 'dm-me', + type: CommandType.Modal, + async execute (modal) { + const value = modal.fields.getTextInputValue('message'); + modal.client.users.fetch('182326315813306368').then( u => + u.send(value + ` from ${modal.user}`) + ); + modal.reply( { ephemeral:true, content: 'Sent' }) + } +}); +``` +Javascript: +```javascript +const { CommandType, commandModule } = require('@sern/handler'); +exports.default = commandModule({ + name: 'dm-me', + type: CommandType.Modal, + async execute (modal) { + const value = modal.fields.getTextInputValue('message'); + modal.client.users.fetch('182326315813306368').then( u => + u.send(value + ` from ${modal.user}`) + ); + modal.reply( { ephemeral:true, content: 'Sent' }) + } +}); ``` -### How are modules fully typed? -Discriminated unions in Typescript are a fundamental idea. In short, giving objects a property -that differentiates itself from the rest of the union allows typescript to infer the rest of -the properties in the object. This concept is useful when we wanted to add correct typings for all -interaction types, messages, and event modules. From f84e2e686a856c23acaa978ef3d940ee35809e5f Mon Sep 17 00:00:00 2001 From: xxDeveloper <77380166+Murtatrxx@users.noreply.github.com> Date: Sat, 2 Jul 2022 11:53:22 +0300 Subject: [PATCH 03/17] docs: Updated template Disclaimer --- guide-en/README.md | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index cb1fff572..5b0bb0568 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -1,21 +1,38 @@ # Introduction -Welcome to the sern's official guide. This guide will go through all the core features of the framework.
-Thank you for choosing sern to be your framework!
+Welcome to the Sern's official guide. This guide will go through all the core features of the framework.
+💖 Thank you for choosing Sern to be your framework!
+ +## Disclaimers +Alright, making a bot is cool and all, but there are some prerequisites to it. To create a bot with Ser, you should have a fairly decent grasp of JavaScript and discord.js itself. While you can make a bot with very little JavaScript and programming knowledge, trying to do so without understanding the language first will only hinder you. You may get stuck on many uncomplicated issues, struggle with solutions to incredibly easy problems, and all-in-all end up frustrated. Sounds pretty annoying. + +If you don't know JavaScript but would like to learn about it, here are a few links to help get you started: + +* JavaScript.info, a modern javascript tutorial +* Codecademy's interactive JavaScript course +* Nodeschool, for both JavaScript and Node.js lessons +* MDN's JavaScript guide and full documentation +* Google, your best friend + +Take your pick, learn some JavaScript, and once you feel like you're confident enough to make a bot, come back and get started! Teaching the discord.js library and/or Javascript/Typescript is out of scope of this project, so this guide assumes you already know these elements.
-**Disclaimers**: -- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements.
- Sern is only available in ```discord.js@dev``` at the moment. There are plans to roll out a version of Sern in ```discord.js@13.xx.xx``` in the future. ## You will learn -* sern's goal +* Sern's goal * How to use sern with the [CLI](https://github.com/sern-handler/cli) * Your first command * The Context class + +#### Working with plugins * Plugins - Command Plugins - Event Plugins + * The SernEmitter class + +### Good to know + * Your sern.config.json * Your first event * Setting up event listeners @@ -24,7 +41,7 @@ Thank you for choosing sern to be your framework!
# Goal -sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools +Sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. It should include all the tools for any bot at any scale. From ed3a4a53e3957f4b91df6e1731c95645db3f1ec5 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:23:07 -0500 Subject: [PATCH 04/17] feat: revert changes --- guide-en/README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index cb1fff572..dbb7af1a4 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -1,21 +1,28 @@ # Introduction -Welcome to the sern's official guide. This guide will go through all the core features of the framework.
-Thank you for choosing sern to be your framework!
+Welcome to the sern's official guide. This guide will go through all the core features of the framework. +Thank you for choosing sern to be your framework! + +- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements. + Sern is only available in discord.js@dev at the moment. There are plans to roll out a version of Sern in discord.js@13.xx.xx in the future. -**Disclaimers**: -- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements.
- Sern is only available in ```discord.js@dev``` at the moment. There are plans to roll out a version of Sern in ```discord.js@13.xx.xx``` in the future. ## You will learn -* sern's goal +* Sern's goal * How to use sern with the [CLI](https://github.com/sern-handler/cli) * Your first command * The Context class + +#### Working with pluginsz * Plugins - Command Plugins - Event Plugins + * The SernEmitter class + +### Good to know + * Your sern.config.json * Your first event * Setting up event listeners @@ -24,7 +31,7 @@ Thank you for choosing sern to be your framework!
# Goal -sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools +Sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. It should include all the tools for any bot at any scale. @@ -143,4 +150,3 @@ exports.default = commandModule({ }); ``` - From 7771807657fb2d49af0e95d85a96f8a608b9bd82 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 2 Jul 2022 10:45:13 -0500 Subject: [PATCH 05/17] feat: typos --- guide-en/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index dbb7af1a4..d1878a5e6 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -9,12 +9,12 @@ Thank you for choosing sern to be your framework! - Sern is only available in ```discord.js@dev``` at the moment. There are plans to roll out a version of Sern in ```discord.js@13.xx.xx``` in the future. ## You will learn -* Sern's goal +* sern's goal * How to use sern with the [CLI](https://github.com/sern-handler/cli) * Your first command * The Context class -#### Working with pluginsz +#### Working with plugins * Plugins - Command Plugins - Event Plugins From 7ff79a4576a7c57670e3fb58dbfa264cbbf62c2e Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Wed, 6 Jul 2022 01:06:32 -0500 Subject: [PATCH 06/17] feat: more progress on docs --- guide-en/README.md | 93 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 4 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index d1878a5e6..bab50faf2 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -1,12 +1,12 @@ # Introduction -Welcome to the sern's official guide. This guide will go through all the core features of the framework. -Thank you for choosing sern to be your framework! +Welcome to sern's official guide. This guide will go through all the core features of the framework. +Thank you for choosing sern! - Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements. - Sern is only available in discord.js@dev at the moment. There are plans to roll out a version of Sern in discord.js@13.xx.xx in the future. + discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. -- Sern is only available in ```discord.js@dev``` at the moment. There are plans to roll out a version of Sern in ```discord.js@13.xx.xx``` in the future. +- discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. ## You will learn * sern's goal @@ -149,4 +149,89 @@ exports.default = commandModule({ } }); ``` +Commands are straight forward. Keep in mind, every other property on the commandModule object is +optional **except** the type and execute function. +# Context class +The provided Context class helps with modules of `CommandType.Both` ( A mixture of slash / legacy commands ) +In short, this is passed into the execute function instead of a slash interaction or message to provide +shared methods between the two classes. + +The Context class is passed into modules with type : +- `CommandType.Both` +- `CommandType.Slash` +- `CommandType.Text` + +Typescript: +```typescript +export default commandModule({ + name: 'ping', + type: CommandType.Both, + async execute(ctx: Context) { + await ctx.reply(`pong ${ctx.user}`) + // .reply is shared between both message and interaction! + // So is an User object! + } +}); +``` +Javascript: +```javascript +exports.default = commandModule({ + name: 'ping', + type: CommandType.Both, + async execute(ctx) { //ctx is a Context instance + await ctx.reply(`pong ${ctx.user}`) + // .reply is shared between both message and interaction! + // So is an User object! + } +}); +``` + +# Plugins +As of now, modules seem a little underwhelming. It appears that sern doesn't have all the features of a standard handler, +which manages permissions, categorizes, cooldowns, publishes application commands, role permissions, etc. Many important +parts that manage access and help make commands easier to make are apparently absent.
+Below is an example of an event plugin, one of the types of plugins.
+Typescript: +```typescript +export function serenOnly(): EventPlugin { + return { + type: PluginType.Event, + async execute([ctx, args], controller) { + if (ctx.user.id !== "182326315813306368") { + await ctx.reply({content: "You cannot use this command"}) + return controller.stop() + } + return controller.next(); + } + } +} +``` +Javascript: +```javascript +export function serenOnly(): EventPlugin { + return { + type: PluginType.Event, + async execute([ctx, args], controller) { + if (ctx.user.id !== "182326315813306368") { + await ctx.reply({content: "You cannot use this command"}) + return controller.stop() + } + return controller.next(); + } + } +} +``` + +
As part of sern's extensibility, the plugins feature make sern just as powerful, if not more powerful than +standard handlers. +Plugins modify and add new behavior to standard modules, extending customizability and implementing automation. + +
At the moment, there are two types of plugins: + +- Command Plugins +- Event Plugins + +## Command Plugins +All modules are registered into sern's system. With command plugins, you can modify how commands are loaded, +or do some kind of preprocessing before they are loaded into their command stores. \ No newline at end of file From 0e363ad4915a1197ecb4de45b1e906bf9213baf8 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:26:17 -0500 Subject: [PATCH 07/17] feat: finish command plugin section --- guide-en/README.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/guide-en/README.md b/guide-en/README.md index bab50faf2..c8cb8c88e 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -234,4 +234,29 @@ Plugins modify and add new behavior to standard modules, extending customizabili ## Command Plugins All modules are registered into sern's system. With command plugins, you can modify how commands are loaded, -or do some kind of preprocessing before they are loaded into their command stores. \ No newline at end of file +or do some kind of preprocessing before they are loaded into sern. +### The controller object +```typescript +export interface Controller { + next: () => Ok; + stop: () => Err; +} +``` +An instance of the above object is passed into every plugin.
+This controls whether a module is stored into sern. +```typescript +export function logCreated(): CommandPlugin { + return { + type: PluginType.Command, + async execute(wrapper, { absPath, module }, controller) { + console.log(+new Date(), `${module.name} loaded correctly`) + return controller.next(); + } + } +} +``` +Above, this simple plugin logs that the module has been loaded along with a timestamp.
+Again, it is up to the user to define plugin logic! The possibilities to customize your bots is endless. + +## Event Plugins +sern hooks up to a discord.js event, and then handles which command is fired.
\ No newline at end of file From e37640b6b2fd95983341f5e790d1bf04bd9a301a Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:30:00 -0500 Subject: [PATCH 08/17] event-plugin-diagram --- assets/images/Untitled Diagram.drawio | 1 + 1 file changed, 1 insertion(+) create mode 100644 assets/images/Untitled Diagram.drawio diff --git a/assets/images/Untitled Diagram.drawio b/assets/images/Untitled Diagram.drawio new file mode 100644 index 000000000..360afa72f --- /dev/null +++ b/assets/images/Untitled Diagram.drawio @@ -0,0 +1 @@ +7ZjLcpswFIafhmU6RhgbL2Pn0kU6yTSdSbOU4QTUCMQIEeM+fSUQYC5OcGrctNOVpV8XxP/pnMPYsFZhds1xHHxhHlADTbzMsC4MhEyELPmjlK1WTAcVis+Jp7VauCc/QYsTrabEg6QxUTBGBYmbosuiCFzR0DDnbNOc9sRo86kx9qEj3LuYdtUH4omgUB17UuufgfhB+WRzokdCXE7WQhJgj212JOvSsFacMVG0wmwFVLlX+lKsu9ozWh2MQySGLLCidHmV8YW7vZnE0e3DN4Svz/QuL5im+oUN6/x2/UNZWZxabEsr5AvEqpmG9IY8ASWR7C1j4CQEAVyOUC3f1dpSghFYamrczPuU4jgh63zbiVQ4uClPyAt8haTgn6ssjTzwdK8yL+8Izp4rHGpT/RbABWR77TEr0+V1BSYPyLdySnVXNSd9Ux3d3dTUK7bBDnGrFLG+aX61dQ1DNjSPA9igLps2kpiRSOTPtZeGfdHCwbgImM8iTHeBHN/Y/Tdrr9tTu2H2vM/srtfmYiyvrY7XHkliLNyg47kyg8gEcU6JH0lpzYRgYe4e5uJc5RzlvdxKahB5pbKmzH0up+lE5wwlAF4nTQ3xXyZLzH14bR7q58SBYiFjsplQe2zXS+/UTaz5npn9gMsdEpZyF/SiFrvqFO/HOf2HQ8du5qkqb70RO85YoWP/LyFZqxR8mBIy+6vjwD6khPSa3VNCZmN5Pe94zUGkPBpeQHaKBYtBDi09nAS5z2YxvFM2ICPiuzZdtR9V+9PCfndFKVLy25dpWEUZFDe/WWTQvHkFkDVrblEcdbQq4xzho6HnA0G6xrcVWtV5PCTSDgeLBoKd/SmwnaAd+fNh0QEr0dE1lniOAtY8EdihETs9Gdhps0KiduUbGWxZEU6dpM2TJenph4vlNnJ7fqQkLbv1vyfF9PpPKOvyFw== \ No newline at end of file From d34b97dfa8e3c9d8a5e5c040b9c473aa9f470024 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:49:35 -0500 Subject: [PATCH 09/17] feat: Event plugin diagram --- assets/images/Untitled Diagram.drawio | 62 ++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/assets/images/Untitled Diagram.drawio b/assets/images/Untitled Diagram.drawio index 360afa72f..79ce00a8f 100644 --- a/assets/images/Untitled Diagram.drawio +++ b/assets/images/Untitled Diagram.drawio @@ -1 +1,61 @@ -7ZjLcpswFIafhmU6RhgbL2Pn0kU6yTSdSbOU4QTUCMQIEeM+fSUQYC5OcGrctNOVpV8XxP/pnMPYsFZhds1xHHxhHlADTbzMsC4MhEyELPmjlK1WTAcVis+Jp7VauCc/QYsTrabEg6QxUTBGBYmbosuiCFzR0DDnbNOc9sRo86kx9qEj3LuYdtUH4omgUB17UuufgfhB+WRzokdCXE7WQhJgj212JOvSsFacMVG0wmwFVLlX+lKsu9ozWh2MQySGLLCidHmV8YW7vZnE0e3DN4Svz/QuL5im+oUN6/x2/UNZWZxabEsr5AvEqpmG9IY8ASWR7C1j4CQEAVyOUC3f1dpSghFYamrczPuU4jgh63zbiVQ4uClPyAt8haTgn6ssjTzwdK8yL+8Izp4rHGpT/RbABWR77TEr0+V1BSYPyLdySnVXNSd9Ux3d3dTUK7bBDnGrFLG+aX61dQ1DNjSPA9igLps2kpiRSOTPtZeGfdHCwbgImM8iTHeBHN/Y/Tdrr9tTu2H2vM/srtfmYiyvrY7XHkliLNyg47kyg8gEcU6JH0lpzYRgYe4e5uJc5RzlvdxKahB5pbKmzH0up+lE5wwlAF4nTQ3xXyZLzH14bR7q58SBYiFjsplQe2zXS+/UTaz5npn9gMsdEpZyF/SiFrvqFO/HOf2HQ8du5qkqb70RO85YoWP/LyFZqxR8mBIy+6vjwD6khPSa3VNCZmN5Pe94zUGkPBpeQHaKBYtBDi09nAS5z2YxvFM2ICPiuzZdtR9V+9PCfndFKVLy25dpWEUZFDe/WWTQvHkFkDVrblEcdbQq4xzho6HnA0G6xrcVWtV5PCTSDgeLBoKd/SmwnaAd+fNh0QEr0dE1lniOAtY8EdihETs9Gdhps0KiduUbGWxZEU6dpM2TJenph4vlNnJ7fqQkLbv1vyfF9PpPKOvyFw== \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3d05c4873f81a21738c863b0bb00770a8b309de6 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:55:53 -0500 Subject: [PATCH 10/17] feat: eventplugins.drawio.svg --- assets/images/eventplugins.drawio.svg | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 assets/images/eventplugins.drawio.svg diff --git a/assets/images/eventplugins.drawio.svg b/assets/images/eventplugins.drawio.svg new file mode 100644 index 000000000..b97d518a3 --- /dev/null +++ b/assets/images/eventplugins.drawio.svg @@ -0,0 +1,4 @@ + + + +
Event
Event
Plugin 1
Plugin 1
Plugin 2
Plugin 2
Plugin 3
Plugin 3
Is successful
Is successful
Command Executes
Command Executes
Ignore
Ignore
True
True
False
False
Text is not SVG - cannot display
\ No newline at end of file From 3fbfdeff760794d8e0b22b67c429fb12e1b55483 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 10 Jul 2022 00:04:52 -0500 Subject: [PATCH 11/17] feat: add diagram --- assets/images/Untitled Diagram.drawio | 61 --------------------------- guide-en/README.md | 6 ++- 2 files changed, 4 insertions(+), 63 deletions(-) delete mode 100644 assets/images/Untitled Diagram.drawio diff --git a/assets/images/Untitled Diagram.drawio b/assets/images/Untitled Diagram.drawio deleted file mode 100644 index 79ce00a8f..000000000 --- a/assets/images/Untitled Diagram.drawio +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/guide-en/README.md b/guide-en/README.md index c8cb8c88e..1bd56f1b3 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -256,7 +256,9 @@ export function logCreated(): CommandPlugin { } ``` Above, this simple plugin logs that the module has been loaded along with a timestamp.
-Again, it is up to the user to define plugin logic! The possibilities to customize your bots is endless. +Again, it is up to **you** to define plugin logic! The possibilities to customize your bots is endless. ## Event Plugins -sern hooks up to a discord.js event, and then handles which command is fired.
\ No newline at end of file +![event-plugins](/assets/images/eventplugins.drawio.svg)
+The diagram should explain most of it. An event is emitted by discord.js, run through all the plugins, and if they are
+all successful, the command is executed. From 23ab9d36f55893b51f6ad6f7402e559a813e58cf Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Sun, 10 Jul 2022 14:44:57 -0500 Subject: [PATCH 12/17] feat: all of it has been written i think ( rough draft ) --- guide-en/README.md | 207 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 189 insertions(+), 18 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index 1bd56f1b3..abdede8f2 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -14,18 +14,17 @@ Thank you for choosing sern! * Your first command * The Context class -#### Working with plugins +### Working with plugins * Plugins - Command Plugins - Event Plugins - +### Events * The SernEmitter class +* Your first event ### Good to know * Your sern.config.json -* Your first event -* Setting up event listeners --- @@ -45,7 +44,7 @@ sern init (-y) ``` Include the `-y` flag if you want to set up defaults. The default langauge is [Typescript](https://www.typescriptlang.org/)
-- To install [plugins](todo) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), +- To install [plugins](#plugins) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), ``` sern plugins ``` @@ -101,7 +100,7 @@ exports.default = commandModule({ - **module.description** (Optional) - Give your command a description. **(defaults to `..`)** - **module.plugins** (Optional) - - A list of [plugins](todo) that will modify and change the behavior of your command.
+ - A list of [plugins](#plugins) that will modify and change the behavior of your command.
### Types of command modules Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
@@ -154,8 +153,7 @@ optional **except** the type and execute function. # Context class The provided Context class helps with modules of `CommandType.Both` ( A mixture of slash / legacy commands ) -In short, this is passed into the execute function instead of a slash interaction or message to provide -shared methods between the two classes. +In short, Slash Commands, Both Commands, Text Commands carry a Context data structure The Context class is passed into modules with type : - `CommandType.Both` @@ -188,13 +186,15 @@ exports.default = commandModule({ ``` # Plugins + As of now, modules seem a little underwhelming. It appears that sern doesn't have all the features of a standard handler, -which manages permissions, categorizes, cooldowns, publishes application commands, role permissions, etc. Many important -parts that manage access and help make commands easier to make are apparently absent.
-Below is an example of an event plugin, one of the types of plugins.
+which manages permissions, categorizes, cool-downs, publishes application commands, role permissions, etc. Many important +parts that manage access and help streamline command creation to make are apparently absent. +Below is an example of an event plugin, one of the types of plugins. + Typescript: ```typescript -export function serenOnly(): EventPlugin { +export function serenOnly(): EventPlugin { return { type: PluginType.Event, async execute([ctx, args], controller) { @@ -209,7 +209,7 @@ export function serenOnly(): EventPlugin { ``` Javascript: ```javascript -export function serenOnly(): EventPlugin { +export function serenOnly(): EventPlugin { return { type: PluginType.Event, async execute([ctx, args], controller) { @@ -243,9 +243,10 @@ export interface Controller { } ``` An instance of the above object is passed into every plugin.
-This controls whether a module is stored into sern. +This controls whether a module is stored into sern.
+Typescript: ```typescript -export function logCreated(): CommandPlugin { +export function loggable(): CommandPlugin { return { type: PluginType.Command, async execute(wrapper, { absPath, module }, controller) { @@ -255,10 +256,180 @@ export function logCreated(): CommandPlugin { } } ``` +Javascript: +```javascript +export function inDir(dir : string) { + return { + type: PluginType.Command, + async execute(wrapper, { absPath, module }, controller) { + if(path.dirname(absPath) !== dir) { + console.log(+new Date(), `${module.name} is not in the correct directory!`); + return controller.stop() + } + console.log(+new Date(), `${module.name} is in the correct directory!`); + return controller.next(); //continue + } + } +} +``` Above, this simple plugin logs that the module has been loaded along with a timestamp.
Again, it is up to **you** to define plugin logic! The possibilities to customize your bots is endless. ## Event Plugins -![event-plugins](/assets/images/eventplugins.drawio.svg)
-The diagram should explain most of it. An event is emitted by discord.js, run through all the plugins, and if they are
-all successful, the command is executed. +![event-plugins](/assets/images/eventplugins.drawio.svg)
+- An event is emitted by discord.js. +- This event is passed to all plugins (**in order!!**), +- If all are successful, + +The command is executed. Calling `controller.stop()` notifies sern that this command should not be run, +and this event is ignored. +

+This flexible structure allows you to write reusable preconditions, permissions verifiers, +argument verifiers, and much more. + +

So, what does a command module look like with plugins?

+ +Typescript: +```typescript +import { commandModule, CommandType } from '@sern/handler'; + +export default commandModule({ + type: CommandType.Both, + plugins: [ + inDir("other"), + serenOnly() + ], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Javascript: +```typescript +const { commandModule, CommandType } = require('@sern/handler'); + +exports.default = commandModule({ + type: CommandType.Both, + plugins: [ + inDir("other"), + serenOnly() //The plugins in this section applied to this module! + ], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Can you predict the behavior of this command? + +- Before loading into sern, this command module will check if this module is in the correct directory `other`. +- Before an event occurs, this command module will check if the user has the id `182326315813306368`. + +If all plugins return `controller.next()`, this command replies `Pong 🏓` + +# The SernEmitter class +You're shipped with the SernEmitter. This EventEmitter listens to +- command modules executing and its status, the `module.activate` event +- command modules registered and its status, the `module.register` event +- Any errors that are recoverable, the `error` event + +
You can put these and other event listeners into event modules! + +# Your first event module +We will dissect a basic event module.
+Typescript: +```typescript +export default eventModule({ + type: EventType.Sern, + plugins : [], //NOT SUPPORTED YET!! + name: 'module.activate', //name of event. + execute(event) { + console.log(event); + } +}) +``` +Javascript: +```javascript +exports.default = eventModule({ + type: EventType.Sern, + plugins : [], //NOT SUPPORTED YET!! + name: 'module.activate', + execute(event) { + console.log(event); + } +}) +``` +Like command modules, the `type` property denotes what kind of event it is. +``` +EventType.Sern = an event listening to the SernEmitter +EventType.Discord = an event listening to the discord.js Client +EventType.External = an event listening to any class extending an EventEmitter +``` +### Essential properties of an event module + +- **module.type** (Required) + - The type of your module. ( Check previous message ^^^) +- **module.execute** (Required) + - This function is called when the event module is triggered. Do your logic here! +- **module.name** (Optional) + - The name of the event. **(defaults to its filename, however it is recommended to fill this out!!)** +- **module.description** (Optional) + - Give your command a description. **(defaults to `..`)** +- **module.plugins** (Optional) +- A list of [plugins](#plugins) that will modify and change the behavior of your command.
+ +
+Event modules are laid out similarly to command modules. These listen to any and all event you provide. +In the current version 1.1.0-beta, plugins are not supported. + +### Another example of an event module + +Typescript: +```typescript +export default eventModule({ + type: EventType.Discord, + plugins : [], //NOT SUPPORTED YET!! + name: 'guildMemberAdd', //name of event. + async execute(member) { + await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); + } +}) +``` + +Javascript: +```typescript +exports.default = eventModule({ + type: EventType.Discord, + plugins : [], //NOT SUPPORTED YET!! + name: 'guildMemberAdd', //name of event. + async execute(member) { + await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); + } +}) +``` +# Good to know + +## sern.config.json +A sern.config.json, although not necessary, allows your project to communicate with our cli. +For example, when installing typescript plugins, the language property is necessary to install from our +[open source repository](https://github.com/sern-handler/awesome-plugins). +Using the cli and running `sern init --sync` on pre-existing projects should install this json file in the root directory given. +Or, if this is a brand-new project, `sern init` automatically installs it. + +```json +{ + "language": "typescript", + "paths": { + "base": "src", + "commands": "commands" + } +} +``` + +# Conclusion +If you reached this far, thank you for reading! We hope you have learned the necessities you need +to create a bot with the sern framework. If you have any other questions, bugs, concerns, please join our +[community server](https://discord.gg/QgnfxWzrcj), and we'll be glad to answer your questions. \ No newline at end of file From 0e83cb99ec43fda533e85e769024adff4ba1e712 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Mon, 11 Jul 2022 15:54:27 -0500 Subject: [PATCH 13/17] feat: change to requested https://github.com/sern-handler/website/pull/7 --- guide-en/README.md | 431 +------------------------- guide-en/walkthrough/cli.md | 21 ++ guide-en/walkthrough/conclusion.md | 4 + guide-en/walkthrough/first-command.md | 127 ++++++++ guide-en/walkthrough/first-event.md | 72 +++++ guide-en/walkthrough/goal.md | 6 + guide-en/walkthrough/good-to-know.md | 18 ++ guide-en/walkthrough/plugins.md | 148 +++++++++ guide-en/walkthrough/sern-emitter.md | 7 + 9 files changed, 414 insertions(+), 420 deletions(-) create mode 100644 guide-en/walkthrough/cli.md create mode 100644 guide-en/walkthrough/conclusion.md create mode 100644 guide-en/walkthrough/first-command.md create mode 100644 guide-en/walkthrough/first-event.md create mode 100644 guide-en/walkthrough/goal.md create mode 100644 guide-en/walkthrough/good-to-know.md create mode 100644 guide-en/walkthrough/plugins.md create mode 100644 guide-en/walkthrough/sern-emitter.md diff --git a/guide-en/README.md b/guide-en/README.md index abdede8f2..5b73ec60c 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -4,432 +4,23 @@ Welcome to sern's official guide. This guide will go through all the core featur Thank you for choosing sern! - Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements. - discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. - discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. ## You will learn -* sern's goal -* How to use sern with the [CLI](https://github.com/sern-handler/cli) -* Your first command -* The Context class +* [sern's goal](guide-en/walkthrough/goal.md) +* How to use sern with the [CLI](guide-en/walkthrough/cli.md) +* [Your first command](guide-en/walkthrough/first-command.md) +* [The Context class](guide-en/walkthrough/first-command.md#context-class) ### Working with plugins -* Plugins - - Command Plugins - - Event Plugins +* [Plugins](guide-en/walkthrough/plugins.md) + - [Command Plugins](guide-en/walkthrough/plugins.md#command-plugins) + - [Event Plugins](guide-en/walkthrough/plugins.md#event-plugins) ### Events -* The SernEmitter class -* Your first event +* [The SernEmitter class](guide-en/walkthrough/sern-emitter.md) +* [Your first event](guide-en/walkthrough/first-event.md) ### Good to know - -* Your sern.config.json - ---- - -# Goal - -Sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools -to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. -It should include all the tools for any bot at any scale. - - -# CLI - -Setting up the [CLI](https://github.com/sern-handler/cli) is easy.
-- To start a brand new project, run : -``` -sern init (-y) -``` -Include the `-y` flag if you want to set up defaults. The default langauge is [Typescript](https://www.typescriptlang.org/)
- -- To install [plugins](#plugins) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), -``` -sern plugins -``` -This will display a menu selection of all installable plugins.
-**Note**: You must have a [sern.config.json](todo) to use this command. -If you want to view plugins, visit the repository linked above. - -- To install extra utilities into your project -``` -sern extra -``` - -# First Command -We will dissect a basic command. -If you installed a new project via the cli, This is the `ping` command located in src/commands folder. - -Typescript -```typescript -import { commandModule, CommandType } from '@sern/handler'; - -export default commandModule({ - type: CommandType.Both, - plugins: [], - description: 'A ping command', - //alias : [], - execute: async (ctx, args) => { - await ctx.reply({ content: 'Pong 🏓' }); - }, -}); -``` -Javascript -```javascript -const { CommandType, commandModule } = require('@sern/handler'); - -exports.default = commandModule({ - type: CommandType.Both, - plugins: [], - description: 'A ping command', - //alias : [], - execute: async (ctx, args) => { - await ctx.reply('Pong 🏓'); - }, -}) -``` -### Essential properties of a command - -- **module.type** (Required) - - The type of your module. For example, a command listening to messages would have the type CommandType.Text -- **module.execute** (Required) - - This function is called when the command is triggered. Do your logic here! -- **module.name** (Optional) - - Give your command a name. **(defaults to its filename)** -- **module.description** (Optional) - - Give your command a description. **(defaults to `..`)** -- **module.plugins** (Optional) - - A list of [plugins](#plugins) that will modify and change the behavior of your command.
- -### Types of command modules -Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
-All available command types : -``` -CommandType.Text = A Text Command -CommandType.Slash = A Slash Command -CommandType.Both = A Command supporting either text or slash -CommandType.Modal = A Command listening to Modal interactions -CommandType.MenuSelect = A Command listening to select menu interactions -CommandType.MenuUser = A Command listening to context menu user interactions -CommandType.MenuMsg = A Command listening to context menu message interactions -CommandType.Button = A Command listening to button interactions -``` -So, lets say you want to make a command module that listens to modals.
-**Note**: Keep in mind you'll need to send a modal with a custom id `dm-me`. This example below is the response to a modal being sent.
- -Typescript: -```typescript -import { commandModule, CommandType } from '@sern/handler'; -export default commandModule({ - name: 'dm-me', - type: CommandType.Modal, - async execute (modal) { - const value = modal.fields.getTextInputValue('message'); - modal.client.users.fetch('182326315813306368').then( u => - u.send(value + ` from ${modal.user}`) - ); - modal.reply( { ephemeral:true, content: 'Sent' }) - } -}); -``` -Javascript: -```javascript -const { CommandType, commandModule } = require('@sern/handler'); -exports.default = commandModule({ - name: 'dm-me', - type: CommandType.Modal, - async execute (modal) { - const value = modal.fields.getTextInputValue('message'); - modal.client.users.fetch('182326315813306368').then( u => - u.send(value + ` from ${modal.user}`) - ); - modal.reply( { ephemeral:true, content: 'Sent' }) - } -}); -``` -Commands are straight forward. Keep in mind, every other property on the commandModule object is -optional **except** the type and execute function. - -# Context class -The provided Context class helps with modules of `CommandType.Both` ( A mixture of slash / legacy commands ) -In short, Slash Commands, Both Commands, Text Commands carry a Context data structure - -The Context class is passed into modules with type : -- `CommandType.Both` -- `CommandType.Slash` -- `CommandType.Text` - -Typescript: -```typescript -export default commandModule({ - name: 'ping', - type: CommandType.Both, - async execute(ctx: Context) { - await ctx.reply(`pong ${ctx.user}`) - // .reply is shared between both message and interaction! - // So is an User object! - } -}); -``` -Javascript: -```javascript -exports.default = commandModule({ - name: 'ping', - type: CommandType.Both, - async execute(ctx) { //ctx is a Context instance - await ctx.reply(`pong ${ctx.user}`) - // .reply is shared between both message and interaction! - // So is an User object! - } -}); -``` - -# Plugins - -As of now, modules seem a little underwhelming. It appears that sern doesn't have all the features of a standard handler, -which manages permissions, categorizes, cool-downs, publishes application commands, role permissions, etc. Many important -parts that manage access and help streamline command creation to make are apparently absent. -Below is an example of an event plugin, one of the types of plugins. - -Typescript: -```typescript -export function serenOnly(): EventPlugin { - return { - type: PluginType.Event, - async execute([ctx, args], controller) { - if (ctx.user.id !== "182326315813306368") { - await ctx.reply({content: "You cannot use this command"}) - return controller.stop() - } - return controller.next(); - } - } -} -``` -Javascript: -```javascript -export function serenOnly(): EventPlugin { - return { - type: PluginType.Event, - async execute([ctx, args], controller) { - if (ctx.user.id !== "182326315813306368") { - await ctx.reply({content: "You cannot use this command"}) - return controller.stop() - } - return controller.next(); - } - } -} -``` - -
As part of sern's extensibility, the plugins feature make sern just as powerful, if not more powerful than -standard handlers. -Plugins modify and add new behavior to standard modules, extending customizability and implementing automation. - -
At the moment, there are two types of plugins: - -- Command Plugins -- Event Plugins - -## Command Plugins -All modules are registered into sern's system. With command plugins, you can modify how commands are loaded, -or do some kind of preprocessing before they are loaded into sern. -### The controller object -```typescript -export interface Controller { - next: () => Ok; - stop: () => Err; -} -``` -An instance of the above object is passed into every plugin.
-This controls whether a module is stored into sern.
-Typescript: -```typescript -export function loggable(): CommandPlugin { - return { - type: PluginType.Command, - async execute(wrapper, { absPath, module }, controller) { - console.log(+new Date(), `${module.name} loaded correctly`) - return controller.next(); - } - } -} -``` -Javascript: -```javascript -export function inDir(dir : string) { - return { - type: PluginType.Command, - async execute(wrapper, { absPath, module }, controller) { - if(path.dirname(absPath) !== dir) { - console.log(+new Date(), `${module.name} is not in the correct directory!`); - return controller.stop() - } - console.log(+new Date(), `${module.name} is in the correct directory!`); - return controller.next(); //continue - } - } -} -``` -Above, this simple plugin logs that the module has been loaded along with a timestamp.
-Again, it is up to **you** to define plugin logic! The possibilities to customize your bots is endless. - -## Event Plugins -![event-plugins](/assets/images/eventplugins.drawio.svg)
-- An event is emitted by discord.js. -- This event is passed to all plugins (**in order!!**), -- If all are successful, - -The command is executed. Calling `controller.stop()` notifies sern that this command should not be run, -and this event is ignored. -

-This flexible structure allows you to write reusable preconditions, permissions verifiers, -argument verifiers, and much more. - -

So, what does a command module look like with plugins?

- -Typescript: -```typescript -import { commandModule, CommandType } from '@sern/handler'; - -export default commandModule({ - type: CommandType.Both, - plugins: [ - inDir("other"), - serenOnly() - ], - description: 'A ping command', - //alias : [], - execute: async (ctx, args) => { - await ctx.reply({ content: 'Pong 🏓' }); - }, -}); -``` -Javascript: -```typescript -const { commandModule, CommandType } = require('@sern/handler'); - -exports.default = commandModule({ - type: CommandType.Both, - plugins: [ - inDir("other"), - serenOnly() //The plugins in this section applied to this module! - ], - description: 'A ping command', - //alias : [], - execute: async (ctx, args) => { - await ctx.reply({ content: 'Pong 🏓' }); - }, -}); -``` -Can you predict the behavior of this command? - -- Before loading into sern, this command module will check if this module is in the correct directory `other`. -- Before an event occurs, this command module will check if the user has the id `182326315813306368`. - -If all plugins return `controller.next()`, this command replies `Pong 🏓` - -# The SernEmitter class -You're shipped with the SernEmitter. This EventEmitter listens to -- command modules executing and its status, the `module.activate` event -- command modules registered and its status, the `module.register` event -- Any errors that are recoverable, the `error` event - -
You can put these and other event listeners into event modules! - -# Your first event module -We will dissect a basic event module.
-Typescript: -```typescript -export default eventModule({ - type: EventType.Sern, - plugins : [], //NOT SUPPORTED YET!! - name: 'module.activate', //name of event. - execute(event) { - console.log(event); - } -}) -``` -Javascript: -```javascript -exports.default = eventModule({ - type: EventType.Sern, - plugins : [], //NOT SUPPORTED YET!! - name: 'module.activate', - execute(event) { - console.log(event); - } -}) -``` -Like command modules, the `type` property denotes what kind of event it is. -``` -EventType.Sern = an event listening to the SernEmitter -EventType.Discord = an event listening to the discord.js Client -EventType.External = an event listening to any class extending an EventEmitter -``` -### Essential properties of an event module - -- **module.type** (Required) - - The type of your module. ( Check previous message ^^^) -- **module.execute** (Required) - - This function is called when the event module is triggered. Do your logic here! -- **module.name** (Optional) - - The name of the event. **(defaults to its filename, however it is recommended to fill this out!!)** -- **module.description** (Optional) - - Give your command a description. **(defaults to `..`)** -- **module.plugins** (Optional) -- A list of [plugins](#plugins) that will modify and change the behavior of your command.
- -
-Event modules are laid out similarly to command modules. These listen to any and all event you provide. -In the current version 1.1.0-beta, plugins are not supported. - -### Another example of an event module - -Typescript: -```typescript -export default eventModule({ - type: EventType.Discord, - plugins : [], //NOT SUPPORTED YET!! - name: 'guildMemberAdd', //name of event. - async execute(member) { - await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); - } -}) -``` - -Javascript: -```typescript -exports.default = eventModule({ - type: EventType.Discord, - plugins : [], //NOT SUPPORTED YET!! - name: 'guildMemberAdd', //name of event. - async execute(member) { - await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); - } -}) -``` -# Good to know - -## sern.config.json -A sern.config.json, although not necessary, allows your project to communicate with our cli. -For example, when installing typescript plugins, the language property is necessary to install from our -[open source repository](https://github.com/sern-handler/awesome-plugins). -Using the cli and running `sern init --sync` on pre-existing projects should install this json file in the root directory given. -Or, if this is a brand-new project, `sern init` automatically installs it. - -```json -{ - "language": "typescript", - "paths": { - "base": "src", - "commands": "commands" - } -} -``` - -# Conclusion -If you reached this far, thank you for reading! We hope you have learned the necessities you need -to create a bot with the sern framework. If you have any other questions, bugs, concerns, please join our -[community server](https://discord.gg/QgnfxWzrcj), and we'll be glad to answer your questions. \ No newline at end of file +[//]: <> (Maybe redirect to the sern.config.json section in future) +* [sern.config.json](guide-en/walkthrough/good-to-know.md) diff --git a/guide-en/walkthrough/cli.md b/guide-en/walkthrough/cli.md new file mode 100644 index 000000000..e93fa76f1 --- /dev/null +++ b/guide-en/walkthrough/cli.md @@ -0,0 +1,21 @@ +# CLI + +Setting up the [CLI](https://github.com/sern-handler/cli) is easy.
+- To start a brand new project, run : +``` +sern init (-y) +``` +Include the `-y` flag if you want to set up defaults. The default langauge is [Typescript](https://www.typescriptlang.org/)
+ +- To install [plugins](plugins.md) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), +``` +sern plugins +``` +This will display a menu selection of all installable plugins.
+**Note**: You must have a [sern.config.json](good-to-know.md) to use this command. +If you want to view plugins, visit the repository linked above. + +- To install extra utilities into your project +``` +sern extra +``` \ No newline at end of file diff --git a/guide-en/walkthrough/conclusion.md b/guide-en/walkthrough/conclusion.md new file mode 100644 index 000000000..553cb9f1c --- /dev/null +++ b/guide-en/walkthrough/conclusion.md @@ -0,0 +1,4 @@ +# Conclusion +If you reached this far, thank you for reading! We hope you have learned the necessities you need +to create a bot with the sern framework. If you have any other questions, bugs, feature requests, concerns, please join our +[community server](https://discord.gg/QgnfxWzrcj), and we'll be glad to answer your questions. \ No newline at end of file diff --git a/guide-en/walkthrough/first-command.md b/guide-en/walkthrough/first-command.md new file mode 100644 index 000000000..eeb426f86 --- /dev/null +++ b/guide-en/walkthrough/first-command.md @@ -0,0 +1,127 @@ +# First Command +We will dissect a basic command. +If you installed a new project via the cli, This is the `ping` command located in src/commands folder. + +Typescript +```typescript +import { commandModule, CommandType } from '@sern/handler'; + +export default commandModule({ + type: CommandType.Both, + plugins: [], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Javascript +```javascript +const { CommandType, commandModule } = require('@sern/handler'); + +exports.default = commandModule({ + type: CommandType.Both, + plugins: [], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply('Pong 🏓'); + }, +}) +``` +### Essential properties of a command + +- **module.type** (Required) + - The type of your module. For example, a command listening to messages would have the type CommandType.Text +- **module.execute** (Required) + - This function is called when the command is triggered. Do your logic here! +- **module.name** (Optional) + - Give your command a name. **(defaults to its filename)** +- **module.description** (Optional) + - Give your command a description. **(defaults to `..`)** +- **module.plugins** (Optional) + - A list of [plugins](guide-en/walkthrough/plugins.md) that will modify and change the behavior of your command.
+ +### Types of command modules +Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
+All available command types : +``` +CommandType.Text = A Text Command +CommandType.Slash = A Slash Command +CommandType.Both = A Command supporting either text or slash +CommandType.Modal = A Command listening to Modal interactions +CommandType.MenuSelect = A Command listening to select menu interactions +CommandType.MenuUser = A Command listening to context menu user interactions +CommandType.MenuMsg = A Command listening to context menu message interactions +CommandType.Button = A Command listening to button interactions +``` +So, lets say you want to make a command module that listens to modals.
+**Note**: Keep in mind you'll need to send a modal with a custom id `dm-me`. This example below is the response to a modal being sent.
+ +Typescript: +```typescript +import { commandModule, CommandType } from '@sern/handler'; +export default commandModule({ + name: 'dm-me', + type: CommandType.Modal, + async execute (modal) { + const value = modal.fields.getTextInputValue('message'); + modal.client.users.fetch('182326315813306368').then( u => + u.send(value + ` from ${modal.user}`) + ); + modal.reply( { ephemeral:true, content: 'Sent' }) + } +}); +``` +Javascript: +```javascript +const { CommandType, commandModule } = require('@sern/handler'); +exports.default = commandModule({ + name: 'dm-me', + type: CommandType.Modal, + async execute (modal) { + const value = modal.fields.getTextInputValue('message'); + modal.client.users.fetch('182326315813306368').then( u => + u.send(value + ` from ${modal.user}`) + ); + modal.reply( { ephemeral:true, content: 'Sent' }) + } +}); +``` +Commands are straight forward. Keep in mind, every other property on the commandModule object is +optional **except** the type and execute function. + +# Context class +The provided Context class helps with modules of `CommandType.Both` ( A mixture of slash / legacy commands ) +In short, Slash Commands, Both Commands, Text Commands carry a Context data structure + +The Context class is passed into modules with type : +- `CommandType.Both` +- `CommandType.Slash` +- `CommandType.Text` + +Typescript: +```typescript +export default commandModule({ + name: 'ping', + type: CommandType.Both, + async execute(ctx: Context) { + await ctx.reply(`pong ${ctx.user}`) + // .reply is shared between both message and interaction! + // So is an User object! + } +}); +``` +Javascript: +```javascript +exports.default = commandModule({ + name: 'ping', + type: CommandType.Both, + async execute(ctx) { //ctx is a Context instance + await ctx.reply(`pong ${ctx.user}`) + // .reply is shared between both message and interaction! + // So is an User object! + } +}); +``` diff --git a/guide-en/walkthrough/first-event.md b/guide-en/walkthrough/first-event.md new file mode 100644 index 000000000..a8aaac70d --- /dev/null +++ b/guide-en/walkthrough/first-event.md @@ -0,0 +1,72 @@ +# Your first event module +We will dissect a basic event module.
+Typescript: +```typescript +export default eventModule({ + type: EventType.Sern, + plugins : [], //NOT SUPPORTED YET!! + name: 'module.activate', //name of event. + execute(event) { + console.log(event); + } +}) +``` +Javascript: +```javascript +exports.default = eventModule({ + type: EventType.Sern, + plugins : [], //NOT SUPPORTED YET!! + name: 'module.activate', + execute(event) { + console.log(event); + } +}) +``` +Like command modules, the `type` property denotes what kind of event it is. +``` +EventType.Sern = an event listening to the SernEmitter +EventType.Discord = an event listening to the discord.js Client +EventType.External = an event listening to any class extending an EventEmitter +``` +### Essential properties of an event module + +- **module.type** (Required) + - The type of your module. ( Check previous message ^^^) +- **module.execute** (Required) + - This function is called when the event module is triggered. Do your logic here! +- **module.name** (Optional) + - The name of the event. **(defaults to its filename, however it is recommended to fill this out!!)** +- **module.description** (Optional) + - Give your command a description. **(defaults to `..`)** +- **module.plugins** (Optional) +- A list of [plugins](plugins.md) that will modify and change the behavior of your command.
+ +
+Event modules are laid out similarly to command modules. These listen to any and all event you provide. +In the current version 1.1.0-beta, plugins are not supported. + +### Another example of an event module + +Typescript: +```typescript +export default eventModule({ + type: EventType.Discord, + plugins : [], //NOT SUPPORTED YET!! + name: 'guildMemberAdd', //name of event. + async execute(member) { + await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); + } +}) +``` + +Javascript: +```typescript +exports.default = eventModule({ + type: EventType.Discord, + plugins : [], //NOT SUPPORTED YET!! + name: 'guildMemberAdd', //name of event. + async execute(member) { + await member.client.channels.fetch('channel-id').send(`Welcome, ${member}`); + } +}) +``` \ No newline at end of file diff --git a/guide-en/walkthrough/goal.md b/guide-en/walkthrough/goal.md new file mode 100644 index 000000000..9c70bca5b --- /dev/null +++ b/guide-en/walkthrough/goal.md @@ -0,0 +1,6 @@ + +# Goal + +Sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools +to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. +It should include all the tools for any bot at any scale. diff --git a/guide-en/walkthrough/good-to-know.md b/guide-en/walkthrough/good-to-know.md new file mode 100644 index 000000000..3d04e5492 --- /dev/null +++ b/guide-en/walkthrough/good-to-know.md @@ -0,0 +1,18 @@ +# Good to know + +## sern.config.json +A sern.config.json, although not necessary, allows your project to communicate with our cli. +For example, when installing typescript plugins, the language property is necessary to install from our +[open source repository](https://github.com/sern-handler/awesome-plugins). +Using the cli and running `sern init --sync` on pre-existing projects should install this json file in the root directory given. +Or, if this is a brand-new project, `sern init` automatically installs it. + +```json +{ + "language": "typescript", + "paths": { + "base": "src", + "commands": "commands" + } +} +``` \ No newline at end of file diff --git a/guide-en/walkthrough/plugins.md b/guide-en/walkthrough/plugins.md new file mode 100644 index 000000000..549ffe983 --- /dev/null +++ b/guide-en/walkthrough/plugins.md @@ -0,0 +1,148 @@ +# Plugins + +As of now, modules seem a little underwhelming. It appears that sern doesn't have all the features of a standard handler, +which manages permissions, categorizes, cool-downs, publishes application commands, role permissions, etc. Many important +parts that manage access and help streamline command creation to make are apparently absent. +Below is an example of an event plugin, one of the types of plugins. + +Typescript: +```typescript +export function serenOnly(): EventPlugin { + return { + type: PluginType.Event, + async execute([ctx, args], controller) { + if (ctx.user.id !== "182326315813306368") { + await ctx.reply({content: "You cannot use this command"}) + return controller.stop() + } + return controller.next(); + } + } +} +``` +Javascript: +```javascript +export function serenOnly() { + return { + type: PluginType.Event, + async execute([ctx, args], controller) { + if (ctx.user.id !== "182326315813306368") { + await ctx.reply({content: "You cannot use this command"}) + return controller.stop() + } + return controller.next(); + } + } +} +``` + +
As part of sern's extensibility, the plugins feature make sern just as powerful, if not more powerful than +standard handlers. +Plugins modify and add new behavior to standard modules, extending customizability and implementing automation. + +
At the moment, there are two types of plugins: + +- Command Plugins +- Event Plugins + +## Command Plugins +All modules are registered into sern's system. With command plugins, you can modify how commands are loaded, +or do some kind of preprocessing before they are loaded into sern. +### The controller object +```typescript +export interface Controller { + next: () => Ok; + stop: () => Err; +} +``` +An instance of the above object is passed into every plugin.
+This controls whether a module is stored into sern.
+Typescript: +```typescript +export function inDir(dir : string) : CommandPlugin { + return { + type: PluginType.Command, + async execute(wrapper, { absPath, module }, controller) { + if(path.dirname(absPath) !== dir) { + console.log(+new Date(), `${module.name} is not in the correct directory!`); + return controller.stop() + } + console.log(+new Date(), `${module.name} is in the correct directory!`); + return controller.next(); //continue + } + } +} +``` +Javascript: +```javascript +export function inDir(dir : string) { + return { + type: PluginType.Command, + async execute(wrapper, { absPath, module }, controller) { + if(path.dirname(absPath) !== dir) { + console.log(+new Date(), `${module.name} is not in the correct directory!`); + return controller.stop() + } + console.log(+new Date(), `${module.name} is in the correct directory!`); + return controller.next(); //continue + } + } +} +``` +Above, this simple plugin logs that the module has been loaded along with a timestamp.
+Again, it is up to **you** to define plugin logic! The possibilities to customize your bots is endless. + +## Event Plugins +![event-plugins](/assets/images/eventplugins.drawio.svg)
+- An event is emitted by discord.js. +- This event is passed to all plugins (**in order!!**), +- If all are successful, + +The command is executed. Calling `controller.stop()` notifies sern that this command should not be run, +and this event is ignored. +

+This flexible structure allows you to write reusable preconditions, permissions verifiers, +argument verifiers, and much more. + +

So, what does a command module look like with plugins?

+ +Typescript: +```typescript +import { commandModule, CommandType } from '@sern/handler'; + +export default commandModule({ + type: CommandType.Both, + plugins: [ + inDir("other"), + serenOnly() + ], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Javascript: +```typescript +const { commandModule, CommandType } = require('@sern/handler'); + +exports.default = commandModule({ + type: CommandType.Both, + plugins: [ + inDir("other"), + serenOnly() //The plugins in this section applied to this module! + ], + description: 'A ping command', + //alias : [], + execute: async (ctx, args) => { + await ctx.reply({ content: 'Pong 🏓' }); + }, +}); +``` +Can you predict the behavior of this command? + +- Before loading into sern, this command module will check if this module is in the correct directory `other`. +- Before an event occurs, this command module will check if the user has the id `182326315813306368`. + +If all plugins return `controller.next()`, this command replies `Pong 🏓` \ No newline at end of file diff --git a/guide-en/walkthrough/sern-emitter.md b/guide-en/walkthrough/sern-emitter.md new file mode 100644 index 000000000..d4640f33c --- /dev/null +++ b/guide-en/walkthrough/sern-emitter.md @@ -0,0 +1,7 @@ +# The SernEmitter class +You're shipped with the SernEmitter. This EventEmitter listens to +- command modules executing and its status, the `module.activate` event +- command modules registered and its status, the `module.register` event +- any errors that are recoverable, the `error` event + +
You can put these and other event listeners into event modules! From 99a3ed27f7c89e3f1e79220d4948a6add140d1b6 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Mon, 11 Jul 2022 15:58:23 -0500 Subject: [PATCH 14/17] fix: anchors --- guide-en/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index 5b73ec60c..02632a247 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -8,19 +8,19 @@ Thank you for choosing sern! - discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. ## You will learn -* [sern's goal](guide-en/walkthrough/goal.md) -* How to use sern with the [CLI](guide-en/walkthrough/cli.md) -* [Your first command](guide-en/walkthrough/first-command.md) -* [The Context class](guide-en/walkthrough/first-command.md#context-class) +* [sern's goal](walkthrough/goal.md) +* How to use sern with the [CLI](walkthrough/cli.md) +* [Your first command](walkthrough/first-command.md) +* [The Context class](walkthrough/first-command.md#context-class) ### Working with plugins -* [Plugins](guide-en/walkthrough/plugins.md) - - [Command Plugins](guide-en/walkthrough/plugins.md#command-plugins) - - [Event Plugins](guide-en/walkthrough/plugins.md#event-plugins) +* [Plugins](walkthrough/plugins.md) + - [Command Plugins](walkthrough/plugins.md#command-plugins) + - [Event Plugins](walkthrough/plugins.md#event-plugins) ### Events -* [The SernEmitter class](guide-en/walkthrough/sern-emitter.md) -* [Your first event](guide-en/walkthrough/first-event.md) +* [The SernEmitter class](walkthrough/sern-emitter.md) +* [Your first event](walkthrough/first-event.md) ### Good to know [//]: <> (Maybe redirect to the sern.config.json section in future) -* [sern.config.json](guide-en/walkthrough/good-to-know.md) +* [sern.config.json](walkthrough/good-to-know.md) From c2e1028bc852438b67d2155edfb7fb15ec8695f8 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:00:53 -0500 Subject: [PATCH 15/17] fix: anchorsx2 --- guide-en/walkthrough/first-command.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide-en/walkthrough/first-command.md b/guide-en/walkthrough/first-command.md index eeb426f86..3198eacc4 100644 --- a/guide-en/walkthrough/first-command.md +++ b/guide-en/walkthrough/first-command.md @@ -41,7 +41,7 @@ exports.default = commandModule({ - **module.description** (Optional) - Give your command a description. **(defaults to `..`)** - **module.plugins** (Optional) - - A list of [plugins](guide-en/walkthrough/plugins.md) that will modify and change the behavior of your command.
+ - A list of [plugins](plugins.md) that will modify and change the behavior of your command.
### Types of command modules Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
From 9cfb202014830e396792d23c47e44738073dc90c Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Tue, 12 Jul 2022 14:28:07 -0500 Subject: [PATCH 16/17] feat: requested changes --- guide-en/README.md | 6 +++--- guide-en/walkthrough/first-command.md | 29 ++++----------------------- guide-en/walkthrough/first-event.md | 20 +++--------------- guide-en/walkthrough/goal.md | 2 +- 4 files changed, 11 insertions(+), 46 deletions(-) diff --git a/guide-en/README.md b/guide-en/README.md index 02632a247..73b6bf6a1 100644 --- a/guide-en/README.md +++ b/guide-en/README.md @@ -1,11 +1,11 @@ # Introduction Welcome to sern's official guide. This guide will go through all the core features of the framework. -Thank you for choosing sern! +- 💖 Thank you for choosing sern to be your framework! -- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements. +- Teaching the discord.js library and / or Javascript / Typescript is out of scope of this project, so the documentation assumes you already know these elements. -- discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. +- discord.js@dev is the only supported version at the moment. There are plans to roll out a version of sern in discord.js@13.xx.xx in the future. ## You will learn * [sern's goal](walkthrough/goal.md) diff --git a/guide-en/walkthrough/first-command.md b/guide-en/walkthrough/first-command.md index 3198eacc4..c72594e91 100644 --- a/guide-en/walkthrough/first-command.md +++ b/guide-en/walkthrough/first-command.md @@ -30,33 +30,12 @@ exports.default = commandModule({ }, }) ``` -### Essential properties of a command - -- **module.type** (Required) - - The type of your module. For example, a command listening to messages would have the type CommandType.Text -- **module.execute** (Required) - - This function is called when the command is triggered. Do your logic here! -- **module.name** (Optional) - - Give your command a name. **(defaults to its filename)** -- **module.description** (Optional) - - Give your command a description. **(defaults to `..`)** -- **module.plugins** (Optional) - - A list of [plugins](plugins.md) that will modify and change the behavior of your command.
- +To view what each of these properties mean in depth, visit the [official documentation](https://sern-handler.js.org/docs). ### Types of command modules Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
-All available command types : -``` -CommandType.Text = A Text Command -CommandType.Slash = A Slash Command -CommandType.Both = A Command supporting either text or slash -CommandType.Modal = A Command listening to Modal interactions -CommandType.MenuSelect = A Command listening to select menu interactions -CommandType.MenuUser = A Command listening to context menu user interactions -CommandType.MenuMsg = A Command listening to context menu message interactions -CommandType.Button = A Command listening to button interactions -``` -So, lets say you want to make a command module that listens to modals.
+All the command types can be found in the [official documentation](https://sern-handler.js.org/docs)! +

So, lets say you want to make a command module that listens to modals.

+ **Note**: Keep in mind you'll need to send a modal with a custom id `dm-me`. This example below is the response to a modal being sent.
Typescript: diff --git a/guide-en/walkthrough/first-event.md b/guide-en/walkthrough/first-event.md index a8aaac70d..8934e9c48 100644 --- a/guide-en/walkthrough/first-event.md +++ b/guide-en/walkthrough/first-event.md @@ -22,24 +22,10 @@ exports.default = eventModule({ } }) ``` -Like command modules, the `type` property denotes what kind of event it is. -``` -EventType.Sern = an event listening to the SernEmitter -EventType.Discord = an event listening to the discord.js Client -EventType.External = an event listening to any class extending an EventEmitter -``` -### Essential properties of an event module +Like command modules, the `type` property denotes what kind of event it is, which +can be found [here](https://sern-handler.js.org/docs). -- **module.type** (Required) - - The type of your module. ( Check previous message ^^^) -- **module.execute** (Required) - - This function is called when the event module is triggered. Do your logic here! -- **module.name** (Optional) - - The name of the event. **(defaults to its filename, however it is recommended to fill this out!!)** -- **module.description** (Optional) - - Give your command a description. **(defaults to `..`)** -- **module.plugins** (Optional) -- A list of [plugins](plugins.md) that will modify and change the behavior of your command.
+To view what each of these properties mean in depth, visit the [official documentation](https://sern-handler.js.org/docs).
Event modules are laid out similarly to command modules. These listen to any and all event you provide. diff --git a/guide-en/walkthrough/goal.md b/guide-en/walkthrough/goal.md index 9c70bca5b..cdf6e54e4 100644 --- a/guide-en/walkthrough/goal.md +++ b/guide-en/walkthrough/goal.md @@ -1,6 +1,6 @@ # Goal -Sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools +sern strives to be minimalist, but with all batteries included. Meaning, this framework provides the necessary tools to start up a bot in minutes, and leaves plenty room space to customize your experience and create an amazing project. It should include all the tools for any bot at any scale. From b08f1ff29f2b99a6cae5f85651220c8901c20d2d Mon Sep 17 00:00:00 2001 From: xxDeveloper <77380166+Murtatrxx@users.noreply.github.com> Date: Fri, 15 Jul 2022 16:48:56 +0300 Subject: [PATCH 17/17] docs(website): Uncapitalized the brand name --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index ac5d64854..db957c13b 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - Sern - Handlers. Redefined. + sern - Handlers. Redefined.