commandkit 0.1.11-dev.20250307192025 → 0.1.11-dev.20250308122630

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
@@ -2831,6 +2831,19 @@ var init_Context = __esm({
2831
2831
  cancel() {
2832
2832
  __privateSet(this, _cancel, true);
2833
2833
  }
2834
+ /**
2835
+ * Sets command runner function to wrap the command execution.
2836
+ * @param fn The function to set.
2837
+ * @example ctx.setCommandRunner(async (execute) => {
2838
+ * // do something before command execution
2839
+ * await execute();
2840
+ * // do something after command execution
2841
+ * })
2842
+ */
2843
+ setCommandRunner(fn) {
2844
+ var _a, _b;
2845
+ (_b = (_a = this.config.customArgs) == null ? void 0 : _a.setCommandRunner) == null ? void 0 : _b.call(_a, fn);
2846
+ }
2834
2847
  };
2835
2848
  _cancel = new WeakMap();
2836
2849
  __name(_MiddlewareContext, "MiddlewareContext");
@@ -3089,11 +3102,13 @@ var init_CommandRegistrar = __esm({
3089
3102
  * Gets the commands data.
3090
3103
  */
3091
3104
  getCommandsData() {
3092
- const commands = this.commandkit.commandHandler.getCommandsArray();
3105
+ const handler = this.commandkit.commandHandler;
3106
+ const commands = handler.getCommandsArray();
3093
3107
  return commands.flatMap((cmd) => {
3108
+ var _a;
3094
3109
  const json = "toJSON" in cmd.data.command ? cmd.data.command.toJSON() : cmd.data.command;
3095
- if (cmd.subcommands && cmd.subcommands.length > 0 && (!json.type || json.type === import_discord9.ApplicationCommandType.ChatInput)) {
3096
- this.processSubcommands(json, cmd.subcommands);
3110
+ if (((_a = cmd.command.subcommands) == null ? void 0 : _a.length) > 0 && (!json.type || json.type === import_discord9.ApplicationCommandType.ChatInput)) {
3111
+ this.processSubcommands(json, cmd.command.subcommands);
3097
3112
  }
3098
3113
  const collections = [json];
3099
3114
  if (cmd.data.userContextMenu && json.type !== import_discord9.ApplicationCommandType.User) {
@@ -3138,12 +3153,12 @@ var init_CommandRegistrar = __esm({
3138
3153
  const directSubcommands = groupedSubcommands.get(null) || [];
3139
3154
  for (const subcommand of directSubcommands) {
3140
3155
  const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3141
- subcommand.id
3156
+ subcommand.command,
3157
+ subcommand.name
3142
3158
  );
3143
3159
  if (subcommandData) {
3144
3160
  const subcommandOption = {
3145
- type: 1,
3146
- // SUB_COMMAND
3161
+ type: import_discord9.ApplicationCommandOptionType.Subcommand,
3147
3162
  name: subcommand.name,
3148
3163
  description: subcommandData.description || "No description provided",
3149
3164
  options: subcommandData.options || [],
@@ -3157,19 +3172,18 @@ var init_CommandRegistrar = __esm({
3157
3172
  if (groupName === null) continue;
3158
3173
  const subcommandGroupOption = {
3159
3174
  type: import_discord9.ApplicationCommandOptionType.SubcommandGroup,
3160
- // SUB_COMMAND_GROUP
3161
3175
  name: groupName,
3162
3176
  description: `${groupName} commands`,
3163
3177
  options: []
3164
3178
  };
3165
3179
  for (const subcommand of groupSubcommands) {
3166
3180
  const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3167
- subcommand.id
3181
+ subcommand.command,
3182
+ subcommand.name
3168
3183
  );
3169
3184
  if (subcommandData) {
3170
3185
  (_b = subcommandGroupOption.options) == null ? void 0 : _b.push({
3171
3186
  type: import_discord9.ApplicationCommandOptionType.Subcommand,
3172
- // SUB_COMMAND
3173
3187
  name: subcommand.name,
3174
3188
  description: subcommandData.description || "No description provided",
3175
3189
  options: subcommandData.options || [],
@@ -3187,15 +3201,24 @@ var init_CommandRegistrar = __esm({
3187
3201
  * Registers loaded commands.
3188
3202
  */
3189
3203
  async register() {
3204
+ if (!this.commandkit.client.isReady()) {
3205
+ throw new Error("Cannot register commands before the client is ready");
3206
+ }
3190
3207
  const commands = this.getCommandsData();
3191
3208
  const guildCommands = commands.filter((command) => {
3192
3209
  var _a;
3193
- return (_a = command.guilds) == null ? void 0 : _a.length;
3210
+ return (_a = command.guilds) == null ? void 0 : _a.filter(Boolean).length;
3211
+ }).map((c) => {
3212
+ var _a;
3213
+ return {
3214
+ ...c,
3215
+ guilds: Array.from(new Set((_a = c.guilds) == null ? void 0 : _a.filter(Boolean)))
3216
+ };
3194
3217
  });
3195
3218
  const globalCommands = commands.filter(
3196
3219
  (command) => {
3197
3220
  var _a;
3198
- return !((_a = command.guilds) == null ? void 0 : _a.length);
3221
+ return !((_a = command.guilds) == null ? void 0 : _a.filter(Boolean).length);
3199
3222
  }
3200
3223
  );
3201
3224
  await this.updateGlobalCommands(globalCommands);
@@ -3311,10 +3334,12 @@ var init_AppCommandHandler = __esm({
3311
3334
  return Array.from(this.loadedCommands.values());
3312
3335
  }
3313
3336
  /**
3314
- * Get subcommand data by ID for the command registrar
3337
+ * Get subcommand data by command ID and subcommand name
3315
3338
  */
3316
- getSubcommandData(id) {
3317
- const subcommand = this.loadedSubCommands.get(id);
3339
+ getSubcommandData(commandId, subcommandName) {
3340
+ const subcommand = Array.from(this.loadedSubCommands.values()).find(
3341
+ (sub) => sub.subcommand.command === commandId && sub.subcommand.name === subcommandName
3342
+ );
3318
3343
  if (!subcommand) return null;
3319
3344
  const commandData = subcommand.data.command;
3320
3345
  return "toJSON" in commandData ? commandData.toJSON() : commandData;
@@ -3385,11 +3410,17 @@ var init_AppCommandHandler = __esm({
3385
3410
  return;
3386
3411
  }
3387
3412
  const executionMode = this.getExecutionMode(source);
3413
+ let runCommand = null;
3388
3414
  const ctx = new MiddlewareContext(this.commandkit, {
3389
3415
  executionMode,
3390
3416
  interaction: !(source instanceof import_discord10.Message) ? source : null,
3391
3417
  message: source instanceof import_discord10.Message ? source : null,
3392
- forwarded: false
3418
+ forwarded: false,
3419
+ customArgs: {
3420
+ setCommandRunner: /* @__PURE__ */ __name((fn2) => {
3421
+ runCommand = fn2;
3422
+ }, "setCommandRunner")
3423
+ }
3393
3424
  });
3394
3425
  for (const middleware of prepared.middlewares) {
3395
3426
  await middleware.data.beforeExecute(ctx);
@@ -3403,7 +3434,8 @@ var init_AppCommandHandler = __esm({
3403
3434
  }
3404
3435
  if (fn) {
3405
3436
  try {
3406
- const executeCommand = /* @__PURE__ */ __name(async () => fn(ctx.clone()), "executeCommand");
3437
+ const _executeCommand = /* @__PURE__ */ __name(async () => fn(ctx.clone()), "_executeCommand");
3438
+ const executeCommand = runCommand != null ? runCommand(_executeCommand) : _executeCommand;
3407
3439
  const res = await this.commandkit.plugins.execute(
3408
3440
  async (ctx2, plugin) => {
3409
3441
  return plugin.executeCommand(ctx2, source, prepared, executeCommand);
@@ -3497,25 +3529,12 @@ var init_AppCommandHandler = __esm({
3497
3529
  }
3498
3530
  }
3499
3531
  const middlewares = [];
3500
- for (const middlewareId of loadedCommand.command.middlewares) {
3532
+ for (const middlewareId of loadedCommand.command.middlewareIds) {
3501
3533
  const middleware = this.loadedMiddlewares.get(middlewareId);
3502
3534
  if (middleware) {
3503
3535
  middlewares.push(middleware);
3504
3536
  }
3505
3537
  }
3506
- if (loadedSubCommand) {
3507
- for (const middlewareId of loadedSubCommand.subcommand.middlewares) {
3508
- const existingIndex = middlewares.findIndex(
3509
- (m) => m.middleware.id === middlewareId
3510
- );
3511
- if (existingIndex === -1) {
3512
- const middleware = this.loadedMiddlewares.get(middlewareId);
3513
- if (middleware) {
3514
- middlewares.push(middleware);
3515
- }
3516
- }
3517
- }
3518
- }
3519
3538
  return {
3520
3539
  command: loadedCommand,
3521
3540
  subcommand: loadedSubCommand,
@@ -3536,26 +3555,17 @@ var init_AppCommandHandler = __esm({
3536
3555
  if (!commandsRouter) {
3537
3556
  throw new Error("Commands router has not yet initialized");
3538
3557
  }
3539
- const { commands, subcommands, middlewares } = commandsRouter.getData();
3558
+ const { commands, middlewares } = commandsRouter.getData();
3540
3559
  for (const [id, middleware] of middlewares) {
3541
3560
  await this.loadMiddleware(id, middleware);
3542
3561
  }
3543
3562
  for (const [id, command] of commands) {
3544
3563
  await this.loadCommand(id, command);
3545
3564
  }
3546
- for (const [id, subcommand] of subcommands) {
3547
- await this.loadSubcommand(id, subcommand);
3548
- }
3549
- for (const loadedSubCommand of this.loadedSubCommands.values()) {
3550
- const pathSegments = loadedSubCommand.subcommand.path.split("/");
3551
- const parentCommandName = pathSegments[pathSegments.length - 3];
3552
- for (const loadedCommand of this.loadedCommands.values()) {
3553
- if (loadedCommand.command.name === parentCommandName) {
3554
- if (!loadedCommand.subcommands) {
3555
- loadedCommand.subcommands = [];
3556
- }
3557
- loadedCommand.subcommands.push(loadedSubCommand.subcommand);
3558
- break;
3565
+ for (const loadedCommand of this.loadedCommands.values()) {
3566
+ if (loadedCommand.command.subcommands) {
3567
+ for (const subcommand of loadedCommand.command.subcommands) {
3568
+ await this.loadSubcommand(subcommand);
3559
3569
  }
3560
3570
  }
3561
3571
  }
@@ -3579,10 +3589,7 @@ var init_AppCommandHandler = __esm({
3579
3589
  }
3580
3590
  this.loadedMiddlewares.set(id, { middleware, data });
3581
3591
  } catch (error) {
3582
- Logger.error(
3583
- `Failed to load middleware ${middleware.name} (${id})`,
3584
- error
3585
- );
3592
+ Logger.error(`Failed to load middleware ${id}`, error);
3586
3593
  }
3587
3594
  }
3588
3595
  async loadCommand(id, command) {
@@ -3595,11 +3602,9 @@ var init_AppCommandHandler = __esm({
3595
3602
  name: command.name,
3596
3603
  description: `${command.name} commands`,
3597
3604
  type: 1
3598
- // CHAT_INPUT
3599
3605
  }
3600
3606
  }
3601
3607
  });
3602
- this.commandNameToId.set(command.name, id);
3603
3608
  return;
3604
3609
  }
3605
3610
  const data = await import(`${toFileURL(command.path)}?t=${Date.now()}`);
@@ -3638,7 +3643,7 @@ var init_AppCommandHandler = __esm({
3638
3643
  Logger.error(`Failed to load command ${command.name} (${id})`, error);
3639
3644
  }
3640
3645
  }
3641
- async loadSubcommand(id, subcommand) {
3646
+ async loadSubcommand(subcommand) {
3642
3647
  try {
3643
3648
  const data = await import(`${toFileURL(subcommand.path)}?t=${Date.now()}`);
3644
3649
  if (!data.command) {
@@ -3660,44 +3665,33 @@ var init_AppCommandHandler = __esm({
3660
3665
  `Invalid export for subcommand ${subcommand.name}: at least one handler function must be provided`
3661
3666
  );
3662
3667
  }
3663
- const localizedCommand = await this.applyLocalizations({
3664
- ...data.command
3665
- });
3666
- this.loadedSubCommands.set(id, {
3668
+ const localizedCommand = await this.applyLocalizations(
3669
+ { ...data.command },
3670
+ subcommand
3671
+ );
3672
+ const subcommandId = subcommand.command + "/" + subcommand.name;
3673
+ this.loadedSubCommands.set(subcommandId, {
3667
3674
  subcommand,
3668
3675
  data: {
3669
3676
  ...data,
3670
3677
  command: localizedCommand
3671
3678
  }
3672
3679
  });
3673
- const parentCommandId = subcommand.id.split("/")[0];
3674
- if (subcommand.group) {
3675
- this.subcommandPathToId.set(
3676
- `${parentCommandId}/${subcommand.group}/${subcommand.name}`,
3677
- id
3678
- );
3679
- } else {
3680
- this.subcommandPathToId.set(
3681
- `${parentCommandId}/${subcommand.name}`,
3682
- id
3683
- );
3684
- }
3680
+ this.subcommandPathToId.set(subcommandId, subcommandId);
3685
3681
  } catch (error) {
3686
- Logger.error(
3687
- `Failed to load subcommand ${subcommand.name} (${id})`,
3688
- error
3689
- );
3682
+ Logger.error(`Failed to load subcommand ${subcommand.name}`, error);
3690
3683
  }
3691
3684
  }
3692
- async applyLocalizations(command) {
3685
+ async applyLocalizations(command, subcommand) {
3693
3686
  var _a, _b, _c, _d, _e;
3694
3687
  const localization = this.commandkit.config.localizationStrategy;
3695
3688
  const validLocales = Object.values(import_discord10.Locale).filter(
3696
3689
  (v) => typeof v === "string"
3697
3690
  );
3691
+ const localizationKey = subcommand ? command.name.split("/")[0] : command.name;
3698
3692
  for (const locale of validLocales) {
3699
3693
  const translation = await localization.locateTranslation(
3700
- command.name,
3694
+ localizationKey,
3701
3695
  locale
3702
3696
  );
3703
3697
  if (!(translation == null ? void 0 : translation.command)) continue;
@@ -3717,6 +3711,8 @@ var init_AppCommandHandler = __esm({
3717
3711
  let o;
3718
3712
  while (o = opt.shift()) {
3719
3713
  (_c = raw.options) == null ? void 0 : _c.forEach((option) => {
3714
+ var _a2;
3715
+ if (subcommand && option.name !== subcommand.name) return;
3720
3716
  if (option.name === o.ref) {
3721
3717
  if (option.name) {
3722
3718
  option.name_localizations ??= {};
@@ -3726,6 +3722,22 @@ var init_AppCommandHandler = __esm({
3726
3722
  option.description_localizations ??= {};
3727
3723
  option.description_localizations[locale] = o.description;
3728
3724
  }
3725
+ const opts = option.options;
3726
+ if ((opts == null ? void 0 : opts.length) && ((_a2 = o.options) == null ? void 0 : _a2.length)) {
3727
+ o.options.forEach((subOpt) => {
3728
+ const targetOption = opts == null ? void 0 : opts.find(
3729
+ (opt2) => opt2.name === subOpt.name
3730
+ );
3731
+ if (targetOption) {
3732
+ targetOption.name_localizations ??= {};
3733
+ targetOption.name_localizations[locale] = subOpt.name;
3734
+ if ("description" in targetOption) {
3735
+ targetOption.description_localizations ??= {};
3736
+ targetOption.description_localizations[locale] = subOpt.description;
3737
+ }
3738
+ }
3739
+ });
3740
+ }
3729
3741
  }
3730
3742
  });
3731
3743
  }
@@ -3734,12 +3746,10 @@ var init_AppCommandHandler = __esm({
3734
3746
  if (translation.command.name) {
3735
3747
  command.setNameLocalization(locale, translation.command.name);
3736
3748
  }
3737
- const raw = command.toJSON();
3738
- return raw;
3739
3749
  } else {
3740
3750
  command.name_localizations ??= {};
3741
3751
  command.name_localizations[locale] = translation.command.name;
3742
- if (command.description) {
3752
+ if (!subcommand && command.description) {
3743
3753
  command.description_localizations ??= {};
3744
3754
  command.description_localizations[locale] = translation.command.description;
3745
3755
  }
@@ -3748,15 +3758,31 @@ var init_AppCommandHandler = __esm({
3748
3758
  let o;
3749
3759
  while (o = opt.shift()) {
3750
3760
  command.options.forEach((option) => {
3761
+ var _a2;
3762
+ if (subcommand && option.name !== subcommand.name) return;
3751
3763
  if (option.name === o.ref) {
3752
- if (option.name) {
3753
- option.name_localizations ??= {};
3754
- option.name_localizations[locale] = o.name;
3755
- }
3756
- if (option.description) {
3764
+ option.name_localizations ??= {};
3765
+ option.name_localizations[locale] = o.name;
3766
+ if ("description" in option) {
3757
3767
  option.description_localizations ??= {};
3758
3768
  option.description_localizations[locale] = o.description;
3759
3769
  }
3770
+ const opts = option.options;
3771
+ if ((opts == null ? void 0 : opts.length) && ((_a2 = o.options) == null ? void 0 : _a2.length)) {
3772
+ o.options.forEach((subOpt) => {
3773
+ const targetOption = opts == null ? void 0 : opts.find(
3774
+ (opt2) => opt2.name === subOpt.name
3775
+ );
3776
+ if (targetOption) {
3777
+ targetOption.name_localizations ??= {};
3778
+ targetOption.name_localizations[locale] = subOpt.name;
3779
+ if ("description" in targetOption) {
3780
+ targetOption.description_localizations ??= {};
3781
+ targetOption.description_localizations[locale] = subOpt.description;
3782
+ }
3783
+ }
3784
+ });
3785
+ }
3760
3786
  }
3761
3787
  });
3762
3788
  }
@@ -3772,243 +3798,208 @@ var init_AppCommandHandler = __esm({
3772
3798
  });
3773
3799
 
3774
3800
  // src/app/router/CommandsRouter.ts
3775
- var import_discord11, import_node_fs3, import_promises3, import_posix, _CommandsRouter, CommandsRouter;
3801
+ var import_discord11, import_node_fs3, import_node_crypto3, import_walk, import_node_path3, _CommandsRouter, CommandsRouter;
3776
3802
  var init_CommandsRouter = __esm({
3777
3803
  "src/app/router/CommandsRouter.ts"() {
3778
3804
  "use strict";
3779
3805
  init_cjs_shims();
3780
3806
  import_discord11 = require("discord.js");
3781
3807
  import_node_fs3 = require("fs");
3782
- import_promises3 = require("fs/promises");
3783
- import_posix = __toESM(require("path/posix"));
3808
+ import_node_crypto3 = __toESM(require("crypto"));
3809
+ import_walk = __toESM(require("@root/walk"));
3810
+ import_node_path3 = __toESM(require("path"));
3784
3811
  _CommandsRouter = class _CommandsRouter {
3785
3812
  constructor(options) {
3786
3813
  this.options = options;
3787
3814
  }
3788
3815
  commands = new import_discord11.Collection();
3789
3816
  middlewares = new import_discord11.Collection();
3790
- subcommands = new import_discord11.Collection();
3791
- isValidPath() {
3792
- return (0, import_node_fs3.existsSync)(this.entrypoint);
3793
- }
3794
- get entrypoint() {
3795
- return this.options.entrypoint;
3796
- }
3797
- clear() {
3798
- this.commands.clear();
3799
- this.middlewares.clear();
3800
- this.subcommands.clear();
3801
- }
3802
- async reload() {
3803
- this.clear();
3804
- return this.scan();
3817
+ fromData(data) {
3818
+ this.commands = new import_discord11.Collection(
3819
+ Object.entries(data.commands).map(([id, command]) => [id, command])
3820
+ );
3821
+ this.middlewares = new import_discord11.Collection(
3822
+ Object.entries(data.middlewares).map(
3823
+ ([id, middleware]) => [
3824
+ id,
3825
+ middleware
3826
+ ]
3827
+ )
3828
+ );
3805
3829
  }
3806
- visualize() {
3807
- let output = "";
3808
- const commands = [...this.commands.values()];
3809
- commands.forEach((command, index) => {
3810
- const isLast = index === commands.length - 1;
3811
- const prefix = isLast ? "\u2514\u2500" : "\u251C\u2500";
3812
- const childPrefix = isLast ? " " : "\u2502 ";
3813
- const categoryPrefix = command.category ? `[${command.category}] ` : "";
3814
- output += `${prefix} ${categoryPrefix}${command.name}
3815
- `;
3816
- const subcommands = command.subcommands.map((id) => this.subcommands.get(id)).filter(Boolean);
3817
- const groupedSubs = /* @__PURE__ */ new Map();
3818
- subcommands.forEach((sub) => {
3819
- if (!groupedSubs.has(sub.group)) {
3820
- groupedSubs.set(sub.group, []);
3821
- }
3822
- groupedSubs.get(sub.group).push(sub);
3823
- });
3824
- const groups = [...groupedSubs.entries()];
3825
- groups.forEach(([group, subs], groupIndex) => {
3826
- const isLastGroup = groupIndex === groups.length - 1;
3827
- if (group) {
3828
- const groupPrefix = isLastGroup ? `${childPrefix}\u2514\u2500` : `${childPrefix}\u251C\u2500`;
3829
- output += `${groupPrefix} Group: ${group}
3830
- `;
3831
- }
3832
- const subPrefix = group ? `${childPrefix}${isLastGroup ? " " : "\u2502 "}` : childPrefix;
3833
- subs.forEach((subcommand, subIndex) => {
3834
- const isLastSub = subIndex === subs.length - 1;
3835
- const subCommandPrefix = isLastSub ? `${subPrefix}\u2514\u2500` : `${subPrefix}\u251C\u2500`;
3836
- output += `${subCommandPrefix} ${subcommand.name}
3837
- `;
3838
- const middlewares = subcommand.middlewares.map((id) => this.middlewares.get(id)).filter(Boolean);
3839
- middlewares.forEach((middleware, mwIndex) => {
3840
- const isLastMw = mwIndex === middlewares.length - 1;
3841
- const mwPrefix = isLastMw ? `${subPrefix}${isLastSub ? " " : "\u2502 "}\u2514\u2500` : `${subPrefix}${isLastSub ? " " : "\u2502 "}\u251C\u2500`;
3842
- output += `${mwPrefix} \u2699\uFE0F ${middleware.name}
3843
- `;
3844
- });
3845
- });
3846
- });
3847
- const commandMiddlewares = command.middlewares.map((id) => this.middlewares.get(id)).filter(Boolean);
3848
- if (commandMiddlewares.length > 0) {
3849
- output += `${childPrefix}\u2514\u2500 Middlewares:
3850
- `;
3851
- commandMiddlewares.forEach((middleware, mwIndex) => {
3852
- const isLastMw = mwIndex === commandMiddlewares.length - 1;
3853
- const mwPrefix = isLastMw ? `${childPrefix} \u2514\u2500` : `${childPrefix} \u251C\u2500`;
3854
- output += `${mwPrefix} \u2699\uFE0F ${middleware.name}
3855
- `;
3856
- });
3857
- }
3858
- output += "\n";
3859
- });
3860
- return output;
3830
+ isValidPath() {
3831
+ return (0, import_node_fs3.existsSync)(this.options.entrypoint);
3861
3832
  }
3862
3833
  getData() {
3863
3834
  return {
3864
3835
  commands: this.commands,
3865
- middlewares: this.middlewares,
3866
- subcommands: this.subcommands
3836
+ middlewares: this.middlewares
3867
3837
  };
3868
3838
  }
3869
3839
  toJSON() {
3870
3840
  return {
3871
3841
  commands: Object.fromEntries(this.commands.entries()),
3872
- middlewares: Object.fromEntries(this.middlewares.entries()),
3873
- subcommands: Object.fromEntries(this.subcommands.entries())
3842
+ middlewares: Object.fromEntries(this.middlewares.entries())
3874
3843
  };
3875
3844
  }
3845
+ clear() {
3846
+ this.commands.clear();
3847
+ this.middlewares.clear();
3848
+ }
3849
+ reload() {
3850
+ this.clear();
3851
+ return this.scan();
3852
+ }
3876
3853
  async scan() {
3877
- if (!this.isValidPath()) return this.toJSON();
3878
- const root = this.entrypoint;
3879
- await this.scanDeep(root);
3854
+ if (!this.isValidPath()) {
3855
+ throw new Error("Invalid path");
3856
+ }
3857
+ await this.traverse();
3858
+ this.applyBindings();
3880
3859
  return this.toJSON();
3881
3860
  }
3882
- async scanDeep(entry, currentDepth = 2) {
3883
- const normalizedPath = import_posix.default.normalize(entry);
3884
- const content = await (0, import_promises3.readdir)(normalizedPath, { withFileTypes: true });
3885
- for (const item of content) {
3886
- const itemPath = import_posix.default.join(normalizedPath, item.name);
3887
- if (this.shouldIgnore(itemPath, item.isDirectory())) continue;
3888
- if (item.isDirectory()) {
3889
- const isCategoryDir = this.isCategoryDirectory(item.name);
3890
- if (currentDepth > 0 || isCategoryDir) {
3891
- const nextDepth = isCategoryDir ? currentDepth : currentDepth - 1;
3892
- await this.scanDeep(itemPath, nextDepth);
3861
+ async traverse() {
3862
+ const validFile = /\.(c|m)?(j|t)sx?$/;
3863
+ const middleware = /^(\w+\.)?middleware\.(c|m)?(j|t)sx?$/;
3864
+ const categoryDir = /^\((\w+)\)$/;
3865
+ const isCategory = /* @__PURE__ */ __name((name) => categoryDir.test(name), "isCategory");
3866
+ const isMiddleware = /* @__PURE__ */ __name((name) => middleware.test(name), "isMiddleware");
3867
+ const isCommand = /* @__PURE__ */ __name((name) => validFile.test(name) && !isMiddleware(name), "isCommand");
3868
+ await import_walk.default.walk(
3869
+ this.options.entrypoint,
3870
+ async (error, pathname, dirent) => {
3871
+ if (error) throw error;
3872
+ const name = dirent.name;
3873
+ if (dirent.isDirectory()) {
3874
+ if (isCategory(name) && this.distanceFromRoot(pathname) > 1) {
3875
+ throw new Error(
3876
+ `Category directories must be at the root. Found "${name}" at "${pathname}"`
3877
+ );
3878
+ }
3879
+ return;
3893
3880
  }
3894
- } else {
3895
- const isInnerSubCommand = currentDepth === 0;
3896
- const isSubCommandGroup = currentDepth === 1;
3897
- const category = this.extractCategory(itemPath);
3898
- const fileName = this.extractName(itemPath);
3899
- const isIndexFile = fileName === "index" && normalizedPath !== this.entrypoint;
3900
- if (this.isMiddleware(itemPath)) {
3901
- this.processMiddleware(itemPath, category);
3902
- } else if (isInnerSubCommand || isSubCommandGroup) {
3903
- this.processSubcommand(
3904
- itemPath,
3905
- import_posix.default.basename(normalizedPath),
3906
- isSubCommandGroup,
3907
- isIndexFile
3908
- );
3909
- } else {
3910
- this.processCommand(
3911
- itemPath,
3912
- category,
3913
- isIndexFile ? normalizedPath : null
3881
+ if (this.distanceFromRoot(pathname, true) > 1) return;
3882
+ if (isMiddleware(name)) {
3883
+ const middleware2 = {
3884
+ id: import_node_crypto3.default.randomUUID(),
3885
+ path: pathname,
3886
+ relativePath: this.toRelativePath(pathname)
3887
+ };
3888
+ this.middlewares.set(middleware2.id, middleware2);
3889
+ return;
3890
+ }
3891
+ if (!isCommand(name)) return;
3892
+ const command = {
3893
+ id: import_node_crypto3.default.randomUUID(),
3894
+ name: this.parseFileName(name),
3895
+ category: this.parseCategory(pathname),
3896
+ middlewareIds: [],
3897
+ path: pathname,
3898
+ relativePath: this.toRelativePath(pathname),
3899
+ subcommands: []
3900
+ };
3901
+ this.commands.set(command.id, command);
3902
+ }
3903
+ );
3904
+ await import_walk.default.walk(
3905
+ this.options.entrypoint,
3906
+ async (error, pathname, dirent) => {
3907
+ if (error) throw error;
3908
+ const name = dirent.name;
3909
+ if (dirent.isDirectory()) return;
3910
+ if (this.distanceFromRoot(pathname, true) <= 1) return;
3911
+ if (isMiddleware(name)) {
3912
+ const middleware2 = {
3913
+ id: import_node_crypto3.default.randomUUID(),
3914
+ path: pathname,
3915
+ relativePath: this.toRelativePath(pathname)
3916
+ };
3917
+ this.middlewares.set(middleware2.id, middleware2);
3918
+ return;
3919
+ }
3920
+ if (!isCommand(name)) return;
3921
+ let currentDir = import_node_path3.default.dirname(pathname);
3922
+ let parentCommand;
3923
+ while (currentDir !== this.options.entrypoint) {
3924
+ const dirName = import_node_path3.default.basename(currentDir);
3925
+ parentCommand = Array.from(this.commands.values()).find(
3926
+ (cmd) => import_node_path3.default.basename(import_node_path3.default.dirname(cmd.path)) === import_node_path3.default.basename(import_node_path3.default.dirname(currentDir)) && this.parseFileName(cmd.path) === dirName
3914
3927
  );
3928
+ if (parentCommand) break;
3929
+ currentDir = import_node_path3.default.dirname(currentDir);
3930
+ }
3931
+ if (parentCommand) {
3932
+ const subcommand = {
3933
+ name: this.parseFileName(name),
3934
+ group: this.parseGroup(pathname),
3935
+ path: pathname,
3936
+ relativePath: this.toRelativePath(pathname),
3937
+ command: parentCommand.id
3938
+ };
3939
+ parentCommand.subcommands.push(subcommand);
3915
3940
  }
3916
3941
  }
3917
- }
3918
- }
3919
- processMiddleware(filePath, category) {
3920
- const middleware = {
3921
- id: crypto.randomUUID(),
3922
- name: this.getAppropriateFileName(filePath),
3923
- path: filePath,
3924
- relativePath: this.getRelativePath(filePath),
3925
- category
3926
- };
3927
- this.middlewares.set(middleware.id, middleware);
3928
- this.applyMiddlewareToCommands(middleware);
3929
- }
3930
- processSubcommand(filePath, parentDirName, isGrouped, isIndexFile = false) {
3931
- const subcommand = {
3932
- id: crypto.randomUUID(),
3933
- name: isIndexFile ? this.getDirectoryName(filePath) : this.extractName(filePath),
3934
- group: isGrouped ? parentDirName : null,
3935
- middlewares: [],
3936
- path: filePath,
3937
- relativePath: this.getRelativePath(filePath)
3938
- };
3939
- this.subcommands.set(subcommand.id, subcommand);
3940
- this.applySubcommandToCommands(subcommand);
3941
- }
3942
- processCommand(filePath, category, parentPath = null) {
3943
- const command = {
3944
- id: crypto.randomUUID(),
3945
- name: parentPath ? this.getDirectoryName(parentPath) : this.extractName(filePath),
3946
- path: filePath,
3947
- relativePath: this.getRelativePath(filePath),
3948
- category,
3949
- middlewares: [],
3950
- subcommands: []
3951
- };
3952
- this.commands.set(command.id, command);
3942
+ );
3953
3943
  }
3954
- /**
3955
- * Gets the appropriate file name, handling index files specially
3956
- * For index files, it returns the parent directory name (excluding category markers)
3957
- */
3958
- getAppropriateFileName(filePath) {
3959
- const fileName = this.extractName(filePath);
3960
- if (fileName === "index" && import_posix.default.dirname(filePath) !== this.entrypoint) {
3961
- return this.getDirectoryName(filePath);
3944
+ applyBindings() {
3945
+ for (const command of this.commands.values()) {
3946
+ const commandName = command.name;
3947
+ const commandDir = import_node_path3.default.dirname(command.path);
3948
+ for (const middleware of this.middlewares.values()) {
3949
+ const middlewareDir = import_node_path3.default.dirname(middleware.path);
3950
+ const middlewareFileName = import_node_path3.default.basename(middleware.path);
3951
+ const isCommandSpecificMiddleware = middlewareFileName.startsWith(
3952
+ commandName + "."
3953
+ );
3954
+ const isSharedMiddleware = middlewareFileName === "middleware.ts" || middlewareFileName === "middleware.js";
3955
+ if (isCommandSpecificMiddleware && middlewareFileName.startsWith(commandName + ".")) {
3956
+ command.middlewareIds.push(middleware.id);
3957
+ continue;
3958
+ }
3959
+ if (isSharedMiddleware) {
3960
+ const relPath = import_node_path3.default.relative(middlewareDir, commandDir);
3961
+ if (!relPath.startsWith("..") && !import_node_path3.default.isAbsolute(relPath)) {
3962
+ command.middlewareIds.push(middleware.id);
3963
+ }
3964
+ }
3965
+ }
3962
3966
  }
3963
- return fileName;
3964
3967
  }
3965
- /**
3966
- * Extract the clean directory name, removing any category markers
3967
- */
3968
- getDirectoryName(filePath) {
3969
- const dirName = import_posix.default.basename(import_posix.default.dirname(filePath));
3970
- return dirName.replace(/^\((\w+)\)$/, "$1");
3971
- }
3972
- // Helper method to identify category directories
3973
- isCategoryDirectory(dirName) {
3974
- return /^\(\w+\)$/.test(dirName);
3968
+ distanceFromRoot(pathname, isFile = false) {
3969
+ const entrypointParts = this.options.entrypoint.split(import_node_path3.default.sep);
3970
+ const pathParts = (!isFile ? pathname : import_node_path3.default.dirname(pathname)).split(
3971
+ import_node_path3.default.sep
3972
+ );
3973
+ const relativeParts = pathParts.slice(entrypointParts.length);
3974
+ return relativeParts.filter((part) => !part.match(/^\(.*\)$/)).length;
3975
3975
  }
3976
- applyMiddlewareToCommands(middleware) {
3977
- for (const command of this.commands.values()) {
3978
- const middlewareFileName = import_posix.default.basename(middleware.path);
3979
- const match = middlewareFileName.startsWith(command.name) || middlewareFileName === "middleware";
3980
- if (!match) continue;
3981
- if (command.middlewares.includes(middleware.id)) continue;
3982
- command.middlewares.push(middleware.id);
3976
+ parseGroup(pathname) {
3977
+ const parts = pathname.split(import_node_path3.default.sep);
3978
+ const parentDirIndex = parts.findIndex(
3979
+ (part) => this.commands.some((cmd) => cmd.name === part)
3980
+ );
3981
+ if (parentDirIndex === -1) return null;
3982
+ const groupName = parts[parts.length - 2];
3983
+ if (!groupName || groupName === parts[parentDirIndex] || groupName.match(/^\(.*\)$/)) {
3984
+ return null;
3983
3985
  }
3984
- }
3985
- applySubcommandToCommands(subcommand) {
3986
- for (const command of this.commands.values()) {
3987
- if (!subcommand.path.startsWith(command.path)) continue;
3988
- if (command.subcommands.includes(subcommand.id)) continue;
3989
- command.subcommands.push(subcommand.id);
3986
+ return groupName;
3987
+ }
3988
+ parseCategory(pathname) {
3989
+ const parts = pathname.split(import_node_path3.default.sep);
3990
+ const entrypointParts = this.options.entrypoint.split(import_node_path3.default.sep);
3991
+ const relativeIndex = entrypointParts.length;
3992
+ const categoryDir = parts[relativeIndex];
3993
+ if (!categoryDir || !/^\((\w+)\)$/.test(categoryDir)) {
3994
+ return null;
3990
3995
  }
3996
+ return categoryDir.slice(1, -1);
3991
3997
  }
3992
- extractCategory(entry) {
3993
- return entry.split(import_posix.default.sep).map((segment) => {
3994
- const match = segment.match(/^\((\w+)\)$/);
3995
- return match ? match[1] : null;
3996
- }).filter(Boolean).join(":");
3997
- }
3998
- getRelativePath(entry) {
3999
- return import_posix.default.relative(this.entrypoint, entry);
4000
- }
4001
- isMiddleware(entry) {
4002
- return !this.shouldIgnore(entry) && ["middleware", ".middleware."].some((ext) => entry.includes(ext));
4003
- }
4004
- shouldIgnore(entry, dir = false) {
4005
- const fileName = import_posix.default.basename(entry);
4006
- if (fileName.startsWith("_")) return true;
4007
- if (!dir) return !/.(c|m)?(j|t)sx?$/.test(fileName);
4008
- return false;
3998
+ parseFileName(filename) {
3999
+ return import_node_path3.default.basename(filename, import_node_path3.default.extname(filename));
4009
4000
  }
4010
- extractName(entry) {
4011
- return import_posix.default.basename(entry).replace(/\.(c|m)?(j|t)sx?$/, "");
4001
+ toRelativePath(pathname) {
4002
+ return import_node_path3.default.relative(this.options.entrypoint, pathname);
4012
4003
  }
4013
4004
  };
4014
4005
  __name(_CommandsRouter, "CommandsRouter");
@@ -4017,14 +4008,14 @@ var init_CommandsRouter = __esm({
4017
4008
  });
4018
4009
 
4019
4010
  // src/app/router/EventsRouter.ts
4020
- var import_node_fs4, import_promises4, import_node_path3, _EventsRouter, EventsRouter;
4011
+ var import_node_fs4, import_promises3, import_node_path4, _EventsRouter, EventsRouter;
4021
4012
  var init_EventsRouter = __esm({
4022
4013
  "src/app/router/EventsRouter.ts"() {
4023
4014
  "use strict";
4024
4015
  init_cjs_shims();
4025
4016
  import_node_fs4 = require("fs");
4026
- import_promises4 = require("fs/promises");
4027
- import_node_path3 = require("path");
4017
+ import_promises3 = require("fs/promises");
4018
+ import_node_path4 = require("path");
4028
4019
  _EventsRouter = class _EventsRouter {
4029
4020
  /**
4030
4021
  * Creates a new EventsRouter instance
@@ -4079,10 +4070,10 @@ var init_EventsRouter = __esm({
4079
4070
  * @returns Promise resolving to the events tree
4080
4071
  */
4081
4072
  async scan() {
4082
- const dirs = await (0, import_promises4.readdir)(this.entrypoint, { withFileTypes: true });
4073
+ const dirs = await (0, import_promises3.readdir)(this.entrypoint, { withFileTypes: true });
4083
4074
  for (const dir of dirs) {
4084
4075
  if (dir.isDirectory()) {
4085
- const path3 = (0, import_node_path3.join)(this.entrypoint, dir.name);
4076
+ const path3 = (0, import_node_path4.join)(this.entrypoint, dir.name);
4086
4077
  const event = await this.scanEvent(dir.name, path3);
4087
4078
  this.events.set(event.event, event);
4088
4079
  }
@@ -4105,16 +4096,16 @@ var init_EventsRouter = __esm({
4105
4096
  */
4106
4097
  async scanEvent(event, path3, listeners = []) {
4107
4098
  var _a;
4108
- const files = await (0, import_promises4.readdir)(path3, { withFileTypes: true });
4099
+ const files = await (0, import_promises3.readdir)(path3, { withFileTypes: true });
4109
4100
  for (const file of files) {
4110
4101
  if (/node_modules/.test(file.name)) continue;
4111
4102
  if (file.isDirectory()) {
4112
- const nextPath = (0, import_node_path3.join)(path3, file.name);
4103
+ const nextPath = (0, import_node_path4.join)(path3, file.name);
4113
4104
  await this.scanEvent(event, nextPath, listeners);
4114
4105
  continue;
4115
4106
  }
4116
4107
  if (file.isFile() && /\.(m|c)?(j|t)sx?$/.test(file.name)) {
4117
- listeners.push((0, import_node_path3.join)(file.parentPath, file.name));
4108
+ listeners.push((0, import_node_path4.join)(file.parentPath, file.name));
4118
4109
  }
4119
4110
  }
4120
4111
  const maybeNamespace = path3.replace(this.entrypoint, "").replaceAll("\\", "/").split("/").shift();
@@ -4291,12 +4282,12 @@ var init_AppEventsHandler = __esm({
4291
4282
 
4292
4283
  // src/utils/types-package.ts
4293
4284
  async function generateTypesPackage() {
4294
- const location = (0, import_node_path4.join)(process.cwd(), "node_modules", "commandkit-types");
4295
- const packageJSON = (0, import_node_path4.join)(location, "package.json");
4296
- const index = (0, import_node_path4.join)(location, "index.js");
4297
- const types = (0, import_node_path4.join)(location, "index.d.ts");
4298
- const locale = (0, import_node_path4.join)(location, "locale.d.ts");
4299
- const command = (0, import_node_path4.join)(location, "command.d.ts");
4285
+ const location = (0, import_node_path5.join)(process.cwd(), "node_modules", "commandkit-types");
4286
+ const packageJSON = (0, import_node_path5.join)(location, "package.json");
4287
+ const index = (0, import_node_path5.join)(location, "index.js");
4288
+ const types = (0, import_node_path5.join)(location, "index.d.ts");
4289
+ const locale = (0, import_node_path5.join)(location, "locale.d.ts");
4290
+ const command = (0, import_node_path5.join)(location, "command.d.ts");
4300
4291
  const exists = (0, import_node_fs5.existsSync)(packageJSON);
4301
4292
  if (exists) return location;
4302
4293
  const packageJSONContent = {
@@ -4317,22 +4308,22 @@ async function generateTypesPackage() {
4317
4308
  command: CommandTypeData;
4318
4309
  }
4319
4310
  }`;
4320
- await (0, import_promises5.mkdir)(location, { recursive: true });
4321
- await (0, import_promises5.writeFile)(packageJSON, JSON.stringify(packageJSONContent, null, 2));
4322
- await (0, import_promises5.writeFile)(index, indexContent);
4323
- await (0, import_promises5.writeFile)(types, typesContent);
4324
- await (0, import_promises5.writeFile)(locale, "");
4325
- await (0, import_promises5.writeFile)(command, "");
4311
+ await (0, import_promises4.mkdir)(location, { recursive: true });
4312
+ await (0, import_promises4.writeFile)(packageJSON, JSON.stringify(packageJSONContent, null, 2));
4313
+ await (0, import_promises4.writeFile)(index, indexContent);
4314
+ await (0, import_promises4.writeFile)(types, typesContent);
4315
+ await (0, import_promises4.writeFile)(locale, "");
4316
+ await (0, import_promises4.writeFile)(command, "");
4326
4317
  return location;
4327
4318
  }
4328
- var import_node_fs5, import_promises5, import_node_path4;
4319
+ var import_node_fs5, import_promises4, import_node_path5;
4329
4320
  var init_types_package = __esm({
4330
4321
  "src/utils/types-package.ts"() {
4331
4322
  "use strict";
4332
4323
  init_cjs_shims();
4333
4324
  import_node_fs5 = require("fs");
4334
- import_promises5 = require("fs/promises");
4335
- import_node_path4 = require("path");
4325
+ import_promises4 = require("fs/promises");
4326
+ import_node_path5 = require("path");
4336
4327
  __name(generateTypesPackage, "generateTypesPackage");
4337
4328
  }
4338
4329
  });
@@ -4374,7 +4365,7 @@ async function loadConfigFileFromPath(target) {
4374
4365
  fileName: target
4375
4366
  });
4376
4367
  const nodeModulesPath = await generateTypesPackage();
4377
- const tmpFile = (0, import_node_path5.join)(nodeModulesPath, "compiled-commandkit.config.mjs");
4368
+ const tmpFile = (0, import_node_path6.join)(nodeModulesPath, "compiled-commandkit.config.mjs");
4378
4369
  import_node_fs6.default.writeFileSync(tmpFile, outputText);
4379
4370
  target = tmpFile;
4380
4371
  }
@@ -4389,13 +4380,13 @@ async function ensureExists(loc) {
4389
4380
  throw new Error(`File not found: ${loc}`);
4390
4381
  }
4391
4382
  }
4392
- var import_rimraf, import_node_path5, import_node_fs6, ts;
4383
+ var import_rimraf, import_node_path6, import_node_fs6, ts;
4393
4384
  var init_common = __esm({
4394
4385
  "src/cli/common.ts"() {
4395
4386
  "use strict";
4396
4387
  init_cjs_shims();
4397
4388
  import_rimraf = require("rimraf");
4398
- import_node_path5 = require("path");
4389
+ import_node_path6 = require("path");
4399
4390
  import_node_fs6 = __toESM(require("fs"));
4400
4391
  init_colors();
4401
4392
  init_types_package();
@@ -4409,7 +4400,7 @@ var init_common = __esm({
4409
4400
 
4410
4401
  // src/config/loader.ts
4411
4402
  function findConfigFile(cwd) {
4412
- const locations = CONFIG_FILE_NAMES.map((name) => (0, import_node_path6.join)(cwd, name));
4403
+ const locations = CONFIG_FILE_NAMES.map((name) => (0, import_node_path7.join)(cwd, name));
4413
4404
  for (const location of locations) {
4414
4405
  if ((0, import_node_fs7.existsSync)(location)) {
4415
4406
  return {
@@ -4428,13 +4419,13 @@ async function loadConfigFile(entrypoint = process.cwd()) {
4428
4419
  loadedConfig = config;
4429
4420
  return config;
4430
4421
  }
4431
- var import_node_fs7, import_node_path6, CONFIG_FILE_NAMES, loadedConfig;
4422
+ var import_node_fs7, import_node_path7, CONFIG_FILE_NAMES, loadedConfig;
4432
4423
  var init_loader = __esm({
4433
4424
  "src/config/loader.ts"() {
4434
4425
  "use strict";
4435
4426
  init_cjs_shims();
4436
4427
  import_node_fs7 = require("fs");
4437
- import_node_path6 = require("path");
4428
+ import_node_path7 = require("path");
4438
4429
  init_common();
4439
4430
  init_config();
4440
4431
  CONFIG_FILE_NAMES = [
@@ -4529,7 +4520,7 @@ var init_CommandKitEventsChannel = __esm({
4529
4520
  });
4530
4521
 
4531
4522
  // src/CommandKit.ts
4532
- var import_node_events2, import_discord12, import_node_path7, _started, _CommandKit_instances, init_fn, initCommands_fn, initEvents_fn, _CommandKit, CommandKit;
4523
+ var import_node_events2, import_discord12, import_node_path8, import_node_fs8, _started, _CommandKit_instances, init_fn, initCommands_fn, initEvents_fn, _CommandKit, CommandKit;
4533
4524
  var init_CommandKit = __esm({
4534
4525
  "src/CommandKit.ts"() {
4535
4526
  "use strict";
@@ -4543,7 +4534,7 @@ var init_CommandKit = __esm({
4543
4534
  import_discord12 = require("discord.js");
4544
4535
  init_DefaultLocalizationStrategy();
4545
4536
  init_utilities();
4546
- import_node_path7 = require("path");
4537
+ import_node_path8 = require("path");
4547
4538
  init_AppCommandHandler();
4548
4539
  init_router();
4549
4540
  init_AppEventsHandler();
@@ -4551,6 +4542,7 @@ var init_CommandKit = __esm({
4551
4542
  init_loader();
4552
4543
  init_constants();
4553
4544
  init_dev_hooks();
4545
+ import_node_fs8 = require("fs");
4554
4546
  init_CommandKitEventsChannel();
4555
4547
  init_plugins();
4556
4548
  init_types_package();
@@ -4626,11 +4618,6 @@ var init_CommandKit = __esm({
4626
4618
  await this.loadPlugins();
4627
4619
  await __privateMethod(this, _CommandKit_instances, init_fn).call(this);
4628
4620
  this.incrementClientListenersCount();
4629
- if (token !== false && !this.options.client.isReady()) {
4630
- await this.options.client.login(
4631
- token ?? process.env.TOKEN ?? process.env.DISCORD_TOKEN
4632
- );
4633
- }
4634
4621
  __privateSet(this, _started, true);
4635
4622
  await this.commandHandler.registrar.register();
4636
4623
  }
@@ -4772,11 +4759,11 @@ var init_CommandKit = __esm({
4772
4759
  if (!appDir2) return null;
4773
4760
  switch (to) {
4774
4761
  case "locales":
4775
- return (0, import_node_path7.join)(appDir2, "locales");
4762
+ return (0, import_node_path8.join)(appDir2, "locales");
4776
4763
  case "commands":
4777
- return (0, import_node_path7.join)(appDir2, "commands");
4764
+ return (0, import_node_path8.join)(appDir2, "commands");
4778
4765
  case "events":
4779
- return (0, import_node_path7.join)(appDir2, "events");
4766
+ return (0, import_node_path8.join)(appDir2, "events");
4780
4767
  default:
4781
4768
  return to;
4782
4769
  }
@@ -4800,10 +4787,12 @@ var init_CommandKit = __esm({
4800
4787
  }, "#init");
4801
4788
  initCommands_fn = /* @__PURE__ */ __name(async function() {
4802
4789
  if (this.commandsRouter.isValidPath()) {
4803
- await this.commandsRouter.scan();
4790
+ const result = await this.commandsRouter.scan();
4804
4791
  if (COMMANDKIT_IS_DEV) {
4805
- const visual = this.commandsRouter.visualize();
4806
- console.log(visual);
4792
+ (0, import_node_fs8.writeFileSync)(
4793
+ "./.commandkit/commands.json",
4794
+ JSON.stringify(result, null, 2)
4795
+ );
4807
4796
  }
4808
4797
  }
4809
4798
  await this.commandHandler.loadCommands();
@@ -4833,7 +4822,7 @@ var init_version = __esm({
4833
4822
  "use strict";
4834
4823
  init_cjs_shims();
4835
4824
  version = /* @__MACRO__ $version */
4836
- "0.1.11-dev.20250307192025";
4825
+ "0.1.11-dev.20250308122630";
4837
4826
  }
4838
4827
  });
4839
4828
 
@@ -4875,7 +4864,7 @@ function getStdio(supportsCommands) {
4875
4864
  }
4876
4865
  function createAppProcess(fileName, cwd, isDev) {
4877
4866
  var _a, _b;
4878
- if (!(0, import_node_fs8.existsSync)((0, import_node_path8.join)(cwd, fileName))) {
4867
+ if (!(0, import_node_fs9.existsSync)((0, import_node_path9.join)(cwd, fileName))) {
4879
4868
  panic(`Could not locate the entrypoint file: ${fileName}`);
4880
4869
  }
4881
4870
  const stdio = getStdio(isDev);
@@ -4897,15 +4886,15 @@ function createAppProcess(fileName, cwd, isDev) {
4897
4886
  (_b = ps.stderr) == null ? void 0 : _b.pipe(process.stderr);
4898
4887
  return ps;
4899
4888
  }
4900
- var import_node_child_process, import_node_path8, import_node_fs8;
4889
+ var import_node_child_process, import_node_path9, import_node_fs9;
4901
4890
  var init_app_process = __esm({
4902
4891
  "src/cli/app-process.ts"() {
4903
4892
  "use strict";
4904
4893
  init_cjs_shims();
4905
4894
  import_node_child_process = require("child_process");
4906
4895
  init_env();
4907
- import_node_path8 = require("path");
4908
- import_node_fs8 = require("fs");
4896
+ import_node_path9 = require("path");
4897
+ import_node_fs9 = require("fs");
4909
4898
  init_common();
4910
4899
  __name(getStdio, "getStdio");
4911
4900
  __name(createAppProcess, "createAppProcess");
@@ -4992,9 +4981,9 @@ async function main() {
4992
4981
  await main();
4993
4982
  `;
4994
4983
  const dist = isDev ? ".commandkit" : distDir || "dist";
4995
- await (0, import_promises6.writeFile)((0, import_node_path9.join)(configPath, dist, "index.js"), code);
4984
+ await (0, import_promises5.writeFile)((0, import_node_path10.join)(configPath, dist, "index.js"), code);
4996
4985
  }
4997
- var import_tsup, import_promises6, import_node_path9, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4986
+ var import_tsup, import_promises5, import_node_path10, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4998
4987
  var init_build = __esm({
4999
4988
  "src/cli/build.ts"() {
5000
4989
  "use strict";
@@ -5002,8 +4991,8 @@ var init_build = __esm({
5002
4991
  import_tsup = require("tsup");
5003
4992
  init_plugins();
5004
4993
  init_loader();
5005
- import_promises6 = require("fs/promises");
5006
- import_node_path9 = require("path");
4994
+ import_promises5 = require("fs/promises");
4995
+ import_node_path10 = require("path");
5007
4996
  init_env();
5008
4997
  __name(buildApplication, "buildApplication");
5009
4998
  envScript = /* @__PURE__ */ __name((dev) => `// --- Environment Variables Loader ---
@@ -5147,7 +5136,7 @@ async function bootstrapDevelopmentServer(configPath) {
5147
5136
  watcher.on("add", hmrHandler);
5148
5137
  watcher.on("unlink", hmrHandler);
5149
5138
  watcher.on("unlinkDir", (path3) => {
5150
- const hasChild = (0, import_node_fs9.readdirSync)(path3).length > 0;
5139
+ const hasChild = (0, import_node_fs10.readdirSync)(path3).length > 0;
5151
5140
  if (hasChild) return hmrHandler(path3);
5152
5141
  });
5153
5142
  watcher.on("error", (e) => {
@@ -5166,7 +5155,7 @@ ${colors_default.yellowBright("re")} - Reload all events
5166
5155
  ${colors_default.yellowBright("rl")} - Reload all locales`
5167
5156
  );
5168
5157
  }
5169
- var import_path2, import_chokidar, import_node_fs9, isCommandSource, isEventSource, isLocaleSource;
5158
+ var import_path2, import_chokidar, import_node_fs10, isCommandSource, isEventSource, isLocaleSource;
5170
5159
  var init_development = __esm({
5171
5160
  "src/cli/development.ts"() {
5172
5161
  "use strict";
@@ -5177,7 +5166,7 @@ var init_development = __esm({
5177
5166
  init_app_process();
5178
5167
  init_build();
5179
5168
  import_chokidar = require("chokidar");
5180
- import_node_fs9 = require("fs");
5169
+ import_node_fs10 = require("fs");
5181
5170
  init_utilities();
5182
5171
  init_colors();
5183
5172
  __name(buildAndStart, "buildAndStart");
@@ -5264,7 +5253,7 @@ __export(generators_exports, {
5264
5253
  });
5265
5254
  async function generateCommand(name, customPath) {
5266
5255
  const cmdPath = (0, import_path4.join)(customPath || COMMANDS_DIR, name);
5267
- if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises7.mkdir)(cmdPath, { recursive: true });
5256
+ if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises6.mkdir)(cmdPath, { recursive: true });
5268
5257
  if ((0, import_fs2.existsSync)((0, import_path4.join)(cmdPath, "command.ts"))) {
5269
5258
  panic(`Command ${name} already exists.`);
5270
5259
  }
@@ -5284,7 +5273,7 @@ export const message: MessageCommand = async (ctx) => {
5284
5273
  await ctx.message.reply('Hello from ${name}!');
5285
5274
  };
5286
5275
  `.trim();
5287
- await (0, import_promises7.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5276
+ await (0, import_promises6.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5288
5277
  console.log(
5289
5278
  colors_default.green(
5290
5279
  `Command ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(cmdPath))}/command.ts`
@@ -5293,10 +5282,10 @@ export const message: MessageCommand = async (ctx) => {
5293
5282
  }
5294
5283
  async function generateEvent(name, customPath) {
5295
5284
  const eventPath = (0, import_path4.join)(customPath || EVENTS_DIR, name);
5296
- if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises7.mkdir)(eventPath, { recursive: true });
5285
+ if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises6.mkdir)(eventPath, { recursive: true });
5297
5286
  let filename = "event.ts";
5298
5287
  if ((0, import_fs2.existsSync)((0, import_path4.join)(eventPath, filename))) {
5299
- const count = (await (0, import_promises7.readdir)(eventPath)).length;
5288
+ const count = (await (0, import_promises6.readdir)(eventPath)).length;
5300
5289
  filename = `${String(count).padStart(2, "0")}_${filename}`;
5301
5290
  }
5302
5291
  const eventFile = `
@@ -5304,7 +5293,7 @@ export default async function on${name[0].toUpperCase() + name.slice(1)}() {
5304
5293
  console.log('${name} event fired!');
5305
5294
  };
5306
5295
  `.trim();
5307
- await (0, import_promises7.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5296
+ await (0, import_promises6.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5308
5297
  console.log(
5309
5298
  colors_default.green(
5310
5299
  `Event ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(eventPath))}/${colors_default.magenta(filename)}`
@@ -5322,7 +5311,7 @@ async function generateLocale(locale, commandName, customPath) {
5322
5311
  panic("Command name is required.");
5323
5312
  }
5324
5313
  const localePath = (0, import_path4.join)(customPath || LOCALES_DIR, locale);
5325
- if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises7.mkdir)(localePath, { recursive: true });
5314
+ if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises6.mkdir)(localePath, { recursive: true });
5326
5315
  if ((0, import_fs2.existsSync)((0, import_path4.join)(localePath, `${commandName}.json`))) {
5327
5316
  panic(`Locale file for ${commandName} already exists.`);
5328
5317
  }
@@ -5333,7 +5322,7 @@ async function generateLocale(locale, commandName, customPath) {
5333
5322
  },
5334
5323
  translations: {}
5335
5324
  };
5336
- await (0, import_promises7.writeFile)(
5325
+ await (0, import_promises6.writeFile)(
5337
5326
  (0, import_path4.join)(localePath, `${commandName}.json`),
5338
5327
  JSON.stringify(localeFile, null, 2)
5339
5328
  );
@@ -5345,12 +5334,12 @@ async function generateLocale(locale, commandName, customPath) {
5345
5334
  )
5346
5335
  );
5347
5336
  }
5348
- var import_promises7, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5337
+ var import_promises6, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5349
5338
  var init_generators = __esm({
5350
5339
  "src/cli/generators.ts"() {
5351
5340
  "use strict";
5352
5341
  init_cjs_shims();
5353
- import_promises7 = require("fs/promises");
5342
+ import_promises6 = require("fs/promises");
5354
5343
  import_path4 = require("path");
5355
5344
  import_discord13 = require("discord.js");
5356
5345
  init_common();