vimcord 1.0.50 → 1.0.52

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