### Manually Install Sunar and Discord.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Install Sunar and its peer dependency, discord.js, using your package manager. Ensure Node.js version 18 or newer is installed on your machine before proceeding. ```bash sunar discord.js ``` -------------------------------- ### Create Ping Slash Command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Implement a simple `/ping` slash command that responds with the bot's WebSocket ping. This demonstrates how to define a basic interaction command with a name and description, and how to execute a reply. ```javascript import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'ping', description: 'Show client ws ping', }); execute(slash, (interaction) => { interaction.reply({ content: `Client WS Ping: ${interaction.client.ws.ping}`, }); }); export { slash }; ``` -------------------------------- ### Initialize Sunar Discord Client Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Create a new `Client` instance, load Sunar modules from specified directories (e.g., commands, signals), and log in to Discord using your bot token. Remember to replace `'YOUR_DISCORD_BOT_TOKEN'` with your actual bot token obtained from the Discord Developer Portal. ```javascript import { Client, dirname, load } from 'sunar'; const start = async () => { const client = new Client({ intents: [] }); // stores all sunar modules, you can add more // directories by passing them after the "signals" // with a comma (e.g. signals,buttons,autocompletes) await load(`${dirname(import.meta.url)}/{commands,signals}/**/*.{js,ts}`); client.login('YOUR_DISCORD_BOT_TOKEN'); }; start(); ``` -------------------------------- ### Create Ready Signal for Bot Initialization Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Define a `ready` signal that executes once when the bot is online and ready. This signal registers all loaded application commands (globally by default) and logs the bot's tag to the console, indicating successful login. ```javascript import { Signal, execute } from 'sunar'; import { registerCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerCommands(client.application); console.log(`Logged in as ${client.user.tag}`); }); export { signal }; ``` -------------------------------- ### Create Sunar App Automatically Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Use `create-sunar` with your preferred package manager to scaffold a new Sunar project. This command prompts for project details like name, language (TypeScript/JavaScript), and desired features. Node.js 18+ is required. ```bash npm create sunar@latest ``` ```bash pnpm create sunar@latest ``` ```bash yarn create sunar@latest ``` ```bash bun create sunar@latest ``` -------------------------------- ### Run Next.js Development Server Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/README.md Commands to start the Next.js development server. This allows you to view the application in your browser at http://localhost:3000. These commands require Node.js and a package manager (npm, pnpm, or yarn) to be installed. ```bash npm run dev # or pnpm dev # or yarn dev ``` -------------------------------- ### Handle Discord Interactions Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/getting-started.mdx Set up an `interactionCreate` signal to process all incoming Discord interactions. This signal uses `handleInteraction` from Sunar's handlers to route and manage various interaction types, ensuring your commands and components function correctly. ```javascript import { Signal, execute } from 'sunar'; import { handleInteraction } from 'sunar/handlers'; const signal = new Signal('interactionCreate'); execute(signal, async (interaction) => { await handleInteraction(interaction); }); export { signal }; ``` -------------------------------- ### Start Sunar Development Server with Package Managers Source: https://github.com/sunarjs/sunar/blob/main/packages/create-sunar/templates/javascript/README.md This snippet provides commands to start the Sunar development server using various popular JavaScript package managers. Users can choose their preferred tool (npm, yarn, pnpm, or bun) to initiate the development environment. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### Start Sunar Development Server with Package Managers Source: https://github.com/sunarjs/sunar/blob/main/packages/create-sunar/templates/typescript/README.md This snippet provides commands to start the Sunar development server using various JavaScript package managers. Users can choose their preferred tool like npm, yarn, pnpm, or bun to initiate the development process. ```bash npm run dev # or yarn dev # or pnpm dev # or bun dev ``` -------------------------------- ### Basic Button Usage with Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/button.mdx Demonstrates how to initialize a basic button with a custom ID and handle its execution using the 'sunar' library. This snippet shows the minimal setup required to create an interactive button. ```js import { Button, execute } from 'sunar'; const button = new Button({ id: 'example' }); execute(button, (interaction) => { // handle execution }); export { button }; ``` -------------------------------- ### Initialize Basic Autocomplete Command in Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/autocomplete.mdx This snippet demonstrates how to create a new `Autocomplete` instance and register its execution handler using `execute` in Sunar. It sets up a basic autocomplete command named 'example' without a linked slash command. ```js import { Autocomplete, execute } from 'sunar'; const autocomplete = new Autocomplete({ name: 'example', }); execute(autocomplete, (interaction, option) => { // handle execution }); export { autocomplete }; ``` -------------------------------- ### Create a Sunar Signal for Discord Events Source: https://github.com/sunarjs/sunar/blob/main/packages/sunar/README.md This example shows how to define a 'ready' signal in Sunar, which executes a function once the Discord bot is online. It registers application commands and logs the bot's tag to the console. ```JavaScript // path: src/signals/ready.js import { Signal, execute } from 'sunar'; import { registerCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerCommands(client.application); console.log(`Logged in as ${client.user.tag}`); }); export { signal }; ``` -------------------------------- ### Implementing a Slash Command to Show User Avatar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/slash.mdx Provides a practical example of a Slash command that retrieves and displays a user's avatar. It illustrates how to define command options (e.g., a target user) and interact with Discord's API to get user information and reply with a file attachment. ```javascript import { Slash, execute } from 'sunar'; import { ApplicationCommandOptionType } from 'discord.js'; const slash = new Slash({ name: 'avatar', description: 'Show user avatar', options: [ { name: 'target', description: 'Target user', type: ApplicationCommandOptionType.User, }, ], }); execute(slash, (interaction) => { const user = interaction.options.getUser('target') ?? interaction.user; const avatarURL = user.displayAvatarURL({ size: 1024, forceStatic: false, }); interaction.reply({ content: `Avatar of user **${interaction.user.username}**`, files: [avatarURL], }); }); export { slash }; ``` -------------------------------- ### Full Modal Implementation with Discord.js and Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/modal.mdx Illustrates a complete example of creating a Discord modal for user feedback, including a slash command to trigger it, text input fields, and handling the modal submission to retrieve user input. ```javascript import { Modal, Slash, execute } from 'sunar'; import { ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle } from 'discord.js'; const slash = new Slash({ name: 'feedback', description: 'Send us feedback' }); execute(slash, (interaction) => { const contentInput = new TextInputBuilder() .setCustomId('content') .setLabel('Content') .setStyle(TextInputStyle.Paragraph) .setPlaceholder('Your feedback content...') .setRequired(true); const row = new ActionRowBuilder().setComponents(contentInput); const modal = new ModalBuilder() .setCustomId('feedback') .setTitle('Submit your feedback') .setComponents(row); interaction.showModal(modal); }); const modal = new Modal({ id: 'feedback' }); execute(modal, (interaction) => { const feedback = interaction.fields.getTextInputValue('content'); // Send feedback somewhere... interaction.reply({ content: 'Thanks for the feedback!', ephemeral: true }); }); export { slash, modal }; ``` -------------------------------- ### Loading Sunar Modules with Glob Pattern in JavaScript Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/load-modules.mdx This snippet demonstrates how to initialize a Sunar client and load modules using the `load` function with a glob pattern. It shows how to specify multiple directories for commands and signals. Users should replace `'YOUR_DISCORD_BOT_TOKEN'` with their actual bot token. For ECMAScript modules, top-level await can be used to simplify the asynchronous setup. ```js import { Client, load } from 'sunar'; const client = new Client(/* your options */); const start = async () => { // you can add more directories to load by // passing them with a comma after "signals" await load('src/{commands,signals}/**/*.{js,ts}'); // [!code highlight] return client.login('YOUR_DISCORD_BOT_TOKEN'); }; start(); ``` -------------------------------- ### Implementing Select Menu with Slash Command in Sunar.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/select-menu.mdx Illustrates a complete example of integrating a Select Menu within a Discord slash command, including creating the menu, sending it in a reply, and handling the subsequent interaction to process user selections. ```js import { SelectMenu, Slash, execute } from 'sunar'; import { ActionRowBuilder, ComponentType, StringSelectMenuBuilder, } from 'discord.js'; const slash = new Slash({ name: 'buy', description: 'Buy something', }); execute(slash, (interaction) => { const select = new StringSelectMenuBuilder() .setCustomId('buy') .setOptions( { label: 'Laptop', value: 'laptop' }, { label: 'Smart TV', value: 'smart-tv' }, { label: 'Tablet', value: 'tablet' }, { label: 'Smartphone', value: 'smartphone' }, ) .setPlaceholder('Select an item to purchase'); const row = new ActionRowBuilder().setComponents(select); interaction.reply({ components: [row] }); }); const select = new SelectMenu({ id: 'buy', type: ComponentType.StringSelect, }); execute(select, (interaction) => { const item = interaction.values.at(0); // Do something with the item... interaction.reply({ content: `You have purchased the **${item}** item` }); }); export { slash, select }; ``` -------------------------------- ### Implementing a Discord Button with Slash Command in Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/button.mdx Illustrates a complete example of creating a Discord button within a slash command. It shows how to build a button with 'discord.js', attach it to a message, and handle its interaction to perform an action like leaving a guild, demonstrating a full interaction flow. ```js import { Button, Slash, execute } from 'sunar'; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionFlagsBits, } from 'discord.js'; const slash = new Slash({ name: 'leave', description: 'Make the bot leave the server', dmPermission: false, defaultMemberPermissions: [PermissionFlagsBits.Administrator], }); execute(slash, (interaction) => { const button = new ButtonBuilder() .setCustomId('confirmLeave') .setLabel('Leave') .setStyle(ButtonStyle.Danger); const row = new ActionRowBuilder().setComponents(button); interaction.reply({ content: 'Are you certain about my leaving the server?', components: [row], }); }); const button = new Button({ id: 'confirmLeave' }); execute(button, async (interaction) => { await interaction.reply({ content: 'Leaving...', ephemeral: true, }); interaction.guild.leave(); }); export { slash, button }; ``` -------------------------------- ### Register Slash Command for Specific Guilds (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/dynamic.mdx This example shows how to register a slash command, 'ping', only for specific Discord guilds. It uses the `config` mutator from `sunar` to pass an array of `guildsIds`. This allows for testing or deploying commands to a limited set of servers before wider release. ```js import { Slash, execute, config } from 'sunar'; const slash = new Slash({ name: 'ping', description: "Ping the bot to check if it's online.", }); config(slash, { guildsIds: ['YOUR_GUILD_ID'], }); execute(slash, (interaction) => { interaction.reply('Pong!'); }); export { slash }; ``` -------------------------------- ### Configure Sunar to handle all supported Discord interactions Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/interactions-handling.mdx This setup configures Sunar to efficiently manage various Discord interactions using a `Signal` named `interactionCreate`. It prepares the framework to handle incoming events such as slash commands, buttons, and other interactions initiated by users in Discord. ```js import { Signal, execute } from 'sunar'; import { handleInteraction } from 'sunar/handlers'; const signal = new Signal('interactionCreate'); execute(signal, async (interaction) => { await handleInteraction(interaction); }); export { signal }; ``` -------------------------------- ### Protecting a Sunar Slash Command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/mutators/protect.mdx This snippet illustrates how to apply the 'protect' mutator to a Sunar Slash command. It demonstrates the basic setup of a 'ping' command and the integration of 'protect' to enforce access control, ensuring only authorized users can execute it. ```js import { Slash, execute, protect } from 'sunar'; const slash = new Slash({ name: 'ping', description: "Ping the bot to check if it's online." }); protect(slash, [/* your protectors */]); execute(slash, (interaction) => { interaction.reply('Pong!'); }); export { slash }; ``` -------------------------------- ### Implement Autocomplete with Slash Command for Fruit Selection Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/autocomplete.mdx This comprehensive example shows how to integrate an autocomplete feature with a Discord slash command. It defines a '/eat' slash command with an autocomplete-enabled 'fruit' option and a separate `Autocomplete` handler that filters a predefined list of fruits based on user input, responding with relevant suggestions. ```js import { Autocomplete, Slash, execute } from 'sunar'; import { ApplicationCommandOptionType } from 'discord.js'; const slash = new Slash({ name: 'eat', description: 'Eat a fruit', options: [ { name: 'fruit', description: 'Select the fruit', type: ApplicationCommandOptionType.String, autocomplete: true, required: true, }, ], }); execute(slash, (interaction) => { const fruit = interaction.options.getString('fruit', true); interaction.reply({ content: `You ate the **${fruit}**.` }); }); const autocomplete = new Autocomplete({ name: 'fruit', commandName: 'eat', // optional }); execute(autocomplete, (interaction, option) => { const data = [ { name: 'Apple', value: 'apple' }, { name: 'Kiwi', value: 'kiwi' }, { name: 'Watermelon', value: 'watermelon' }, { name: 'Banana', value: 'banana' }, { name: 'Strawberry', value: 'strawberry' }, ]; const results = data.filter((e) => e.name.toLowerCase().includes(option.value.toLowerCase()) ); interaction.respond(results); }); export { slash, autocomplete }; ``` -------------------------------- ### Implement Guild Member Add Signal in Sunar (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/signal.mdx This example illustrates a more complex implementation of a Sunar Signal to handle the `guildMemberAdd` event. It demonstrates how to find a specific text channel and send a welcome message to new members, including type checking for the channel. ```js import { Signal, execute } from 'sunar'; import { TextChannel } from 'discord.js'; const signal = new Signal('guildMemberAdd'); execute(signal, (member) => { const channel = member.guild.channels.cache.find( (c) => c.name === 'welcomes', ); if (!(channel instanceof TextChannel)) return; channel.send({ content: `${member} just joined!` }); }); export { signal }; ``` -------------------------------- ### Configure a 5-second cooldown for a Sunar command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx This example shows how to add a simple 5-second cooldown to a Sunar command using the `config` mutator. The `cooldown` property is set to 5000 milliseconds, preventing the command from being spammed. ```js import { Slash, execute, config } from 'sunar'; const slash = new Slash({ name: 'avatar', description: 'Show your user avatar' }); config(slash, { cooldown: 5_000, // 5000 miliseconds = 5 seconds }); execute(slash, (interaction) => { const avatarURL = interaction.user.displayAvatarURL(); interaction.reply({ content: `Showing ${interaction.user} avatar!`, files: [avatarURL], }); }); export { slash }; ``` -------------------------------- ### Configure Sunar to handle only specific Discord interactions Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/interactions-handling.mdx This configuration sets up Sunar to selectively manage and respond to specific types of Discord interactions based on their nature, such as slash commands, context menu commands, buttons, modals, select menus, and autocomplete commands. This setup allows your bot to efficiently manage and respond to specific interaction types on Discord, ensuring accurate and timely responses tailored to the user's actions. Customize the handling logic within each handler function (`handleSlash`, `handleContextMenu`, etc.) as needed to implement your bot's functionality and interaction flow according to Discord's API capabilities and user experience requirements. ```js import { Signal, execute } from 'sunar'; import { handleAutocomplete, handleModal, handleSelectMenu, handleSlash, handleButton, handleContextMenu, } from 'sunar/handlers'; const signal = new Signal('interactionCreate'); execute(signal, async (interaction) => { if (interaction.isChatInputCommand()) await handleSlash(interaction); // [!code highlight] if (interaction.isContextMenuCommand()) await handleContextMenu(interaction); // [!code highlight] if (interaction.isButton()) await handleButton(interaction); // [!code highlight] if (interaction.isModalSubmit()) await handleModal(interaction); // [!code highlight] if (interaction.isAnySelectMenu()) await handleSelectMenu(interaction); // [!code highlight] if (interaction.isAutocomplete()) await handleAutocomplete(interaction); // [!code highlight] }); export { signal }; ``` -------------------------------- ### Set Sunar.js Command Cooldown Usage Limit Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx This example demonstrates how to implement a cooldown with a usage cap for a slash command in Sunar. The `avatar` command is configured to have a cooldown period of 5 seconds and a usage limit of 3. This means the command can be used up to 3 times within the cooldown period before subsequent uses trigger the cooldown. ```js import { Slash, execute, config } from 'sunar'; const slash = new Slash({ name: 'avatar', description: 'Show your user avatar' }); config(slash, { cooldown: { time: 5_000, // 5 seconds limit: 3 // [!code highlight] } }); execute(slash, (interaction) => { const avatarURL = interaction.user.displayAvatarURL(); interaction.reply({ content: `Showing ${interaction.user} avatar!`, files: [avatarURL] }); }); export { slash }; ``` -------------------------------- ### Exclude Specific IDs from Sunar.js Command Cooldowns Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx This feature allows you to bypass cooldown limits for certain entities, such as excluding server IDs in a Guild scope configuration or excluding user IDs in a User scope configuration. In this example, the `avatar` command is configured with a User scope cooldown of 5 seconds, and the `exclude` property is used to bypass cooldowns for specific user IDs. ```js import { Slash, execute, config } from 'sunar'; const slash = new Slash({ name: 'avatar', description: 'Show your user avatar' }); config(slash, { cooldown: { time: 5_000, // 5 seconds exclude: ['SOME_USER_ID'], // [!code highlight] // scope: CooldownScope.User (default) } }); execute(slash, (interaction) => { const avatarURL = interaction.user.displayAvatarURL(); interaction.reply({ content: `Showing ${interaction.user} avatar!`, files: [avatarURL] }); }); export { slash }; ``` -------------------------------- ### Create and execute a basic Context Menu command in JavaScript Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/context-menu.mdx Demonstrates how to initialize a ContextMenu command with a name and type, and set up its execution handler using the `sunar` library for Discord bots. ```js import { ContextMenu, execute } from 'sunar'; import { ApplicationCommandType } from 'discord.js'; const contextMenu = new ContextMenu({ name: 'example', type: ApplicationCommandType.User, }); execute(contextMenu, (interaction) => { // handle execution }); export { contextMenu }; ``` -------------------------------- ### Initialize Sunar Client for Discord Bot Source: https://github.com/sunarjs/sunar/blob/main/packages/sunar/README.md This snippet demonstrates how to set up a new Discord bot client using Sunar. It initializes the client with specified intents, loads Sunar modules from given directories, and logs the bot into Discord using a provided token. ```JavaScript // path: src/index.js import { Client, load } from 'sunar'; const start = async () => { const client = new Client({ intents: [] }); // stores all sunar modules, you can add more // directories by passing them after the "signals" // with a comma (e.g. signals,buttons,autocompletes) await load('src/{commands,signals}/**/*.{js,ts}'); client.login('YOUR_DISCORD_BOT_TOKEN'); }; start(); ``` -------------------------------- ### Basic Usage of Sunar Slash Command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/slash.mdx Demonstrates the fundamental steps to define and execute a simple Slash command using the `sunar` library. It shows how to create a new `Slash` instance with a name and description, and then register an execution handler for it. ```javascript import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'example', description: 'example description', }); execute(slash, (interaction) => { // handle execution }); export { slash }; ``` -------------------------------- ### Basic Modal Usage with Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/modal.mdx Demonstrates how to import and initialize a Modal, then handle its execution using the `execute` function in Sunar. ```javascript import { Modal, execute } from 'sunar'; const modal = new Modal({ id: 'example' }); execute(modal, (interaction) => { // handle execution }); export { modal }; ``` -------------------------------- ### Basic Select Menu Usage in Sunar.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/select-menu.mdx Demonstrates the fundamental way to create a SelectMenu instance and register an execution handler using the 'sunar' library for basic interaction handling. ```js import { SelectMenu, execute } from 'sunar'; const select = new SelectMenu({ id: 'example', type: ComponentType.StringSelect, }); execute(select, (interaction) => { // handle execution }); export { select }; ``` -------------------------------- ### Create a Discord bot command with Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/index.mdx Define a new slash command or a context menu using Sunar's intuitive API and configure its properties such as name, description, options (if applicable), and permissions. ```js import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'ping', description: "Ping the bot to check if it's online." }); execute(slash, (interaction) => { interaction.reply('Pong!'); }); export { slash }; ``` -------------------------------- ### Register Commands on Bot Ready (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/dynamic.mdx This snippet demonstrates how to register bot commands globally when the bot is ready. It uses the `Signal` and `execute` functions from `sunar` to listen for the 'ready' event and then calls `registerCommands` with the client's application object. This ensures commands are available as soon as the bot logs in. ```js import { Signal, execute } from 'sunar'; import { registerCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerCommands(client.application); console.log(`${client.user.tag} logged!`); }); export { signal }; ``` -------------------------------- ### Initialize New Sunar Discord Bot Project Source: https://github.com/sunarjs/sunar/blob/main/packages/create-sunar/README.md Run one of the following commands in your terminal to create a new Discord bot project using the `create-sunar` CLI. You will be prompted to configure project details such as project name, preferred language (TypeScript or JavaScript), and desired features (e.g., Biome, TSX, TSUP, Prettier, ESLint). ```bash npm create sunar@latest ``` ```bash yarn create sunar@latest ``` ```bash pnpm create sunar@latest ``` ```bash bun create sunar@latest ``` -------------------------------- ### ContextMenuConfig API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/context-menu.mdx Configuration for the documentation generator to extract the `ContextMenuConfig` type definition from the specified TypeScript file. This indicates where the detailed API structure for ContextMenu commands can be found. ```APIDOC { "file": "./content/docs/props.ts", "name": "ContextMenuConfig" } ``` -------------------------------- ### Initialize and Execute a Sunar Group Command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/group.mdx This snippet demonstrates how to import the Group class and execute a new Group instance, defining a hierarchical command structure for Discord slash commands. ```js import { Group, execute } from 'sunar'; const group = new Group('root', 'parent', 'sub'); execute(group, (interaction) => { // handle execution }); export { group }; ``` -------------------------------- ### Listen for the Discord.js 'ready' signal in Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/index.mdx Wait for the `ready` signal from discord.js, indicating that the bot is connected and ready to register commands. ```js import { Signal, execute } from 'sunar'; const signal = new Signal('ready', { once: true }); execute(signal, (client) => { console.log(`${client.user.tag} logged!`); }); export { signal }; ``` -------------------------------- ### Implement a Context Menu command to show user avatar in JavaScript Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/context-menu.mdx Illustrates a practical implementation of a Context Menu command that retrieves and displays the target user's avatar URL upon interaction, replying with the image in a Discord channel. ```js import { ContextMenu, execute } from 'sunar'; import { ApplicationCommandType } from 'discord.js'; const contextMenu = new ContextMenu({ name: 'Show avatar', type: ApplicationCommandType.User, }); execute(contextMenu, (interaction) => { const avatarURL = interaction.targetUser.displayAvatarURL({ size: 1024, forceStatic: false, }); interaction.reply({ content: `Avatar of user **${interaction.user.username}**`, files: [avatarURL], }); }); export { contextMenu }; ``` -------------------------------- ### ButtonOptions API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/button.mdx Defines the configuration options available when initializing a 'Button' object in Sunar. These options allow customization of the button's appearance and behavior. ```APIDOC interface ButtonOptions { /** * The custom ID for the button. */ id: string; /** * Whether the button is disabled. */ disabled?: boolean; /** * The style of the button. */ style?: ButtonStyle; /** * The label of the button. */ label?: string; /** * The URL for a link button. */ url?: string; /** * The emoji for the button. */ emoji?: string | APIPartialEmoji; } ``` -------------------------------- ### Register Global Commands on Bot Ready (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/global.mdx This JavaScript snippet demonstrates how to register global commands using the 'sunar' library when the bot is ready. It utilizes the 'registerGlobalCommands' function to ensure commands are universally available across all Discord servers where the bot is present, logging the bot's tag upon successful registration. ```javascript import { Signal, execute } from 'sunar'; import { registerGlobalCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerGlobalCommands(client.application); console.log(`${client.user.tag} logged!`); }); export { signal }; ``` -------------------------------- ### Using Protector Middleware in Sunar.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/protector.mdx This snippet demonstrates the basic usage of a Protector in Sunar.js. It shows how to import the Protector class, instantiate it with specific commands to intercept, and then use the 'execute' function to attach a handler for the intercepted commands. ```js import { Protector, execute } from 'sunar'; const protector = new Protector({ commands: ['slash'], }); execute(protector, (arg) => { // handle execution }); export { protector }; ``` -------------------------------- ### Apply Sunar Protector to a Discord Slash Command Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/index.mdx This JavaScript snippet demonstrates how to create a Discord Slash command and apply a previously defined `Protector` to it using `protect(slash, [onlyAdmins])`. The command will only execute its reply logic if the user passes the protector's checks, ensuring only administrators can use it. This showcases how to integrate middleware for command access control. ```js import { Slash, execute, protect } from 'sunar'; import { onlyAdmins } from '../protectors/only-admins.js'; const slash = new Slash({ name: 'protected', description: 'This is a protected slash command', }); protect(slash, [onlyAdmins]); // [!code highlight] execute(slash, (interaction) => { interaction.reply({ content: 'You are an admin!' }); }); export { slash }; ``` -------------------------------- ### Create a simple Discord bot command with Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx This snippet demonstrates how to define a basic slash command named 'avatar' using Sunar, which responds with the user's display avatar URL. It sets up the command structure and its execution logic. ```js import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'avatar', description: 'Show your user avatar' }); execute(slash, (interaction) => { const avatarURL = interaction.user.displayAvatarURL(); interaction.reply({ content: `Showing ${interaction.user} avatar!`, files: [avatarURL], }); }); export { slash }; ``` -------------------------------- ### SlashConfig Interface Definition Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/slash.mdx Defines the configuration object for a Sunar Slash command. It specifies the command's name, description, and an optional array of command options, which dictate user input fields and their types. ```APIDOC interface SlashConfig { name: string; // The name of the slash command. description: string; // A brief description of the slash command. options?: ApplicationCommandOption[]; // Optional: An array of command options. } interface ApplicationCommandOption { name: string; // The name of the option. description: string; // A description of the option. type: ApplicationCommandOptionType; // The type of the option (e.g., User, String, Integer). // Additional properties like 'required', 'choices', 'channel_types', etc., may also be present. } ``` -------------------------------- ### Implement Subcommand Logic with Sunar Group Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/group.mdx Shows how to create and execute a specific subcommand within a defined Group hierarchy, handling the interaction logic for the 'sub' command. ```js import { Group, execute } from 'sunar'; const group = new Group('example', 'parent', 'sub'); // protect(group, [...]) // config(group, {...}) execute(group, (interaction) => { // handle execution }); export { group }; ``` -------------------------------- ### Register commands dynamically using Sunar's registry Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/index.mdx Add the `registerCommands` function provided by Sunar to dynamically register all the stored commands with your Discord bot's application. ```js import { Signal, execute } from 'sunar'; import { registerCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerCommands(client.application); console.log(`${client.user.tag} logged!`); }); export { signal }; ``` -------------------------------- ### Export a Sunar signal for loading Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/working-with-signals.mdx Ensure Sunar can properly load and utilize defined signals by exporting them from their respective files. This makes the signal accessible to the Sunar module system. ```js import { Signal, execute } from 'sunar'; const signal = new Signal('ready', { once: true }); execute(signal, () => { console.log('Bot is ready!'); }); export { signal }; ``` -------------------------------- ### AutocompleteOptions API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/autocomplete.mdx This section provides a reference to the `AutocompleteOptions` interface, detailing the configuration properties available when creating an `Autocomplete` command in Sunar. It points to the source TypeScript definition for full details. ```json { "file": "./content/docs/props.ts", "name": "AutocompleteOptions" } ``` -------------------------------- ### Protect Command with Member Permissions Middleware Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/verify-member-permissions.mdx Demonstrates how to apply the `memberPerms` middleware using Sunar's `protect` function to restrict command execution based on required user permissions, such as 'Administrator'. ```js protect(builder, [memberPerms("Administrator")]) ``` -------------------------------- ### Define Slash Command Execution with Sunar.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/mutators/execute.mdx This JavaScript snippet demonstrates how to use the `execute` function from 'sunar' to define the behavior for a slash command. It imports `Slash` and `execute`, creates a new slash command named 'ping', and then uses `execute` to specify that when the command is triggered, the bot should reply with 'Pong!'. ```js import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'ping', description: "Ping the bot to check if it's online.", }); execute(slash, (interaction) => { interaction.reply('Pong!'); }); export { slash }; ``` -------------------------------- ### Define a Sunar Slash Command for Discord Source: https://github.com/sunarjs/sunar/blob/main/packages/sunar/README.md This snippet illustrates how to create a simple 'ping' slash command using Sunar. When invoked, the command replies to the interaction with the bot's WebSocket ping. ```JavaScript // path: src/commands/ping.js import { Slash, execute } from 'sunar'; const slash = new Slash({ name: 'ping', description: 'Show client ws ping', }); execute(slash, (interaction) => { interaction.reply({ content: `Client WS Ping: ${interaction.client.ws.ping}`, }); }); export { slash }; ``` -------------------------------- ### Create a new signal in Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/working-with-signals.mdx Define a new signal using Sunar to signify specific events or states within your bot's operation. For instance, a 'ready' signal can indicate bot initialization completion. ```js import { Signal } from 'sunar'; const signal = new Signal('ready', { once: true }); ``` -------------------------------- ### Handle Discord Events with Sunar Signal (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/signal.mdx This snippet demonstrates how to create and execute a basic Signal in Sunar to handle Discord events like `messageCreate`. It shows the import of `Signal` and `execute` from 'sunar' and how to define a callback function for event handling. ```js import { Signal, execute } from 'sunar'; const signal = new Signal('messageCreate'); execute(signal, (message) => { // handle execution }); export { signal }; ``` -------------------------------- ### Sunar CooldownContext API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx Reference for the `CooldownContext` object, which is passed to the `cooldown` signal. It contains details about the active cooldown. ```APIDOC CooldownContext: - remaining: number description: The time remaining on the cooldown in milliseconds. ``` -------------------------------- ### Define Root Slash Command with Subcommand Group Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/group.mdx Illustrates how to create the root slash command using Sunar's Slash class, including a subcommand group and a subcommand option, essential for structuring hierarchical Discord commands. ```js import { Slash } from 'sunar'; import { ApplicationCommandOptionType } from 'discord.js'; const slash = new Slash({ name: 'example', description: 'this is a example', options: [ { name: 'parent', description: 'this is the parent', type: ApplicationCommandOptionType.SubcommandGroup, options: [ { name: 'sub', description: 'this is the sub', type: ApplicationCommandOptionType.Subcommand }, ], }, ], }); export { slash }; ``` -------------------------------- ### Configuring Discord Bot Commands with Sunar (JavaScript) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/mutators/config.mdx This JavaScript snippet demonstrates how to use the `config` mutator in Sunar to apply settings like cooldowns and guild-specific IDs to a Discord slash command. It shows how to import `Slash`, `execute`, and `config`, define a slash command, and then apply configuration using the `config` function. ```js import { Slash, execute, config } from 'sunar'; const slash = new Slash({ name: 'ping', description: "Ping the bot to check if it's online.", }); config(slash, { cooldown: 5000, guildsIds: [/* ... */], }); execute(slash, (interaction) => { interaction.reply('Pong!'); }); export { slash }; ``` -------------------------------- ### ButtonConfig API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/button.mdx Defines the configuration properties for a button, potentially used internally or for advanced customization within the Sunar framework. This includes the button's ID and its associated handler function. ```APIDOC interface ButtonConfig { /** * The custom ID of the button. */ id: string; /** * The handler function for the button interaction. */ handler: (interaction: ButtonInteraction) => Promise | void; /** * Whether the button is ephemeral. */ ephemeral?: boolean; } ``` -------------------------------- ### Applying Admin Only Middleware Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/admin-only.mdx This snippet shows how to apply the `adminOnly` middleware to a command builder using the `protect` function in Sunar, ensuring that only administrators can execute the associated commands. ```js protect(builder, [adminOnly]) ``` -------------------------------- ### Handle Sunar command cooldown signal and notify user Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx This snippet demonstrates how to listen for the `cooldown` signal in Sunar to detect when a user attempts to use a command or component while on cooldown. It uses the `CooldownContext` to inform the user about the remaining cooldown time. ```js import { Signal, execute } from 'sunar'; const signal = new Signal('cooldown'); execute(signal, (interaction, context) => { interaction.reply({ content: `You need to wait ${context.remaining} milliseconds before using this again.` }); }); export { signal }; ``` -------------------------------- ### API Reference: config Mutator (Sunar) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/mutators/config.mdx This entry refers to the TypeScript definition for the `config` mutator, indicating its source file and interface name for documentation generation. ```APIDOC { "file": "./content/docs/props.ts", "name": "IConfigMut" } ``` -------------------------------- ### API Reference: CooldownConfig Interface (Sunar) Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/mutators/config.mdx This entry refers to the TypeScript definition for the `CooldownConfig` interface, indicating its source file and name for documentation generation. ```APIDOC { "file": "./content/docs/props.ts", "name": "CooldownConfig" } ``` -------------------------------- ### Sunar Role-Based Access Control Logic Implementation Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/verify-member-roles.mdx This code defines a `roles` function that creates a Sunar Protector. It checks if a user has the required Discord roles for commands, components, and signals, preventing execution or replying with an error if roles are missing. ```js import { GuildMemberRoleManager, Message, Role, inlineCode } from 'discord.js'; import { Protector, execute } from 'sunar'; /** @param {Role[]} missing */ const res = (missing) => { const missingRoles = missing.map((r) => inlineCode(r.name)).join(', '); return `You need the ${missingRoles} roles.`; }; /** @param {...Role} roles */ export function roles(...roles) { const protector = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); execute(protector, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; if (!entry.guild) return next(); const missing = getMissingRoles(entry.member?.roles); const isMissing = missing.length > 0; if (entry instanceof Message) { if (!isMissing) return next(); return entry.reply({ content: res(missing) }); } if (entry.isAutocomplete() && isMissing) return entry.respond([]); if (entry.isRepliable() && isMissing) return entry.reply({ content: res(missing), ephemeral: true }); return !isMissing && next(); }); /** @param {GuildMemberRoleManager | string[] | undefined} manager */ function getMissingRoles(manager) { if (!manager || Array.isArray(manager)) return []; const missing = roles .map((r) => { const role = manager.guild.roles.resolve(r); if (role && !manager.cache.has(role.id)) return role; }) .filter((r) => r != null); return missing; } return protector; } ``` ```ts import { type GuildMemberRoleManager, Message, type Role, type RoleResolvable, inlineCode } from 'discord.js'; import { Protector, execute } from 'sunar'; const res = (missing: Role[]) => { const missingRoles = missing.map((r) => inlineCode(r.name)).join(', '); return `You need the ${missingRoles} roles.`; }; export function roles(...roles: RoleResolvable[]) { const protector = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); execute(protector, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; if (!entry.guild) return next(); const missing = getMissingRoles(entry.member?.roles); const isMissing = missing.length > 0; if (entry instanceof Message) { if (!isMissing) return next(); return entry.reply({ content: res(missing) }); } if (entry.isAutocomplete() && isMissing) return entry.respond([]); if (entry.isRepliable() && isMissing) return entry.reply({ content: res(missing), ephemeral: true }); return !isMissing && next(); }); function getMissingRoles(manager?: GuildMemberRoleManager | string[]): Role[] { if (!manager || Array.isArray(manager)) return []; const missing = roles .map((r) => { const role = manager.guild.roles.resolve(r); if (role && !manager.cache.has(role.id)) return role; }) .filter((r) => r != null); return missing; } return protector; } ``` -------------------------------- ### Handle Sunar signal execution with `execute` Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/working-with-signals.mdx Manage signal emission by using the `execute` mutator. This involves passing the signal and a callback function, which will run when the signal is triggered. ```js import { Signal, execute } from 'sunar'; const signal = new Signal('ready', { once: true }); execute(signal, () => { console.log('Bot is ready!'); }); ``` -------------------------------- ### Registering Guild-Specific Commands in Sunar.js Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/registering-commands/guilds.mdx This JavaScript snippet demonstrates how to register commands specifically for a list of Discord guilds using `registerGuildCommands` from `sunar/registry`. It's typically executed within a `ready` signal handler. This method is recommended for development environments to test commands without affecting all servers your bot is in. Remember to replace `'YOUR_GUILD_ID'` with your actual guild IDs. ```js import { Signal, execute } from 'sunar'; import { registerGuildCommands } from 'sunar/registry'; const signal = new Signal('ready', { once: true }); execute(signal, async (client) => { await registerGuildCommands(client.application, ['YOUR_GUILD_ID']); console.log(`${client.user.tag} logged!`); }); export { signal }; ``` -------------------------------- ### Handle Discord Interactions with Sunar Signal Source: https://github.com/sunarjs/sunar/blob/main/packages/sunar/README.md This code defines an 'interactionCreate' signal to process all incoming Discord interactions. It uses Sunar's `handleInteraction` utility to manage commands, buttons, and other interaction types. ```JavaScript // path: src/signals/interaction-create.js import { Signal, execute } from 'sunar'; import { handleInteraction } from 'sunar/handlers'; const signal = new Signal('interactionCreate'); execute(signal, async (interaction) => { await handleInteraction(interaction); }); export { signal }; ``` -------------------------------- ### Implement Member Permissions Middleware Logic Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/verify-member-permissions.mdx Provides the core logic for the `memberPerms` middleware, which checks if a Discord member has the specified permissions. It handles different interaction types (messages, autocomplete, repliable interactions) and provides appropriate responses when permissions are missing, ensuring commands are only executed by authorized users. ```js import { Message, PermissionResolvable, PermissionsBitField, PermissionsString, inlineCode } from 'discord.js'; import { Protector, execute } from 'sunar'; /** @param {PermissionsString[]} missing */ const res = (missing) => { const missingPerms = missing.map((p) => inlineCode(p)).join(', '); return `You need the ${missingPerms} permissions.`; }; /** @param {...PermissionResolvable} perms */ export function memberPerms(...perms) { const protector = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); execute(protector, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; if (!entry.guild) return next(); const missing = getMissingPerms(entry.member?.permissions); const isMissing = missing.length > 0; if (entry instanceof Message) { if (!isMissing) return next(); return entry.reply({ content: res(missing) }); } if (entry.isAutocomplete() && isMissing) return entry.respond([]); if (entry.isRepliable() && isMissing) return entry.reply({ content: res(missing), ephemeral: true }); return !isMissing && next(); }); /** @param {Readonly | string | undefined} bitField */ function getMissingPerms(bitField) { if (!bitField || typeof bitField === 'string') return []; return bitField.missing(perms); } return protector; } ``` ```ts import { Message, type PermissionResolvable, type PermissionsBitField, type PermissionsString, inlineCode } from 'discord.js'; import { Protector, execute } from 'sunar'; const res = (missing: PermissionsString[]) => { const missingPerms = missing.map((p) => inlineCode(p)).join(', '); return `You need the ${missingPerms} permissions.`; }; export function memberPerms(...perms: PermissionResolvable[]) { const protector = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); execute(protector, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; if (!entry.guild) return next(); const missing = getMissingPerms(entry.member?.permissions); const isMissing = missing.length > 0; if (entry instanceof Message) { if (!isMissing) return next(); return entry.reply({ content: res(missing) }); } if (entry.isAutocomplete() && isMissing) return entry.respond([]); if (entry.isRepliable() && isMissing) return entry.reply({ content: res(missing), ephemeral: true }); return !isMissing && next(); }); function getMissingPerms(bitField?: Readonly | string): PermissionsString[] { if (!bitField || typeof bitField === 'string') return []; return bitField.missing(perms); } return protector; } ``` -------------------------------- ### Sunar CooldownScope Enum API Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/implementing-cooldowns.mdx Reference for the `CooldownScope` enum, defining the different levels at which cooldowns can be applied. ```APIDOC CooldownScope: - User: Limits per user. - Channel: Limits per channel. - Guild: Limits per server/guild. - Global: Limits globally across all users, channels, and servers. ``` -------------------------------- ### Sunar Middleware Usage for Role Protection Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/verify-member-roles.mdx This snippet demonstrates how to apply the `roles` protector to a command builder in Sunar, restricting its usage to members possessing the specified role ID. ```js protect(builder, [roles("123456")]) ``` -------------------------------- ### Applying Owner-Only Middleware in Sunar Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/owner-only.mdx This snippet demonstrates how to apply the `ownerOnly` middleware to a command builder using Sunar's `protect` function. This ensures that the associated command or component can only be executed by the bot's designated owners. ```js protect(builder, [ownerOnly]) ``` -------------------------------- ### Admin Only Middleware Implementation Logic Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/guides/middlewares/admin-only.mdx This code defines the `adminOnly` middleware using Sunar's `Protector` class. It checks if a user has administrator permissions (PermissionFlagsBits.Administrator) for various interaction types (commands, components, signals) and prevents non-admin users from proceeding, providing appropriate feedback. ```js import { Message, PermissionFlagsBits, PermissionsBitField } from 'discord.js'; import { Protector, execute } from 'sunar'; const adminOnly = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); const content = 'Only the admins can use this.'; /** @param {PermissionsBitField | string | undefined} permissions */ function checkIsAdmin(permissions) { if (!permissions || typeof permissions === 'string') return false; return permissions.has(PermissionFlagsBits.Administrator); } execute(adminOnly, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; const isAdmin = checkIsAdmin(entry.member?.permissions); if (entry instanceof Message) { if (isAdmin) return next(); return entry.reply({ content }); } if (entry.isAutocomplete() && !isAdmin) return entry.respond([]); if (entry.isRepliable() && !isAdmin) return entry.reply({ content, ephemeral: true }); return isAdmin && next(); }); export { adminOnly }; ``` ```ts import { Message, PermissionFlagsBits, type PermissionsBitField } from 'discord.js'; import { Protector, execute } from 'sunar'; const adminOnly = new Protector({ commands: ['autocomplete', 'contextMenu', 'slash'], components: ['button', 'modal', 'selectMenu'], signals: ['interactionCreate', 'messageCreate'], }); const content = 'Only the admins can use this.'; function checkIsAdmin(permissions?: PermissionsBitField | string) { if (!permissions || typeof permissions === 'string') return false; return permissions.has(PermissionFlagsBits.Administrator); } execute(adminOnly, (arg, next) => { const entry = Array.isArray(arg) ? arg[0] : arg; const isAdmin = checkIsAdmin(entry.member?.permissions); if (entry instanceof Message) { if (isAdmin) return next(); return entry.reply({ content }); } if (entry.isAutocomplete() && !isAdmin) return entry.respond([]); if (entry.isRepliable() && !isAdmin) return entry.reply({ content, ephemeral: true }); return isAdmin && next(); }); export { adminOnly }; ``` -------------------------------- ### GroupConfig Type Reference Source: https://github.com/sunarjs/sunar/blob/main/apps/docs/content/docs/builders/group.mdx Reference to the `GroupConfig` type, which defines configuration options for Sunar Group commands. This type is generated from the specified TypeScript file. ```APIDOC { "file": "./content/docs/props.ts", "name": "GroupConfig" } ```