@mostfeatured/dbi 0.2.11 → 0.2.13
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.
- package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/parser.js +10 -3
- package/dist/src/types/Components/HTMLComponentsV2/parser.js.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js +18 -3
- package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js +11 -2
- package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js.map +1 -1
- package/dist/test/index.js +3 -2
- package/dist/test/index.js.map +1 -1
- package/llm.txt +1088 -0
- package/package.json +1 -1
- package/src/types/Components/HTMLComponentsV2/parser.ts +10 -3
- package/src/types/Components/HTMLComponentsV2/svelteParser.ts +17 -4
- package/src/types/Components/HTMLComponentsV2/svelteRenderer.ts +10 -2
- package/test/index.ts +3 -2
package/llm.txt
ADDED
|
@@ -0,0 +1,1088 @@
|
|
|
1
|
+
# DBI - Discord Bot Infrastructure
|
|
2
|
+
|
|
3
|
+
> The most advanced, modern, and developer-friendly Discord bot framework available.
|
|
4
|
+
> NPM Package: @mostfeatured/dbi
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
DBI (Discord Bot Infrastructure) is a powerful NPM module that provides a complete infrastructure for building production-ready Discord bots with minimal boilerplate. It wraps Discord.js v14 and provides type-safe, structured patterns for building scalable bots.
|
|
9
|
+
|
|
10
|
+
## Key Features
|
|
11
|
+
|
|
12
|
+
- **Slash Commands**: Full support for Discord's application commands with type-safe options
|
|
13
|
+
- **Components V2**: Buttons, Select Menus, Modals with built-in state management
|
|
14
|
+
- **Svelte Integration**: Build reactive Discord UIs with Svelte 5 components
|
|
15
|
+
- **Localization**: Multi-language support for both content and interactions
|
|
16
|
+
- **Message Commands**: Automatic slash-to-message command conversion
|
|
17
|
+
- **Reference System**: Pass complex data through components without database
|
|
18
|
+
- **Rate Limiting**: Built-in per-user, channel, guild rate limiting
|
|
19
|
+
- **Multi-Client**: Support for multiple bot clients simultaneously
|
|
20
|
+
- **Hybrid Sharding**: Built-in support for discord-hybrid-sharding
|
|
21
|
+
- **Type Safety**: Full TypeScript support with intelligent autocomplete
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @mostfeatured/dbi discord.js
|
|
27
|
+
# or
|
|
28
|
+
pnpm add @mostfeatured/dbi discord.js
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Project Structure
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
my-bot/
|
|
35
|
+
├── dbi.js # DBI configuration
|
|
36
|
+
├── login.js # Bot startup script
|
|
37
|
+
├── publish.js # Command publishing script
|
|
38
|
+
└── src/
|
|
39
|
+
├── commands/ # Slash commands
|
|
40
|
+
├── events/ # Discord event handlers
|
|
41
|
+
├── components/ # Buttons, Select Menus, Modals
|
|
42
|
+
└── locales/ # Language files
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Core Concepts
|
|
48
|
+
|
|
49
|
+
### 1. Creating DBI Instance
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
const { createDBI } = require("@mostfeatured/dbi");
|
|
53
|
+
|
|
54
|
+
const dbi = createDBI("my-bot", {
|
|
55
|
+
strict: true,
|
|
56
|
+
discord: {
|
|
57
|
+
token: process.env.DISCORD_TOKEN,
|
|
58
|
+
options: {
|
|
59
|
+
intents: ["Guilds", "GuildMessages", "MessageContent"]
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
defaults: {
|
|
63
|
+
locale: { name: "en" },
|
|
64
|
+
defaultMemberPermissions: ["SendMessages"],
|
|
65
|
+
directMessages: false
|
|
66
|
+
},
|
|
67
|
+
references: {
|
|
68
|
+
autoClear: {
|
|
69
|
+
ttl: 60 * 60 * 1000, // 1 hour
|
|
70
|
+
check: 60 * 1000 // Check every minute
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
inlineListeners: {
|
|
74
|
+
autoClear: {
|
|
75
|
+
ttl: 15 * 60 * 1000, // 15 minutes
|
|
76
|
+
check: 60 * 1000
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
module.exports = dbi;
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 2. The Register Pattern
|
|
85
|
+
|
|
86
|
+
DBI uses a register pattern to define all bot features:
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
dbi.register(({ ChatInput, Button, Event, Locale }) => {
|
|
90
|
+
ChatInput({ /* ... */ });
|
|
91
|
+
Button({ /* ... */ });
|
|
92
|
+
Event({ /* ... */ });
|
|
93
|
+
Locale({ /* ... */ });
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Available register functions:
|
|
98
|
+
- `ChatInput` - Slash commands
|
|
99
|
+
- `Button` - Button components
|
|
100
|
+
- `StringSelectMenu`, `UserSelectMenu`, `RoleSelectMenu`, `ChannelSelectMenu`, `MentionableSelectMenu` - Select menus
|
|
101
|
+
- `Modal` - Modal dialogs
|
|
102
|
+
- `MessageContextMenu`, `UserContextMenu` - Context menu commands
|
|
103
|
+
- `Event` - Discord events
|
|
104
|
+
- `Locale` - Content localization
|
|
105
|
+
- `InteractionLocale` - Interaction name localization
|
|
106
|
+
- `CustomEvent` - Custom event definitions
|
|
107
|
+
- `HTMLComponentsV2` - Svelte/Eta template components
|
|
108
|
+
- `ChatInputOptions` - Command option builders
|
|
109
|
+
- `onUnload` - Cleanup callback for hot reloading
|
|
110
|
+
|
|
111
|
+
### 3. Starting the Bot
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
const { Utils } = require("@mostfeatured/dbi");
|
|
115
|
+
const dbi = require("./dbi");
|
|
116
|
+
|
|
117
|
+
async function start() {
|
|
118
|
+
await Utils.recursiveImport("./src"); // Import all files
|
|
119
|
+
await dbi.load(); // Load features
|
|
120
|
+
await dbi.login(); // Connect to Discord
|
|
121
|
+
}
|
|
122
|
+
start();
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 4. Publishing Commands
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
const { Utils } = require("@mostfeatured/dbi");
|
|
129
|
+
const dbi = require("./dbi");
|
|
130
|
+
|
|
131
|
+
async function publish() {
|
|
132
|
+
await Utils.recursiveImport("./src");
|
|
133
|
+
await dbi.load();
|
|
134
|
+
|
|
135
|
+
// Development: Guild-specific (instant)
|
|
136
|
+
await dbi.publish("Guild", "YOUR_GUILD_ID");
|
|
137
|
+
|
|
138
|
+
// Production: Global (up to 1 hour delay)
|
|
139
|
+
// await dbi.publish("Global");
|
|
140
|
+
|
|
141
|
+
await dbi.unload();
|
|
142
|
+
}
|
|
143
|
+
publish();
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Chat Input Commands (Slash Commands)
|
|
149
|
+
|
|
150
|
+
### Basic Command
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
dbi.register(({ ChatInput }) => {
|
|
154
|
+
ChatInput({
|
|
155
|
+
name: "ping",
|
|
156
|
+
description: "Check the bot's latency",
|
|
157
|
+
async onExecute({ interaction, dbi }) {
|
|
158
|
+
const latency = dbi.client().client.ws.ping;
|
|
159
|
+
await interaction.reply(`🏓 Pong! Latency: ${latency}ms`);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Command Options
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
dbi.register(({ ChatInput, ChatInputOptions }) => {
|
|
169
|
+
ChatInput({
|
|
170
|
+
name: "greet",
|
|
171
|
+
description: "Greet someone",
|
|
172
|
+
options: [
|
|
173
|
+
ChatInputOptions.user({
|
|
174
|
+
name: "user",
|
|
175
|
+
description: "User to greet",
|
|
176
|
+
required: true
|
|
177
|
+
}),
|
|
178
|
+
ChatInputOptions.string({
|
|
179
|
+
name: "message",
|
|
180
|
+
description: "Custom message",
|
|
181
|
+
required: false,
|
|
182
|
+
minLength: 1,
|
|
183
|
+
maxLength: 200
|
|
184
|
+
}),
|
|
185
|
+
ChatInputOptions.boolean({
|
|
186
|
+
name: "mention",
|
|
187
|
+
description: "Mention the user?",
|
|
188
|
+
required: false
|
|
189
|
+
})
|
|
190
|
+
],
|
|
191
|
+
onExecute({ interaction }) {
|
|
192
|
+
const user = interaction.options.getUser("user");
|
|
193
|
+
const message = interaction.options.getString("message") || "Hello!";
|
|
194
|
+
const mention = interaction.options.getBoolean("mention");
|
|
195
|
+
|
|
196
|
+
interaction.reply(mention ? `${user} ${message}` : `${user.username}: ${message}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### ChatInputOptions Methods
|
|
203
|
+
|
|
204
|
+
| Method | Description |
|
|
205
|
+
|--------|-------------|
|
|
206
|
+
| `string()` | Free text input |
|
|
207
|
+
| `stringChoices()` | Text with predefined choices |
|
|
208
|
+
| `stringAutocomplete()` | Text with dynamic autocomplete |
|
|
209
|
+
| `integer()` | Whole number |
|
|
210
|
+
| `integerChoices()` | Integer with choices |
|
|
211
|
+
| `integerAutocomplete()` | Integer with autocomplete |
|
|
212
|
+
| `number()` | Decimal number |
|
|
213
|
+
| `numberChoices()` | Number with choices |
|
|
214
|
+
| `numberAutocomplete()` | Number with autocomplete |
|
|
215
|
+
| `boolean()` | True/false |
|
|
216
|
+
| `user()` | User mention |
|
|
217
|
+
| `channel()` | Channel mention (supports `channelTypes[]`) |
|
|
218
|
+
| `role()` | Role mention |
|
|
219
|
+
| `mentionable()` | User or role |
|
|
220
|
+
| `attachment()` | File upload |
|
|
221
|
+
|
|
222
|
+
### Autocomplete
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
ChatInputOptions.stringAutocomplete({
|
|
226
|
+
name: "item",
|
|
227
|
+
description: "Search for an item",
|
|
228
|
+
required: true,
|
|
229
|
+
async onComplete({ value, interaction }) {
|
|
230
|
+
const items = await searchDatabase(value);
|
|
231
|
+
return items.slice(0, 25).map(item => ({
|
|
232
|
+
name: item.displayName,
|
|
233
|
+
value: item.id
|
|
234
|
+
}));
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Subcommands
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
const Discord = require("discord.js");
|
|
243
|
+
|
|
244
|
+
ChatInput({
|
|
245
|
+
name: "config",
|
|
246
|
+
description: "Bot configuration",
|
|
247
|
+
options: [
|
|
248
|
+
{
|
|
249
|
+
type: Discord.ApplicationCommandOptionType.Subcommand,
|
|
250
|
+
name: "view",
|
|
251
|
+
description: "View configuration"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
type: Discord.ApplicationCommandOptionType.Subcommand,
|
|
255
|
+
name: "set",
|
|
256
|
+
description: "Change a setting",
|
|
257
|
+
options: [
|
|
258
|
+
ChatInputOptions.string({ name: "key", description: "Setting name", required: true }),
|
|
259
|
+
ChatInputOptions.string({ name: "value", description: "New value", required: true })
|
|
260
|
+
]
|
|
261
|
+
}
|
|
262
|
+
],
|
|
263
|
+
onExecute({ interaction }) {
|
|
264
|
+
const subcommand = interaction.options.getSubcommand();
|
|
265
|
+
// Handle based on subcommand
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Permissions
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
ChatInput({
|
|
274
|
+
name: "ban",
|
|
275
|
+
description: "Ban a user",
|
|
276
|
+
defaultMemberPermissions: ["BanMembers"], // Required permission
|
|
277
|
+
directMessages: false, // Disable in DMs
|
|
278
|
+
onExecute({ interaction }) { /* ... */ }
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Context Menus
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
// Message Context Menu (right-click on message)
|
|
286
|
+
dbi.register(({ MessageContextMenu }) => {
|
|
287
|
+
MessageContextMenu({
|
|
288
|
+
name: "Report Message",
|
|
289
|
+
async onExecute({ interaction }) {
|
|
290
|
+
const message = interaction.targetMessage;
|
|
291
|
+
await interaction.reply({ content: `Reported: ${message.id}`, ephemeral: true });
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// User Context Menu (right-click on user)
|
|
297
|
+
dbi.register(({ UserContextMenu }) => {
|
|
298
|
+
UserContextMenu({
|
|
299
|
+
name: "View Profile",
|
|
300
|
+
async onExecute({ interaction }) {
|
|
301
|
+
const user = interaction.targetUser;
|
|
302
|
+
await interaction.reply({ content: `Profile: ${user.tag}`, ephemeral: true });
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Components
|
|
311
|
+
|
|
312
|
+
### Buttons
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
const Discord = require("discord.js");
|
|
316
|
+
|
|
317
|
+
dbi.register(({ ChatInput, Button }) => {
|
|
318
|
+
Button({
|
|
319
|
+
name: "action-btn",
|
|
320
|
+
options: {
|
|
321
|
+
style: Discord.ButtonStyle.Primary,
|
|
322
|
+
label: "Click Me",
|
|
323
|
+
emoji: "👋"
|
|
324
|
+
},
|
|
325
|
+
onExecute({ interaction, data }) {
|
|
326
|
+
const [action] = data; // Access referenced data
|
|
327
|
+
interaction.reply({ content: `Action: ${action}`, ephemeral: true });
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
ChatInput({
|
|
332
|
+
name: "actions",
|
|
333
|
+
description: "Show action buttons",
|
|
334
|
+
onExecute({ interaction, dbi }) {
|
|
335
|
+
const button = dbi.interaction("action-btn");
|
|
336
|
+
|
|
337
|
+
interaction.reply({
|
|
338
|
+
content: "Choose an action:",
|
|
339
|
+
components: [{
|
|
340
|
+
type: Discord.ComponentType.ActionRow,
|
|
341
|
+
components: [
|
|
342
|
+
button.toJSON({
|
|
343
|
+
overrides: { label: "Accept", style: Discord.ButtonStyle.Success },
|
|
344
|
+
reference: { data: ["accept"] }
|
|
345
|
+
}),
|
|
346
|
+
button.toJSON({
|
|
347
|
+
overrides: { label: "Decline", style: Discord.ButtonStyle.Danger },
|
|
348
|
+
reference: { data: ["decline"] }
|
|
349
|
+
})
|
|
350
|
+
]
|
|
351
|
+
}]
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Button Styles: `Primary`, `Secondary`, `Success`, `Danger`, `Link`, `Premium`
|
|
359
|
+
|
|
360
|
+
### Select Menus
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
dbi.register(({ StringSelectMenu }) => {
|
|
364
|
+
StringSelectMenu({
|
|
365
|
+
name: "color-select",
|
|
366
|
+
options: {
|
|
367
|
+
placeholder: "Choose a color...",
|
|
368
|
+
minValues: 1,
|
|
369
|
+
maxValues: 1,
|
|
370
|
+
options: [
|
|
371
|
+
{ label: "Red", value: "red", emoji: "🔴", description: "A warm color" },
|
|
372
|
+
{ label: "Green", value: "green", emoji: "🟢" },
|
|
373
|
+
{ label: "Blue", value: "blue", emoji: "🔵" }
|
|
374
|
+
]
|
|
375
|
+
},
|
|
376
|
+
onExecute({ interaction }) {
|
|
377
|
+
const selected = interaction.values[0];
|
|
378
|
+
interaction.reply(`You selected: ${selected}`);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
// Other select menu types
|
|
384
|
+
UserSelectMenu({ /* ... */ }); // Select users
|
|
385
|
+
RoleSelectMenu({ /* ... */ }); // Select roles
|
|
386
|
+
ChannelSelectMenu({ /* ... */ }); // Select channels
|
|
387
|
+
MentionableSelectMenu({ /* ... */ }); // Select users or roles
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Modals
|
|
391
|
+
|
|
392
|
+
```javascript
|
|
393
|
+
dbi.register(({ Modal, Button }) => {
|
|
394
|
+
Modal({
|
|
395
|
+
name: "feedback-modal",
|
|
396
|
+
options: {
|
|
397
|
+
title: "Send Feedback",
|
|
398
|
+
components: [
|
|
399
|
+
{
|
|
400
|
+
type: Discord.ComponentType.ActionRow,
|
|
401
|
+
components: [{
|
|
402
|
+
type: Discord.ComponentType.TextInput,
|
|
403
|
+
customId: "subject",
|
|
404
|
+
label: "Subject",
|
|
405
|
+
style: Discord.TextInputStyle.Short,
|
|
406
|
+
placeholder: "Brief description",
|
|
407
|
+
required: true,
|
|
408
|
+
minLength: 5,
|
|
409
|
+
maxLength: 100
|
|
410
|
+
}]
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
type: Discord.ComponentType.ActionRow,
|
|
414
|
+
components: [{
|
|
415
|
+
type: Discord.ComponentType.TextInput,
|
|
416
|
+
customId: "message",
|
|
417
|
+
label: "Message",
|
|
418
|
+
style: Discord.TextInputStyle.Paragraph,
|
|
419
|
+
placeholder: "Your detailed feedback...",
|
|
420
|
+
required: true
|
|
421
|
+
}]
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
async onExecute({ interaction }) {
|
|
426
|
+
const subject = interaction.fields.getTextInputValue("subject");
|
|
427
|
+
const message = interaction.fields.getTextInputValue("message");
|
|
428
|
+
await interaction.reply({ content: "Thanks for your feedback!", ephemeral: true });
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
Button({
|
|
433
|
+
name: "open-feedback",
|
|
434
|
+
options: { style: Discord.ButtonStyle.Primary, label: "Feedback" },
|
|
435
|
+
async onExecute({ interaction, dbi }) {
|
|
436
|
+
const modal = dbi.interaction("feedback-modal").toJSON();
|
|
437
|
+
await interaction.showModal(modal);
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Reference System
|
|
444
|
+
|
|
445
|
+
Pass data through components without database:
|
|
446
|
+
|
|
447
|
+
```javascript
|
|
448
|
+
// Primitive values are encoded in custom ID
|
|
449
|
+
button.toJSON({
|
|
450
|
+
reference: {
|
|
451
|
+
data: ["userId123", 42, true] // string, number, boolean
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// Objects are stored in memory with auto-cleanup
|
|
456
|
+
button.toJSON({
|
|
457
|
+
reference: {
|
|
458
|
+
data: [{ complex: "object", nested: { data: true } }],
|
|
459
|
+
ttl: 300000 // Auto-expire in 5 minutes
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
// Access in handler
|
|
464
|
+
Button({
|
|
465
|
+
name: "my-btn",
|
|
466
|
+
onExecute({ data }) {
|
|
467
|
+
const [primitiveOrObject] = data;
|
|
468
|
+
|
|
469
|
+
// If object, has $ref and $unRef
|
|
470
|
+
if (primitiveOrObject?.$ref) {
|
|
471
|
+
console.log(primitiveOrObject.$ref); // Reference ID
|
|
472
|
+
primitiveOrObject.$unRef(); // Clean up when done
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Inline Components
|
|
479
|
+
|
|
480
|
+
Create one-time use components without pre-registration:
|
|
481
|
+
|
|
482
|
+
```javascript
|
|
483
|
+
dbi.register(({ ChatInput, createInlineButton, createInlineStringSelectMenu }) => {
|
|
484
|
+
ChatInput({
|
|
485
|
+
name: "confirm",
|
|
486
|
+
description: "Confirm an action",
|
|
487
|
+
async onExecute({ interaction }) {
|
|
488
|
+
const confirmBtn = createInlineButton({
|
|
489
|
+
options: { style: Discord.ButtonStyle.Success, label: "Confirm" },
|
|
490
|
+
onExecute({ interaction }) {
|
|
491
|
+
interaction.reply("Confirmed!");
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
const cancelBtn = createInlineButton({
|
|
496
|
+
options: { style: Discord.ButtonStyle.Danger, label: "Cancel" },
|
|
497
|
+
onExecute({ interaction }) {
|
|
498
|
+
interaction.reply("Cancelled!");
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
await interaction.reply({
|
|
503
|
+
content: "Are you sure?",
|
|
504
|
+
components: [{
|
|
505
|
+
type: Discord.ComponentType.ActionRow,
|
|
506
|
+
components: [confirmBtn.toJSON(), cancelBtn.toJSON()]
|
|
507
|
+
}]
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Inline creators: `createInlineButton`, `createInlineStringSelectMenu`, `createInlineUserSelectMenu`, `createInlineRoleSelectMenu`, `createInlineChannelSelectMenu`, `createInlineMentionableSelectMenu`, `createInlineModal`, `createInlineEvent`
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Events
|
|
519
|
+
|
|
520
|
+
### Basic Event Handler
|
|
521
|
+
|
|
522
|
+
```javascript
|
|
523
|
+
dbi.register(({ Event }) => {
|
|
524
|
+
Event({
|
|
525
|
+
name: "clientReady",
|
|
526
|
+
id: "ready-logger", // Unique ID for multiple handlers of same event
|
|
527
|
+
onExecute({ client }) {
|
|
528
|
+
console.log(`Bot is online as ${client.user.tag}`);
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
Event({
|
|
533
|
+
name: "messageCreate",
|
|
534
|
+
id: "message-handler",
|
|
535
|
+
onExecute({ message }) {
|
|
536
|
+
if (message.author.bot) return;
|
|
537
|
+
console.log(`${message.author.tag}: ${message.content}`);
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
Event({
|
|
542
|
+
name: "guildMemberAdd",
|
|
543
|
+
id: "welcome",
|
|
544
|
+
async onExecute({ member }) {
|
|
545
|
+
const channel = member.guild.systemChannel;
|
|
546
|
+
if (channel) await channel.send(`Welcome ${member}!`);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Common Events
|
|
553
|
+
|
|
554
|
+
| Event Name | Parameters |
|
|
555
|
+
|------------|------------|
|
|
556
|
+
| `clientReady` | `{ client }` |
|
|
557
|
+
| `messageCreate` | `{ message }` |
|
|
558
|
+
| `messageDelete` | `{ message }` |
|
|
559
|
+
| `messageUpdate` | `{ oldMessage, newMessage }` |
|
|
560
|
+
| `guildCreate` | `{ guild }` |
|
|
561
|
+
| `guildDelete` | `{ guild }` |
|
|
562
|
+
| `guildMemberAdd` | `{ member }` |
|
|
563
|
+
| `guildMemberRemove` | `{ member }` |
|
|
564
|
+
| `interactionCreate` | `{ interaction }` |
|
|
565
|
+
| `voiceStateUpdate` | `{ oldState, newState }` |
|
|
566
|
+
|
|
567
|
+
### Custom Events
|
|
568
|
+
|
|
569
|
+
```javascript
|
|
570
|
+
dbi.register(({ CustomEvent, Event }) => {
|
|
571
|
+
CustomEvent({
|
|
572
|
+
name: "userLevelUp",
|
|
573
|
+
map: { userId: "userId", newLevel: "newLevel", guild: "guild" }
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
Event({
|
|
577
|
+
name: "userLevelUp",
|
|
578
|
+
id: "levelup-announcer",
|
|
579
|
+
onExecute({ userId, newLevel, guild }) {
|
|
580
|
+
guild.systemChannel?.send(`🎉 <@${userId}> reached level ${newLevel}!`);
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
// Trigger from anywhere
|
|
586
|
+
dbi.emit("userLevelUp", { userId: "123", newLevel: 10, guild: someGuild });
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### DBI Internal Events
|
|
590
|
+
|
|
591
|
+
```javascript
|
|
592
|
+
dbi.events.on("beforeInteraction", async (ctx) => {
|
|
593
|
+
console.log(`Interaction: ${ctx.dbiInteraction.name}`);
|
|
594
|
+
return true; // Continue execution
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
dbi.events.on("afterInteraction", async (ctx) => {
|
|
598
|
+
console.log(`Completed: ${ctx.dbiInteraction.name}`);
|
|
599
|
+
return true;
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
dbi.events.on("interactionError", async ({ interaction, error }) => {
|
|
603
|
+
console.error("Error:", error);
|
|
604
|
+
await interaction.reply({ content: "An error occurred.", ephemeral: true });
|
|
605
|
+
return true;
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
dbi.events.on("interactionRateLimit", async ({ interaction, remainingTime }) => {
|
|
609
|
+
const seconds = Math.ceil(remainingTime / 1000);
|
|
610
|
+
await interaction.reply({ content: `Cooldown: ${seconds}s`, ephemeral: true });
|
|
611
|
+
return false; // Don't execute
|
|
612
|
+
});
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Localization
|
|
618
|
+
|
|
619
|
+
### Content Localization
|
|
620
|
+
|
|
621
|
+
```javascript
|
|
622
|
+
dbi.register(({ Locale }) => {
|
|
623
|
+
Locale({
|
|
624
|
+
name: "en",
|
|
625
|
+
data: {
|
|
626
|
+
greeting: "Hello!",
|
|
627
|
+
welcome: "Welcome, {0}!",
|
|
628
|
+
levelUp: "{0} reached level {1}!",
|
|
629
|
+
commands: {
|
|
630
|
+
help: { title: "Help Menu", description: "Available commands:" }
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
Locale({
|
|
636
|
+
name: "tr",
|
|
637
|
+
data: {
|
|
638
|
+
greeting: "Merhaba!",
|
|
639
|
+
welcome: "Hoş geldin, {0}!",
|
|
640
|
+
levelUp: "{0} seviye {1}'e ulaştı!",
|
|
641
|
+
commands: {
|
|
642
|
+
help: { title: "Yardım Menüsü", description: "Mevcut komutlar:" }
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Using Locales
|
|
650
|
+
|
|
651
|
+
```javascript
|
|
652
|
+
ChatInput({
|
|
653
|
+
name: "greet",
|
|
654
|
+
description: "Greet the user",
|
|
655
|
+
onExecute({ interaction, locale }) {
|
|
656
|
+
// User's locale (based on Discord client language)
|
|
657
|
+
const greeting = locale.user.data.greeting();
|
|
658
|
+
const welcome = locale.user.data.welcome(interaction.user.username);
|
|
659
|
+
const title = locale.user.data.commands.help.title();
|
|
660
|
+
|
|
661
|
+
// Guild's locale
|
|
662
|
+
const guildGreeting = locale.guild?.data.greeting?.();
|
|
663
|
+
|
|
664
|
+
interaction.reply(welcome);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// Access specific locale
|
|
669
|
+
const enLocale = dbi.locale("en");
|
|
670
|
+
const message = enLocale.data.levelUp("John", 10);
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Interaction Localization (Command Translations)
|
|
674
|
+
|
|
675
|
+
```javascript
|
|
676
|
+
dbi.register(({ ChatInput, InteractionLocale }) => {
|
|
677
|
+
ChatInput({
|
|
678
|
+
name: "ayarlar", // Turkish default
|
|
679
|
+
description: "Bot ayarlarını değiştir",
|
|
680
|
+
onExecute({ interaction }) { /* ... */ }
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
InteractionLocale({
|
|
684
|
+
name: "ayarlar",
|
|
685
|
+
data: {
|
|
686
|
+
en: {
|
|
687
|
+
name: "settings",
|
|
688
|
+
description: "Change bot settings",
|
|
689
|
+
options: {
|
|
690
|
+
dil: {
|
|
691
|
+
name: "language",
|
|
692
|
+
description: "Preferred language"
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
},
|
|
696
|
+
es: {
|
|
697
|
+
name: "ajustes",
|
|
698
|
+
description: "Cambiar configuración del bot"
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## Svelte Components (HTMLComponentsV2)
|
|
708
|
+
|
|
709
|
+
Build reactive Discord UIs with Svelte 5:
|
|
710
|
+
|
|
711
|
+
### Registration
|
|
712
|
+
|
|
713
|
+
```javascript
|
|
714
|
+
const path = require("path");
|
|
715
|
+
|
|
716
|
+
dbi.register(({ HTMLComponentsV2, ChatInput }) => {
|
|
717
|
+
HTMLComponentsV2({
|
|
718
|
+
name: "counter",
|
|
719
|
+
mode: "svelte",
|
|
720
|
+
file: path.join(__dirname, "counter.svelte")
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
ChatInput({
|
|
724
|
+
name: "counter",
|
|
725
|
+
description: "Interactive counter",
|
|
726
|
+
async onExecute({ interaction, dbi }) {
|
|
727
|
+
const component = dbi.interaction("counter");
|
|
728
|
+
await component.send(interaction, {
|
|
729
|
+
data: { count: 0 }
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
});
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### Svelte Component (counter.svelte)
|
|
737
|
+
|
|
738
|
+
```svelte
|
|
739
|
+
<script>
|
|
740
|
+
/// <reference types="@mostfeatured/dbi/svelte" />
|
|
741
|
+
|
|
742
|
+
let { count = 0 } = $props();
|
|
743
|
+
|
|
744
|
+
function increment() {
|
|
745
|
+
data.count++;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function decrement() {
|
|
749
|
+
data.count--;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
function reset(ctx) {
|
|
753
|
+
data.count = 0;
|
|
754
|
+
ctx.interaction.reply({ content: "Reset!", flags: ["Ephemeral"] });
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
onMount(() => {
|
|
758
|
+
const interval = setInterval(() => {
|
|
759
|
+
// Auto-updates component every second
|
|
760
|
+
}, 1000);
|
|
761
|
+
return () => clearInterval(interval); // Cleanup
|
|
762
|
+
});
|
|
763
|
+
</script>
|
|
764
|
+
|
|
765
|
+
<components>
|
|
766
|
+
<container accent-color="5865F2">
|
|
767
|
+
<components>
|
|
768
|
+
<text-display>## Counter: {count}</text-display>
|
|
769
|
+
<action-row>
|
|
770
|
+
<button style="Primary" handler={decrement}>-1</button>
|
|
771
|
+
<button style="Primary" handler={increment}>+1</button>
|
|
772
|
+
<button style="Danger" handler={reset}>Reset</button>
|
|
773
|
+
</action-row>
|
|
774
|
+
</components>
|
|
775
|
+
</container>
|
|
776
|
+
</components>
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### Svelte HTML Elements
|
|
780
|
+
|
|
781
|
+
Layout:
|
|
782
|
+
- `<components>` - Root wrapper
|
|
783
|
+
- `<action-row>` - Container for buttons (max 5) or single select menu
|
|
784
|
+
- `<container accent-color="hex" spoiler>` - Colored container
|
|
785
|
+
- `<section>` - Section with components and accessory
|
|
786
|
+
- `<separator divider spacing="1-3">` - Visual divider
|
|
787
|
+
|
|
788
|
+
Interactive:
|
|
789
|
+
- `<button style="Primary|Secondary|Success|Danger|Link|Premium" handler={fn} emoji="🎉" disabled>Label</button>`
|
|
790
|
+
- `<string-select placeholder="..." min-values="1" max-values="3" handler={fn}>`
|
|
791
|
+
- `<option value="x" description="..." emoji="..." default>Label</option>`
|
|
792
|
+
- `<user-select>`, `<role-select>`, `<channel-select>`, `<mentionable-select>`
|
|
793
|
+
|
|
794
|
+
Display:
|
|
795
|
+
- `<text-display>Markdown content</text-display>`
|
|
796
|
+
- `<thumbnail url="...">` or `<thumbnail media="...">`
|
|
797
|
+
- `<media-gallery>` with `<item url="..." description="..." spoiler>`
|
|
798
|
+
- `<file url="attachment://file.pdf" spoiler>`
|
|
799
|
+
|
|
800
|
+
Modal:
|
|
801
|
+
- `<text-input id="..." label="..." placeholder="..." style="Short|Paragraph" min-length="1" max-length="100" required>Default</text-input>`
|
|
802
|
+
|
|
803
|
+
### Svelte Globals
|
|
804
|
+
|
|
805
|
+
```javascript
|
|
806
|
+
// Reactive data updates
|
|
807
|
+
data.property = newValue; // Triggers re-render
|
|
808
|
+
|
|
809
|
+
// Render control
|
|
810
|
+
render(); // Force immediate render
|
|
811
|
+
update(); // Use interaction.update()
|
|
812
|
+
rerender(); // Use message.edit()
|
|
813
|
+
noRender(); // Disable auto-render for this handler
|
|
814
|
+
setThrottle(ms); // Set min interval between renders
|
|
815
|
+
|
|
816
|
+
// Lifecycle
|
|
817
|
+
onMount(() => { return cleanup; });
|
|
818
|
+
onDestroy(() => { /* cleanup */ });
|
|
819
|
+
destroy(); // Manually destroy component
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
---
|
|
823
|
+
|
|
824
|
+
## Rate Limiting
|
|
825
|
+
|
|
826
|
+
### Declarative Rate Limits
|
|
827
|
+
|
|
828
|
+
```javascript
|
|
829
|
+
ChatInput({
|
|
830
|
+
name: "daily",
|
|
831
|
+
description: "Daily reward",
|
|
832
|
+
rateLimits: [
|
|
833
|
+
{ type: "User", duration: 86400000 } // 24 hours
|
|
834
|
+
],
|
|
835
|
+
onExecute({ interaction }) {
|
|
836
|
+
interaction.reply("Here's your daily reward!");
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
Rate Limit Types: `User`, `Channel`, `Guild`, `Member`, `Message`
|
|
842
|
+
|
|
843
|
+
### Dynamic Rate Limits
|
|
844
|
+
|
|
845
|
+
```javascript
|
|
846
|
+
ChatInput({
|
|
847
|
+
name: "action",
|
|
848
|
+
description: "Do something",
|
|
849
|
+
async onExecute({ interaction, setRateLimit }) {
|
|
850
|
+
const isPremium = await checkPremium(interaction.user.id);
|
|
851
|
+
await setRateLimit("User", isPremium ? 30000 : 300000);
|
|
852
|
+
interaction.reply("Done!");
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
---
|
|
858
|
+
|
|
859
|
+
## Message Commands
|
|
860
|
+
|
|
861
|
+
Enable prefix-based commands that mirror slash commands:
|
|
862
|
+
|
|
863
|
+
```javascript
|
|
864
|
+
const dbi = createDBI("my-bot", {
|
|
865
|
+
discord: { /* ... */ },
|
|
866
|
+
messageCommands: {
|
|
867
|
+
prefixes: ["!", ".", "?"],
|
|
868
|
+
// Or dynamic: async ({ message }) => [await getGuildPrefix(message.guild?.id)]
|
|
869
|
+
typeAliases: {
|
|
870
|
+
booleans: { "yes": true, "no": false, "on": true, "off": false }
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
defaults: {
|
|
874
|
+
messageCommands: {
|
|
875
|
+
deferReplyContent: "Processing..."
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
Usage: `!ping`, `!greet @User Hello!`
|
|
882
|
+
|
|
883
|
+
### Aliases and Rest Arguments
|
|
884
|
+
|
|
885
|
+
```javascript
|
|
886
|
+
ChatInput({
|
|
887
|
+
name: "help",
|
|
888
|
+
description: "Show help",
|
|
889
|
+
other: {
|
|
890
|
+
messageCommand: {
|
|
891
|
+
aliases: ["h", "?", "commands"],
|
|
892
|
+
ignore: false // Set true to disable message command
|
|
893
|
+
}
|
|
894
|
+
},
|
|
895
|
+
onExecute({ interaction }) { /* ... */ }
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
// Rest string (captures all remaining text)
|
|
899
|
+
ChatInputOptions.string({
|
|
900
|
+
name: "message",
|
|
901
|
+
description: "The message",
|
|
902
|
+
required: true,
|
|
903
|
+
messageCommands: { rest: true }
|
|
904
|
+
})
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
---
|
|
908
|
+
|
|
909
|
+
## Multi-Client Support
|
|
910
|
+
|
|
911
|
+
```javascript
|
|
912
|
+
const dbi = createDBI("my-bot", {
|
|
913
|
+
discord: [
|
|
914
|
+
{ namespace: "main", token: process.env.MAIN_TOKEN, options: { intents: ["Guilds"] } },
|
|
915
|
+
{ namespace: "music", token: process.env.MUSIC_TOKEN, options: { intents: ["GuildVoiceStates"] } }
|
|
916
|
+
]
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
// Access clients
|
|
920
|
+
const mainClient = dbi.client("main");
|
|
921
|
+
const musicClient = dbi.client("music");
|
|
922
|
+
|
|
923
|
+
// Publish to specific client
|
|
924
|
+
ChatInput({
|
|
925
|
+
name: "play",
|
|
926
|
+
description: "Play music",
|
|
927
|
+
publish: "music", // Only on music bot
|
|
928
|
+
onExecute({ clientNamespace }) { /* ... */ }
|
|
929
|
+
});
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
---
|
|
933
|
+
|
|
934
|
+
## Sharding
|
|
935
|
+
|
|
936
|
+
```javascript
|
|
937
|
+
// Default sharding
|
|
938
|
+
const dbi = createDBI("my-bot", { sharding: "default", /* ... */ });
|
|
939
|
+
|
|
940
|
+
// Hybrid sharding (discord-hybrid-sharding)
|
|
941
|
+
const dbi = createDBI("my-bot", { sharding: "hybrid", /* ... */ });
|
|
942
|
+
|
|
943
|
+
// Access cluster info
|
|
944
|
+
if (dbi.cluster) {
|
|
945
|
+
console.log(`Cluster: ${dbi.cluster.id}, Shards: ${dbi.cluster.shards}`);
|
|
946
|
+
}
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
---
|
|
950
|
+
|
|
951
|
+
## Hot Reloading
|
|
952
|
+
|
|
953
|
+
```javascript
|
|
954
|
+
dbi.register(({ ChatInput, Event, onUnload }) => {
|
|
955
|
+
let interval;
|
|
956
|
+
|
|
957
|
+
Event({
|
|
958
|
+
name: "clientReady",
|
|
959
|
+
id: "updater",
|
|
960
|
+
onExecute() {
|
|
961
|
+
interval = setInterval(() => { /* ... */ }, 60000);
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
onUnload(() => {
|
|
966
|
+
if (interval) clearInterval(interval);
|
|
967
|
+
console.log("Cleaned up!");
|
|
968
|
+
});
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
// Reload flow
|
|
972
|
+
await dbi.unload();
|
|
973
|
+
Utils.recursiveUnload("./src");
|
|
974
|
+
await Utils.recursiveImport("./src");
|
|
975
|
+
await dbi.load();
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
---
|
|
979
|
+
|
|
980
|
+
## Flag-based Loading
|
|
981
|
+
|
|
982
|
+
```javascript
|
|
983
|
+
ChatInput({
|
|
984
|
+
name: "debug-info",
|
|
985
|
+
description: "Debug information",
|
|
986
|
+
flag: "debug", // Only loaded with debug flag
|
|
987
|
+
onExecute({ interaction }) { /* ... */ }
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
// Load with specific flags
|
|
991
|
+
await dbi.load("debug");
|
|
992
|
+
await dbi.load("debug", "admin");
|
|
993
|
+
await dbi.load("all"); // Load everything
|
|
994
|
+
await dbi.load(); // Only non-flagged features
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
---
|
|
998
|
+
|
|
999
|
+
## Data Management
|
|
1000
|
+
|
|
1001
|
+
```javascript
|
|
1002
|
+
// Store/retrieve data
|
|
1003
|
+
dbi.set("config", { prefix: "!" });
|
|
1004
|
+
const config = dbi.get("config");
|
|
1005
|
+
dbi.has("config");
|
|
1006
|
+
dbi.delete("config");
|
|
1007
|
+
|
|
1008
|
+
// Access registered features
|
|
1009
|
+
const pingCmd = dbi.interaction("ping");
|
|
1010
|
+
const readyEvent = dbi.event("ready-handler");
|
|
1011
|
+
const enLocale = dbi.locale("en");
|
|
1012
|
+
|
|
1013
|
+
// Access collections
|
|
1014
|
+
dbi.data.interactions; // Discord.Collection
|
|
1015
|
+
dbi.data.events;
|
|
1016
|
+
dbi.data.locales;
|
|
1017
|
+
dbi.data.refs; // Reference storage
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
---
|
|
1021
|
+
|
|
1022
|
+
## Execution Context
|
|
1023
|
+
|
|
1024
|
+
All handlers receive a context object:
|
|
1025
|
+
|
|
1026
|
+
```javascript
|
|
1027
|
+
onExecute({
|
|
1028
|
+
interaction, // Discord.js interaction
|
|
1029
|
+
dbi, // DBI instance
|
|
1030
|
+
dbiInteraction, // The registered interaction object
|
|
1031
|
+
locale, // { user: DBILocale, guild?: DBILocale }
|
|
1032
|
+
setRateLimit, // (type, duration) => Promise<void>
|
|
1033
|
+
other, // Custom shared data
|
|
1034
|
+
clientNamespace, // Multi-client namespace
|
|
1035
|
+
v2, // Components V2 enabled
|
|
1036
|
+
data // Referenced data array (components only)
|
|
1037
|
+
}) { /* ... */ }
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
---
|
|
1041
|
+
|
|
1042
|
+
## API Quick Reference
|
|
1043
|
+
|
|
1044
|
+
### DBI Instance Methods
|
|
1045
|
+
|
|
1046
|
+
| Method | Description |
|
|
1047
|
+
|--------|-------------|
|
|
1048
|
+
| `register(callback)` | Register bot features |
|
|
1049
|
+
| `load(...flags)` | Load registered features |
|
|
1050
|
+
| `unload()` | Unload all features |
|
|
1051
|
+
| `login()` | Connect to Discord |
|
|
1052
|
+
| `publish(type, guildId?)` | Publish commands |
|
|
1053
|
+
| `interaction(name)` | Get registered interaction |
|
|
1054
|
+
| `event(name)` | Get registered event |
|
|
1055
|
+
| `locale(name)` | Get registered locale |
|
|
1056
|
+
| `client(namespace?)` | Get client |
|
|
1057
|
+
| `emit(name, args)` | Emit custom event |
|
|
1058
|
+
| `get/set/has/delete` | Data management |
|
|
1059
|
+
|
|
1060
|
+
### Interaction Methods
|
|
1061
|
+
|
|
1062
|
+
| Method | Description |
|
|
1063
|
+
|--------|-------------|
|
|
1064
|
+
| `toJSON(args?)` | Get JSON for Discord API |
|
|
1065
|
+
| `createBuilder()` | Get fluent builder |
|
|
1066
|
+
|
|
1067
|
+
### Component Builder Methods
|
|
1068
|
+
|
|
1069
|
+
| Method | Description |
|
|
1070
|
+
|--------|-------------|
|
|
1071
|
+
| `setLabel(label)` | Set button label |
|
|
1072
|
+
| `setEmoji(emoji)` | Set emoji |
|
|
1073
|
+
| `setStyle(style)` | Set style |
|
|
1074
|
+
| `setReference(data)` | Set reference data |
|
|
1075
|
+
| `setTTL(ms)` | Set time-to-live |
|
|
1076
|
+
| `toJSON()` | Build final JSON |
|
|
1077
|
+
|
|
1078
|
+
---
|
|
1079
|
+
|
|
1080
|
+
## License
|
|
1081
|
+
|
|
1082
|
+
GPL-3.0 License
|
|
1083
|
+
|
|
1084
|
+
---
|
|
1085
|
+
|
|
1086
|
+
Made by TheArmagan and the MostFeatured team
|
|
1087
|
+
Package: @mostfeatured/dbi
|
|
1088
|
+
GitHub: https://github.com/MostFeatured/DiscordBotInfrastructure
|