From 40a2e39fc82b18ab30adfc48cd87e5cee81f3660 Mon Sep 17 00:00:00 2001 From: DuroCodes Date: Wed, 8 May 2024 23:58:28 -0400 Subject: [PATCH] feat: rewrite most of the docs pages --- bun.lockb | Bin 270717 -> 270672 bytes ec.config.mjs | 2 +- src/components/PackageManagers.astro | 60 ++++++++ .../blog/{2022-09-28.md => 2022-09-28.mdx} | 6 +- .../blog/{2022-09-30.md => 2022-09-30.mdx} | 10 +- .../docs/guide/getting-started/choose-ide.md | 2 +- .../docs/guide/getting-started/preparing.md | 8 +- .../docs/guide/walkthrough/autocomplete.md | 56 +++++++- src/content/docs/guide/walkthrough/cli.md | 37 ----- src/content/docs/guide/walkthrough/cli.mdx | 43 ++++++ .../docs/guide/walkthrough/conclusion.md | 11 -- .../docs/guide/walkthrough/conclusion.mdx | 16 +++ .../guide/walkthrough/dependency-injection.md | 113 ---------------- .../walkthrough/dependency-injection.mdx | 128 ++++++++++++++++++ .../docs/guide/walkthrough/first-command.mdx | 57 +++++--- .../docs/guide/walkthrough/first-event.mdx | 35 +++-- src/content/docs/guide/walkthrough/goal.md | 52 ------- src/content/docs/guide/walkthrough/goal.mdx | 57 ++++++++ .../docs/guide/walkthrough/good-to-know.md | 10 +- .../docs/guide/walkthrough/new-project.md | 13 -- .../docs/guide/walkthrough/new-project.mdx | 13 ++ .../docs/guide/walkthrough/plugins.mdx | 77 +++++++---- .../docs/guide/walkthrough/sern-emitter.md | 16 --- .../docs/guide/walkthrough/sern-emitter.mdx | 21 +++ .../docs/guide/walkthrough/services.mdx | 76 ++++++----- .../docs/guide/walkthrough/transition.mdx | 8 +- 26 files changed, 556 insertions(+), 371 deletions(-) create mode 100644 src/components/PackageManagers.astro rename src/content/docs/blog/{2022-09-28.md => 2022-09-28.mdx} (95%) rename src/content/docs/blog/{2022-09-30.md => 2022-09-30.mdx} (86%) delete mode 100644 src/content/docs/guide/walkthrough/cli.md create mode 100644 src/content/docs/guide/walkthrough/cli.mdx delete mode 100644 src/content/docs/guide/walkthrough/conclusion.md create mode 100644 src/content/docs/guide/walkthrough/conclusion.mdx delete mode 100644 src/content/docs/guide/walkthrough/dependency-injection.md create mode 100644 src/content/docs/guide/walkthrough/dependency-injection.mdx delete mode 100644 src/content/docs/guide/walkthrough/goal.md create mode 100644 src/content/docs/guide/walkthrough/goal.mdx delete mode 100644 src/content/docs/guide/walkthrough/new-project.md create mode 100644 src/content/docs/guide/walkthrough/new-project.mdx delete mode 100644 src/content/docs/guide/walkthrough/sern-emitter.md create mode 100644 src/content/docs/guide/walkthrough/sern-emitter.mdx diff --git a/bun.lockb b/bun.lockb index 0f9d77d2065af05622c8350ec87a5348b6de39ed..030944d3aa3040a12df919fe59dab7cc72d11125 100755 GIT binary patch delta 43267 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 diff --git a/ec.config.mjs b/ec.config.mjs index 624133242..06c611287 100644 --- a/ec.config.mjs +++ b/ec.config.mjs @@ -6,7 +6,7 @@ export default defineEcConfig({ defaultProps: { showLineNumbers: false, overridesByLang: { - 'js,javascript,typescript,ts': { + 'js,javascript,typescript,ts,json': { showLineNumbers: true, }, }, diff --git a/src/components/PackageManagers.astro b/src/components/PackageManagers.astro new file mode 100644 index 000000000..ce9ca31b3 --- /dev/null +++ b/src/components/PackageManagers.astro @@ -0,0 +1,60 @@ +--- +import { Tabs, TabItem, Code } from "@astrojs/starlight/components"; + +type Command = "add" | "update" | "remove"; +type PackageManager = (typeof packageManagers)[number]; + +const packageManagers = ["NPM", "PNPM", "Yarn", "Bun"] as const; + +interface Props { + command: Command; + text: string; +} + +const packageManagerCode = ( + command: Command, + text: string, + manager: PackageManager, +) => { + const commands = { + add: { + NPM: `npm install ${text}`, + Yarn: `yarn add ${text}`, + PNPM: `pnpm add ${text}`, + Bun: `bun add ${text}`, + }, + update: { + NPM: `npm update ${text}`, + Yarn: `yarn upgrade ${text}`, + PNPM: `pnpm update ${text}`, + Bun: `bun update ${text}`, + }, + remove: { + NPM: `npm uninstall ${text}`, + Yarn: `yarn remove ${text}`, + PNPM: `pnpm remove ${text}`, + Bun: `bun remove ${text}`, + }, + create: { + NPM: `npm create ${text}`, + Yarn: `yarn create ${text}`, + PNPM: `pnpm create ${text}`, + Bun: `bun create ${text}`, + } + }; + + return commands[command][manager]; +}; + +const { command, text } = Astro.props; +--- + + + { + packageManagers.map((manager) => ( + + + + )) + } + diff --git a/src/content/docs/blog/2022-09-28.md b/src/content/docs/blog/2022-09-28.mdx similarity index 95% rename from src/content/docs/blog/2022-09-28.md rename to src/content/docs/blog/2022-09-28.mdx index 10d476c90..d5097f20a 100644 --- a/src/content/docs/blog/2022-09-28.md +++ b/src/content/docs/blog/2022-09-28.mdx @@ -11,9 +11,9 @@ date: 2022-09-28 Today we're announcing the ability to create class based modules! To get started, install -``` -npm install @sern/handler@latest -``` +import PackageManagers from '~/components/PackageManagers.astro'; + + Quick List of changes! diff --git a/src/content/docs/blog/2022-09-30.md b/src/content/docs/blog/2022-09-30.mdx similarity index 86% rename from src/content/docs/blog/2022-09-30.md rename to src/content/docs/blog/2022-09-30.mdx index cf9340863..95337a622 100644 --- a/src/content/docs/blog/2022-09-30.md +++ b/src/content/docs/blog/2022-09-30.mdx @@ -16,13 +16,13 @@ Today I'm going to show you how to get started with sern and all its cool featur Install the CLI: -``` -npm i -g @sern/cli -``` +import PackageManagers from '~/components/PackageManagers.astro'; + + and then run -``` +```sh sern init ``` @@ -30,7 +30,7 @@ sern init You can also run `sern init -y` if you want to use the default options. ::: -The CLI is written in Typescript and open-sourced on [Github](https://github.com/sern-handler/cli). (thanks [evo](https://github.com/EvolutionX-10)!) +The CLI is written in TypeScript and open-source on [GitHub](https://github.com/sern-handler/cli). (thanks [evo](https://github.com/EvolutionX-10)!) ### Step 2: Have some way to store secrets. diff --git a/src/content/docs/guide/getting-started/choose-ide.md b/src/content/docs/guide/getting-started/choose-ide.md index 7e2808f09..91439c1af 100644 --- a/src/content/docs/guide/getting-started/choose-ide.md +++ b/src/content/docs/guide/getting-started/choose-ide.md @@ -6,7 +6,7 @@ Choosing an IDE is a matter of personal preference. They make programming easier suggestions for choosing an IDE: - [Visual Studio Code](https://code.visualstudio.com) - - we have an [snippet extension](https://marketplace.visualstudio.com/items?itemName=SrIzan.sern-snippets) to help automate development :) + - We have an [snippet extension](https://marketplace.visualstudio.com/items?itemName=SrIzan.sern-snippets) to help automate development :) - [Sublime Text](https://www.sublimetext.com/) - [NotePad++](https://notepad-plus-plus.org/) - [nvim](https://neovim.io/) (chad) diff --git a/src/content/docs/guide/getting-started/preparing.md b/src/content/docs/guide/getting-started/preparing.md index 8501af058..1af518e1a 100644 --- a/src/content/docs/guide/getting-started/preparing.md +++ b/src/content/docs/guide/getting-started/preparing.md @@ -2,12 +2,10 @@ title: Preparing to Code --- -After installing an IDE, you need to install node. +After installing an IDE, you need to install `node`. Node is necessary to use `sern`, as it's based on `Discord.js`. -[Click to download the LTS version of node right here](https://nodejs.org/en/download/). +You can download Node from the official website [here](https://nodejs.org/en/download/). -After you downloaded node you will need: - -#### [Discord token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) +After you've downloaded Node you will need a [Discord token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) CONTINUE 🤓 diff --git a/src/content/docs/guide/walkthrough/autocomplete.md b/src/content/docs/guide/walkthrough/autocomplete.md index 23b5aac19..e617aae88 100644 --- a/src/content/docs/guide/walkthrough/autocomplete.md +++ b/src/content/docs/guide/walkthrough/autocomplete.md @@ -4,12 +4,15 @@ sidebar: order: 9 --- -Autocomplete is a special interaction where it can happen on multiple options on a single command. We've handled this with a simple -tree search algorithm in a nested options tree. +Autocomplete is a special interaction which can happen on multiple options can be suggested for a single command. + +We've implemented this functionality using a simple tree search algorithm within a nested options tree. ## Example -```ts title="src/commands/cheese.ts" {13-21} +In this example, the option `list` will autocomplete with the cheeses `gouda`, `parmesan`, and `harvarti`. + +```ts title="src/commands/cheese.ts" {13-22} export default commandModule({ type: CommandType.Slash, description: "show me cheese", @@ -23,9 +26,10 @@ export default commandModule({ command: { onEvent: [], execute: (ctx) => { + // focus can be used to refine the options const focus = ctx.options.getFocused(); ctx.respond( - ["gouda", "parmesan", "harvati"].map((cheese) => ({ + ["gouda", "parmesan", "harvarti"].map((cheese) => ({ name: cheese, value: cheese, })), @@ -41,4 +45,48 @@ export default commandModule({ }); ``` +## Using Focus + +The `focus` object can be used to refine the options. For example, if the user types `g`, the focus object will be `g`. + +We can filter the cheeses based on the focus object, and return only the cheeses that start with the focus object. + +You can do a lot more with the focus object, such as performing API calls, or implementing a fuzzy search. + +```ts title="src/commands/cheese.ts" {13-23} +export default commandModule({ + type: CommandType.Slash, + description: "show me cheese", + options: [ + { + name: "list", + type: ApplicationCommandOptionType.String, + description: "pick a cheese to show", + required: true, + autocomplete: true, + command: { + onEvent: [], + execute: (ctx) => { + const focus = ctx.options.getFocused(); + ctx.respond( + ["gouda", "parmesan", "harvarti"] + .filter((cheese) => cheese.startsWith(focus)) + .map((cheese) => ({ + name: cheese, + value: cheese, + })), + ); + }, + }, + }, + ], + execute: (ctx, [, args]) => { + const cheese = args.getString("list", true); + ctx.reply("selected cheese"); + }, +}); +``` + +:::tip Sern will handle autocomplete interactions at arbitrary depths and subcommand levels. +::: diff --git a/src/content/docs/guide/walkthrough/cli.md b/src/content/docs/guide/walkthrough/cli.md deleted file mode 100644 index 7a3f8cba6..000000000 --- a/src/content/docs/guide/walkthrough/cli.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: CLI -sidebar: - order: 3 ---- - -Setting up the [CLI](https://github.com/sern-handler/cli) is easy. - -The cli is your plug to the sern ecosystem. This will allow you to install plugins with ease, install extra utilities, and much more. -If you haven't yet: - -```sh -npm install -g @sern/cli -``` - -- To install [plugins](plugins.md) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins), - -```sh -sern plugins -``` - -:::caution -Make sure to have a correct [sern.config.json](../good-to-know.md#sernconfigjson) -::: - -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 - -```sh -sern extra -``` - -We have a more in depth [guide](../../cli/README.md) of the CLI diff --git a/src/content/docs/guide/walkthrough/cli.mdx b/src/content/docs/guide/walkthrough/cli.mdx new file mode 100644 index 000000000..c82f311b2 --- /dev/null +++ b/src/content/docs/guide/walkthrough/cli.mdx @@ -0,0 +1,43 @@ +--- +title: CLI +sidebar: + order: 3 +--- + +Setting up the [CLI](https://github.com/sern-handler/cli) is easy. + +The CLI is your plug to the sern ecosystem. It allows you to install plugins with ease, install extra utilities, and much more. + +## Installing the CLI + +If you haven't already installed the CLI globally, you can do so by running: + +import PackageManagers from '~/components/PackageManagers.astro'; + + + +## Adding Plugins + +:::caution +You must have a [sern.config.json](../good-to-know.md#sernconfigjson) to use this command. +::: + +To install [plugins](../plugins) maintained by the community [repository](https://github.com/sern-handler/awesome-plugins): + +```sh +sern plugins +``` + +This will display a menu selection of all installable plugins. + +If you'd like to view all plugins, check out our [plugins page](../../../plugins). + +## Extra Utilities + +To install extra utilities into your project, run: + +```sh +sern extra +``` + +We have a more in depth [guide](../../../cli/about) on the CLI if you're interested in learning more. diff --git a/src/content/docs/guide/walkthrough/conclusion.md b/src/content/docs/guide/walkthrough/conclusion.md deleted file mode 100644 index fa5ec1a38..000000000 --- a/src/content/docs/guide/walkthrough/conclusion.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Conclusion -sidebar: - order: 12 ---- - -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://sern.dev/discord), and we'll be glad to answer your questions. - -![](/blog/newlogo/paperlogo.png) diff --git a/src/content/docs/guide/walkthrough/conclusion.mdx b/src/content/docs/guide/walkthrough/conclusion.mdx new file mode 100644 index 000000000..9e793090f --- /dev/null +++ b/src/content/docs/guide/walkthrough/conclusion.mdx @@ -0,0 +1,16 @@ +--- +title: Conclusion +sidebar: + order: 12 +--- + +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://sern.dev/discord), and we'll be glad to answer your questions! + +import { Image } from 'astro:assets'; +import paperLogo from '~/assets/blog/paper-logo.png'; + +paper logo diff --git a/src/content/docs/guide/walkthrough/dependency-injection.md b/src/content/docs/guide/walkthrough/dependency-injection.md deleted file mode 100644 index ebaf585c4..000000000 --- a/src/content/docs/guide/walkthrough/dependency-injection.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Dependency Injection -sidebar: - order: 10 ---- - -:::caution -This contains version 2 code. Please view [transitioning to v3](./transition) -::: - -Since version 2.0.0, dependency injection, thanks to [iti](https://github.com/molszanski/iti), is a feature to customize your bot's utilities and structures. - -Minimal setup for any project. - -```ts -const client = new Client({ - ...options, -}); -Sern.makeDependencies({ - build: (root) => - root.add({ - "@sern/client": single(() => client), - }), -}); -``` - -For any typescript project, you'll need to add an interface to get intellisense and typings. - -```typescript -interface MyDependencies extends Dependencies { - "@sern/client": Singleton; -} -``` - -Full Dependency Injection setup - -```typescript -const client = new Client({ - ...options, -}); - -interface MyDependencies extends Dependencies { - "@sern/client": Singleton; -} - -export const useContainer = Sern.makeDependencies({ - build: (root) => - root.add({ - "@sern/client": single(() => client), - }), -}); -``` - -Everything else is handled. However, you may want customize things. - -## Adding dependencies to root - -Each sern built dependency must implement its contracts. - -- `@sern/logger`: Log data. [Logging](../../api/interfaces/Logging) -- `@sern/errors`: Handling errors and lifetime. [ErrorHandling](../../api/interfaces/ErrorHandling) -- `@sern/modules`: Managing all command modules. [ModuleManager](../../api/interfaces/ModuleManager) -- `@sern/emitter`: is the key to emit events and occurences in a project. [SernEmitter](../../api/classes/SernEmitter) - -You may also add disposers so that when the application crashes, the targeted dependency calls that function. - -```typescript -export const useContainer = Sern.makeDependencies({ - build: (root) => - root - .add({ - "@sern/client": single(() => client), - }) - .addDisposer({ "@sern/client": (client) => client.destroy() }), -}); -``` - -:::tip -Below is v3 api. -::: - -## Init - -Do you need to perform intializing behavor for a dependency? - -```ts -import { Init } from "@sern/handler"; -class Database implements Init { - init() { - await this.connect(); - console.log("Connected"); - } -} -``` - -Modify you Dependencies interface: - -```ts title="src/dependencies.d.ts" -import type { Initializable } from "@sern/handler"; - -interface Dependencies extends CoreDependencies { - database: Initializable; -} -``` - -Make sure its been added: - -```ts title="src/index.ts" -await makeDependencies({ - build: root => root - .add({ database => new Database() }) -}) -``` diff --git a/src/content/docs/guide/walkthrough/dependency-injection.mdx b/src/content/docs/guide/walkthrough/dependency-injection.mdx new file mode 100644 index 000000000..a0ee5b081 --- /dev/null +++ b/src/content/docs/guide/walkthrough/dependency-injection.mdx @@ -0,0 +1,128 @@ +--- +title: Dependency Injection +sidebar: + order: 10 +--- + +:::danger +This contains version 2 code. Please view [transitioning to v3](../transition) for the `Service` API. +::: + +Since version 2.0.0, dependency injection, thanks to [iti](https://github.com/molszanski/iti), is a feature to customize your bot's utilities and structures. + +For example, a minimal setup for any project might look like this: + +```ts title="src/index.ts" +const client = new Client({ + ...options, +}); + +Sern.makeDependencies({ + build: (root) => + root.add({ + "@sern/client": single(() => client), + }), +}); +``` + +For any TypeScript project, you'll need to add an interface to get intellisense and typings. + +```ts title="src/dependencies.d.ts" +interface MyDependencies extends Dependencies { + "@sern/client": Singleton; +} +``` + +## Full Example + +Your full setup may have the following structure: + +import { FileTree } from '@astrojs/starlight/components'; + + +- src/ + - index.ts **(your main file and client)** + - dependencies.d.ts **(for intellisense)** + + +```ts title="src/index.ts" +const client = new Client({ + ...options, +}); + +interface MyDependencies extends Dependencies { + "@sern/client": Singleton; +} + +export const useContainer = Sern.makeDependencies({ + build: (root) => + root.add({ + "@sern/client": single(() => client), + }), +}); +``` + +Everything else is handled. However, you may want customize things. + +## Adding Dependencies to Root + +Each sern built dependency must implement its contracts: + +- `@sern/logger`: Logging data → [`Logging`](../../../api/interfaces/logging) +- `@sern/errors`: Handling errors and lifetime → [`ErrorHandling`](../../../api/interfaces/errorhandling) +- `@sern/modules`: Managing all command modules → [`ModuleManager`](../../../api/interfaces/modulemanager) +- `@sern/emitter`: The key to emit events and occurences in a project → [`Emitter`](../../../api/interfaces/emitter) + +You may also add disposers so that when the application crashes, the targeted dependency calls that function. + +```ts title="src/index.ts" +export const useContainer = Sern.makeDependencies({ + build: (root) => + root + .add({ + "@sern/client": single(() => client), + }) + .addDisposer({ "@sern/client": (client) => client.destroy() }), +}); +``` + +:::caution +Below is v3 API. +::: + +## Init + +import { Steps } from '@astrojs/starlight/components'; + + +1. Do you need to perform intializing behavor for a dependency? + ```ts title="src/database.ts" + import { Init } from "@sern/handler"; + + class Database implements Init { + init() { + await this.connect(); + console.log("Connected"); + } + } + ``` + +2. Modify your `Dependencies` interface: + ```ts title="src/dependencies.d.ts" {4} + import type { Initializable } from "@sern/handler"; + + interface Dependencies extends CoreDependencies { + database: Initializable; + } + ``` + +3. Make sure its been added: + ```ts title="src/index.ts" {3} + await makeDependencies({ + build: root => root + .add({ database => new Database() }) + }) + ``` + +4. Now, when your bot starts, the `init` method will be called. 🎉 + diff --git a/src/content/docs/guide/walkthrough/first-command.mdx b/src/content/docs/guide/walkthrough/first-command.mdx index c2b9323d4..3614729bc 100644 --- a/src/content/docs/guide/walkthrough/first-command.mdx +++ b/src/content/docs/guide/walkthrough/first-command.mdx @@ -4,19 +4,29 @@ sidebar: order: 5 --- -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. - :::tip -TLDR: command modules are discord bot commands. There are many types, and each one will correspond to an event from discord. -For example, CommandType.Slash commands will listen to slash command interactions. +**TLDR:** Command modules are Discord bot commands. There are many types, and each one will correspond to an event from Discord. For example, `CommandType.Slash` commands will listen to slash command interactions. ::: +## Introduction + +In this guide, we'll walk you through creating your first command module. + +If you installed a new project via the CLI, your file should be here: + +import { FileTree } from '@astrojs/starlight/components'; + + +- src/commands/ + - ping.ts **(right here, probably)** +- ... + + import { Tabs, TabItem } from '@astrojs/starlight/components'; - ```js + ```js title="src/commands/ping.js" const { CommandType, commandModule } = require("@sern/handler"); export default commandModule({ @@ -30,8 +40,8 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; }); ``` - - ```ts + + ```ts title="src/commands/ping.ts" import { commandModule, CommandType } from "@sern/handler"; export default commandModule({ @@ -47,22 +57,27 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; -To view what each of these properties mean in depth, visit the [official documentation](https://sern.dev/docs/api/enums/CommandType). +To view what each of these properties mean in depth, visit the docs for [`CommandType`](../../../api/enumerations/commandtype). -### Types of command modules +## Command Module Types -Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields.
-All the command types can be found in the [official documentation](https://sern.dev/docs/api/enums/CommandType)! +Every command module `type` is part of an enum. This field allows type inference for the rest of a module's fields. -

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

+All the command types can be found in the [`CommandType`](../../../api/enumerations/commandtype) enum! -**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. -
+## Example Modal Command + +So, lets say you want to make a command module that listens to modals. + +:::tip +Keep in mind, you'll need to send a modal with a custom id of `dm-me`. This example below is the response to a modal being sent. +::: ```javascript const { CommandType, commandModule } = require("@sern/handler"); + exports.default = commandModule({ name: "dm-me", type: CommandType.Modal, @@ -76,9 +91,10 @@ All the command types can be found in the [official documentation](https://sern. }); ``` - + ```typescript import { commandModule, CommandType } from "@sern/handler"; + export default commandModule({ name: "dm-me", type: CommandType.Modal, @@ -94,14 +110,13 @@ All the command types can be found in the [official documentation](https://sern. -Commands are straight forward. Keep in mind, every other property on the commandModule object is -optional **except** the type and execute function. +Commands are straight forward. Keep in mind, the only required fields for command modules are the `type` and `execute` function. -# Context class +## Context Class -The provided Context class helps with modules of `CommandType.Both` (A mixture of slash / legacy commands). +The provided [`Context`](../../../api/classes/context) class helps with modules of `CommandType.Both` (A mixture of slash / legacy commands). -The Context class is passed into modules with type: +The `Context` class is passed into modules with type: - `CommandType.Both` - `CommandType.Slash` diff --git a/src/content/docs/guide/walkthrough/first-event.mdx b/src/content/docs/guide/walkthrough/first-event.mdx index 0c707e905..705c7f410 100644 --- a/src/content/docs/guide/walkthrough/first-event.mdx +++ b/src/content/docs/guide/walkthrough/first-event.mdx @@ -4,17 +4,19 @@ sidebar: order: 6 --- -We will dissect a basic event module.
- :::tip -TLDR: event modules are event listeners. there are three types EventType.Discord, EventType.Sern, EventType.External +**TLDR:** Event modules are event listeners. There are three types: `EventType.Discord`, `EventType.Sern`, and `EventType.External`. ::: +## Introduction + +In this guide, we'll walk you through creating your first event module. + import { Tabs, TabItem } from '@astrojs/starlight/components'; - ```javascript + ```js title="src/events/activate.js" exports.default = eventModule({ type: EventType.Sern, plugins : [], @@ -25,8 +27,8 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; }) ``` - - ```typescript + + ```ts title="src/events/activate.ts" export default eventModule({ type: EventType.Sern, plugins : [], @@ -39,16 +41,15 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; -Like command modules, the `type` property denotes what kind of event it is, which -can be found [here](https://sern.dev/docs/api/enums/EventType). +Similar to command modules, the `type` property denotes what kind of event it is. You can view [`EventType`](../../../api/enumerations/eventtype) for more information. -To view what each of these properties mean in depth, visit the [official documentation](https://sern.dev/docs/api/enums/EventType). +To view what each of these properties mean in depth, visit the docs for [`EventType`](../../../api/enumerations/eventtype). -## External +## External Events -In version 2 & 3, any dependency that you have passed into makeDependencies can be registered here as well. +In versions 2 & 3, any dependency that you have passed into `makeDependencies` can be registered here as well. -```ts title="src/index.ts" +```ts title="src/index.ts" {3} await makeDependencies({ build: root => root.add({ eventlistener: single(() => new EventEmitter()) @@ -56,14 +57,18 @@ await makeDependencies({ }) ``` -```ts title="events/myevent.ts" +In your event module, you can now listen to events from `eventlistener`, which will be emitted from the `EventEmitter`. + +```ts title="src/events/myevent.ts" {3} export default eventModule({ type: EventType.External, emitter: 'eventlistener', execute: (args) => { - console.log('Got event from eventlistener: ', args); + console.log('Got event from eventlistener: ', args); } }) ``` - +:::note +Make sure that the `emitter` property matches the name of the dependency you passed into `makeDependencies`. +::: \ No newline at end of file diff --git a/src/content/docs/guide/walkthrough/goal.md b/src/content/docs/guide/walkthrough/goal.md deleted file mode 100644 index 6dc142a13..000000000 --- a/src/content/docs/guide/walkthrough/goal.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Goal -sidebar: - order: 1 ---- - -This walkthrough will be written in [TypeScript](https://www.typescriptlang.org/) but will have JavaScript snippets throughout. - -# Make robust, modular, bots - -- _Modularity_: sern is built with modularity in mind. You can swap pieces and parts easily. -- _Familiar_: commands and structures are similar to classic v12 handlers and the official discord.js command handler guide, while packing many features -- _Concise_: Too much code is a liability. with sern, write less for more 🤯 - -### Using @sapphire/framework - -```ts title="commands/ping.ts" showLineNumbers -import { Command } from "@sapphire/framework"; -import type { CommandInteraction } from "discord.js"; - -export class PingCommand extends Command { - public constructor(context: Command.Context) { - super(context, { - description: "Pong!", - chatInputCommand: { - register: true, - }, - }); - } - public async chatInputRun(interaction: CommandInteraction) { - await interaction.reply("Pong!"); - } -} -``` - -### Using @sern/handler - -```ts title="commands/ping.ts" showLineNumbers -import { commandModule, CommandType } from "@sern/handler"; -import { publish } from "../plugins"; - -export default commandModule({ - type: CommandType.Both, - plugins: [publish()], - description: "Pong!", - execute: (ctx, args) => { - await ctx.reply("Pong!"); - }, -}); -``` - -Keep in mind the above example acts as both a slash command AND text command diff --git a/src/content/docs/guide/walkthrough/goal.mdx b/src/content/docs/guide/walkthrough/goal.mdx new file mode 100644 index 000000000..6704eec59 --- /dev/null +++ b/src/content/docs/guide/walkthrough/goal.mdx @@ -0,0 +1,57 @@ +--- +title: Goal +sidebar: + order: 1 +--- + +This walkthrough will be written in [TypeScript](https://www.typescriptlang.org/) but will have JavaScript snippets throughout. + +## Make robust, modular, bots + +- **Modularity**: sern is built with modularity in mind. You can swap pieces and parts easily. +- **Familiar**: Commands and structures are similar to classic v12 handlers and the official Discord.js command handler guide, while packing many features! +- **Concise**: Too much code is a liability. With sern, write less for more. 🤯 + +## Why sern? + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + + + + ```ts title="commands/ping.ts" + import { Command } from "@sapphire/framework"; + import type { CommandInteraction } from "discord.js"; + + export class PingCommand extends Command { + public constructor(context: Command.Context) { + super(context, { + description: "Pong!", + chatInputCommand: { + register: true, + }, + }); + } + public async chatInputRun(interaction: CommandInteraction) { + await interaction.reply("Pong!"); + } + } + ``` + + + ```ts title="commands/ping.ts" + import { commandModule, CommandType } from "@sern/handler"; + + export default commandModule({ + type: CommandType.Both, + description: "Pong!", + execute: async (ctx, args) => { + await ctx.reply("Pong!"); + }, + }); + ``` + + + +Keep in mind the sern example acts as both a slash command AND a text command. The Sapphire example is only a slash command, and it's more code than sern. + +## Be smart. Choose sern. diff --git a/src/content/docs/guide/walkthrough/good-to-know.md b/src/content/docs/guide/walkthrough/good-to-know.md index 417c5dabc..207756a99 100644 --- a/src/content/docs/guide/walkthrough/good-to-know.md +++ b/src/content/docs/guide/walkthrough/good-to-know.md @@ -6,15 +6,15 @@ sidebar: ## sern.config.json -

A sern.config.json, although not necessary, allows your project to communicate with our cli.

+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).
+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 file in the your project. -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 +```json title="sern.config.json" { "language": "typescript", "paths": { diff --git a/src/content/docs/guide/walkthrough/new-project.md b/src/content/docs/guide/walkthrough/new-project.md deleted file mode 100644 index 6af40bfa0..000000000 --- a/src/content/docs/guide/walkthrough/new-project.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: New Project -sidebar: - order: 2 ---- - -```sh -npm create @sern/bot -``` - -and follow the interactive prompts. - -if somehow you need help, feel free to ask [here](https://sern.dev/discord) diff --git a/src/content/docs/guide/walkthrough/new-project.mdx b/src/content/docs/guide/walkthrough/new-project.mdx new file mode 100644 index 000000000..e43ce7de5 --- /dev/null +++ b/src/content/docs/guide/walkthrough/new-project.mdx @@ -0,0 +1,13 @@ +--- +title: New Project +sidebar: + order: 2 +--- + +import PackageManagers from '~/components/PackageManagers.astro'; + + + +Once you've used this command, follow the interactive prompts to create your new project. + +If you need help, feel free to ask on our [Discord](https://sern.dev/discord). diff --git a/src/content/docs/guide/walkthrough/plugins.mdx b/src/content/docs/guide/walkthrough/plugins.mdx index 2066a9e8b..0ad406117 100644 --- a/src/content/docs/guide/walkthrough/plugins.mdx +++ b/src/content/docs/guide/walkthrough/plugins.mdx @@ -5,25 +5,31 @@ sidebar: --- :::tip -TLDR: Plugins help reduce code repetition and are installable via `sern plugins`. Put them onto the plugins field of a command/event module. +**TLDR:** Plugins help reduce code repetition and are installable via `sern plugins`. Put them into the `plugins` field of a command/event module. ::: -## Installing +## Installation Chances are, you just want your bot to work. Plugins can preprocess and create reusable conditions for modules. -run: +To install plugins, you can use the CLI: ```sh sern plugins ``` -- Install your favorite(s) (or the ones that look the coolest). In my imaginary mind, I installed the ownerOnly plugin. - - This should install in `plugins` directory in `src`. -- Some plugins only work with specific types. Most are targeted towards slash / both modules. -- Add to your module. +:::caution +Some plugins only work with specific command types. Most, however, are targeted towards slash / both modules. +::: -```ts +import { Steps } from '@astrojs/starlight/components'; + + +1. Install your favorite(s) (or the ones that look the coolest). In my imaginary mind, I installed the `ownerOnly` plugin. (This should install to `src/plugins`) +2. Add the plugin to your module in the `plugins` field. + + +```ts title="src/commands/ping.ts" {6} import { commandModule, CommandType } from '@sern/handler' import { ownerOnly } from '../plugins' @@ -39,13 +45,17 @@ export default commandModule({ #### ┗|` O′|┛ perfect, your first plugin! -## Creating your own plugins +## Creating Plugins -The controller determines in plugins whether to continue or fail. +Plugins are essentially functions that use the controller object to determine whether to continue or stop the execution of a command. -### The controller object +### Controller Object -```typescript +The controller object is passed into every plugin. It has two methods: `next` and `stop`. + +Plugins use these methods to control the flow of the command. For example, if a plugin fails, it can call `controller.stop()` to prevent the command from executing. + +```ts export interface Controller { next: () => Ok; stop: () => Err; @@ -55,28 +65,31 @@ export interface Controller { ## Init Plugins Init plugins modify how commands are loaded or do preprocessing. -An instance of the above object is passed into every plugin.
-This controls whether a module is stored into sern.
-```typescript +An instance of `Controller` (as seen above) is passed into every plugin. This controls whether a module is stored into sern. + +```ts title="src/plugins/inDir.ts" {11} {14} import { CommandInitPlugin } from "@sern/handler"; import path from "path"; + export const inDir = (dir: string) => { return CommandInitPlugin(({ module, absPath }) => { if (path.dirname(absPath) !== dir) { console.log( - +new Date(), + Date.now(), `${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 + console.log(Date.now(), `${module.name} is in the correct directory!`); + return controller.next(); // continue to next plugin }); }; ``` -Above, this simple plugin logs that the module has been loaded along with a timestamp.
+:::tip +The plugin above simply checks if the module is in the correct directory. If it's not, it logs a message and stops the command from being loaded. +::: ## Event Plugins @@ -85,20 +98,24 @@ import eventPlugins from '~/assets/docs/event-plugins.png'; control plugins -- An event is emitted by discord.js. -- This event is passed to all plugins (**in order!!**), -- If all are successful, + +1. An event is emitted by `discord.js`. +2. This event is passed to all plugins (**in order!!**), +3. If all are successful, the command is executed. + -The command is executed. Calling `controller.stop()` notifies sern that this command should not be run, -and command is ignored. +:::note +Calling `controller.stop()` notifies sern that this command should not be run, and command is ignored. +::: -Can you predict the behavior of this command? +#### 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`. + +1. Before loading into sern, this command module will check if this module is in the correct directory: `other`. +2. Before an event occurs, this command module will check if the user has the id `182326315813306368`. +3. If all plugins return `controller.next()`, this command replies `Pong 🏓` + :::tip Event Plugins are good for filtering, preconditions, parsing. -::: - -If all plugins return `controller.next()`, this command replies `Pong 🏓` +::: \ No newline at end of file diff --git a/src/content/docs/guide/walkthrough/sern-emitter.md b/src/content/docs/guide/walkthrough/sern-emitter.md deleted file mode 100644 index f819dc4f8..000000000 --- a/src/content/docs/guide/walkthrough/sern-emitter.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Sern Emitter -sidebar: - order: 11 ---- - -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 -- On default, sern creates a single SernEmitter for your bot process. -- any error that occurs, the `error` event -- `warn` events, where it is possible to throw errors - -You can put these and other event listeners into [event modules](./first-event.md)! -
View all events diff --git a/src/content/docs/guide/walkthrough/sern-emitter.mdx b/src/content/docs/guide/walkthrough/sern-emitter.mdx new file mode 100644 index 000000000..1dc87001e --- /dev/null +++ b/src/content/docs/guide/walkthrough/sern-emitter.mdx @@ -0,0 +1,21 @@ +--- +title: Sern Emitter +sidebar: + order: 11 +--- + +You're shipped with the `SernEmitter` class. This `EventEmitter` listens to + +import { Steps } from '@astrojs/starlight/components'; + + +1. Command modules executing and its status; the `module.activate` event +2. Command modules registered and its status; the `module.register` event +3. On default, sern creates a single SernEmitter for your bot process. +4. Any error that occurs; the `error` event +5. `warn` events, where it is possible to throw errors + + +You can put these and other event listeners into [event modules](../first-event)! + +You can view all events in the [`SernEventsMapping`](../../../api/interfaces/serneventsmapping) interface. \ No newline at end of file diff --git a/src/content/docs/guide/walkthrough/services.mdx b/src/content/docs/guide/walkthrough/services.mdx index 40ca288b6..a94b0607d 100644 --- a/src/content/docs/guide/walkthrough/services.mdx +++ b/src/content/docs/guide/walkthrough/services.mdx @@ -4,16 +4,16 @@ sidebar: order: 8 --- -:::tip +:::danger This is version 3 api only!! ::: :::tip -TLDR: The direct upgrade to useContainer. if you set up a bot with create-bot, check dependencies.d.ts. +**TLDR:** The direct upgrade to `useContainer`. if you set up a bot with `create-bot`, check `dependencies.d.ts`. Dependencies are the types that Services uses. ::: -You need someway to use dependencies in your command module. Services to the rescue! +You need some way to use dependencies in your command module. Services to the rescue! ```ts title="src/dependencies.d.ts" import { CoreDependencies, Singleton } from "@sern/handler"; @@ -24,28 +24,31 @@ interface Dependencies extends CoreDependencies { } ``` -Recall, some keys in Dependencies are special. +## Special Dependencies -> Special key dependency must implement its contracts. -> -> - `@sern/client`: Your discord client. -> [Emitter](../../api/interfaces/Emitter) -> - `@sern/logger`: Log data -> [Logging](../../api/interfaces/Logging) -> - `@sern/errors`: Handling errors and lifetime -> [ErrorHandling](../../api/interfaces/ErrorHandling) -> - `@sern/modules`: Managing all command modules -> [ModuleManager](../../api/interfaces/ModuleManager) -> - `@sern/emitter`: is the key to emit events and occurences in a project -> [Emitter](../../api/interfaces/Emitter) +Some keys in `Dependencies` are special and are used by sern internally: + +- `@sern/client`: Your Discord client. → [`Emitter`](../../../api/interfaces/emitter) +- `@sern/logger`: Logging data → [`Logging`](../../../api/interfaces/logging) +- `@sern/errors`: Handling errors and lifetime → [`ErrorHandling`](../../../api/interfaces/errorhandling) +- `@sern/modules`: Managing all command modules → [`ModuleManager`](../../../api/interfaces/modulemanager) +- `@sern/emitter`: The key to emit events and occurences in a project → [`Emitter`](../../../api/interfaces/emitter) + +## Usage Lets try to access the client you provided. -```ts title="src/commands/ping.ts" +```ts title="src/commands/ping.ts" {8} import { Service } from "@sern/handler"; export default commandModule({ // ... execute: (ctx) => { - //Client! + // Type is inferred from the dependencies file. + // → Dependencies['@sern/client'] const client = Service("@sern/client"); }, - // + // ... }); ``` @@ -53,16 +56,18 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ## Safety -- Services cannot be called in other services while makeDependencies is forming. +Services cannot be called in other services while `makeDependencies` is forming. + +For example, let's pass a logger into our database: + +### Example - Lets pass a logger into our database. - ```ts title="index.ts" await makeDependencies({ build: root => root - //Overriding the default logger provided. + // Overriding the default logger provided. .upsert({ '@sern/logger': single(() => new Logger()) }) // Wiring our logger into the database. @@ -77,7 +82,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; await makeDependencies({ build: (root) => root - //Overriding the default logger provided. + // Overriding the default logger provided. .upsert({ "@sern/logger": single(() => new Logger()) }) // Wiring our logger into the database. @@ -89,7 +94,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ```ts title="index.ts" import { Service, makeDependencies } from "@sern/handler"; - //Calling Service prematurely! + // Calling Service prematurely! const logger = Service("@sern/logger"); class Database { @@ -102,18 +107,12 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; -- Services can only be used after sern has made dependencies. - - Calling a service before will crash your application. -- Services can be safely used outside of commandModules. - - - Be careful to not cause too many side effects. - -- You will need to wire dependencies together. +### Another Example ```ts title="index.ts" - await makeDependencies(...pass your options here) + await makeDependencies(/* ...pass your options here */) ``` ```ts title="commands/ping.ts" @@ -133,12 +132,19 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; -- Services can only be used after sern has made dependencies. - - Calling a service before will crash your application. -- Services can be safely used outside of commandModules. - - Be careful to not cause too many side effects. +## Important -## Related api +import { Steps } from '@astrojs/starlight/components'; -- use `Service` for single dependency. -- use `Services` for multiple dependencies. + +1. Services can only be used after sern has made dependencies.
→ Calling a service before will crash your application. +2. Services can be safely used outside of a `commandModule`.
→ Be careful to not cause too many side effects. +3. You will need to wire dependencies together.
→ This is a good practice to keep your code clean. +4. Services can only be used after sern has made dependencies.
→ Calling a service before will crash your application. +5. Services can be safely used outside of a `commandModule`.
→ Be careful to not cause too many side effects. +
+ +## Related API + +- Use `Service` for single dependency. +- Use `Services` for multiple dependencies. diff --git a/src/content/docs/guide/walkthrough/transition.mdx b/src/content/docs/guide/walkthrough/transition.mdx index 32bcf33b4..4eaa42b94 100644 --- a/src/content/docs/guide/walkthrough/transition.mdx +++ b/src/content/docs/guide/walkthrough/transition.mdx @@ -9,10 +9,10 @@ sidebar: + await makeDependencies({ build: () => {} }) ``` -v3 comes with the new [Service api](../services). To make sure to enable intellisense -include a dependencies.d.ts file into compilation. [Click here for all new features](../../../blog/3.0.0) +v3 comes with the new [Service API](../services). To make sure to enable intellisense, +include a `dependencies.d.ts` file into compilation. (Check out the [changelog](../../../blog/3.0.0) for all new features) -```ts +```ts title="dependencies.d.ts" /** * This file serves as intellisense for sern projects. * Types are declared here for dependencies to function properly @@ -48,7 +48,7 @@ import { FileTree } from '@astrojs/starlight/components'; - commands/ - events/ - plugins/ - - dependencies.d.ts + - dependencies.d.ts **(add this)** - index.ts - .env - .gitignore