vimcord 1.0.50 → 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.cjs CHANGED
@@ -82,6 +82,7 @@ __export(index_exports, {
82
82
  createMongoPlugin: () => createMongoPlugin,
83
83
  createMongoSchema: () => createMongoSchema,
84
84
  createPrefixCommandConfig: () => createPrefixCommandConfig,
85
+ createRandomId: () => createRandomId,
85
86
  createSlashCommandConfig: () => createSlashCommandConfig,
86
87
  createStaffConfig: () => createStaffConfig,
87
88
  createToolsConfig: () => createToolsConfig,
@@ -334,9 +335,13 @@ var BaseCommandBuilder = class {
334
335
  await config.beforeExecute?.({ cancel: () => cancel = true }, ...args);
335
336
  if (cancel) return;
336
337
  if (config.logExecution !== false) {
337
- const cmdName = this.options.name || this.builder?.name || "Unknown";
338
+ const optionsWithName = this.options;
339
+ const builderWithName = this;
340
+ const cmdName = optionsWithName.name ?? builderWithName.builder?.name ?? "Unknown";
338
341
  const location = ctx.guild ? `${ctx.guild.name} (${ctx.guild.id})` : "Direct Messages";
339
- client.logger.commandExecuted(cmdName, ctx.user.username, location);
342
+ if (client.logger) {
343
+ client.logger.commandExecuted(cmdName, ctx.user.username, location);
344
+ }
340
345
  }
341
346
  const result = await config.execute?.(...args);
342
347
  await config.afterExecute?.(result, ...args);
@@ -564,9 +569,7 @@ var Logger = class {
564
569
  extend(extras) {
565
570
  for (const [key, fn] of Object.entries(extras)) {
566
571
  if (typeof fn === "function") {
567
- this[key] = function(...args) {
568
- return fn.call(this, ...args);
569
- };
572
+ this[key] = (...args) => fn.call(this, ...args);
570
573
  }
571
574
  }
572
575
  return this;
@@ -936,12 +939,14 @@ var contextCommandHandler = new EventBuilder({
936
939
  if (!command) {
937
940
  const content = `**${interaction.commandName}** is not a registered context command.`;
938
941
  if (interaction.replied || interaction.deferred) {
939
- return interaction.followUp({ content, flags: "Ephemeral" });
942
+ await interaction.followUp({ content, flags: "Ephemeral" });
943
+ } else {
944
+ await interaction.reply({ content, flags: "Ephemeral" });
940
945
  }
941
- return interaction.reply({ content, flags: "Ephemeral" });
946
+ return;
942
947
  }
943
948
  try {
944
- return await command.run(client, client, interaction);
949
+ await command.run(client, client, interaction);
945
950
  } catch (err) {
946
951
  await client.error.handleCommandError(err, interaction.guild, interaction);
947
952
  }
@@ -1000,12 +1005,14 @@ var slashCommandHandler = new EventBuilder({
1000
1005
  if (!command) {
1001
1006
  const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
1002
1007
  if (interaction.replied || interaction.deferred) {
1003
- return interaction.followUp({ content, flags: "Ephemeral" });
1008
+ await interaction.followUp({ content, flags: "Ephemeral" });
1009
+ } else {
1010
+ await interaction.reply({ content, flags: "Ephemeral" });
1004
1011
  }
1005
- return interaction.reply({ content, flags: "Ephemeral" });
1012
+ return;
1006
1013
  }
1007
1014
  try {
1008
- return await command.run(client, client, interaction);
1015
+ await command.run(client, client, interaction);
1009
1016
  } catch (err) {
1010
1017
  await client.error.handleCommandError(err, interaction.guild, interaction);
1011
1018
  }
@@ -1789,7 +1796,7 @@ var VimcordErrorHandler = class {
1789
1796
  var import_chalk2 = __toESM(require("chalk"));
1790
1797
 
1791
1798
  // package.json
1792
- var version = "1.0.50";
1799
+ var version = "1.0.51";
1793
1800
 
1794
1801
  // src/client/vimcord.logger.ts
1795
1802
  var clientLoggerFactory = (client) => new Logger({ prefixEmoji: "\u26A1", prefix: `vimcord (i${client.clientId})` }).extend({
@@ -1865,9 +1872,11 @@ function getDevMode() {
1865
1872
  }
1866
1873
 
1867
1874
  // src/configs/app.config.ts
1875
+ var packageJson = getPackageJson();
1876
+ var version2 = typeof packageJson.version === "string" ? packageJson.version : "1.0.0";
1868
1877
  var defaultConfig = {
1869
1878
  name: "Discord Bot",
1870
- version: getPackageJson()?.version ?? "1.0.0",
1879
+ version: version2,
1871
1880
  devMode: getDevMode(),
1872
1881
  verbose: false,
1873
1882
  enableCLI: false,
@@ -2191,11 +2200,16 @@ var CommandManager = class {
2191
2200
  slash;
2192
2201
  prefix;
2193
2202
  context;
2203
+ logger;
2194
2204
  constructor(client) {
2195
2205
  this.client = client;
2196
2206
  this.slash = new SlashCommandManager(client);
2197
2207
  this.prefix = new PrefixCommandManager(client);
2198
2208
  this.context = new ContextCommandManager(client);
2209
+ this.logger = new Logger({
2210
+ prefixEmoji: "\u26A1",
2211
+ prefix: `vimcord (i${client.clientId}) [CommandManager]`
2212
+ });
2199
2213
  }
2200
2214
  getAllAppCommands(options = {}) {
2201
2215
  return [...this.slash.getAll(options), ...this.context.getAll(options)];
@@ -2203,23 +2217,21 @@ var CommandManager = class {
2203
2217
  async registerGlobal(options = {}) {
2204
2218
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2205
2219
  if (!client.rest) {
2206
- console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
2220
+ this.logger.error("Failed to register app commands globally: REST is not initialized");
2207
2221
  return;
2208
2222
  }
2209
2223
  const commands = this.getAllAppCommands(options).map((cmd) => cmd.builder.toJSON());
2210
2224
  if (!commands.length) {
2211
- console.log("[CommandManager] No commands to register globally");
2225
+ this.logger.info("No commands to register globally");
2212
2226
  return;
2213
2227
  }
2214
- console.log(
2215
- `[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} globally...`
2216
- );
2228
+ this.logger.info(`Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} globally...`);
2217
2229
  try {
2218
2230
  await client.rest.put(import_discord8.Routes.applicationCommands(client.user.id), { body: commands });
2219
- console.log(`[CommandManager] \u2714 Registered app ${commands.length === 1 ? "command" : "commands"} globally`);
2231
+ this.logger.success(`Registered app ${commands.length === 1 ? "command" : "commands"} globally`);
2220
2232
  } catch (err) {
2221
- console.error(
2222
- `[CommandManager] \u2716 Failed to register app ${commands.length === 1 ? "command" : "commands"} globally`,
2233
+ this.logger.error(
2234
+ `Failed to register app ${commands.length === 1 ? "command" : "commands"} globally`,
2223
2235
  err
2224
2236
  );
2225
2237
  }
@@ -2227,60 +2239,66 @@ var CommandManager = class {
2227
2239
  async unregisterGlobal() {
2228
2240
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2229
2241
  if (!client.rest) {
2230
- console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
2242
+ this.logger.error("Failed to remove app commands globally: REST is not initialized");
2231
2243
  return;
2232
2244
  }
2233
2245
  try {
2234
2246
  await client.rest.put(import_discord8.Routes.applicationCommands(client.user.id), { body: [] });
2235
- console.log(`[CommandManager] \u2714 Removed app commands globally`);
2247
+ this.logger.success("Removed app commands globally");
2236
2248
  } catch (err) {
2237
- console.error(`[CommandManager] \u2716 Failed to remove app commands globally`, err);
2249
+ this.logger.error("Failed to remove app commands globally", err);
2238
2250
  }
2239
2251
  }
2240
2252
  async registerGuild(options = {}) {
2241
2253
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2242
2254
  if (!client.rest) {
2243
- console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
2255
+ this.logger.error("Failed to register app commands by guild: REST is not initialized");
2244
2256
  return;
2245
2257
  }
2246
2258
  const commands = this.getAllAppCommands(options).map((cmd) => cmd.builder.toJSON());
2247
2259
  if (!commands.length) {
2248
- console.log("[CommandManager] No commands to register by guild");
2260
+ this.logger.info("No commands to register by guild");
2249
2261
  return;
2250
2262
  }
2251
2263
  const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
2252
- console.log(
2253
- `[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} for ${guildIds.length} guilds...`
2264
+ this.logger.info(
2265
+ `Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} for ${guildIds.length} guilds...`
2254
2266
  );
2255
2267
  await Promise.all(
2256
- guildIds.map(
2257
- (guildId) => client.rest.put(import_discord8.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
2268
+ guildIds.map(async (guildId) => {
2269
+ try {
2270
+ await client.rest.put(import_discord8.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands });
2258
2271
  const gName = client.guilds.cache.get(guildId)?.name || "n/a";
2259
- console.log(
2260
- `[CommandManager] \u2714 Set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`
2272
+ this.logger.success(
2273
+ `Set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`
2261
2274
  );
2262
- }).catch((err) => {
2275
+ } catch (err) {
2263
2276
  const gName = client.guilds.cache.get(guildId)?.name || "n/a";
2264
- console.log(
2265
- `[CommandManager] \u2716 Failed to set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`,
2277
+ this.logger.error(
2278
+ `Failed to set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`,
2266
2279
  err
2267
2280
  );
2268
- })
2269
- )
2281
+ }
2282
+ })
2270
2283
  );
2271
2284
  }
2272
2285
  async unregisterGuild(options = {}) {
2273
2286
  const client = await Vimcord.getReadyInstance(this.client.clientId);
2274
2287
  if (!client.rest) {
2275
- console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
2288
+ this.logger.error("Failed to unregister app commands by guild: REST is not initialized");
2276
2289
  return;
2277
2290
  }
2278
2291
  const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
2279
- console.log(`[CommandManager] Unregistering commands from ${guildIds.length} guilds...`);
2292
+ this.logger.info(`Unregistering commands from ${guildIds.length} guilds...`);
2280
2293
  await Promise.all(
2281
- guildIds.map(
2282
- (guildId) => client.rest.put(import_discord8.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))
2283
- )
2294
+ guildIds.map(async (guildId) => {
2295
+ try {
2296
+ await client.rest.put(import_discord8.Routes.applicationGuildCommands(client.user.id, guildId), { body: [] });
2297
+ this.logger.success(`Removed app commands in guild: ${guildId}`);
2298
+ } catch (err) {
2299
+ this.logger.error(`Failed to remove app commands in guild: ${guildId}`, err);
2300
+ }
2301
+ })
2284
2302
  );
2285
2303
  }
2286
2304
  };
@@ -2788,8 +2806,8 @@ var Vimcord = class _Vimcord extends import_discord11.Client {
2788
2806
  return this.config.app.version;
2789
2807
  }
2790
2808
  // prettier-ignore
2791
- set $version(version2) {
2792
- this.config.app.version = version2;
2809
+ set $version(version3) {
2810
+ this.config.app.version = version3;
2793
2811
  }
2794
2812
  /** Current dev mode state */
2795
2813
  // prettier-ignore
@@ -3561,49 +3579,77 @@ var BetterContainer = class {
3561
3579
 
3562
3580
  // src/tools/BetterModal.ts
3563
3581
  var import_discord13 = require("discord.js");
3564
- var import_qznt7 = require("qznt");
3565
- var BetterModal = class {
3566
- id;
3567
- options;
3568
- modal;
3582
+ var DEFAULT_CONFIG = {
3583
+ timeout: 6e4
3584
+ };
3585
+ function createRandomId() {
3586
+ return `v-${Math.random().toString(36).split(".")[1]}`;
3587
+ }
3588
+ var BetterModal = class _BetterModal {
3589
+ customId;
3569
3590
  components = /* @__PURE__ */ new Map();
3570
- config;
3571
- constructor(options = {}) {
3572
- this.id = options.id || this.createModalId();
3573
- this.options = options;
3574
- this.modal = new import_discord13.ModalBuilder().setCustomId(this.id);
3575
- this.config = options.config || globalToolsConfig;
3576
- if (options.title) {
3577
- this.setTitle(options.title);
3578
- }
3579
- if (options.components?.length) {
3580
- this.addComponents(...options.components);
3581
- }
3591
+ labelComponents = [];
3592
+ modal;
3593
+ constructor(options) {
3594
+ this.customId = options?.customId ?? createRandomId();
3595
+ this.modal = new import_discord13.ModalBuilder().setCustomId(this.customId);
3596
+ if (options?.title) this.setTitle(options.title);
3597
+ if (options?.components?.length) this.addComponents(...options.components);
3582
3598
  }
3583
- createModalId() {
3584
- return `modal:${import_qznt7.$.rnd.str(10, "alpha", { casing: "mixed" })}-${Date.now()}`;
3599
+ validateComponentLength() {
3600
+ if ((this.components.size ?? 0) >= 25) {
3601
+ throw new Error("[BetterModal] Modal can only have 25 components");
3602
+ }
3585
3603
  }
3586
3604
  createComponentId() {
3587
- return `modal-component:${this.id}-${import_qznt7.$.rnd.str(4, "alpha", { casing: "mixed" })}-${Date.now().toString().slice(-4)}`;
3605
+ return `${this.customId}:${createRandomId()}`;
3588
3606
  }
3589
- validateComponentLength() {
3590
- if (this.components.size >= 5) throw new Error("Modal can only have 5 components");
3591
- }
3592
- toJSON() {
3593
- return this.modal.toJSON();
3607
+ createLabelComponent(data) {
3608
+ const component = new import_discord13.LabelBuilder().setLabel(data.label);
3609
+ if (data.description) component.setDescription(data.description);
3610
+ return component;
3594
3611
  }
3595
3612
  build() {
3596
- this.modal.setLabelComponents(Array.from(this.components.values()));
3613
+ if (!this.modal.data.title) throw new Error("[BetterModal] Modal must have a title");
3614
+ this.modal.setLabelComponents(this.labelComponents);
3597
3615
  return this.modal;
3598
3616
  }
3617
+ clone() {
3618
+ return new _BetterModal({
3619
+ customId: this.customId,
3620
+ title: this.modal.data.title,
3621
+ components: Array.from(this.components.values())
3622
+ });
3623
+ }
3624
+ toJSON() {
3625
+ return this.build().toJSON();
3626
+ }
3627
+ /**
3628
+ * Sets the title of the modal.
3629
+ * @param title The title of the modal.
3630
+ */
3599
3631
  setTitle(title) {
3600
3632
  this.modal.setTitle(title);
3601
3633
  return this;
3602
3634
  }
3635
+ /** Sets components for the modal. */
3636
+ setComponents(...components) {
3637
+ this.components.clear();
3638
+ this.labelComponents = [];
3639
+ this.addComponents(...components);
3640
+ return this;
3641
+ }
3642
+ /** Adds components to the modal. */
3603
3643
  addComponents(...components) {
3604
3644
  for (const component of components) {
3605
3645
  if ("textInput" in component) {
3606
3646
  this.addTextInput(component.textInput);
3647
+ } else if ("checkbox" in component) {
3648
+ this.addCheckbox(component.checkbox);
3649
+ } else if ("checkboxGroup" in component) {
3650
+ this.addCheckboxGroup(component.checkboxGroup);
3651
+ } else if ("radioGroup" in component) {
3652
+ this.addRadioGroup(component.radioGroup);
3607
3653
  } else if ("stringSelect" in component) {
3608
3654
  this.addStringSelect(component.stringSelect);
3609
3655
  } else if ("channelSelect" in component) {
@@ -3620,112 +3666,144 @@ var BetterModal = class {
3620
3666
  }
3621
3667
  return this;
3622
3668
  }
3623
- setComponents(...components) {
3624
- this.modal.spliceLabelComponents(0, this.modal.components.length);
3625
- this.addComponents(...components);
3626
- return this;
3627
- }
3628
3669
  addTextInput(data) {
3629
3670
  this.validateComponentLength();
3630
- let { label, description, custom_id, ...rest } = data;
3631
- custom_id ||= this.createComponentId();
3632
- const textInputComponent = new import_discord13.TextInputBuilder(rest).setCustomId(custom_id);
3633
- if (!rest.style) textInputComponent.setStyle(import_discord13.TextInputStyle.Short);
3634
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setTextInputComponent(textInputComponent);
3635
- if (description) labelComponent.setDescription(description);
3636
- this.components.set(custom_id, labelComponent);
3671
+ const customId = data.customId ?? this.createComponentId();
3672
+ const textInput = new import_discord13.TextInputBuilder({ ...data, customId });
3673
+ const label = this.createLabelComponent(data);
3674
+ label.setTextInputComponent(textInput);
3675
+ this.components.set(customId, { textInput: data });
3676
+ this.labelComponents.push(label);
3637
3677
  return this;
3638
3678
  }
3639
3679
  addStringSelect(data) {
3640
3680
  this.validateComponentLength();
3641
- let { label, description, custom_id, ...rest } = data;
3642
- custom_id ||= this.createComponentId();
3643
- const stringSelectComponent = new import_discord13.StringSelectMenuBuilder(rest).setCustomId(custom_id);
3644
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setStringSelectMenuComponent(stringSelectComponent);
3645
- if (description) labelComponent.setDescription(description);
3646
- this.components.set(custom_id, labelComponent);
3681
+ const customId = data.customId ?? this.createComponentId();
3682
+ const select = new import_discord13.StringSelectMenuBuilder({ ...data, customId });
3683
+ const label = this.createLabelComponent(data);
3684
+ label.setStringSelectMenuComponent(select);
3685
+ this.components.set(customId, { stringSelect: data });
3686
+ this.labelComponents.push(label);
3687
+ return this;
3688
+ }
3689
+ addCheckbox(data) {
3690
+ this.validateComponentLength();
3691
+ const customId = data.custom_id ?? this.createComponentId();
3692
+ const checkbox = new import_discord13.CheckboxBuilder({ ...data, custom_id: customId });
3693
+ const label = this.createLabelComponent(data);
3694
+ label.setCheckboxComponent(checkbox);
3695
+ this.components.set(customId, { checkbox: data });
3696
+ this.labelComponents.push(label);
3697
+ return this;
3698
+ }
3699
+ addCheckboxGroup(data) {
3700
+ this.validateComponentLength();
3701
+ const customId = data.custom_id ?? this.createComponentId();
3702
+ const checkboxGroup = new import_discord13.CheckboxGroupBuilder({ ...data, custom_id: customId });
3703
+ const label = this.createLabelComponent(data);
3704
+ label.setCheckboxGroupComponent(checkboxGroup);
3705
+ this.components.set(customId, { checkboxGroup: data });
3706
+ this.labelComponents.push(label);
3707
+ return this;
3708
+ }
3709
+ addRadioGroup(data) {
3710
+ this.validateComponentLength();
3711
+ const customId = data.custom_id ?? this.createComponentId();
3712
+ const radioGroup = new import_discord13.RadioGroupBuilder({ ...data, custom_id: customId });
3713
+ const label = this.createLabelComponent(data);
3714
+ label.setRadioGroupComponent(radioGroup);
3715
+ this.components.set(customId, { radioGroup: data });
3716
+ this.labelComponents.push(label);
3647
3717
  return this;
3648
3718
  }
3649
3719
  addChannelSelect(data) {
3650
3720
  this.validateComponentLength();
3651
- let { label, description, custom_id, ...rest } = data;
3652
- custom_id ||= this.createComponentId();
3653
- const channelSelectComponent = new import_discord13.ChannelSelectMenuBuilder(rest).setCustomId(custom_id);
3654
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setChannelSelectMenuComponent(channelSelectComponent);
3655
- if (description) labelComponent.setDescription(description);
3656
- this.components.set(custom_id, labelComponent);
3721
+ const customId = data.customId ?? this.createComponentId();
3722
+ const channelSelect = new import_discord13.ChannelSelectMenuBuilder({ ...data, customId });
3723
+ const label = this.createLabelComponent(data);
3724
+ label.setChannelSelectMenuComponent(channelSelect);
3725
+ this.components.set(customId, { channelSelect: data });
3726
+ this.labelComponents.push(label);
3657
3727
  return this;
3658
3728
  }
3659
3729
  addUserSelect(data) {
3660
3730
  this.validateComponentLength();
3661
- let { label, description, custom_id, ...rest } = data;
3662
- custom_id ||= this.createComponentId();
3663
- const userSelectComponent = new import_discord13.UserSelectMenuBuilder(rest).setCustomId(custom_id);
3664
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setUserSelectMenuComponent(userSelectComponent);
3665
- if (description) labelComponent.setDescription(description);
3666
- this.components.set(custom_id, labelComponent);
3731
+ const customId = data.customId ?? this.createComponentId();
3732
+ const userSelect = new import_discord13.UserSelectMenuBuilder({ ...data, customId });
3733
+ const label = this.createLabelComponent(data);
3734
+ label.setUserSelectMenuComponent(userSelect);
3735
+ this.components.set(customId, { userSelect: data });
3736
+ this.labelComponents.push(label);
3667
3737
  return this;
3668
3738
  }
3669
3739
  addRoleSelect(data) {
3670
3740
  this.validateComponentLength();
3671
- let { label, description, custom_id, ...rest } = data;
3672
- custom_id ||= this.createComponentId();
3673
- const roleSelectComponent = new import_discord13.RoleSelectMenuBuilder(rest).setCustomId(custom_id);
3674
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setRoleSelectMenuComponent(roleSelectComponent);
3675
- if (description) labelComponent.setDescription(description);
3676
- this.components.set(custom_id, labelComponent);
3741
+ const customId = data.customId ?? this.createComponentId();
3742
+ const roleSelect = new import_discord13.RoleSelectMenuBuilder({ ...data, customId });
3743
+ const label = this.createLabelComponent(data);
3744
+ label.setRoleSelectMenuComponent(roleSelect);
3745
+ this.components.set(customId, { roleSelect: data });
3746
+ this.labelComponents.push(label);
3677
3747
  return this;
3678
3748
  }
3679
3749
  addMentionableSelect(data) {
3680
3750
  this.validateComponentLength();
3681
- let { label, description, custom_id, ...rest } = data;
3682
- custom_id ||= this.createComponentId();
3683
- const mentionableSelectComponent = new import_discord13.MentionableSelectMenuBuilder(rest).setCustomId(custom_id);
3684
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setMentionableSelectMenuComponent(mentionableSelectComponent);
3685
- if (description) labelComponent.setDescription(description);
3686
- this.components.set(custom_id, labelComponent);
3751
+ const customId = data.customId ?? this.createComponentId();
3752
+ const mentionableSelect = new import_discord13.MentionableSelectMenuBuilder({ ...data, customId });
3753
+ const label = this.createLabelComponent(data);
3754
+ label.setMentionableSelectMenuComponent(mentionableSelect);
3755
+ this.components.set(customId, { mentionableSelect: data });
3756
+ this.labelComponents.push(label);
3687
3757
  return this;
3688
3758
  }
3689
3759
  addFileUpload(data) {
3690
3760
  this.validateComponentLength();
3691
- let { label, description, custom_id, ...rest } = data;
3692
- custom_id ||= this.createComponentId();
3693
- const fileUploadComponent = new import_discord13.FileUploadBuilder(rest).setCustomId(custom_id);
3694
- const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setFileUploadComponent(fileUploadComponent);
3695
- if (description) labelComponent.setDescription(description);
3696
- this.components.set(custom_id, labelComponent);
3761
+ const customId = data.custom_id ?? this.createComponentId();
3762
+ const fileUpload = new import_discord13.FileUploadBuilder({ ...data, custom_id: customId });
3763
+ const label = this.createLabelComponent(data);
3764
+ label.setFileUploadComponent(fileUpload);
3765
+ this.components.set(customId, { fileUpload: data });
3766
+ this.labelComponents.push(label);
3697
3767
  return this;
3698
3768
  }
3699
3769
  /**
3700
- * Shows the modal via interaction.
3701
- * @param interaction The interaction used to show the modal
3770
+ * Shows the modal to the user via interaction.
3771
+ * @param interaction The command interaction to show the modal with.
3772
+ * @param options Modal options.
3702
3773
  */
3703
- async show(interaction) {
3704
- if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
3705
- if (!this.modal.data.title) throw new Error("Modal must have a title");
3706
- this.build();
3707
- await interaction.showModal(this.modal).catch((err) => {
3708
- console.error("Modal failed to send", err);
3709
- });
3774
+ async show(interaction, options) {
3775
+ if (!interaction) throw new Error("[BetterModal] Interaction is null or undefined");
3776
+ const modal = this.build();
3777
+ await interaction.showModal(modal, options);
3778
+ }
3779
+ /**
3780
+ * Shows the modal and waits for it to be submitted.
3781
+ * @param interaction The interaction to show the modal with.
3782
+ * @param options Modal submission options.
3783
+ */
3784
+ async showAndAwait(interaction, options) {
3785
+ await this.show(interaction);
3786
+ return this.awaitSubmit(interaction, options);
3710
3787
  }
3711
3788
  /**
3712
- * Waits for the modal to be submitted and returns the component data.
3713
- * @param interaction The interaction used to show the modal
3714
- * @param options Options */
3789
+ * Waits for this modal to be submitted, returning a helper utility object.
3790
+ * @param interaction The interaction to show the modal with.
3791
+ * @param options Modal submission options.
3792
+ */
3715
3793
  async awaitSubmit(interaction, options) {
3716
- if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
3794
+ if (!interaction) throw new Error("[BetterModal] Interaction is null or undefined");
3795
+ const timeout = options?.timeout ?? DEFAULT_CONFIG.timeout;
3717
3796
  try {
3718
3797
  const modalSubmit = await interaction.awaitModalSubmit({
3719
- filter: (i) => i.customId === this.id,
3720
- time: options?.timeout ?? this.config.timeouts.modalSubmit,
3721
- ...options
3798
+ filter: (i) => i.customId === this.customId,
3799
+ time: timeout
3722
3800
  });
3723
- if (options?.autoDefer) {
3801
+ if (options?.deferUpdate) {
3724
3802
  await modalSubmit.deferUpdate();
3725
3803
  }
3726
3804
  const fields = /* @__PURE__ */ new Map();
3727
3805
  const values = [];
3728
- for (const [customId] of this.components) {
3806
+ for (const customId of this.components.keys()) {
3729
3807
  let value = null;
3730
3808
  try {
3731
3809
  value = modalSubmit.fields.getTextInputValue(customId);
@@ -3742,31 +3820,17 @@ var BetterModal = class {
3742
3820
  values.push(value);
3743
3821
  }
3744
3822
  return {
3745
- getField(customId, required) {
3746
- const value = fields.get(customId);
3747
- if (required && value === void 0) {
3748
- throw new Error(`ModalSubmitResult: Field ${customId} is required but was not found`);
3749
- }
3750
- return value;
3751
- },
3752
3823
  values,
3753
3824
  interaction: modalSubmit,
3825
+ getField: (customId) => fields.get(customId),
3754
3826
  reply: (options2) => dynaSend(modalSubmit, options2),
3755
- deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2),
3756
- followUp: async (options2) => await modalSubmit.followUp(options2)
3827
+ followUp: async (options2) => dynaSend(modalSubmit, options2),
3828
+ deferUpdate: () => modalSubmit.deferUpdate()
3757
3829
  };
3758
- } catch (error) {
3830
+ } catch {
3759
3831
  return null;
3760
3832
  }
3761
3833
  }
3762
- /**
3763
- * Shows the modal and waits for the modal to be submitted, returning the component data.
3764
- * @param interaction The interaction used to show the modal
3765
- * @param options Options */
3766
- async showAndAwait(interaction, options) {
3767
- await this.show(interaction);
3768
- return this.awaitSubmit(interaction, options);
3769
- }
3770
3834
  };
3771
3835
 
3772
3836
  // src/tools/Paginator.ts
@@ -3991,7 +4055,7 @@ var Paginator = class {
3991
4055
  if (disabledNavRow.components.length > 0) {
3992
4056
  newComponents.push(disabledNavRow);
3993
4057
  }
3994
- await this.data.message.edit({ components: newComponents }).catch(Boolean);
4058
+ await this.data.message.edit({ components: newComponents });
3995
4059
  if (this.options.useReactions) {
3996
4060
  await this.nav_removeFromMessage();
3997
4061
  }
@@ -4002,7 +4066,7 @@ var Paginator = class {
4002
4066
  }
4003
4067
  break;
4004
4068
  case 2 /* DeleteMessage */:
4005
- await this.data.message.delete().catch(Boolean);
4069
+ await this.data.message.delete();
4006
4070
  break;
4007
4071
  case 3 /* DoNothing */:
4008
4072
  break;
@@ -4012,16 +4076,16 @@ var Paginator = class {
4012
4076
  async nav_removeFromMessage() {
4013
4077
  if (!this.data.message?.editable) return;
4014
4078
  if (this.options.useReactions) {
4015
- await this.data.message.reactions.removeAll().catch(Boolean);
4079
+ await this.data.message.reactions.removeAll();
4016
4080
  } else {
4017
4081
  const newComponents = this.data.message.components.filter((c) => c.type !== import_discord14.ComponentType.Container);
4018
- await this.data.message.edit({ components: newComponents }).catch(Boolean);
4082
+ await this.data.message.edit({ components: newComponents });
4019
4083
  }
4020
4084
  }
4021
4085
  async nav_addReactions() {
4022
4086
  if (!this.data.message || !this.options.useReactions || !this.data.navigation.reactions.length) return;
4023
4087
  for (const r of this.data.navigation.reactions) {
4024
- await this.data.message.react(r.id).catch(Boolean);
4088
+ await this.data.message.react(r.id);
4025
4089
  }
4026
4090
  }
4027
4091
  async collect_components() {
@@ -4056,7 +4120,7 @@ var Paginator = class {
4056
4120
  }
4057
4121
  switch (i.customId) {
4058
4122
  case "ssm_chapterSelect":
4059
- await i.deferUpdate().catch(Boolean);
4123
+ await i.deferUpdate();
4060
4124
  const chapterIndex = this.chapters.findIndex(
4061
4125
  (c) => c.id === i.values[0]
4062
4126
  );
@@ -4064,25 +4128,25 @@ var Paginator = class {
4064
4128
  await this.refresh();
4065
4129
  break;
4066
4130
  case "btn_first":
4067
- await i.deferUpdate().catch(Boolean);
4131
+ await i.deferUpdate();
4068
4132
  this.callEventStack("first", this.data.page.current, this.data.page.index);
4069
4133
  await this.setPage(this.data.page.index.chapter, 0);
4070
4134
  await this.refresh();
4071
4135
  break;
4072
4136
  case "btn_back":
4073
- await i.deferUpdate().catch(Boolean);
4137
+ await i.deferUpdate();
4074
4138
  this.callEventStack("back", this.data.page.current, this.data.page.index);
4075
4139
  await this.setPage(this.data.page.index.chapter, this.data.page.index.nested - 1);
4076
4140
  await this.refresh();
4077
4141
  break;
4078
4142
  case "btn_next":
4079
- await i.deferUpdate().catch(Boolean);
4143
+ await i.deferUpdate();
4080
4144
  this.callEventStack("next", this.data.page.current, this.data.page.index);
4081
4145
  await this.setPage(this.data.page.index.chapter, this.data.page.index.nested + 1);
4082
4146
  await this.refresh();
4083
4147
  break;
4084
4148
  case "btn_last":
4085
- await i.deferUpdate().catch(Boolean);
4149
+ await i.deferUpdate();
4086
4150
  this.callEventStack("last", this.data.page.current, this.data.page.index);
4087
4151
  await this.setPage(
4088
4152
  this.data.page.index.chapter,
@@ -4480,6 +4544,7 @@ async function prompt(handler, options, sendOptions) {
4480
4544
  createMongoPlugin,
4481
4545
  createMongoSchema,
4482
4546
  createPrefixCommandConfig,
4547
+ createRandomId,
4483
4548
  createSlashCommandConfig,
4484
4549
  createStaffConfig,
4485
4550
  createToolsConfig,