@mostfeatured/dbi 0.2.16 → 0.2.18
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/index.d.ts +4 -0
- package/dist/src/types/Components/HTMLComponentsV2/index.d.ts.map +1 -1
- package/dist/src/types/Components/HTMLComponentsV2/index.js +40 -5
- package/dist/src/types/Components/HTMLComponentsV2/index.js.map +1 -1
- package/dist/src/types/Event.d.ts +21 -13
- package/dist/src/types/Event.d.ts.map +1 -1
- package/dist/src/types/Event.js.map +1 -1
- package/dist/test/index.js +1 -1
- package/dist/test/index.js.map +1 -1
- package/generated/namespaceData.d.ts +3 -1
- package/package.json +6 -2
- package/.gitattributes +0 -2
- package/.hintrc +0 -8
- package/.vscode/settings.json +0 -3
- package/docs/ADVANCED_FEATURES.md +0 -840
- package/docs/API_REFERENCE.md +0 -929
- package/docs/CHAT_INPUT.md +0 -811
- package/docs/COMPONENTS.md +0 -1039
- package/docs/EVENTS.md +0 -568
- package/docs/GETTING_STARTED.md +0 -398
- package/docs/LOCALIZATION.md +0 -777
- package/docs/README.md +0 -345
- package/docs/SVELTE_COMPONENTS.md +0 -1111
- package/docs/llm/ADVANCED_FEATURES.txt +0 -521
- package/docs/llm/API_REFERENCE.txt +0 -659
- package/docs/llm/CHAT_INPUT.txt +0 -514
- package/docs/llm/COMPONENTS.txt +0 -595
- package/docs/llm/EVENTS.txt +0 -449
- package/docs/llm/GETTING_STARTED.txt +0 -296
- package/docs/llm/LOCALIZATION.txt +0 -501
- package/docs/llm/README.txt +0 -193
- package/docs/llm/SVELTE_COMPONENTS.txt +0 -566
- package/src/DBI.ts +0 -1007
- package/src/Events.ts +0 -189
- package/src/data/eventMap.json +0 -248
- package/src/index.ts +0 -23
- package/src/methods/handleMessageCommands.ts +0 -482
- package/src/methods/hookEventListeners.ts +0 -119
- package/src/methods/hookInteractionListeners.ts +0 -314
- package/src/methods/publishInteractions.ts +0 -256
- package/src/types/ApplicationRoleConnectionMetadata.ts +0 -19
- package/src/types/Builders/ButtonBuilder.ts +0 -53
- package/src/types/Builders/ChannelSelectMenuBuilder.ts +0 -53
- package/src/types/Builders/MentionableSelectMenuBuilder.ts +0 -53
- package/src/types/Builders/ModalBuilder.ts +0 -53
- package/src/types/Builders/RoleSelectMenuBuilder.ts +0 -53
- package/src/types/Builders/StringSelectMenuBuilder.ts +0 -53
- package/src/types/Builders/UserSelectMenuBuilder.ts +0 -53
- package/src/types/ChatInput/ChatInput.ts +0 -28
- package/src/types/ChatInput/ChatInputOptions.ts +0 -388
- package/src/types/Components/Button.ts +0 -39
- package/src/types/Components/ChannelSelectMenu.ts +0 -43
- package/src/types/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.ts +0 -78
- package/src/types/Components/HTMLComponentsV2/index.ts +0 -761
- package/src/types/Components/HTMLComponentsV2/parser.ts +0 -649
- package/src/types/Components/HTMLComponentsV2/svelteParser.ts +0 -1503
- package/src/types/Components/HTMLComponentsV2/svelteRenderer.ts +0 -416
- package/src/types/Components/MentionableSelectMenu.ts +0 -43
- package/src/types/Components/Modal.ts +0 -46
- package/src/types/Components/RoleSelectMenu.ts +0 -43
- package/src/types/Components/StringSelectMenu.ts +0 -43
- package/src/types/Components/UserSelectMenu.ts +0 -43
- package/src/types/Event.ts +0 -145
- package/src/types/Interaction.ts +0 -100
- package/src/types/other/CustomEvent.ts +0 -19
- package/src/types/other/FakeMessageInteraction.ts +0 -408
- package/src/types/other/InteractionLocale.ts +0 -34
- package/src/types/other/Locale.ts +0 -70
- package/src/types/other/MessageContextMenu.ts +0 -27
- package/src/types/other/UserContextMenu.ts +0 -25
- package/src/utils/MemoryStore.ts +0 -28
- package/src/utils/UtilTypes.ts +0 -11
- package/src/utils/customId.ts +0 -49
- package/src/utils/permissions.ts +0 -5
- package/src/utils/recursiveImport.ts +0 -35
- package/src/utils/recursiveUnload.ts +0 -25
- package/src/utils/unloadModule.ts +0 -7
- package/test/index.ts +0 -176
- package/test/product-showcase.svelte +0 -558
- package/test/test.ts +0 -3
- package/tsconfig.json +0 -51
package/docs/COMPONENTS.md
DELETED
|
@@ -1,1039 +0,0 @@
|
|
|
1
|
-
# Components Guide
|
|
2
|
-
|
|
3
|
-
DBI provides comprehensive support for Discord's interactive components: Buttons, Select Menus, and Modals. This guide covers how to create, configure, and handle all component types.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
- [Buttons](#buttons)
|
|
10
|
-
- [Select Menus](#select-menus)
|
|
11
|
-
- [Modals](#modals)
|
|
12
|
-
- [Reference System](#reference-system)
|
|
13
|
-
- [Inline Components](#inline-components)
|
|
14
|
-
- [Builder Pattern](#builder-pattern)
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## Buttons
|
|
19
|
-
|
|
20
|
-
### Basic Button
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
const Discord = require("discord.js");
|
|
24
|
-
|
|
25
|
-
dbi.register(({ ChatInput, Button }) => {
|
|
26
|
-
// Define the button handler
|
|
27
|
-
Button({
|
|
28
|
-
name: "greet-button",
|
|
29
|
-
|
|
30
|
-
// Default button appearance
|
|
31
|
-
options: {
|
|
32
|
-
style: Discord.ButtonStyle.Primary,
|
|
33
|
-
label: "Click Me!",
|
|
34
|
-
emoji: "👋"
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
// Executed when button is clicked
|
|
38
|
-
onExecute({ interaction }) {
|
|
39
|
-
interaction.reply({
|
|
40
|
-
content: "Hello! You clicked the button! 🎉",
|
|
41
|
-
ephemeral: true
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// Command that sends the button
|
|
47
|
-
ChatInput({
|
|
48
|
-
name: "greet",
|
|
49
|
-
description: "Get a greeting button",
|
|
50
|
-
|
|
51
|
-
onExecute({ interaction, dbi }) {
|
|
52
|
-
// Get the button and convert to JSON for Discord
|
|
53
|
-
const button = dbi.interaction("greet-button").toJSON();
|
|
54
|
-
|
|
55
|
-
interaction.reply({
|
|
56
|
-
content: "Click the button below!",
|
|
57
|
-
components: [
|
|
58
|
-
{
|
|
59
|
-
type: Discord.ComponentType.ActionRow,
|
|
60
|
-
components: [button]
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Button Styles
|
|
70
|
-
|
|
71
|
-
| Style | Constant | Use Case |
|
|
72
|
-
|-------|----------|----------|
|
|
73
|
-
| Primary | `ButtonStyle.Primary` | Main action (blue) |
|
|
74
|
-
| Secondary | `ButtonStyle.Secondary` | Alternative action (gray) |
|
|
75
|
-
| Success | `ButtonStyle.Success` | Positive action (green) |
|
|
76
|
-
| Danger | `ButtonStyle.Danger` | Destructive action (red) |
|
|
77
|
-
| Link | `ButtonStyle.Link` | External URL (gray with icon) |
|
|
78
|
-
| Premium | `ButtonStyle.Premium` | SKU-based button |
|
|
79
|
-
|
|
80
|
-
### Button with Overrides
|
|
81
|
-
|
|
82
|
-
Override default button options when sending:
|
|
83
|
-
|
|
84
|
-
```javascript
|
|
85
|
-
dbi.register(({ ChatInput, Button }) => {
|
|
86
|
-
Button({
|
|
87
|
-
name: "action-button",
|
|
88
|
-
options: {
|
|
89
|
-
style: Discord.ButtonStyle.Primary,
|
|
90
|
-
label: "Default Label"
|
|
91
|
-
},
|
|
92
|
-
onExecute({ interaction, data }) {
|
|
93
|
-
interaction.reply(`Action: ${data[0]}`);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
ChatInput({
|
|
98
|
-
name: "actions",
|
|
99
|
-
description: "Show action buttons",
|
|
100
|
-
|
|
101
|
-
onExecute({ interaction, dbi }) {
|
|
102
|
-
const button = dbi.interaction("action-button");
|
|
103
|
-
|
|
104
|
-
interaction.reply({
|
|
105
|
-
content: "Choose an action:",
|
|
106
|
-
components: [
|
|
107
|
-
{
|
|
108
|
-
type: Discord.ComponentType.ActionRow,
|
|
109
|
-
components: [
|
|
110
|
-
// Override label and style
|
|
111
|
-
button.toJSON({
|
|
112
|
-
overrides: {
|
|
113
|
-
label: "Accept",
|
|
114
|
-
style: Discord.ButtonStyle.Success,
|
|
115
|
-
emoji: "✅"
|
|
116
|
-
},
|
|
117
|
-
reference: { data: ["accept"] }
|
|
118
|
-
}),
|
|
119
|
-
button.toJSON({
|
|
120
|
-
overrides: {
|
|
121
|
-
label: "Decline",
|
|
122
|
-
style: Discord.ButtonStyle.Danger,
|
|
123
|
-
emoji: "❌"
|
|
124
|
-
},
|
|
125
|
-
reference: { data: ["decline"] }
|
|
126
|
-
})
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Link Button
|
|
137
|
-
|
|
138
|
-
Link buttons don't need a handler:
|
|
139
|
-
|
|
140
|
-
```javascript
|
|
141
|
-
dbi.register(({ ChatInput }) => {
|
|
142
|
-
ChatInput({
|
|
143
|
-
name: "links",
|
|
144
|
-
description: "Show useful links",
|
|
145
|
-
|
|
146
|
-
onExecute({ interaction }) {
|
|
147
|
-
interaction.reply({
|
|
148
|
-
content: "Useful links:",
|
|
149
|
-
components: [
|
|
150
|
-
{
|
|
151
|
-
type: Discord.ComponentType.ActionRow,
|
|
152
|
-
components: [
|
|
153
|
-
{
|
|
154
|
-
type: Discord.ComponentType.Button,
|
|
155
|
-
style: Discord.ButtonStyle.Link,
|
|
156
|
-
label: "Website",
|
|
157
|
-
url: "https://example.com",
|
|
158
|
-
emoji: "🌐"
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
type: Discord.ComponentType.Button,
|
|
162
|
-
style: Discord.ButtonStyle.Link,
|
|
163
|
-
label: "Documentation",
|
|
164
|
-
url: "https://docs.example.com",
|
|
165
|
-
emoji: "📚"
|
|
166
|
-
}
|
|
167
|
-
]
|
|
168
|
-
}
|
|
169
|
-
]
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
### Disabled Button
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
dbi.register(({ ChatInput, Button }) => {
|
|
180
|
-
Button({
|
|
181
|
-
name: "disabled-demo",
|
|
182
|
-
options: {
|
|
183
|
-
style: Discord.ButtonStyle.Primary,
|
|
184
|
-
label: "Click Me"
|
|
185
|
-
},
|
|
186
|
-
onExecute({ interaction }) {
|
|
187
|
-
// Disable the button after click
|
|
188
|
-
const button = dbi.interaction("disabled-demo").toJSON({
|
|
189
|
-
overrides: { disabled: true, label: "Clicked!" }
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
interaction.update({
|
|
193
|
-
components: [
|
|
194
|
-
{
|
|
195
|
-
type: Discord.ComponentType.ActionRow,
|
|
196
|
-
components: [button]
|
|
197
|
-
}
|
|
198
|
-
]
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
## Select Menus
|
|
208
|
-
|
|
209
|
-
DBI supports all five types of select menus.
|
|
210
|
-
|
|
211
|
-
### String Select Menu
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
dbi.register(({ ChatInput, StringSelectMenu }) => {
|
|
215
|
-
StringSelectMenu({
|
|
216
|
-
name: "color-select",
|
|
217
|
-
|
|
218
|
-
options: {
|
|
219
|
-
placeholder: "Choose a color...",
|
|
220
|
-
minValues: 1,
|
|
221
|
-
maxValues: 1,
|
|
222
|
-
options: [
|
|
223
|
-
{ label: "Red", value: "red", emoji: "🔴", description: "A warm color" },
|
|
224
|
-
{ label: "Green", value: "green", emoji: "🟢", description: "Nature's color" },
|
|
225
|
-
{ label: "Blue", value: "blue", emoji: "🔵", description: "The sky's color" }
|
|
226
|
-
]
|
|
227
|
-
},
|
|
228
|
-
|
|
229
|
-
onExecute({ interaction }) {
|
|
230
|
-
const selected = interaction.values[0];
|
|
231
|
-
interaction.reply(`You selected: ${selected}`);
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
ChatInput({
|
|
236
|
-
name: "colors",
|
|
237
|
-
description: "Pick a color",
|
|
238
|
-
|
|
239
|
-
onExecute({ interaction, dbi }) {
|
|
240
|
-
const select = dbi.interaction("color-select").toJSON();
|
|
241
|
-
|
|
242
|
-
interaction.reply({
|
|
243
|
-
content: "Choose your favorite color:",
|
|
244
|
-
components: [
|
|
245
|
-
{
|
|
246
|
-
type: Discord.ComponentType.ActionRow,
|
|
247
|
-
components: [select]
|
|
248
|
-
}
|
|
249
|
-
]
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### Multi-Select
|
|
257
|
-
|
|
258
|
-
```javascript
|
|
259
|
-
dbi.register(({ StringSelectMenu }) => {
|
|
260
|
-
StringSelectMenu({
|
|
261
|
-
name: "toppings-select",
|
|
262
|
-
|
|
263
|
-
options: {
|
|
264
|
-
placeholder: "Select toppings...",
|
|
265
|
-
minValues: 1,
|
|
266
|
-
maxValues: 5,
|
|
267
|
-
options: [
|
|
268
|
-
{ label: "Cheese", value: "cheese", emoji: "🧀" },
|
|
269
|
-
{ label: "Pepperoni", value: "pepperoni", emoji: "🍕" },
|
|
270
|
-
{ label: "Mushrooms", value: "mushrooms", emoji: "🍄" },
|
|
271
|
-
{ label: "Olives", value: "olives", emoji: "🫒" },
|
|
272
|
-
{ label: "Onions", value: "onions", emoji: "🧅" }
|
|
273
|
-
]
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
onExecute({ interaction }) {
|
|
277
|
-
const selected = interaction.values;
|
|
278
|
-
interaction.reply(`Toppings: ${selected.join(", ")}`);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### User Select Menu
|
|
285
|
-
|
|
286
|
-
```javascript
|
|
287
|
-
dbi.register(({ ChatInput, UserSelectMenu }) => {
|
|
288
|
-
UserSelectMenu({
|
|
289
|
-
name: "user-select",
|
|
290
|
-
|
|
291
|
-
options: {
|
|
292
|
-
placeholder: "Select a user...",
|
|
293
|
-
minValues: 1,
|
|
294
|
-
maxValues: 1
|
|
295
|
-
},
|
|
296
|
-
|
|
297
|
-
onExecute({ interaction }) {
|
|
298
|
-
const user = interaction.users.first();
|
|
299
|
-
interaction.reply(`You selected: ${user.tag}`);
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
ChatInput({
|
|
304
|
-
name: "select-user",
|
|
305
|
-
description: "Select a user",
|
|
306
|
-
|
|
307
|
-
onExecute({ interaction, dbi }) {
|
|
308
|
-
const select = dbi.interaction("user-select").toJSON();
|
|
309
|
-
|
|
310
|
-
interaction.reply({
|
|
311
|
-
content: "Select a user:",
|
|
312
|
-
components: [
|
|
313
|
-
{
|
|
314
|
-
type: Discord.ComponentType.ActionRow,
|
|
315
|
-
components: [select]
|
|
316
|
-
}
|
|
317
|
-
]
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
});
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Role Select Menu
|
|
325
|
-
|
|
326
|
-
```javascript
|
|
327
|
-
dbi.register(({ RoleSelectMenu }) => {
|
|
328
|
-
RoleSelectMenu({
|
|
329
|
-
name: "role-select",
|
|
330
|
-
|
|
331
|
-
options: {
|
|
332
|
-
placeholder: "Select roles...",
|
|
333
|
-
minValues: 1,
|
|
334
|
-
maxValues: 10
|
|
335
|
-
},
|
|
336
|
-
|
|
337
|
-
onExecute({ interaction }) {
|
|
338
|
-
const roles = interaction.roles;
|
|
339
|
-
const roleNames = roles.map(r => r.name).join(", ");
|
|
340
|
-
interaction.reply(`Selected roles: ${roleNames}`);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
### Channel Select Menu
|
|
347
|
-
|
|
348
|
-
```javascript
|
|
349
|
-
dbi.register(({ ChannelSelectMenu }) => {
|
|
350
|
-
ChannelSelectMenu({
|
|
351
|
-
name: "channel-select",
|
|
352
|
-
|
|
353
|
-
options: {
|
|
354
|
-
placeholder: "Select a channel...",
|
|
355
|
-
channelTypes: [
|
|
356
|
-
Discord.ChannelType.GuildText,
|
|
357
|
-
Discord.ChannelType.GuildVoice
|
|
358
|
-
]
|
|
359
|
-
},
|
|
360
|
-
|
|
361
|
-
onExecute({ interaction }) {
|
|
362
|
-
const channel = interaction.channels.first();
|
|
363
|
-
interaction.reply(`Selected: ${channel.name}`);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
### Mentionable Select Menu
|
|
370
|
-
|
|
371
|
-
```javascript
|
|
372
|
-
dbi.register(({ MentionableSelectMenu }) => {
|
|
373
|
-
MentionableSelectMenu({
|
|
374
|
-
name: "mentionable-select",
|
|
375
|
-
|
|
376
|
-
options: {
|
|
377
|
-
placeholder: "Select users or roles...",
|
|
378
|
-
minValues: 1,
|
|
379
|
-
maxValues: 5
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
onExecute({ interaction }) {
|
|
383
|
-
const users = interaction.users;
|
|
384
|
-
const roles = interaction.roles;
|
|
385
|
-
|
|
386
|
-
let response = "";
|
|
387
|
-
if (users.size) response += `Users: ${users.map(u => u.tag).join(", ")}\n`;
|
|
388
|
-
if (roles.size) response += `Roles: ${roles.map(r => r.name).join(", ")}`;
|
|
389
|
-
|
|
390
|
-
interaction.reply(response || "Nothing selected");
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### Dynamic Select Options
|
|
397
|
-
|
|
398
|
-
Override select options when sending:
|
|
399
|
-
|
|
400
|
-
```javascript
|
|
401
|
-
dbi.register(({ ChatInput, StringSelectMenu }) => {
|
|
402
|
-
StringSelectMenu({
|
|
403
|
-
name: "dynamic-select",
|
|
404
|
-
options: {
|
|
405
|
-
placeholder: "Select...",
|
|
406
|
-
options: [] // Will be overridden
|
|
407
|
-
},
|
|
408
|
-
onExecute({ interaction, data }) {
|
|
409
|
-
const [category] = data;
|
|
410
|
-
const selected = interaction.values[0];
|
|
411
|
-
interaction.reply(`${category}: ${selected}`);
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
ChatInput({
|
|
416
|
-
name: "shop",
|
|
417
|
-
description: "Browse the shop",
|
|
418
|
-
|
|
419
|
-
async onExecute({ interaction, dbi }) {
|
|
420
|
-
const items = await fetchShopItems();
|
|
421
|
-
|
|
422
|
-
const select = dbi.interaction("dynamic-select").toJSON({
|
|
423
|
-
overrides: {
|
|
424
|
-
placeholder: "Select an item to buy...",
|
|
425
|
-
options: items.map(item => ({
|
|
426
|
-
label: item.name,
|
|
427
|
-
value: item.id,
|
|
428
|
-
description: `$${item.price}`,
|
|
429
|
-
emoji: item.emoji
|
|
430
|
-
}))
|
|
431
|
-
},
|
|
432
|
-
reference: { data: ["shop"] }
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
interaction.reply({
|
|
436
|
-
content: "🛒 **Shop**",
|
|
437
|
-
components: [
|
|
438
|
-
{ type: Discord.ComponentType.ActionRow, components: [select] }
|
|
439
|
-
]
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
## Modals
|
|
449
|
-
|
|
450
|
-
Modals are popup forms that collect user input.
|
|
451
|
-
|
|
452
|
-
### Basic Modal
|
|
453
|
-
|
|
454
|
-
```javascript
|
|
455
|
-
dbi.register(({ ChatInput, Button, Modal }) => {
|
|
456
|
-
// Define the modal
|
|
457
|
-
Modal({
|
|
458
|
-
name: "feedback-modal",
|
|
459
|
-
|
|
460
|
-
options: {
|
|
461
|
-
title: "Send Feedback",
|
|
462
|
-
components: [
|
|
463
|
-
{
|
|
464
|
-
type: Discord.ComponentType.ActionRow,
|
|
465
|
-
components: [
|
|
466
|
-
{
|
|
467
|
-
type: Discord.ComponentType.TextInput,
|
|
468
|
-
customId: "subject",
|
|
469
|
-
label: "Subject",
|
|
470
|
-
style: Discord.TextInputStyle.Short,
|
|
471
|
-
placeholder: "Brief description",
|
|
472
|
-
required: true,
|
|
473
|
-
minLength: 5,
|
|
474
|
-
maxLength: 100
|
|
475
|
-
}
|
|
476
|
-
]
|
|
477
|
-
},
|
|
478
|
-
{
|
|
479
|
-
type: Discord.ComponentType.ActionRow,
|
|
480
|
-
components: [
|
|
481
|
-
{
|
|
482
|
-
type: Discord.ComponentType.TextInput,
|
|
483
|
-
customId: "message",
|
|
484
|
-
label: "Message",
|
|
485
|
-
style: Discord.TextInputStyle.Paragraph,
|
|
486
|
-
placeholder: "Your detailed feedback...",
|
|
487
|
-
required: true,
|
|
488
|
-
minLength: 20,
|
|
489
|
-
maxLength: 2000
|
|
490
|
-
}
|
|
491
|
-
]
|
|
492
|
-
}
|
|
493
|
-
]
|
|
494
|
-
},
|
|
495
|
-
|
|
496
|
-
async onExecute({ interaction }) {
|
|
497
|
-
const subject = interaction.fields.getTextInputValue("subject");
|
|
498
|
-
const message = interaction.fields.getTextInputValue("message");
|
|
499
|
-
|
|
500
|
-
// Process the feedback
|
|
501
|
-
await saveFeedback({ subject, message, userId: interaction.user.id });
|
|
502
|
-
|
|
503
|
-
await interaction.reply({
|
|
504
|
-
content: "Thank you for your feedback! ✅",
|
|
505
|
-
ephemeral: true
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
// Button that opens the modal
|
|
511
|
-
Button({
|
|
512
|
-
name: "feedback-button",
|
|
513
|
-
options: {
|
|
514
|
-
style: Discord.ButtonStyle.Primary,
|
|
515
|
-
label: "Send Feedback",
|
|
516
|
-
emoji: "📝"
|
|
517
|
-
},
|
|
518
|
-
async onExecute({ interaction, dbi }) {
|
|
519
|
-
const modal = dbi.interaction("feedback-modal").toJSON();
|
|
520
|
-
await interaction.showModal(modal);
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
|
|
524
|
-
// Command that sends the button
|
|
525
|
-
ChatInput({
|
|
526
|
-
name: "feedback",
|
|
527
|
-
description: "Send us feedback",
|
|
528
|
-
|
|
529
|
-
onExecute({ interaction, dbi }) {
|
|
530
|
-
const button = dbi.interaction("feedback-button").toJSON();
|
|
531
|
-
|
|
532
|
-
interaction.reply({
|
|
533
|
-
content: "We'd love to hear your feedback!",
|
|
534
|
-
components: [
|
|
535
|
-
{ type: Discord.ComponentType.ActionRow, components: [button] }
|
|
536
|
-
]
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
### Modal with Pre-filled Data
|
|
544
|
-
|
|
545
|
-
```javascript
|
|
546
|
-
dbi.register(({ Modal, Button }) => {
|
|
547
|
-
Modal({
|
|
548
|
-
name: "edit-modal",
|
|
549
|
-
options: {
|
|
550
|
-
title: "Edit Item",
|
|
551
|
-
components: [
|
|
552
|
-
{
|
|
553
|
-
type: Discord.ComponentType.ActionRow,
|
|
554
|
-
components: [
|
|
555
|
-
{
|
|
556
|
-
type: Discord.ComponentType.TextInput,
|
|
557
|
-
customId: "name",
|
|
558
|
-
label: "Name",
|
|
559
|
-
style: Discord.TextInputStyle.Short,
|
|
560
|
-
value: "" // Will be overridden
|
|
561
|
-
}
|
|
562
|
-
]
|
|
563
|
-
},
|
|
564
|
-
{
|
|
565
|
-
type: Discord.ComponentType.ActionRow,
|
|
566
|
-
components: [
|
|
567
|
-
{
|
|
568
|
-
type: Discord.ComponentType.TextInput,
|
|
569
|
-
customId: "description",
|
|
570
|
-
label: "Description",
|
|
571
|
-
style: Discord.TextInputStyle.Paragraph,
|
|
572
|
-
value: "" // Will be overridden
|
|
573
|
-
}
|
|
574
|
-
]
|
|
575
|
-
}
|
|
576
|
-
]
|
|
577
|
-
},
|
|
578
|
-
|
|
579
|
-
async onExecute({ interaction, data }) {
|
|
580
|
-
const [itemId] = data;
|
|
581
|
-
const name = interaction.fields.getTextInputValue("name");
|
|
582
|
-
const description = interaction.fields.getTextInputValue("description");
|
|
583
|
-
|
|
584
|
-
await updateItem(itemId, { name, description });
|
|
585
|
-
|
|
586
|
-
interaction.reply({
|
|
587
|
-
content: "Item updated! ✅",
|
|
588
|
-
ephemeral: true
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
});
|
|
592
|
-
|
|
593
|
-
Button({
|
|
594
|
-
name: "edit-button",
|
|
595
|
-
options: { style: Discord.ButtonStyle.Secondary, label: "Edit" },
|
|
596
|
-
|
|
597
|
-
async onExecute({ interaction, data, dbi }) {
|
|
598
|
-
const [itemId] = data;
|
|
599
|
-
const item = await getItem(itemId);
|
|
600
|
-
|
|
601
|
-
// Pre-fill the modal with current values
|
|
602
|
-
const modal = dbi.interaction("edit-modal").toJSON({
|
|
603
|
-
overrides: {
|
|
604
|
-
components: [
|
|
605
|
-
{
|
|
606
|
-
type: Discord.ComponentType.ActionRow,
|
|
607
|
-
components: [{
|
|
608
|
-
type: Discord.ComponentType.TextInput,
|
|
609
|
-
customId: "name",
|
|
610
|
-
label: "Name",
|
|
611
|
-
style: Discord.TextInputStyle.Short,
|
|
612
|
-
value: item.name // Pre-filled!
|
|
613
|
-
}]
|
|
614
|
-
},
|
|
615
|
-
{
|
|
616
|
-
type: Discord.ComponentType.ActionRow,
|
|
617
|
-
components: [{
|
|
618
|
-
type: Discord.ComponentType.TextInput,
|
|
619
|
-
customId: "description",
|
|
620
|
-
label: "Description",
|
|
621
|
-
style: Discord.TextInputStyle.Paragraph,
|
|
622
|
-
value: item.description // Pre-filled!
|
|
623
|
-
}]
|
|
624
|
-
}
|
|
625
|
-
]
|
|
626
|
-
},
|
|
627
|
-
reference: { data: [itemId] }
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
await interaction.showModal(modal);
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
});
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
---
|
|
637
|
-
|
|
638
|
-
## Reference System
|
|
639
|
-
|
|
640
|
-
The reference system allows you to pass data through components without using a database.
|
|
641
|
-
|
|
642
|
-
### How It Works
|
|
643
|
-
|
|
644
|
-
When you add `reference.data` to a component:
|
|
645
|
-
- **Primitive values** (string, number, boolean) are encoded directly in the custom ID
|
|
646
|
-
- **Objects** are stored in memory with a reference ID
|
|
647
|
-
|
|
648
|
-
### Primitive References
|
|
649
|
-
|
|
650
|
-
```javascript
|
|
651
|
-
dbi.register(({ Button }) => {
|
|
652
|
-
Button({
|
|
653
|
-
name: "action-btn",
|
|
654
|
-
options: { style: Discord.ButtonStyle.Primary, label: "Action" },
|
|
655
|
-
|
|
656
|
-
onExecute({ interaction, data }) {
|
|
657
|
-
// data contains the referenced values
|
|
658
|
-
const [userId, actionType, timestamp] = data;
|
|
659
|
-
|
|
660
|
-
console.log(`User: ${userId}, Action: ${actionType}, Time: ${timestamp}`);
|
|
661
|
-
interaction.reply(`Processed action: ${actionType}`);
|
|
662
|
-
}
|
|
663
|
-
});
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
// When creating the button:
|
|
667
|
-
const button = dbi.interaction("action-btn").toJSON({
|
|
668
|
-
reference: {
|
|
669
|
-
data: [
|
|
670
|
-
"123456789", // string
|
|
671
|
-
42, // number
|
|
672
|
-
true, // boolean
|
|
673
|
-
Date.now() // number (timestamp)
|
|
674
|
-
]
|
|
675
|
-
}
|
|
676
|
-
});
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
### Object References
|
|
680
|
-
|
|
681
|
-
```javascript
|
|
682
|
-
dbi.register(({ Button }) => {
|
|
683
|
-
Button({
|
|
684
|
-
name: "cart-btn",
|
|
685
|
-
options: { style: Discord.ButtonStyle.Primary, label: "View Cart" },
|
|
686
|
-
|
|
687
|
-
onExecute({ interaction, data }) {
|
|
688
|
-
const [cart] = data;
|
|
689
|
-
|
|
690
|
-
// cart is a full object!
|
|
691
|
-
console.log(cart.items);
|
|
692
|
-
console.log(cart.total);
|
|
693
|
-
|
|
694
|
-
// Clean up the reference when done
|
|
695
|
-
cart.$unRef();
|
|
696
|
-
|
|
697
|
-
interaction.reply(`Cart total: $${cart.total}`);
|
|
698
|
-
}
|
|
699
|
-
});
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
// When creating the button:
|
|
703
|
-
const cart = {
|
|
704
|
-
items: ["item1", "item2", "item3"],
|
|
705
|
-
total: 99.99,
|
|
706
|
-
userId: "123456789"
|
|
707
|
-
};
|
|
708
|
-
|
|
709
|
-
const button = dbi.interaction("cart-btn").toJSON({
|
|
710
|
-
reference: {
|
|
711
|
-
data: [cart], // Object is stored in memory
|
|
712
|
-
ttl: 300000 // Auto-expire in 5 minutes
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
### Reference TTL
|
|
718
|
-
|
|
719
|
-
References can auto-expire:
|
|
720
|
-
|
|
721
|
-
```javascript
|
|
722
|
-
// Component-level TTL
|
|
723
|
-
const button = dbi.interaction("my-btn").toJSON({
|
|
724
|
-
reference: {
|
|
725
|
-
data: [myData],
|
|
726
|
-
ttl: 60000 // Expires in 1 minute
|
|
727
|
-
}
|
|
728
|
-
});
|
|
729
|
-
|
|
730
|
-
// Global auto-clear in DBI config
|
|
731
|
-
const dbi = createDBI("bot", {
|
|
732
|
-
references: {
|
|
733
|
-
autoClear: {
|
|
734
|
-
ttl: 3600000, // Default TTL: 1 hour
|
|
735
|
-
check: 60000 // Check every minute
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
### Manual Reference Management
|
|
742
|
-
|
|
743
|
-
```javascript
|
|
744
|
-
dbi.register(({ Button }) => {
|
|
745
|
-
Button({
|
|
746
|
-
name: "data-btn",
|
|
747
|
-
options: { style: Discord.ButtonStyle.Primary, label: "Process" },
|
|
748
|
-
|
|
749
|
-
onExecute({ interaction, data }) {
|
|
750
|
-
const [complexData] = data;
|
|
751
|
-
|
|
752
|
-
// Check if reference still exists
|
|
753
|
-
if (!complexData) {
|
|
754
|
-
return interaction.reply({
|
|
755
|
-
content: "This button has expired!",
|
|
756
|
-
ephemeral: true
|
|
757
|
-
});
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// Use the $ref property to identify the reference
|
|
761
|
-
console.log(`Reference ID: ${complexData.$ref}`);
|
|
762
|
-
|
|
763
|
-
// Manually remove the reference
|
|
764
|
-
complexData.$unRef(); // or: dbi.data.refs.delete(complexData.$ref)
|
|
765
|
-
|
|
766
|
-
interaction.reply("Data processed and cleaned up!");
|
|
767
|
-
}
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
---
|
|
773
|
-
|
|
774
|
-
## Inline Components
|
|
775
|
-
|
|
776
|
-
Inline components are created dynamically and don't need pre-registration.
|
|
777
|
-
|
|
778
|
-
### Inline Button
|
|
779
|
-
|
|
780
|
-
```javascript
|
|
781
|
-
dbi.register(({ ChatInput, createInlineButton }) => {
|
|
782
|
-
ChatInput({
|
|
783
|
-
name: "confirm",
|
|
784
|
-
description: "Confirm an action",
|
|
785
|
-
|
|
786
|
-
async onExecute({ interaction }) {
|
|
787
|
-
// Create an inline button that expires
|
|
788
|
-
const confirmBtn = createInlineButton({
|
|
789
|
-
options: {
|
|
790
|
-
style: Discord.ButtonStyle.Success,
|
|
791
|
-
label: "Confirm"
|
|
792
|
-
},
|
|
793
|
-
// TTL is automatic based on config.inlineListeners.autoClear.ttl
|
|
794
|
-
onExecute({ interaction }) {
|
|
795
|
-
interaction.reply("Action confirmed! ✅");
|
|
796
|
-
}
|
|
797
|
-
});
|
|
798
|
-
|
|
799
|
-
const cancelBtn = createInlineButton({
|
|
800
|
-
options: {
|
|
801
|
-
style: Discord.ButtonStyle.Danger,
|
|
802
|
-
label: "Cancel"
|
|
803
|
-
},
|
|
804
|
-
onExecute({ interaction }) {
|
|
805
|
-
interaction.reply("Action cancelled. ❌");
|
|
806
|
-
}
|
|
807
|
-
});
|
|
808
|
-
|
|
809
|
-
await interaction.reply({
|
|
810
|
-
content: "Are you sure?",
|
|
811
|
-
components: [
|
|
812
|
-
{
|
|
813
|
-
type: Discord.ComponentType.ActionRow,
|
|
814
|
-
components: [
|
|
815
|
-
confirmBtn.toJSON(),
|
|
816
|
-
cancelBtn.toJSON()
|
|
817
|
-
]
|
|
818
|
-
}
|
|
819
|
-
]
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
});
|
|
823
|
-
});
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
### Inline Select Menu
|
|
827
|
-
|
|
828
|
-
```javascript
|
|
829
|
-
dbi.register(({ ChatInput, createInlineStringSelectMenu }) => {
|
|
830
|
-
ChatInput({
|
|
831
|
-
name: "poll",
|
|
832
|
-
description: "Create a quick poll",
|
|
833
|
-
|
|
834
|
-
async onExecute({ interaction }) {
|
|
835
|
-
const votes = new Map();
|
|
836
|
-
|
|
837
|
-
const select = createInlineStringSelectMenu({
|
|
838
|
-
options: {
|
|
839
|
-
placeholder: "Cast your vote...",
|
|
840
|
-
options: [
|
|
841
|
-
{ label: "Option A", value: "a" },
|
|
842
|
-
{ label: "Option B", value: "b" },
|
|
843
|
-
{ label: "Option C", value: "c" }
|
|
844
|
-
]
|
|
845
|
-
},
|
|
846
|
-
onExecute({ interaction }) {
|
|
847
|
-
const vote = interaction.values[0];
|
|
848
|
-
votes.set(interaction.user.id, vote);
|
|
849
|
-
|
|
850
|
-
interaction.reply({
|
|
851
|
-
content: `You voted for ${vote}!`,
|
|
852
|
-
ephemeral: true
|
|
853
|
-
});
|
|
854
|
-
}
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
await interaction.reply({
|
|
858
|
-
content: "🗳️ **Quick Poll**\nVote for your choice!",
|
|
859
|
-
components: [
|
|
860
|
-
{ type: Discord.ComponentType.ActionRow, components: [select.toJSON()] }
|
|
861
|
-
]
|
|
862
|
-
});
|
|
863
|
-
}
|
|
864
|
-
});
|
|
865
|
-
});
|
|
866
|
-
```
|
|
867
|
-
|
|
868
|
-
### Inline Modal
|
|
869
|
-
|
|
870
|
-
```javascript
|
|
871
|
-
dbi.register(({ ChatInput, Button, createInlineModal }) => {
|
|
872
|
-
ChatInput({
|
|
873
|
-
name: "input",
|
|
874
|
-
description: "Get user input",
|
|
875
|
-
|
|
876
|
-
async onExecute({ interaction }) {
|
|
877
|
-
const modal = createInlineModal({
|
|
878
|
-
options: {
|
|
879
|
-
title: "Enter Information",
|
|
880
|
-
components: [
|
|
881
|
-
{
|
|
882
|
-
type: Discord.ComponentType.ActionRow,
|
|
883
|
-
components: [{
|
|
884
|
-
type: Discord.ComponentType.TextInput,
|
|
885
|
-
customId: "input",
|
|
886
|
-
label: "Your Input",
|
|
887
|
-
style: Discord.TextInputStyle.Short,
|
|
888
|
-
required: true
|
|
889
|
-
}]
|
|
890
|
-
}
|
|
891
|
-
]
|
|
892
|
-
},
|
|
893
|
-
onExecute({ interaction }) {
|
|
894
|
-
const input = interaction.fields.getTextInputValue("input");
|
|
895
|
-
interaction.reply(`You entered: ${input}`);
|
|
896
|
-
}
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
await interaction.showModal(modal.toJSON());
|
|
900
|
-
}
|
|
901
|
-
});
|
|
902
|
-
});
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
### Available Inline Creators
|
|
906
|
-
|
|
907
|
-
| Function | Creates |
|
|
908
|
-
|----------|---------|
|
|
909
|
-
| `createInlineButton()` | Inline button |
|
|
910
|
-
| `createInlineStringSelectMenu()` | Inline string select |
|
|
911
|
-
| `createInlineUserSelectMenu()` | Inline user select |
|
|
912
|
-
| `createInlineRoleSelectMenu()` | Inline role select |
|
|
913
|
-
| `createInlineChannelSelectMenu()` | Inline channel select |
|
|
914
|
-
| `createInlineMentionableSelectMenu()` | Inline mentionable select |
|
|
915
|
-
| `createInlineModal()` | Inline modal |
|
|
916
|
-
| `createInlineEvent()` | Inline event listener |
|
|
917
|
-
|
|
918
|
-
---
|
|
919
|
-
|
|
920
|
-
## Builder Pattern
|
|
921
|
-
|
|
922
|
-
DBI provides builder classes for more fluent component creation.
|
|
923
|
-
|
|
924
|
-
### Button Builder
|
|
925
|
-
|
|
926
|
-
```javascript
|
|
927
|
-
dbi.register(({ ChatInput, Button }) => {
|
|
928
|
-
Button({
|
|
929
|
-
name: "builder-btn",
|
|
930
|
-
options: {
|
|
931
|
-
style: Discord.ButtonStyle.Primary,
|
|
932
|
-
label: "Default"
|
|
933
|
-
},
|
|
934
|
-
onExecute({ interaction }) {
|
|
935
|
-
interaction.reply("Clicked!");
|
|
936
|
-
}
|
|
937
|
-
});
|
|
938
|
-
|
|
939
|
-
ChatInput({
|
|
940
|
-
name: "builder-demo",
|
|
941
|
-
description: "Builder pattern demo",
|
|
942
|
-
|
|
943
|
-
onExecute({ interaction, dbi }) {
|
|
944
|
-
const btn = dbi.interaction("builder-btn");
|
|
945
|
-
|
|
946
|
-
// Use the builder for fluent configuration
|
|
947
|
-
const built = btn.createBuilder()
|
|
948
|
-
.setLabel("Custom Label")
|
|
949
|
-
.setEmoji("🎉")
|
|
950
|
-
.setStyle(Discord.ButtonStyle.Success)
|
|
951
|
-
.setReference(["data1", "data2"])
|
|
952
|
-
.setTTL(60000)
|
|
953
|
-
.toJSON();
|
|
954
|
-
|
|
955
|
-
interaction.reply({
|
|
956
|
-
content: "Builder pattern!",
|
|
957
|
-
components: [
|
|
958
|
-
{ type: Discord.ComponentType.ActionRow, components: [built] }
|
|
959
|
-
]
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
});
|
|
963
|
-
});
|
|
964
|
-
```
|
|
965
|
-
|
|
966
|
-
### Select Menu Builder
|
|
967
|
-
|
|
968
|
-
```javascript
|
|
969
|
-
dbi.register(({ StringSelectMenu }) => {
|
|
970
|
-
StringSelectMenu({
|
|
971
|
-
name: "builder-select",
|
|
972
|
-
options: {
|
|
973
|
-
placeholder: "Select...",
|
|
974
|
-
options: []
|
|
975
|
-
},
|
|
976
|
-
onExecute({ interaction }) {
|
|
977
|
-
interaction.reply(`Selected: ${interaction.values.join(", ")}`);
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
});
|
|
981
|
-
|
|
982
|
-
// Usage:
|
|
983
|
-
const select = dbi.interaction("builder-select");
|
|
984
|
-
|
|
985
|
-
const built = select.createBuilder()
|
|
986
|
-
.setPlaceholder("Choose items...")
|
|
987
|
-
.setMinValues(1)
|
|
988
|
-
.setMaxValues(3)
|
|
989
|
-
.setOptions([
|
|
990
|
-
{ label: "A", value: "a" },
|
|
991
|
-
{ label: "B", value: "b" },
|
|
992
|
-
{ label: "C", value: "c" }
|
|
993
|
-
])
|
|
994
|
-
.toJSON();
|
|
995
|
-
```
|
|
996
|
-
|
|
997
|
-
---
|
|
998
|
-
|
|
999
|
-
## Component Execution Context
|
|
1000
|
-
|
|
1001
|
-
All components receive a context object in `onExecute`:
|
|
1002
|
-
|
|
1003
|
-
```javascript
|
|
1004
|
-
dbi.register(({ Button }) => {
|
|
1005
|
-
Button({
|
|
1006
|
-
name: "context-demo",
|
|
1007
|
-
options: { style: Discord.ButtonStyle.Primary, label: "Demo" },
|
|
1008
|
-
|
|
1009
|
-
onExecute(ctx) {
|
|
1010
|
-
const {
|
|
1011
|
-
interaction, // Discord.js ButtonInteraction
|
|
1012
|
-
data, // Referenced data array
|
|
1013
|
-
dbi, // DBI instance
|
|
1014
|
-
dbiInteraction, // The DBIButton instance
|
|
1015
|
-
locale, // Locale helpers
|
|
1016
|
-
setRateLimit, // Rate limit setter
|
|
1017
|
-
other, // Custom shared data
|
|
1018
|
-
clientNamespace, // Multi-client namespace
|
|
1019
|
-
v2 // Components V2 enabled
|
|
1020
|
-
} = ctx;
|
|
1021
|
-
|
|
1022
|
-
// Use as needed
|
|
1023
|
-
interaction.reply("Demo!");
|
|
1024
|
-
}
|
|
1025
|
-
});
|
|
1026
|
-
});
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
---
|
|
1030
|
-
|
|
1031
|
-
## Next Steps
|
|
1032
|
-
|
|
1033
|
-
- [Events](./EVENTS.md) - Handle Discord events
|
|
1034
|
-
- [Svelte Components](./SVELTE_COMPONENTS.md) - Build reactive UIs
|
|
1035
|
-
- [Advanced Features](./ADVANCED_FEATURES.md) - Rate limiting and more
|
|
1036
|
-
|
|
1037
|
-
---
|
|
1038
|
-
|
|
1039
|
-
> 📄 **LLM-optimized version:** [llm/COMPONENTS.txt](./llm/COMPONENTS.txt)
|