js-discord-modularcommand 2.5.0 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +252 -35
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,69 +1,286 @@
1
- # JS Discord ModularCommand
1
+ # Discord.js Modular Command
2
2
 
3
- A module to create and manage modular commands in a simple way for Discord.js bots.
3
+ [![npm version](https://img.shields.io/npm/v/js-discord-modularcommand.svg?style=flat-square)](https://www.npmjs.com/package/js-discord-modularcommand)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
4
5
 
5
- ## What is it for?
6
+ A powerful and elegant library for creating modular, feature-rich slash commands for your [Discord.js](https://discord.js.org/) bot.
6
7
 
7
- This library simplifies the creation and management of slash commands for [Discord.js](https://discord.js.org/). It allows you to structure your commands in a modular way, making it easier to handle logic, permissions, cooldowns, localizations, and interactive components like buttons and modals.
8
+ `js-discord-modularcommand` simplifies command management by providing a clean, chainable structure for defining commands, handling interactions, and managing localizations. Move away from boilerplate code and focus on what truly matters: your bot's logic.
8
9
 
9
- ## How to use it?
10
+ ## Features
10
11
 
11
- First, install the package in your project:
12
+ - **Modular by Design:** Structure each command in its own file for a clean and scalable project architecture.
13
+ - **Effortless Localization:** Built-in support for multiple languages for command descriptions, options, and in-command responses.
14
+ - **Interactive Components Made Easy:** Fluent builders for creating and managing Buttons, Modals, and Select Menus with their own handlers, all within the command's context.
15
+ - **Chainable Configuration:** Use a fluent, chainable API to configure every aspect of your command, from descriptions and options to permissions and cooldowns.
16
+ - **Simplified Handlers:** The library abstracts away the complexity of handling different interaction types. You just provide the logic.
17
+
18
+ ## Installation
19
+
20
+ Install the package using npm or your favorite package manager:
12
21
 
13
22
  ```sh
14
- npm install js-discord-modularcommand@latest
23
+ npm install js-discord-modularcommand
15
24
  ```
16
25
 
17
- Then, you can create your commands in a modular fashion. Here is a basic example of a `ping` command:
26
+ ## Getting Started
27
+
28
+ The core of the library is the `ModularCommand` class. You create an instance of it for each command and chain methods to configure it.
29
+
30
+ Here is a basic example of a `ping` command:
18
31
 
19
32
  ```javascript
20
- // filepath: commands/ping.js
33
+ // filepath: /commands/ping.js
21
34
  const { ModularCommand, RegisterCommand } = require('js-discord-modularcommand');
22
- const { PermissionFlagsBits, Locale } = require('discord.js');
35
+ const { Locale } = require('discord.js');
36
+
37
+ // 1. Create a new command instance
38
+ const pingCommand = new ModularCommand('ping');
23
39
 
24
- // Create a new command instance
25
- const PingCommand = new ModularCommand('ping');
40
+ // 2. Configure the command using chainable methods
41
+ pingCommand.setDescription('Replies with Pong!')
26
42
 
27
- // Set the description
28
- PingCommand.setDescription('Sends a ping message!');
43
+ // Optional: Set a 5-second cooldown
44
+ pingCommand.setCooldown(5)
45
+
46
+ // Optional: Add localized descriptions for the command itself
47
+ pingCommand.setLocalizationDescription({
48
+ [Locale.EnglishUS]: 'Replies with Pong!',
49
+ [Locale.SpanishLATAM]: '¡Responde con Pong!',
50
+ })
51
+
52
+ // Optional: Define response phrases for different languages
53
+ pingCommand.setLocalizationPhrases({
54
+ [Locale.EnglishUS]: {
55
+ 'pong_reply': 'Pong! 🏓',
56
+ },
57
+ [Locale.SpanishLATAM]: {
58
+ 'pong_reply': '¡Pong! 🏓',
59
+ }
60
+ })
29
61
 
30
- // Optional: Add a permission check
31
- PingCommand.setPermissionCheck(async ({ interaction }) => {
32
- return interaction.member.permissions.has(PermissionFlagsBits.Administrator);
62
+ // 3. Define the execution logic
63
+ // The 'locale' object contains the phrases for the user's language
64
+ pingCommand.setExecute(async ({ interaction, locale }) => {
65
+ await interaction.reply({
66
+ content: locale['pong_reply']
67
+ });
33
68
  });
34
69
 
35
- // Optional: Localization to use with 'locale'
36
- PingCommand.setLocalizationPhrases({
70
+ // 4. Export the command for the handler
71
+ module.exports = RegisterCommand(pingCommand);
72
+ ```
73
+
74
+ ## Advanced Usage: Interactive Components
75
+
76
+ Easily add interactive components to your commands.
77
+
78
+ ### Buttons
79
+
80
+ Create buttons and attach specific logic to each one.
81
+
82
+ ```javascript
83
+ // filepath: /commands/vote.js
84
+ const { ModularCommand, RegisterCommand } = require('js-discord-modularcommand');
85
+ const { ButtonStyle, Locale, MessageFlags } = require('discord.js');
86
+ const { ActionRowBuilder } = require('@discordjs/builders');
87
+
88
+ const voteCommand = new ModularCommand('votecommand');
89
+
90
+ voteCommand.setDescription('Starts a simple poll.');
91
+
92
+ voteCommand.setLocalizationPhrases({
37
93
  [Locale.EnglishUS]: {
38
- response: 'Replies with Pong!',
94
+ 'poll_question': 'What is your favorite color?',
95
+ 'votecommand.yes': 'Green',
96
+ 'votecommand.no': 'Blue',
97
+ 'reply.yes': 'You voted for Green!',
98
+ 'reply.no': 'You voted for Blue!',
39
99
  },
40
100
  [Locale.SpanishLATAM]: {
41
- response: 'Responde con Pong!',
101
+ 'poll_question': '¿Cuál es tu color favorito?',
102
+ 'votecommand.yes': 'Verde',
103
+ 'votecommand.no': 'Azul',
104
+ 'reply.yes': '¡Has votado por el Verde!',
105
+ 'reply.no': '¡Has votado por el Azul!',
42
106
  }
43
107
  });
44
108
 
45
- // Optional: Set a cooldown (in seconds) by default is 3 seconds
46
- PingCommand.setCooldown(5);
109
+ // Create and handle the "Yes" button
110
+ const yesButton = voteCommand.addButton('yes', async ({ interaction, locale }) => {
111
+ await interaction.reply({
112
+ content: locale['reply.yes'],
113
+ flags: MessageFlags.Ephemeral
114
+ });
115
+ });
116
+
117
+ // Create and handle the "No" button
118
+ const noButton = voteCommand.addButton('no', async ({ interaction, locale }) => {
119
+ await interaction.reply({
120
+ content: locale['reply.no'],
121
+ flags: MessageFlags.Ephemeral
122
+ });
123
+ });
47
124
 
48
- // Set the command's description
49
- PingCommand.setDescription('Replies with Pong!');
125
+ // Customize the underlying discord.js button
126
+ yesButton.getButton().setStyle(ButtonStyle.Success);
127
+ noButton.getButton().setStyle(ButtonStyle.Primary);
50
128
 
51
- // Optional: Add more localization descriptions for the command itself
52
- PingCommand.setLocalizationDescription({
53
- [Locale.EnglishUS]: 'Replies with Pong!',
54
- [Locale.SpanishLATAM]: 'Responde con Pong!',
129
+ // Main command execution: sends the message with the buttons
130
+ voteCommand.setExecute(async ({ interaction, locale }) => {
131
+ const row = new ActionRowBuilder();
132
+
133
+ row.addComponents(
134
+ yesButton.build(locale), // .build(locale) applies the correct localization
135
+ noButton.build(locale)
136
+ );
137
+
138
+ await interaction.reply({
139
+ content: locale['poll_question'],
140
+ components: [row]
141
+ });
142
+ });
143
+
144
+ module.exports = RegisterCommand(voteCommand);
145
+ ```
146
+
147
+ ### Select Menus
148
+
149
+ Build and handle string select menus seamlessly.
150
+
151
+ ```javascript
152
+ // filepath: /commands/starter.js
153
+ const { ModularCommand, RegisterCommand } = require('js-discord-modularcommand');
154
+ const { ActionRowBuilder } = require('@discordjs/builders');
155
+ const { Locale, MessageFlags } = require('discord.js');
156
+
157
+ const starterCommand = new ModularCommand('starter');
158
+
159
+ starterCommand.setDescription('Choose your starter Pokémon.')
160
+
161
+ starterCommand.setLocalizationPhrases({
162
+ [Locale.EnglishUS]: {
163
+ 'select_prompt': 'Please select your starter:',
164
+ 'menuselection.placeholder': 'Make a selection!',
165
+ 'menuselection.bulbasaur.label': 'Bulbasaur',
166
+ 'menuselection.bulbasaur.description': 'The Seed Pokémon.',
167
+ 'menuselection.charmander.label': 'Charmander',
168
+ 'menuselection.charmander.description': 'The Lizard Pokémon.',
169
+ 'menuselection.squirtle.label': 'Squirtle',
170
+ 'menuselection.squirtle.description': 'The Tiny Turtle Pokémon.',
171
+ 'response': 'You chose {selection}!',
172
+ },
173
+ [Locale.SpanishLATAM]: {
174
+ 'select_prompt': 'Por favor, elige tu inicial:',
175
+ 'menuselection.placeholder': '¡Haz una selección!',
176
+ 'menuselection.bulbasaur.label': 'Bulbasaur',
177
+ 'menuselection.bulbasaur.description': 'El Pokémon Semilla.',
178
+ 'menuselection.charmander.label': 'Charmander',
179
+ 'menuselection.charmander.description': 'El Pokémon Lagartija.',
180
+ 'menuselection.squirtle.label': 'Squirtle',
181
+ 'menuselection.squirtle.description': 'El Pokémon Agua.',
182
+ 'response': '¡Elegiste a {selection}!',
183
+ }
184
+ });
185
+
186
+ const starterMenu = starterCommand.addSelectMenu('menuselection');
187
+
188
+ // Value must match the key in localization phrases
189
+ starterMenu.addOption('bulbasaur')
190
+ starterMenu.addOption('charmander')
191
+ starterMenu.addOption('squirtle')
192
+
193
+ starterMenu.setExecute(async ({ interaction, selected, locale }) => {
194
+ // 'selected' directly gives you the value of the chosen option
195
+ const selectionLabel = locale[`menuselection.${selected}.label`];
196
+ await interaction.update({
197
+ content: locale['response'].replace('{selection}', selectionLabel),
198
+ components: [] // Remove menu after selection
199
+ });
55
200
  });
56
201
 
57
- // Set the executor function
58
- PingCommand.setExecute(async ({ interaction, locale }) => {
59
- await interaction.reply(locale['response']);
202
+ starterCommand.setExecute(async ({ interaction, locale }) => {
203
+ const row = new ActionRowBuilder()
204
+ row.addComponents(starterMenu.build(locale));
205
+
206
+ await interaction.reply({
207
+ content: locale['select_prompt'],
208
+ components: [row],
209
+ flags: MessageFlags.Ephemeral
210
+ });
60
211
  });
61
212
 
62
- module.exports = RegisterCommand(PingCommand)
213
+ module.exports = RegisterCommand(starterCommand);
63
214
  ```
64
215
 
65
- In your main file, you can load the commands and register their executors with your Discord client.
216
+ ### Modals (Pop-up Forms)
217
+
218
+ Display pop-up forms to collect detailed user input.
219
+
220
+ ```javascript
221
+ // filepath: /commands/feedback.js
222
+ const { ModularCommand, RegisterCommand } = require('js-discord-modularcommand');
223
+ const { TextInputStyle, Locale, MessageFlags } = require('discord.js');
224
+
225
+ const feedbackCommand = new ModularCommand('feedback');
226
+
227
+ feedbackCommand.setDescription('Submit feedback about the bot.')
228
+
229
+ feedbackCommand.setLocalizationPhrases({
230
+ [Locale.EnglishUS]: {
231
+ 'form.title': 'Feedback Form',
232
+ 'form.subject.label': 'Subject',
233
+ 'form.subject.placeholder': 'e.g., Feature Request',
234
+ 'form.message.label': 'Message',
235
+ 'form.message.placeholder': 'Your detailed feedback here...',
236
+ 'success_reply': 'Thank you for your feedback!',
237
+ },
238
+ [Locale.SpanishLATAM]: {
239
+ 'form.title': 'Formulario de Comentarios',
240
+ 'form.subject.label': 'Asunto',
241
+ 'form.subject.placeholder': 'Ej: Solicitud de función',
242
+ 'form.message.label': 'Mensaje',
243
+ 'form.message.placeholder': 'Tus comentarios detallados aquí...',
244
+ 'success_reply': '¡Gracias por tus comentarios!',
245
+ }
246
+ });
247
+
248
+ const feedbackModal = feedbackCommand.addModal('form');
249
+
250
+ // Define text inputs
251
+ const subjectInput = feedbackModal.newTextInput('subject')
252
+ .setStyle(TextInputStyle.Short)
253
+ .setRequired(true)
254
+ .data
255
+ .custom_id;
256
+
257
+ const messageInput = feedbackModal.newTextInput('message')
258
+ .setStyle(TextInputStyle.Paragraph)
259
+ .setRequired(true)
260
+ .data
261
+ .custom_id;
262
+
263
+ // This function runs when the user submits the modal
264
+ feedbackModal.setExecute(async ({ interaction, args, locale }) => {
265
+ const subject = args[subjectInput];
266
+ const message = args[messageInput];
267
+
268
+ // Process the data
269
+ console.log(`New Feedback: ${subject} - ${message}`);
270
+ await interaction.reply({
271
+ content: locale['success_reply'],
272
+ flags: MessageFlags.Ephemeral
273
+ });
274
+ });
275
+
276
+ // This function runs when the /feedback command is used, showing the modal
277
+ feedbackCommand.setExecute(async ({ interaction, locale }) => {
278
+ await interaction.showModal(feedbackModal.build(locale));
279
+ });
280
+
281
+ module.exports = RegisterCommand(feedbackCommand);
282
+ ```
66
283
 
67
284
  ## License
68
285
 
69
- This project is under the MIT License. See the [LICENSE](LICENSE) file
286
+ This project is licensed under the MIT License. See the `LICENSE` file for details.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-discord-modularcommand",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "discord",