commandkit 0.1.11-dev.20250308073818 → 0.1.11-dev.20250308130523

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
@@ -41,9 +41,9 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
41
41
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
42
42
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
43
43
 
44
- // ../../node_modules/.pnpm/tsup@8.4.0_jiti@1.21.7_postcss@8.4.49_tsx@4.19.2_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js
44
+ // ../../node_modules/.pnpm/tsup@8.4.0_jiti@1.21.7_postcss@8.5.3_tsx@4.19.2_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js
45
45
  var init_cjs_shims = __esm({
46
- "../../node_modules/.pnpm/tsup@8.4.0_jiti@1.21.7_postcss@8.4.49_tsx@4.19.2_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js"() {
46
+ "../../node_modules/.pnpm/tsup@8.4.0_jiti@1.21.7_postcss@8.5.3_tsx@4.19.2_typescript@5.7.3_yaml@2.7.0/node_modules/tsup/assets/cjs_shims.js"() {
47
47
  "use strict";
48
48
  }
49
49
  });
@@ -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,303 +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, path2, _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
- path2 = __toESM(require("path"));
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 = 3) {
3883
- const normalizedPath = path2.normalize(entry);
3884
- const content = await (0, import_promises3.readdir)(normalizedPath, { withFileTypes: true });
3885
- const isRootOrDirectSubdir = normalizedPath === this.entrypoint || path2.dirname(normalizedPath) === this.entrypoint || // Check if parent directories between this and entrypoint are all category directories
3886
- this.getPathSegmentsBetween(normalizedPath, this.entrypoint).every(
3887
- (segment) => this.isCategoryDirectory(segment)
3888
- );
3889
- const effectiveDepth = isRootOrDirectSubdir ? 3 : currentDepth;
3890
- for (const item of content) {
3891
- const itemPath = path2.join(normalizedPath, item.name);
3892
- if (this.shouldIgnore(itemPath, item.isDirectory())) continue;
3893
- if (item.isDirectory()) {
3894
- const isCategoryDir = this.isCategoryDirectory(item.name);
3895
- if (isCategoryDir || effectiveDepth >= 0) {
3896
- const nextDepth = isCategoryDir ? effectiveDepth : effectiveDepth - 1;
3897
- 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;
3898
3880
  }
3899
- } else {
3900
- const category = this.extractCategory(itemPath);
3901
- const fileName = this.extractName(itemPath);
3902
- const isIndexFile = fileName === "index";
3903
- if (this.isMiddleware(itemPath)) {
3904
- this.processMiddleware(itemPath, category);
3905
- } else if (effectiveDepth <= 1) {
3906
- this.processSubcommand(
3907
- itemPath,
3908
- path2.basename(normalizedPath),
3909
- effectiveDepth === 0,
3910
- // isSubCommandGroup when depth is 0
3911
- isIndexFile,
3912
- effectiveDepth,
3913
- category
3914
- );
3915
- } else {
3916
- this.processCommand(
3917
- itemPath,
3918
- category,
3919
- isIndexFile ? normalizedPath : null
3920
- );
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;
3921
3890
  }
3922
- }
3923
- }
3924
- }
3925
- /**
3926
- * Gets path segments between two paths, excluding the start and end paths
3927
- * Used to check if all directories between a path and the entrypoint are category directories
3928
- */
3929
- getPathSegmentsBetween(path1, path22) {
3930
- const normalizedPath1 = path2.normalize(path1);
3931
- const normalizedPath2 = path2.normalize(path22);
3932
- if (normalizedPath1 === normalizedPath2) return [];
3933
- const relativePath = path2.relative(normalizedPath2, normalizedPath1);
3934
- return relativePath.split(path2.sep).filter((segment) => segment !== "." && segment !== "..");
3935
- }
3936
- processMiddleware(filePath, category) {
3937
- const middleware = {
3938
- id: crypto.randomUUID(),
3939
- name: this.getAppropriateFileName(filePath),
3940
- path: filePath,
3941
- relativePath: this.getRelativePath(filePath),
3942
- category
3943
- };
3944
- this.middlewares.set(middleware.id, middleware);
3945
- this.applyMiddlewareToCommands(middleware);
3946
- }
3947
- processSubcommand(filePath, parentDirName, isGrouped, isIndexFile = false, depth, category) {
3948
- if (isIndexFile) {
3949
- const cleanParentDirName = this.extractDirOmitCategory(parentDirName);
3950
- const parentCommand = this.commands.find((cmd) => {
3951
- return cmd.name === cleanParentDirName;
3952
- });
3953
- if (!parentCommand) {
3891
+ if (!isCommand(name)) return;
3954
3892
  const command = {
3955
- id: crypto.randomUUID(),
3956
- name: cleanParentDirName,
3957
- category,
3958
- middlewares: [],
3959
- path: filePath,
3960
- relativePath: this.getRelativePath(filePath),
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),
3961
3899
  subcommands: []
3962
3900
  };
3963
3901
  this.commands.set(command.id, command);
3964
3902
  }
3965
- } else {
3966
- const subcommand = {
3967
- id: crypto.randomUUID(),
3968
- name: this.extractName(filePath),
3969
- // For subcommands, the group is the directory name (excluding category markers)
3970
- group: isGrouped ? this.extractDirOmitCategory(parentDirName) : null,
3971
- middlewares: [],
3972
- path: filePath,
3973
- category,
3974
- relativePath: this.getRelativePath(filePath)
3975
- };
3976
- this.subcommands.set(subcommand.id, subcommand);
3977
- this.applySubcommandToCommands(subcommand);
3978
- }
3979
- }
3980
- processCommand(filePath, category, parentPath = null) {
3981
- console.log({ filePath, category, parentPath });
3982
- const command = {
3983
- id: crypto.randomUUID(),
3984
- name: parentPath ? this.getDirectoryName(parentPath) : this.extractName(filePath),
3985
- path: filePath,
3986
- relativePath: this.getRelativePath(filePath),
3987
- category,
3988
- middlewares: [],
3989
- subcommands: []
3990
- };
3991
- this.commands.set(command.id, command);
3992
- }
3993
- extractDirOmitCategory(dirPath) {
3994
- const segments = path2.normalize(dirPath).split(path2.sep).reverse();
3995
- let name = "";
3996
- while (segments.length > 0) {
3997
- const segment = segments.pop();
3998
- if (this.isCategoryDirectory(segment)) continue;
3999
- name = segment;
4000
- break;
4001
- }
4002
- return name;
4003
- }
4004
- /**
4005
- * Gets the appropriate file name, handling index files specially
4006
- * For index files, it returns the parent directory name (excluding category markers)
4007
- */
4008
- getAppropriateFileName(filePath) {
4009
- const fileName = this.extractName(filePath);
4010
- if (fileName === "index" && path2.dirname(filePath) !== this.entrypoint) {
4011
- return this.getDirectoryName(filePath);
4012
- }
4013
- return fileName;
4014
- }
4015
- /**
4016
- * Extract the clean directory name, removing any category markers
4017
- */
4018
- getDirectoryName(filePath) {
4019
- const dirName = path2.basename(path2.dirname(filePath));
4020
- return dirName.replace(/^\((\w+)\)$/, "$1");
4021
- }
4022
- // Helper method to identify category directories
4023
- isCategoryDirectory(dirName) {
4024
- return /^\(\w+\)$/.test(dirName);
4025
- }
4026
- applyMiddlewareToCommands(middleware) {
4027
- for (const command of this.commands.values()) {
4028
- const middlewareFileName = path2.basename(middleware.path);
4029
- const match = middlewareFileName.startsWith(command.name) || middlewareFileName === "middleware";
4030
- if (!match) continue;
4031
- if (command.middlewares.includes(middleware.id)) continue;
4032
- command.middlewares.push(middleware.id);
4033
- }
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
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);
3940
+ }
3941
+ }
3942
+ );
4034
3943
  }
4035
- applySubcommandToCommands(subcommand) {
3944
+ applyBindings() {
4036
3945
  for (const command of this.commands.values()) {
4037
- const subcommandPathParts = path2.normalize(subcommand.path).split(path2.sep);
4038
3946
  const commandName = command.name;
4039
- const relevantDirectories = subcommandPathParts.map((part) => path2.basename(part)).filter((part) => !this.isCategoryDirectory(part));
4040
- if (relevantDirectories.includes(commandName)) {
4041
- if (!command.subcommands.includes(subcommand.id)) {
4042
- command.subcommands.push(subcommand.id);
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
+ }
4043
3964
  }
4044
3965
  }
4045
3966
  }
4046
3967
  }
4047
- extractCategory(entry) {
4048
- return path2.normalize(entry).split(path2.sep).map((segment) => {
4049
- const match = segment.match(/^\((\w+)\)$/);
4050
- return match ? match[1] : null;
4051
- }).filter(Boolean).join(":") || null;
4052
- }
4053
- getRelativePath(entry) {
4054
- return path2.relative(this.entrypoint, entry);
4055
- }
4056
- isMiddleware(entry) {
4057
- const fileName = path2.basename(entry);
4058
- return fileName === "middleware.js" || fileName === "middleware.ts" || fileName === "middleware.mjs" || fileName === "middleware.cjs" || fileName === "middleware.jsx" || fileName === "middleware.tsx" || /\.middleware\.(c|m)?(j|t)sx?$/.test(fileName);
4059
- }
4060
- shouldIgnore(entry, dir = false) {
4061
- const fileName = path2.basename(entry);
4062
- if (fileName.startsWith("_")) return true;
4063
- if (!dir) {
4064
- const ext = path2.extname(fileName).toLowerCase();
4065
- return ![".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"].includes(ext);
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
+ }
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;
4066
3985
  }
4067
- return false;
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;
3995
+ }
3996
+ return categoryDir.slice(1, -1);
3997
+ }
3998
+ parseFileName(filename) {
3999
+ return import_node_path3.default.basename(filename, import_node_path3.default.extname(filename));
4068
4000
  }
4069
- extractName(entry) {
4070
- const fileName = path2.basename(entry);
4071
- return path2.parse(fileName).name;
4001
+ toRelativePath(pathname) {
4002
+ return import_node_path3.default.relative(this.options.entrypoint, pathname);
4072
4003
  }
4073
4004
  };
4074
4005
  __name(_CommandsRouter, "CommandsRouter");
@@ -4077,14 +4008,14 @@ var init_CommandsRouter = __esm({
4077
4008
  });
4078
4009
 
4079
4010
  // src/app/router/EventsRouter.ts
4080
- var import_node_fs4, import_promises4, import_node_path3, _EventsRouter, EventsRouter;
4011
+ var import_node_fs4, import_promises3, import_node_path4, _EventsRouter, EventsRouter;
4081
4012
  var init_EventsRouter = __esm({
4082
4013
  "src/app/router/EventsRouter.ts"() {
4083
4014
  "use strict";
4084
4015
  init_cjs_shims();
4085
4016
  import_node_fs4 = require("fs");
4086
- import_promises4 = require("fs/promises");
4087
- import_node_path3 = require("path");
4017
+ import_promises3 = require("fs/promises");
4018
+ import_node_path4 = require("path");
4088
4019
  _EventsRouter = class _EventsRouter {
4089
4020
  /**
4090
4021
  * Creates a new EventsRouter instance
@@ -4139,10 +4070,10 @@ var init_EventsRouter = __esm({
4139
4070
  * @returns Promise resolving to the events tree
4140
4071
  */
4141
4072
  async scan() {
4142
- const dirs = await (0, import_promises4.readdir)(this.entrypoint, { withFileTypes: true });
4073
+ const dirs = await (0, import_promises3.readdir)(this.entrypoint, { withFileTypes: true });
4143
4074
  for (const dir of dirs) {
4144
4075
  if (dir.isDirectory()) {
4145
- const path3 = (0, import_node_path3.join)(this.entrypoint, dir.name);
4076
+ const path3 = (0, import_node_path4.join)(this.entrypoint, dir.name);
4146
4077
  const event = await this.scanEvent(dir.name, path3);
4147
4078
  this.events.set(event.event, event);
4148
4079
  }
@@ -4165,16 +4096,16 @@ var init_EventsRouter = __esm({
4165
4096
  */
4166
4097
  async scanEvent(event, path3, listeners = []) {
4167
4098
  var _a;
4168
- const files = await (0, import_promises4.readdir)(path3, { withFileTypes: true });
4099
+ const files = await (0, import_promises3.readdir)(path3, { withFileTypes: true });
4169
4100
  for (const file of files) {
4170
4101
  if (/node_modules/.test(file.name)) continue;
4171
4102
  if (file.isDirectory()) {
4172
- const nextPath = (0, import_node_path3.join)(path3, file.name);
4103
+ const nextPath = (0, import_node_path4.join)(path3, file.name);
4173
4104
  await this.scanEvent(event, nextPath, listeners);
4174
4105
  continue;
4175
4106
  }
4176
4107
  if (file.isFile() && /\.(m|c)?(j|t)sx?$/.test(file.name)) {
4177
- listeners.push((0, import_node_path3.join)(file.parentPath, file.name));
4108
+ listeners.push((0, import_node_path4.join)(file.parentPath, file.name));
4178
4109
  }
4179
4110
  }
4180
4111
  const maybeNamespace = path3.replace(this.entrypoint, "").replaceAll("\\", "/").split("/").shift();
@@ -4351,12 +4282,12 @@ var init_AppEventsHandler = __esm({
4351
4282
 
4352
4283
  // src/utils/types-package.ts
4353
4284
  async function generateTypesPackage() {
4354
- const location = (0, import_node_path4.join)(process.cwd(), "node_modules", "commandkit-types");
4355
- const packageJSON = (0, import_node_path4.join)(location, "package.json");
4356
- const index = (0, import_node_path4.join)(location, "index.js");
4357
- const types = (0, import_node_path4.join)(location, "index.d.ts");
4358
- const locale = (0, import_node_path4.join)(location, "locale.d.ts");
4359
- 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");
4360
4291
  const exists = (0, import_node_fs5.existsSync)(packageJSON);
4361
4292
  if (exists) return location;
4362
4293
  const packageJSONContent = {
@@ -4377,22 +4308,22 @@ async function generateTypesPackage() {
4377
4308
  command: CommandTypeData;
4378
4309
  }
4379
4310
  }`;
4380
- await (0, import_promises5.mkdir)(location, { recursive: true });
4381
- await (0, import_promises5.writeFile)(packageJSON, JSON.stringify(packageJSONContent, null, 2));
4382
- await (0, import_promises5.writeFile)(index, indexContent);
4383
- await (0, import_promises5.writeFile)(types, typesContent);
4384
- await (0, import_promises5.writeFile)(locale, "");
4385
- 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, "");
4386
4317
  return location;
4387
4318
  }
4388
- var import_node_fs5, import_promises5, import_node_path4;
4319
+ var import_node_fs5, import_promises4, import_node_path5;
4389
4320
  var init_types_package = __esm({
4390
4321
  "src/utils/types-package.ts"() {
4391
4322
  "use strict";
4392
4323
  init_cjs_shims();
4393
4324
  import_node_fs5 = require("fs");
4394
- import_promises5 = require("fs/promises");
4395
- import_node_path4 = require("path");
4325
+ import_promises4 = require("fs/promises");
4326
+ import_node_path5 = require("path");
4396
4327
  __name(generateTypesPackage, "generateTypesPackage");
4397
4328
  }
4398
4329
  });
@@ -4434,7 +4365,7 @@ async function loadConfigFileFromPath(target) {
4434
4365
  fileName: target
4435
4366
  });
4436
4367
  const nodeModulesPath = await generateTypesPackage();
4437
- 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");
4438
4369
  import_node_fs6.default.writeFileSync(tmpFile, outputText);
4439
4370
  target = tmpFile;
4440
4371
  }
@@ -4449,13 +4380,13 @@ async function ensureExists(loc) {
4449
4380
  throw new Error(`File not found: ${loc}`);
4450
4381
  }
4451
4382
  }
4452
- var import_rimraf, import_node_path5, import_node_fs6, ts;
4383
+ var import_rimraf, import_node_path6, import_node_fs6, ts;
4453
4384
  var init_common = __esm({
4454
4385
  "src/cli/common.ts"() {
4455
4386
  "use strict";
4456
4387
  init_cjs_shims();
4457
4388
  import_rimraf = require("rimraf");
4458
- import_node_path5 = require("path");
4389
+ import_node_path6 = require("path");
4459
4390
  import_node_fs6 = __toESM(require("fs"));
4460
4391
  init_colors();
4461
4392
  init_types_package();
@@ -4469,7 +4400,7 @@ var init_common = __esm({
4469
4400
 
4470
4401
  // src/config/loader.ts
4471
4402
  function findConfigFile(cwd) {
4472
- 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));
4473
4404
  for (const location of locations) {
4474
4405
  if ((0, import_node_fs7.existsSync)(location)) {
4475
4406
  return {
@@ -4488,13 +4419,13 @@ async function loadConfigFile(entrypoint = process.cwd()) {
4488
4419
  loadedConfig = config;
4489
4420
  return config;
4490
4421
  }
4491
- var import_node_fs7, import_node_path6, CONFIG_FILE_NAMES, loadedConfig;
4422
+ var import_node_fs7, import_node_path7, CONFIG_FILE_NAMES, loadedConfig;
4492
4423
  var init_loader = __esm({
4493
4424
  "src/config/loader.ts"() {
4494
4425
  "use strict";
4495
4426
  init_cjs_shims();
4496
4427
  import_node_fs7 = require("fs");
4497
- import_node_path6 = require("path");
4428
+ import_node_path7 = require("path");
4498
4429
  init_common();
4499
4430
  init_config();
4500
4431
  CONFIG_FILE_NAMES = [
@@ -4589,7 +4520,7 @@ var init_CommandKitEventsChannel = __esm({
4589
4520
  });
4590
4521
 
4591
4522
  // src/CommandKit.ts
4592
- var import_node_events2, import_discord12, import_node_path7, import_node_fs8, _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;
4593
4524
  var init_CommandKit = __esm({
4594
4525
  "src/CommandKit.ts"() {
4595
4526
  "use strict";
@@ -4603,7 +4534,7 @@ var init_CommandKit = __esm({
4603
4534
  import_discord12 = require("discord.js");
4604
4535
  init_DefaultLocalizationStrategy();
4605
4536
  init_utilities();
4606
- import_node_path7 = require("path");
4537
+ import_node_path8 = require("path");
4607
4538
  init_AppCommandHandler();
4608
4539
  init_router();
4609
4540
  init_AppEventsHandler();
@@ -4688,12 +4619,14 @@ var init_CommandKit = __esm({
4688
4619
  await __privateMethod(this, _CommandKit_instances, init_fn).call(this);
4689
4620
  this.incrementClientListenersCount();
4690
4621
  if (token !== false && !this.options.client.isReady()) {
4622
+ this.client.once(import_discord12.Events.ClientReady, async () => {
4623
+ await this.commandHandler.registrar.register();
4624
+ });
4691
4625
  await this.options.client.login(
4692
4626
  token ?? process.env.TOKEN ?? process.env.DISCORD_TOKEN
4693
4627
  );
4694
4628
  }
4695
4629
  __privateSet(this, _started, true);
4696
- await this.commandHandler.registrar.register();
4697
4630
  }
4698
4631
  /**
4699
4632
  * Loads all the plugins.
@@ -4833,11 +4766,11 @@ var init_CommandKit = __esm({
4833
4766
  if (!appDir2) return null;
4834
4767
  switch (to) {
4835
4768
  case "locales":
4836
- return (0, import_node_path7.join)(appDir2, "locales");
4769
+ return (0, import_node_path8.join)(appDir2, "locales");
4837
4770
  case "commands":
4838
- return (0, import_node_path7.join)(appDir2, "commands");
4771
+ return (0, import_node_path8.join)(appDir2, "commands");
4839
4772
  case "events":
4840
- return (0, import_node_path7.join)(appDir2, "events");
4773
+ return (0, import_node_path8.join)(appDir2, "events");
4841
4774
  default:
4842
4775
  return to;
4843
4776
  }
@@ -4863,8 +4796,6 @@ var init_CommandKit = __esm({
4863
4796
  if (this.commandsRouter.isValidPath()) {
4864
4797
  const result = await this.commandsRouter.scan();
4865
4798
  if (COMMANDKIT_IS_DEV) {
4866
- const visual = this.commandsRouter.visualize();
4867
- Logger.info(visual);
4868
4799
  (0, import_node_fs8.writeFileSync)(
4869
4800
  "./.commandkit/commands.json",
4870
4801
  JSON.stringify(result, null, 2)
@@ -4898,7 +4829,7 @@ var init_version = __esm({
4898
4829
  "use strict";
4899
4830
  init_cjs_shims();
4900
4831
  version = /* @__MACRO__ $version */
4901
- "0.1.11-dev.20250308073818";
4832
+ "0.1.11-dev.20250308130523";
4902
4833
  }
4903
4834
  });
4904
4835
 
@@ -4940,7 +4871,7 @@ function getStdio(supportsCommands) {
4940
4871
  }
4941
4872
  function createAppProcess(fileName, cwd, isDev) {
4942
4873
  var _a, _b;
4943
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(cwd, fileName))) {
4874
+ if (!(0, import_node_fs9.existsSync)((0, import_node_path9.join)(cwd, fileName))) {
4944
4875
  panic(`Could not locate the entrypoint file: ${fileName}`);
4945
4876
  }
4946
4877
  const stdio = getStdio(isDev);
@@ -4962,14 +4893,14 @@ function createAppProcess(fileName, cwd, isDev) {
4962
4893
  (_b = ps.stderr) == null ? void 0 : _b.pipe(process.stderr);
4963
4894
  return ps;
4964
4895
  }
4965
- var import_node_child_process, import_node_path8, import_node_fs9;
4896
+ var import_node_child_process, import_node_path9, import_node_fs9;
4966
4897
  var init_app_process = __esm({
4967
4898
  "src/cli/app-process.ts"() {
4968
4899
  "use strict";
4969
4900
  init_cjs_shims();
4970
4901
  import_node_child_process = require("child_process");
4971
4902
  init_env();
4972
- import_node_path8 = require("path");
4903
+ import_node_path9 = require("path");
4973
4904
  import_node_fs9 = require("fs");
4974
4905
  init_common();
4975
4906
  __name(getStdio, "getStdio");
@@ -5057,9 +4988,9 @@ async function main() {
5057
4988
  await main();
5058
4989
  `;
5059
4990
  const dist = isDev ? ".commandkit" : distDir || "dist";
5060
- await (0, import_promises6.writeFile)((0, import_node_path9.join)(configPath, dist, "index.js"), code);
4991
+ await (0, import_promises5.writeFile)((0, import_node_path10.join)(configPath, dist, "index.js"), code);
5061
4992
  }
5062
- var import_tsup, import_promises6, import_node_path9, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4993
+ var import_tsup, import_promises5, import_node_path10, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
5063
4994
  var init_build = __esm({
5064
4995
  "src/cli/build.ts"() {
5065
4996
  "use strict";
@@ -5067,8 +4998,8 @@ var init_build = __esm({
5067
4998
  import_tsup = require("tsup");
5068
4999
  init_plugins();
5069
5000
  init_loader();
5070
- import_promises6 = require("fs/promises");
5071
- import_node_path9 = require("path");
5001
+ import_promises5 = require("fs/promises");
5002
+ import_node_path10 = require("path");
5072
5003
  init_env();
5073
5004
  __name(buildApplication, "buildApplication");
5074
5005
  envScript = /* @__PURE__ */ __name((dev) => `// --- Environment Variables Loader ---
@@ -5329,7 +5260,7 @@ __export(generators_exports, {
5329
5260
  });
5330
5261
  async function generateCommand(name, customPath) {
5331
5262
  const cmdPath = (0, import_path4.join)(customPath || COMMANDS_DIR, name);
5332
- if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises7.mkdir)(cmdPath, { recursive: true });
5263
+ if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises6.mkdir)(cmdPath, { recursive: true });
5333
5264
  if ((0, import_fs2.existsSync)((0, import_path4.join)(cmdPath, "command.ts"))) {
5334
5265
  panic(`Command ${name} already exists.`);
5335
5266
  }
@@ -5349,7 +5280,7 @@ export const message: MessageCommand = async (ctx) => {
5349
5280
  await ctx.message.reply('Hello from ${name}!');
5350
5281
  };
5351
5282
  `.trim();
5352
- await (0, import_promises7.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5283
+ await (0, import_promises6.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5353
5284
  console.log(
5354
5285
  colors_default.green(
5355
5286
  `Command ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(cmdPath))}/command.ts`
@@ -5358,10 +5289,10 @@ export const message: MessageCommand = async (ctx) => {
5358
5289
  }
5359
5290
  async function generateEvent(name, customPath) {
5360
5291
  const eventPath = (0, import_path4.join)(customPath || EVENTS_DIR, name);
5361
- if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises7.mkdir)(eventPath, { recursive: true });
5292
+ if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises6.mkdir)(eventPath, { recursive: true });
5362
5293
  let filename = "event.ts";
5363
5294
  if ((0, import_fs2.existsSync)((0, import_path4.join)(eventPath, filename))) {
5364
- const count = (await (0, import_promises7.readdir)(eventPath)).length;
5295
+ const count = (await (0, import_promises6.readdir)(eventPath)).length;
5365
5296
  filename = `${String(count).padStart(2, "0")}_${filename}`;
5366
5297
  }
5367
5298
  const eventFile = `
@@ -5369,7 +5300,7 @@ export default async function on${name[0].toUpperCase() + name.slice(1)}() {
5369
5300
  console.log('${name} event fired!');
5370
5301
  };
5371
5302
  `.trim();
5372
- await (0, import_promises7.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5303
+ await (0, import_promises6.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5373
5304
  console.log(
5374
5305
  colors_default.green(
5375
5306
  `Event ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(eventPath))}/${colors_default.magenta(filename)}`
@@ -5387,7 +5318,7 @@ async function generateLocale(locale, commandName, customPath) {
5387
5318
  panic("Command name is required.");
5388
5319
  }
5389
5320
  const localePath = (0, import_path4.join)(customPath || LOCALES_DIR, locale);
5390
- if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises7.mkdir)(localePath, { recursive: true });
5321
+ if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises6.mkdir)(localePath, { recursive: true });
5391
5322
  if ((0, import_fs2.existsSync)((0, import_path4.join)(localePath, `${commandName}.json`))) {
5392
5323
  panic(`Locale file for ${commandName} already exists.`);
5393
5324
  }
@@ -5398,7 +5329,7 @@ async function generateLocale(locale, commandName, customPath) {
5398
5329
  },
5399
5330
  translations: {}
5400
5331
  };
5401
- await (0, import_promises7.writeFile)(
5332
+ await (0, import_promises6.writeFile)(
5402
5333
  (0, import_path4.join)(localePath, `${commandName}.json`),
5403
5334
  JSON.stringify(localeFile, null, 2)
5404
5335
  );
@@ -5410,12 +5341,12 @@ async function generateLocale(locale, commandName, customPath) {
5410
5341
  )
5411
5342
  );
5412
5343
  }
5413
- var import_promises7, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5344
+ var import_promises6, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5414
5345
  var init_generators = __esm({
5415
5346
  "src/cli/generators.ts"() {
5416
5347
  "use strict";
5417
5348
  init_cjs_shims();
5418
- import_promises7 = require("fs/promises");
5349
+ import_promises6 = require("fs/promises");
5419
5350
  import_path4 = require("path");
5420
5351
  import_discord13 = require("discord.js");
5421
5352
  init_common();