vimcord 1.0.49 → 1.0.51

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/index.js CHANGED
@@ -204,6 +204,7 @@ var BaseCommandBuilder = class {
204
204
  async run(client, ...args) {
205
205
  const config = this.resolveConfig(client);
206
206
  const ctx = this.extractContext(args);
207
+ let cancel = false;
207
208
  try {
208
209
  if (!config.enabled) {
209
210
  return await config.onUsedWhenDisabled?.(...args);
@@ -218,11 +219,16 @@ var BaseCommandBuilder = class {
218
219
  if (!await this.checkConditions(config, ...args)) {
219
220
  return await config.onConditionsNotMet?.(...args);
220
221
  }
221
- await config.beforeExecute?.(...args);
222
+ await config.beforeExecute?.({ cancel: () => cancel = true }, ...args);
223
+ if (cancel) return;
222
224
  if (config.logExecution !== false) {
223
- const cmdName = this.options.name || this.builder?.name || "Unknown";
225
+ const optionsWithName = this.options;
226
+ const builderWithName = this;
227
+ const cmdName = optionsWithName.name ?? builderWithName.builder?.name ?? "Unknown";
224
228
  const location = ctx.guild ? `${ctx.guild.name} (${ctx.guild.id})` : "Direct Messages";
225
- client.logger.commandExecuted(cmdName, ctx.user.username, location);
229
+ if (client.logger) {
230
+ client.logger.commandExecuted(cmdName, ctx.user.username, location);
231
+ }
226
232
  }
227
233
  const result = await config.execute?.(...args);
228
234
  await config.afterExecute?.(result, ...args);
@@ -450,9 +456,7 @@ var Logger = class {
450
456
  extend(extras) {
451
457
  for (const [key, fn] of Object.entries(extras)) {
452
458
  if (typeof fn === "function") {
453
- this[key] = function(...args) {
454
- return fn.call(this, ...args);
455
- };
459
+ this[key] = (...args) => fn.call(this, ...args);
456
460
  }
457
461
  }
458
462
  return this;
@@ -822,12 +826,14 @@ var contextCommandHandler = new EventBuilder({
822
826
  if (!command) {
823
827
  const content = `**${interaction.commandName}** is not a registered context command.`;
824
828
  if (interaction.replied || interaction.deferred) {
825
- return interaction.followUp({ content, flags: "Ephemeral" });
829
+ await interaction.followUp({ content, flags: "Ephemeral" });
830
+ } else {
831
+ await interaction.reply({ content, flags: "Ephemeral" });
826
832
  }
827
- return interaction.reply({ content, flags: "Ephemeral" });
833
+ return;
828
834
  }
829
835
  try {
830
- return await command.run(client, client, interaction);
836
+ await command.run(client, client, interaction);
831
837
  } catch (err) {
832
838
  await client.error.handleCommandError(err, interaction.guild, interaction);
833
839
  }
@@ -886,12 +892,14 @@ var slashCommandHandler = new EventBuilder({
886
892
  if (!command) {
887
893
  const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
888
894
  if (interaction.replied || interaction.deferred) {
889
- return interaction.followUp({ content, flags: "Ephemeral" });
895
+ await interaction.followUp({ content, flags: "Ephemeral" });
896
+ } else {
897
+ await interaction.reply({ content, flags: "Ephemeral" });
890
898
  }
891
- return interaction.reply({ content, flags: "Ephemeral" });
899
+ return;
892
900
  }
893
901
  try {
894
- return await command.run(client, client, interaction);
902
+ await command.run(client, client, interaction);
895
903
  } catch (err) {
896
904
  await client.error.handleCommandError(err, interaction.guild, interaction);
897
905
  }
@@ -1693,7 +1701,7 @@ var VimcordErrorHandler = class {
1693
1701
  import chalk2 from "chalk";
1694
1702
 
1695
1703
  // package.json
1696
- var version = "1.0.48";
1704
+ var version = "1.0.51";
1697
1705
 
1698
1706
  // src/client/vimcord.logger.ts
1699
1707
  var clientLoggerFactory = (client) => new Logger({ prefixEmoji: "\u26A1", prefix: `vimcord (i${client.clientId})` }).extend({
@@ -1769,9 +1777,11 @@ function getDevMode() {
1769
1777
  }
1770
1778
 
1771
1779
  // src/configs/app.config.ts
1780
+ var packageJson = getPackageJson();
1781
+ var version2 = typeof packageJson.version === "string" ? packageJson.version : "1.0.0";
1772
1782
  var defaultConfig = {
1773
1783
  name: "Discord Bot",
1774
- version: getPackageJson()?.version ?? "1.0.0",
1784
+ version: version2,
1775
1785
  devMode: getDevMode(),
1776
1786
  verbose: false,
1777
1787
  enableCLI: false,
@@ -2095,11 +2105,16 @@ var CommandManager = class {
2095
2105
  slash;
2096
2106
  prefix;
2097
2107
  context;
2108
+ logger;
2098
2109
  constructor(client) {
2099
2110
  this.client = client;
2100
2111
  this.slash = new SlashCommandManager(client);
2101
2112
  this.prefix = new PrefixCommandManager(client);
2102
2113
  this.context = new ContextCommandManager(client);
2114
+ this.logger = new Logger({
2115
+ prefixEmoji: "\u26A1",
2116
+ prefix: `vimcord (i${client.clientId}) [CommandManager]`
2117
+ });
2103
2118
  }
2104
2119
  getAllAppCommands(options = {}) {
2105
2120
  return [...this.slash.getAll(options), ...this.context.getAll(options)];
@@ -2107,23 +2122,21 @@ var CommandManager = class {
2107
2122
  async registerGlobal(options = {}) {
2108
2123
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2109
2124
  if (!client.rest) {
2110
- console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
2125
+ this.logger.error("Failed to register app commands globally: REST is not initialized");
2111
2126
  return;
2112
2127
  }
2113
2128
  const commands = this.getAllAppCommands(options).map((cmd) => cmd.builder.toJSON());
2114
2129
  if (!commands.length) {
2115
- console.log("[CommandManager] No commands to register globally");
2130
+ this.logger.info("No commands to register globally");
2116
2131
  return;
2117
2132
  }
2118
- console.log(
2119
- `[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} globally...`
2120
- );
2133
+ this.logger.info(`Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} globally...`);
2121
2134
  try {
2122
2135
  await client.rest.put(Routes.applicationCommands(client.user.id), { body: commands });
2123
- console.log(`[CommandManager] \u2714 Registered app ${commands.length === 1 ? "command" : "commands"} globally`);
2136
+ this.logger.success(`Registered app ${commands.length === 1 ? "command" : "commands"} globally`);
2124
2137
  } catch (err) {
2125
- console.error(
2126
- `[CommandManager] \u2716 Failed to register app ${commands.length === 1 ? "command" : "commands"} globally`,
2138
+ this.logger.error(
2139
+ `Failed to register app ${commands.length === 1 ? "command" : "commands"} globally`,
2127
2140
  err
2128
2141
  );
2129
2142
  }
@@ -2131,60 +2144,66 @@ var CommandManager = class {
2131
2144
  async unregisterGlobal() {
2132
2145
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2133
2146
  if (!client.rest) {
2134
- console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
2147
+ this.logger.error("Failed to remove app commands globally: REST is not initialized");
2135
2148
  return;
2136
2149
  }
2137
2150
  try {
2138
2151
  await client.rest.put(Routes.applicationCommands(client.user.id), { body: [] });
2139
- console.log(`[CommandManager] \u2714 Removed app commands globally`);
2152
+ this.logger.success("Removed app commands globally");
2140
2153
  } catch (err) {
2141
- console.error(`[CommandManager] \u2716 Failed to remove app commands globally`, err);
2154
+ this.logger.error("Failed to remove app commands globally", err);
2142
2155
  }
2143
2156
  }
2144
2157
  async registerGuild(options = {}) {
2145
2158
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2146
2159
  if (!client.rest) {
2147
- console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
2160
+ this.logger.error("Failed to register app commands by guild: REST is not initialized");
2148
2161
  return;
2149
2162
  }
2150
2163
  const commands = this.getAllAppCommands(options).map((cmd) => cmd.builder.toJSON());
2151
2164
  if (!commands.length) {
2152
- console.log("[CommandManager] No commands to register by guild");
2165
+ this.logger.info("No commands to register by guild");
2153
2166
  return;
2154
2167
  }
2155
2168
  const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
2156
- console.log(
2157
- `[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} for ${guildIds.length} guilds...`
2169
+ this.logger.info(
2170
+ `Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} for ${guildIds.length} guilds...`
2158
2171
  );
2159
2172
  await Promise.all(
2160
- guildIds.map(
2161
- (guildId) => client.rest.put(Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
2173
+ guildIds.map(async (guildId) => {
2174
+ try {
2175
+ await client.rest.put(Routes.applicationGuildCommands(client.user.id, guildId), { body: commands });
2162
2176
  const gName = client.guilds.cache.get(guildId)?.name || "n/a";
2163
- console.log(
2164
- `[CommandManager] \u2714 Set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`
2177
+ this.logger.success(
2178
+ `Set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`
2165
2179
  );
2166
- }).catch((err) => {
2180
+ } catch (err) {
2167
2181
  const gName = client.guilds.cache.get(guildId)?.name || "n/a";
2168
- console.log(
2169
- `[CommandManager] \u2716 Failed to set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`,
2182
+ this.logger.error(
2183
+ `Failed to set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`,
2170
2184
  err
2171
2185
  );
2172
- })
2173
- )
2186
+ }
2187
+ })
2174
2188
  );
2175
2189
  }
2176
2190
  async unregisterGuild(options = {}) {
2177
2191
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2178
2192
  if (!client.rest) {
2179
- console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
2193
+ this.logger.error("Failed to unregister app commands by guild: REST is not initialized");
2180
2194
  return;
2181
2195
  }
2182
2196
  const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
2183
- console.log(`[CommandManager] Unregistering commands from ${guildIds.length} guilds...`);
2197
+ this.logger.info(`Unregistering commands from ${guildIds.length} guilds...`);
2184
2198
  await Promise.all(
2185
- guildIds.map(
2186
- (guildId) => client.rest.put(Routes.applicationGuildCommands(client.user.id, guildId), { body: [] }).then(() => console.log(`[CommandManager] \u2714 Removed app commands in guild: ${guildId}`)).catch((err) => console.log(`[CommandManager] \u2716 Failed to remove app commands in guild: ${guildId}`, err))
2187
- )
2199
+ guildIds.map(async (guildId) => {
2200
+ try {
2201
+ await client.rest.put(Routes.applicationGuildCommands(client.user.id, guildId), { body: [] });
2202
+ this.logger.success(`Removed app commands in guild: ${guildId}`);
2203
+ } catch (err) {
2204
+ this.logger.error(`Failed to remove app commands in guild: ${guildId}`, err);
2205
+ }
2206
+ })
2188
2207
  );
2189
2208
  }
2190
2209
  };
@@ -2692,8 +2711,8 @@ var Vimcord = class _Vimcord extends Client2 {
2692
2711
  return this.config.app.version;
2693
2712
  }
2694
2713
  // prettier-ignore
2695
- set $version(version2) {
2696
- this.config.app.version = version2;
2714
+ set $version(version3) {
2715
+ this.config.app.version = version3;
2697
2716
  }
2698
2717
  /** Current dev mode state */
2699
2718
  // prettier-ignore
@@ -3472,59 +3491,89 @@ var BetterContainer = class {
3472
3491
  // src/tools/BetterModal.ts
3473
3492
  import {
3474
3493
  ChannelSelectMenuBuilder,
3494
+ CheckboxBuilder,
3495
+ CheckboxGroupBuilder,
3475
3496
  FileUploadBuilder,
3476
3497
  LabelBuilder,
3477
3498
  MentionableSelectMenuBuilder,
3478
3499
  ModalBuilder,
3500
+ RadioGroupBuilder,
3479
3501
  RoleSelectMenuBuilder,
3480
3502
  StringSelectMenuBuilder,
3481
3503
  TextInputBuilder,
3482
- TextInputStyle,
3483
3504
  UserSelectMenuBuilder
3484
3505
  } from "discord.js";
3485
- import { $ as $6 } from "qznt";
3486
- var BetterModal = class {
3487
- id;
3488
- options;
3489
- modal;
3506
+ var DEFAULT_CONFIG = {
3507
+ timeout: 6e4
3508
+ };
3509
+ function createRandomId() {
3510
+ return `v-${Math.random().toString(36).split(".")[1]}`;
3511
+ }
3512
+ var BetterModal = class _BetterModal {
3513
+ customId;
3490
3514
  components = /* @__PURE__ */ new Map();
3491
- config;
3492
- constructor(options = {}) {
3493
- this.id = options.id || this.createModalId();
3494
- this.options = options;
3495
- this.modal = new ModalBuilder().setCustomId(this.id);
3496
- this.config = options.config || globalToolsConfig;
3497
- if (options.title) {
3498
- this.setTitle(options.title);
3499
- }
3500
- if (options.components?.length) {
3501
- this.addComponents(...options.components);
3502
- }
3515
+ labelComponents = [];
3516
+ modal;
3517
+ constructor(options) {
3518
+ this.customId = options?.customId ?? createRandomId();
3519
+ this.modal = new ModalBuilder().setCustomId(this.customId);
3520
+ if (options?.title) this.setTitle(options.title);
3521
+ if (options?.components?.length) this.addComponents(...options.components);
3503
3522
  }
3504
- createModalId() {
3505
- return `modal:${$6.rnd.str(10, "alpha", { casing: "mixed" })}-${Date.now()}`;
3523
+ validateComponentLength() {
3524
+ if ((this.components.size ?? 0) >= 25) {
3525
+ throw new Error("[BetterModal] Modal can only have 25 components");
3526
+ }
3506
3527
  }
3507
3528
  createComponentId() {
3508
- return `modal-component:${this.id}-${$6.rnd.str(4, "alpha", { casing: "mixed" })}-${Date.now().toString().slice(-4)}`;
3529
+ return `${this.customId}:${createRandomId()}`;
3509
3530
  }
3510
- validateComponentLength() {
3511
- if (this.components.size >= 5) throw new Error("Modal can only have 5 components");
3512
- }
3513
- toJSON() {
3514
- return this.modal.toJSON();
3531
+ createLabelComponent(data) {
3532
+ const component = new LabelBuilder().setLabel(data.label);
3533
+ if (data.description) component.setDescription(data.description);
3534
+ return component;
3515
3535
  }
3516
3536
  build() {
3517
- this.modal.setLabelComponents(Array.from(this.components.values()));
3537
+ if (!this.modal.data.title) throw new Error("[BetterModal] Modal must have a title");
3538
+ this.modal.setLabelComponents(this.labelComponents);
3518
3539
  return this.modal;
3519
3540
  }
3541
+ clone() {
3542
+ return new _BetterModal({
3543
+ customId: this.customId,
3544
+ title: this.modal.data.title,
3545
+ components: Array.from(this.components.values())
3546
+ });
3547
+ }
3548
+ toJSON() {
3549
+ return this.build().toJSON();
3550
+ }
3551
+ /**
3552
+ * Sets the title of the modal.
3553
+ * @param title The title of the modal.
3554
+ */
3520
3555
  setTitle(title) {
3521
3556
  this.modal.setTitle(title);
3522
3557
  return this;
3523
3558
  }
3559
+ /** Sets components for the modal. */
3560
+ setComponents(...components) {
3561
+ this.components.clear();
3562
+ this.labelComponents = [];
3563
+ this.addComponents(...components);
3564
+ return this;
3565
+ }
3566
+ /** Adds components to the modal. */
3524
3567
  addComponents(...components) {
3525
3568
  for (const component of components) {
3526
3569
  if ("textInput" in component) {
3527
3570
  this.addTextInput(component.textInput);
3571
+ } else if ("checkbox" in component) {
3572
+ this.addCheckbox(component.checkbox);
3573
+ } else if ("checkboxGroup" in component) {
3574
+ this.addCheckboxGroup(component.checkboxGroup);
3575
+ } else if ("radioGroup" in component) {
3576
+ this.addRadioGroup(component.radioGroup);
3528
3577
  } else if ("stringSelect" in component) {
3529
3578
  this.addStringSelect(component.stringSelect);
3530
3579
  } else if ("channelSelect" in component) {
@@ -3541,112 +3590,144 @@ var BetterModal = class {
3541
3590
  }
3542
3591
  return this;
3543
3592
  }
3544
- setComponents(...components) {
3545
- this.modal.spliceLabelComponents(0, this.modal.components.length);
3546
- this.addComponents(...components);
3547
- return this;
3548
- }
3549
3593
  addTextInput(data) {
3550
3594
  this.validateComponentLength();
3551
- let { label, description, custom_id, ...rest } = data;
3552
- custom_id ||= this.createComponentId();
3553
- const textInputComponent = new TextInputBuilder(rest).setCustomId(custom_id);
3554
- if (!rest.style) textInputComponent.setStyle(TextInputStyle.Short);
3555
- const labelComponent = new LabelBuilder().setLabel(label).setTextInputComponent(textInputComponent);
3556
- if (description) labelComponent.setDescription(description);
3557
- this.components.set(custom_id, labelComponent);
3595
+ const customId = data.customId ?? this.createComponentId();
3596
+ const textInput = new TextInputBuilder({ ...data, customId });
3597
+ const label = this.createLabelComponent(data);
3598
+ label.setTextInputComponent(textInput);
3599
+ this.components.set(customId, { textInput: data });
3600
+ this.labelComponents.push(label);
3558
3601
  return this;
3559
3602
  }
3560
3603
  addStringSelect(data) {
3561
3604
  this.validateComponentLength();
3562
- let { label, description, custom_id, ...rest } = data;
3563
- custom_id ||= this.createComponentId();
3564
- const stringSelectComponent = new StringSelectMenuBuilder(rest).setCustomId(custom_id);
3565
- const labelComponent = new LabelBuilder().setLabel(label).setStringSelectMenuComponent(stringSelectComponent);
3566
- if (description) labelComponent.setDescription(description);
3567
- this.components.set(custom_id, labelComponent);
3605
+ const customId = data.customId ?? this.createComponentId();
3606
+ const select = new StringSelectMenuBuilder({ ...data, customId });
3607
+ const label = this.createLabelComponent(data);
3608
+ label.setStringSelectMenuComponent(select);
3609
+ this.components.set(customId, { stringSelect: data });
3610
+ this.labelComponents.push(label);
3611
+ return this;
3612
+ }
3613
+ addCheckbox(data) {
3614
+ this.validateComponentLength();
3615
+ const customId = data.custom_id ?? this.createComponentId();
3616
+ const checkbox = new CheckboxBuilder({ ...data, custom_id: customId });
3617
+ const label = this.createLabelComponent(data);
3618
+ label.setCheckboxComponent(checkbox);
3619
+ this.components.set(customId, { checkbox: data });
3620
+ this.labelComponents.push(label);
3621
+ return this;
3622
+ }
3623
+ addCheckboxGroup(data) {
3624
+ this.validateComponentLength();
3625
+ const customId = data.custom_id ?? this.createComponentId();
3626
+ const checkboxGroup = new CheckboxGroupBuilder({ ...data, custom_id: customId });
3627
+ const label = this.createLabelComponent(data);
3628
+ label.setCheckboxGroupComponent(checkboxGroup);
3629
+ this.components.set(customId, { checkboxGroup: data });
3630
+ this.labelComponents.push(label);
3631
+ return this;
3632
+ }
3633
+ addRadioGroup(data) {
3634
+ this.validateComponentLength();
3635
+ const customId = data.custom_id ?? this.createComponentId();
3636
+ const radioGroup = new RadioGroupBuilder({ ...data, custom_id: customId });
3637
+ const label = this.createLabelComponent(data);
3638
+ label.setRadioGroupComponent(radioGroup);
3639
+ this.components.set(customId, { radioGroup: data });
3640
+ this.labelComponents.push(label);
3568
3641
  return this;
3569
3642
  }
3570
3643
  addChannelSelect(data) {
3571
3644
  this.validateComponentLength();
3572
- let { label, description, custom_id, ...rest } = data;
3573
- custom_id ||= this.createComponentId();
3574
- const channelSelectComponent = new ChannelSelectMenuBuilder(rest).setCustomId(custom_id);
3575
- const labelComponent = new LabelBuilder().setLabel(label).setChannelSelectMenuComponent(channelSelectComponent);
3576
- if (description) labelComponent.setDescription(description);
3577
- this.components.set(custom_id, labelComponent);
3645
+ const customId = data.customId ?? this.createComponentId();
3646
+ const channelSelect = new ChannelSelectMenuBuilder({ ...data, customId });
3647
+ const label = this.createLabelComponent(data);
3648
+ label.setChannelSelectMenuComponent(channelSelect);
3649
+ this.components.set(customId, { channelSelect: data });
3650
+ this.labelComponents.push(label);
3578
3651
  return this;
3579
3652
  }
3580
3653
  addUserSelect(data) {
3581
3654
  this.validateComponentLength();
3582
- let { label, description, custom_id, ...rest } = data;
3583
- custom_id ||= this.createComponentId();
3584
- const userSelectComponent = new UserSelectMenuBuilder(rest).setCustomId(custom_id);
3585
- const labelComponent = new LabelBuilder().setLabel(label).setUserSelectMenuComponent(userSelectComponent);
3586
- if (description) labelComponent.setDescription(description);
3587
- this.components.set(custom_id, labelComponent);
3655
+ const customId = data.customId ?? this.createComponentId();
3656
+ const userSelect = new UserSelectMenuBuilder({ ...data, customId });
3657
+ const label = this.createLabelComponent(data);
3658
+ label.setUserSelectMenuComponent(userSelect);
3659
+ this.components.set(customId, { userSelect: data });
3660
+ this.labelComponents.push(label);
3588
3661
  return this;
3589
3662
  }
3590
3663
  addRoleSelect(data) {
3591
3664
  this.validateComponentLength();
3592
- let { label, description, custom_id, ...rest } = data;
3593
- custom_id ||= this.createComponentId();
3594
- const roleSelectComponent = new RoleSelectMenuBuilder(rest).setCustomId(custom_id);
3595
- const labelComponent = new LabelBuilder().setLabel(label).setRoleSelectMenuComponent(roleSelectComponent);
3596
- if (description) labelComponent.setDescription(description);
3597
- this.components.set(custom_id, labelComponent);
3665
+ const customId = data.customId ?? this.createComponentId();
3666
+ const roleSelect = new RoleSelectMenuBuilder({ ...data, customId });
3667
+ const label = this.createLabelComponent(data);
3668
+ label.setRoleSelectMenuComponent(roleSelect);
3669
+ this.components.set(customId, { roleSelect: data });
3670
+ this.labelComponents.push(label);
3598
3671
  return this;
3599
3672
  }
3600
3673
  addMentionableSelect(data) {
3601
3674
  this.validateComponentLength();
3602
- let { label, description, custom_id, ...rest } = data;
3603
- custom_id ||= this.createComponentId();
3604
- const mentionableSelectComponent = new MentionableSelectMenuBuilder(rest).setCustomId(custom_id);
3605
- const labelComponent = new LabelBuilder().setLabel(label).setMentionableSelectMenuComponent(mentionableSelectComponent);
3606
- if (description) labelComponent.setDescription(description);
3607
- this.components.set(custom_id, labelComponent);
3675
+ const customId = data.customId ?? this.createComponentId();
3676
+ const mentionableSelect = new MentionableSelectMenuBuilder({ ...data, customId });
3677
+ const label = this.createLabelComponent(data);
3678
+ label.setMentionableSelectMenuComponent(mentionableSelect);
3679
+ this.components.set(customId, { mentionableSelect: data });
3680
+ this.labelComponents.push(label);
3608
3681
  return this;
3609
3682
  }
3610
3683
  addFileUpload(data) {
3611
3684
  this.validateComponentLength();
3612
- let { label, description, custom_id, ...rest } = data;
3613
- custom_id ||= this.createComponentId();
3614
- const fileUploadComponent = new FileUploadBuilder(rest).setCustomId(custom_id);
3615
- const labelComponent = new LabelBuilder().setLabel(label).setFileUploadComponent(fileUploadComponent);
3616
- if (description) labelComponent.setDescription(description);
3617
- this.components.set(custom_id, labelComponent);
3685
+ const customId = data.custom_id ?? this.createComponentId();
3686
+ const fileUpload = new FileUploadBuilder({ ...data, custom_id: customId });
3687
+ const label = this.createLabelComponent(data);
3688
+ label.setFileUploadComponent(fileUpload);
3689
+ this.components.set(customId, { fileUpload: data });
3690
+ this.labelComponents.push(label);
3618
3691
  return this;
3619
3692
  }
3620
3693
  /**
3621
- * Shows the modal via interaction.
3622
- * @param interaction The interaction used to show the modal
3694
+ * Shows the modal to the user via interaction.
3695
+ * @param interaction The command interaction to show the modal with.
3696
+ * @param options Modal options.
3623
3697
  */
3624
- async show(interaction) {
3625
- if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
3626
- if (!this.modal.data.title) throw new Error("Modal must have a title");
3627
- this.build();
3628
- await interaction.showModal(this.modal).catch((err) => {
3629
- console.error("Modal failed to send", err);
3630
- });
3698
+ async show(interaction, options) {
3699
+ if (!interaction) throw new Error("[BetterModal] Interaction is null or undefined");
3700
+ const modal = this.build();
3701
+ await interaction.showModal(modal, options);
3702
+ }
3703
+ /**
3704
+ * Shows the modal and waits for it to be submitted.
3705
+ * @param interaction The interaction to show the modal with.
3706
+ * @param options Modal submission options.
3707
+ */
3708
+ async showAndAwait(interaction, options) {
3709
+ await this.show(interaction);
3710
+ return this.awaitSubmit(interaction, options);
3631
3711
  }
3632
3712
  /**
3633
- * Waits for the modal to be submitted and returns the component data.
3634
- * @param interaction The interaction used to show the modal
3635
- * @param options Options */
3713
+ * Waits for this modal to be submitted, returning a helper utility object.
3714
+ * @param interaction The interaction to show the modal with.
3715
+ * @param options Modal submission options.
3716
+ */
3636
3717
  async awaitSubmit(interaction, options) {
3637
- if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
3718
+ if (!interaction) throw new Error("[BetterModal] Interaction is null or undefined");
3719
+ const timeout = options?.timeout ?? DEFAULT_CONFIG.timeout;
3638
3720
  try {
3639
3721
  const modalSubmit = await interaction.awaitModalSubmit({
3640
- filter: (i) => i.customId === this.id,
3641
- time: options?.timeout ?? this.config.timeouts.modalSubmit,
3642
- ...options
3722
+ filter: (i) => i.customId === this.customId,
3723
+ time: timeout
3643
3724
  });
3644
- if (options?.autoDefer) {
3725
+ if (options?.deferUpdate) {
3645
3726
  await modalSubmit.deferUpdate();
3646
3727
  }
3647
3728
  const fields = /* @__PURE__ */ new Map();
3648
3729
  const values = [];
3649
- for (const [customId] of this.components) {
3730
+ for (const customId of this.components.keys()) {
3650
3731
  let value = null;
3651
3732
  try {
3652
3733
  value = modalSubmit.fields.getTextInputValue(customId);
@@ -3663,31 +3744,17 @@ var BetterModal = class {
3663
3744
  values.push(value);
3664
3745
  }
3665
3746
  return {
3666
- getField(customId, required) {
3667
- const value = fields.get(customId);
3668
- if (required && value === void 0) {
3669
- throw new Error(`ModalSubmitResult: Field ${customId} is required but was not found`);
3670
- }
3671
- return value;
3672
- },
3673
3747
  values,
3674
3748
  interaction: modalSubmit,
3749
+ getField: (customId) => fields.get(customId),
3675
3750
  reply: (options2) => dynaSend(modalSubmit, options2),
3676
- deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2),
3677
- followUp: async (options2) => await modalSubmit.followUp(options2)
3751
+ followUp: async (options2) => dynaSend(modalSubmit, options2),
3752
+ deferUpdate: () => modalSubmit.deferUpdate()
3678
3753
  };
3679
- } catch (error) {
3754
+ } catch {
3680
3755
  return null;
3681
3756
  }
3682
3757
  }
3683
- /**
3684
- * Shows the modal and waits for the modal to be submitted, returning the component data.
3685
- * @param interaction The interaction used to show the modal
3686
- * @param options Options */
3687
- async showAndAwait(interaction, options) {
3688
- await this.show(interaction);
3689
- return this.awaitSubmit(interaction, options);
3690
- }
3691
3758
  };
3692
3759
 
3693
3760
  // src/tools/Paginator.ts
@@ -3921,7 +3988,7 @@ var Paginator = class {
3921
3988
  if (disabledNavRow.components.length > 0) {
3922
3989
  newComponents.push(disabledNavRow);
3923
3990
  }
3924
- await this.data.message.edit({ components: newComponents }).catch(Boolean);
3991
+ await this.data.message.edit({ components: newComponents });
3925
3992
  if (this.options.useReactions) {
3926
3993
  await this.nav_removeFromMessage();
3927
3994
  }
@@ -3932,7 +3999,7 @@ var Paginator = class {
3932
3999
  }
3933
4000
  break;
3934
4001
  case 2 /* DeleteMessage */:
3935
- await this.data.message.delete().catch(Boolean);
4002
+ await this.data.message.delete();
3936
4003
  break;
3937
4004
  case 3 /* DoNothing */:
3938
4005
  break;
@@ -3942,16 +4009,16 @@ var Paginator = class {
3942
4009
  async nav_removeFromMessage() {
3943
4010
  if (!this.data.message?.editable) return;
3944
4011
  if (this.options.useReactions) {
3945
- await this.data.message.reactions.removeAll().catch(Boolean);
4012
+ await this.data.message.reactions.removeAll();
3946
4013
  } else {
3947
4014
  const newComponents = this.data.message.components.filter((c) => c.type !== ComponentType2.Container);
3948
- await this.data.message.edit({ components: newComponents }).catch(Boolean);
4015
+ await this.data.message.edit({ components: newComponents });
3949
4016
  }
3950
4017
  }
3951
4018
  async nav_addReactions() {
3952
4019
  if (!this.data.message || !this.options.useReactions || !this.data.navigation.reactions.length) return;
3953
4020
  for (const r of this.data.navigation.reactions) {
3954
- await this.data.message.react(r.id).catch(Boolean);
4021
+ await this.data.message.react(r.id);
3955
4022
  }
3956
4023
  }
3957
4024
  async collect_components() {
@@ -3986,7 +4053,7 @@ var Paginator = class {
3986
4053
  }
3987
4054
  switch (i.customId) {
3988
4055
  case "ssm_chapterSelect":
3989
- await i.deferUpdate().catch(Boolean);
4056
+ await i.deferUpdate();
3990
4057
  const chapterIndex = this.chapters.findIndex(
3991
4058
  (c) => c.id === i.values[0]
3992
4059
  );
@@ -3994,25 +4061,25 @@ var Paginator = class {
3994
4061
  await this.refresh();
3995
4062
  break;
3996
4063
  case "btn_first":
3997
- await i.deferUpdate().catch(Boolean);
4064
+ await i.deferUpdate();
3998
4065
  this.callEventStack("first", this.data.page.current, this.data.page.index);
3999
4066
  await this.setPage(this.data.page.index.chapter, 0);
4000
4067
  await this.refresh();
4001
4068
  break;
4002
4069
  case "btn_back":
4003
- await i.deferUpdate().catch(Boolean);
4070
+ await i.deferUpdate();
4004
4071
  this.callEventStack("back", this.data.page.current, this.data.page.index);
4005
4072
  await this.setPage(this.data.page.index.chapter, this.data.page.index.nested - 1);
4006
4073
  await this.refresh();
4007
4074
  break;
4008
4075
  case "btn_next":
4009
- await i.deferUpdate().catch(Boolean);
4076
+ await i.deferUpdate();
4010
4077
  this.callEventStack("next", this.data.page.current, this.data.page.index);
4011
4078
  await this.setPage(this.data.page.index.chapter, this.data.page.index.nested + 1);
4012
4079
  await this.refresh();
4013
4080
  break;
4014
4081
  case "btn_last":
4015
- await i.deferUpdate().catch(Boolean);
4082
+ await i.deferUpdate();
4016
4083
  this.callEventStack("last", this.data.page.current, this.data.page.index);
4017
4084
  await this.setPage(
4018
4085
  this.data.page.index.chapter,
@@ -4414,6 +4481,7 @@ export {
4414
4481
  createMongoPlugin,
4415
4482
  createMongoSchema,
4416
4483
  createPrefixCommandConfig,
4484
+ createRandomId,
4417
4485
  createSlashCommandConfig,
4418
4486
  createStaffConfig,
4419
4487
  createToolsConfig,