commandkit 0.1.11-dev.20250306101654 → 0.1.11-dev.20250307192025

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
@@ -1011,81 +1011,6 @@ var init_components = __esm({
1011
1011
  }
1012
1012
  });
1013
1013
 
1014
- // src/app/i18n/DefaultLocalizationStrategy.ts
1015
- var import_promises, import_node_path, _DefaultLocalizationStrategy, DefaultLocalizationStrategy;
1016
- var init_DefaultLocalizationStrategy = __esm({
1017
- "src/app/i18n/DefaultLocalizationStrategy.ts"() {
1018
- "use strict";
1019
- init_cjs_shims();
1020
- import_promises = require("fs/promises");
1021
- import_node_path = require("path");
1022
- _DefaultLocalizationStrategy = class _DefaultLocalizationStrategy {
1023
- constructor(commandkit) {
1024
- this.commandkit = commandkit;
1025
- }
1026
- translations = /* @__PURE__ */ new Map();
1027
- async locateTranslation(scope, locale) {
1028
- const localesPath = this.commandkit.getPath("locales");
1029
- if (!localesPath) return null;
1030
- const path3 = (0, import_node_path.join)(localesPath, locale, `${scope}.json`);
1031
- try {
1032
- const data = await (0, import_promises.readFile)(path3, "utf-8");
1033
- return JSON.parse(data);
1034
- } catch {
1035
- return null;
1036
- }
1037
- }
1038
- async getTranslationStrict(scope, locale) {
1039
- const key = `${scope}:${locale}`;
1040
- if (!this.translations.has(key)) {
1041
- const translation = await this.locateTranslation(scope, locale);
1042
- if (!translation) {
1043
- throw new Error(`Translation not found for ${key}`);
1044
- }
1045
- this.translations.set(key, translation);
1046
- return translation;
1047
- }
1048
- return this.translations.get(key);
1049
- }
1050
- async getTranslation(scope, locale) {
1051
- try {
1052
- return this.getTranslationStrict(scope, locale);
1053
- } catch (e) {
1054
- return null;
1055
- }
1056
- }
1057
- async translate(request) {
1058
- const { scope, key, args, locale } = request;
1059
- const translation = await this.getTranslation(scope, locale);
1060
- if (!translation) return `${scope}.${key}`;
1061
- const value = translation.translations[key];
1062
- const translated = this.applyTranslation(value, args);
1063
- return translated || `${scope}.${key}`;
1064
- }
1065
- applyTranslation(translation, args) {
1066
- if (!translation || !args) return translation;
1067
- return translation.replace(/{([^}]+)}/g, (_, key) => {
1068
- return String(args[key] ?? `{${key}}`);
1069
- });
1070
- }
1071
- };
1072
- __name(_DefaultLocalizationStrategy, "DefaultLocalizationStrategy");
1073
- DefaultLocalizationStrategy = _DefaultLocalizationStrategy;
1074
- }
1075
- });
1076
-
1077
- // src/utils/constants.ts
1078
- var COMMANDKIT_CACHE_TAG, COMMANDKIT_IS_DEV, COMMANDKIT_IS_TEST;
1079
- var init_constants = __esm({
1080
- "src/utils/constants.ts"() {
1081
- "use strict";
1082
- init_cjs_shims();
1083
- COMMANDKIT_CACHE_TAG = Symbol("kCommandKitCacheTag");
1084
- COMMANDKIT_IS_DEV = !!process.env.COMMANDKIT_IS_DEV;
1085
- COMMANDKIT_IS_TEST = process.env.COMMANDKIT_IS_TEST === "true";
1086
- }
1087
- });
1088
-
1089
1014
  // src/plugins/PluginCommon.ts
1090
1015
  var _PluginCommon, PluginCommon;
1091
1016
  var init_PluginCommon = __esm({
@@ -1157,11 +1082,83 @@ var init_CompilerPlugin = __esm({
1157
1082
  });
1158
1083
 
1159
1084
  // src/plugins/RuntimePlugin.ts
1085
+ function isRuntimePlugin(plugin) {
1086
+ return plugin instanceof RuntimePlugin;
1087
+ }
1088
+ var _RuntimePlugin, RuntimePlugin;
1160
1089
  var init_RuntimePlugin = __esm({
1161
1090
  "src/plugins/RuntimePlugin.ts"() {
1162
1091
  "use strict";
1163
1092
  init_cjs_shims();
1164
1093
  init_PluginCommon();
1094
+ _RuntimePlugin = class _RuntimePlugin extends PluginCommon {
1095
+ /**
1096
+ * Called before commands are loaded
1097
+ */
1098
+ async onBeforeCommandsLoad(ctx) {
1099
+ }
1100
+ /**
1101
+ * Called after commands are loaded
1102
+ */
1103
+ async onAfterCommandsLoad(ctx) {
1104
+ }
1105
+ /**
1106
+ * Called before events are loaded
1107
+ */
1108
+ async onBeforeEventsLoad(ctx) {
1109
+ }
1110
+ /**
1111
+ * Called after events are loaded
1112
+ */
1113
+ async onAfterEventsLoad(ctx) {
1114
+ }
1115
+ /**
1116
+ * Called before the client logs in
1117
+ */
1118
+ async onBeforeClientLogin(ctx) {
1119
+ }
1120
+ /**
1121
+ * Called after the client logs in
1122
+ */
1123
+ async onAfterClientLogin(ctx) {
1124
+ }
1125
+ /**
1126
+ * Called before interaction is handled
1127
+ * @param interaction The interaction
1128
+ */
1129
+ async onBeforeInteraction(ctx, interaction) {
1130
+ }
1131
+ /**
1132
+ * Called after interaction is handled
1133
+ * @param interaction The interaction that was handled
1134
+ */
1135
+ async onAfterInteraction(ctx, interaction) {
1136
+ }
1137
+ /**
1138
+ * Called before message command is processed
1139
+ * @param message The message
1140
+ */
1141
+ async onBeforeMessageCommand(ctx, message) {
1142
+ }
1143
+ /**
1144
+ * Called before message update command is processed
1145
+ * @param message The message
1146
+ */
1147
+ async onBeforeMessageUpdateCommand(ctx, oldMessage, newMessage) {
1148
+ }
1149
+ /**
1150
+ * Called before command is executed. This method can execute the command itself.
1151
+ * @param source The source that triggered the command
1152
+ * @param command The command
1153
+ * @param execute The function that executes the command
1154
+ */
1155
+ async executeCommand(ctx, source, command, execute) {
1156
+ return false;
1157
+ }
1158
+ };
1159
+ __name(_RuntimePlugin, "RuntimePlugin");
1160
+ RuntimePlugin = _RuntimePlugin;
1161
+ __name(isRuntimePlugin, "isRuntimePlugin");
1165
1162
  }
1166
1163
  });
1167
1164
 
@@ -1386,6 +1383,18 @@ var init_CommandKitPluginRuntime = __esm({
1386
1383
  getPlugin(pluginName) {
1387
1384
  return this.plugins.get(pluginName) ?? null;
1388
1385
  }
1386
+ async softRegisterPlugin(plugin) {
1387
+ const pluginName = plugin.name;
1388
+ if (this.plugins.has(pluginName)) return;
1389
+ try {
1390
+ await plugin.activate(this);
1391
+ this.plugins.set(pluginName, plugin);
1392
+ } catch (e) {
1393
+ throw new Error(
1394
+ `Failed to activate plugin "${pluginName}": ${(e == null ? void 0 : e.stack) || e}`
1395
+ );
1396
+ }
1397
+ }
1389
1398
  async registerPlugin(plugin) {
1390
1399
  const pluginName = plugin.name;
1391
1400
  if (this.plugins.has(pluginName)) {
@@ -1467,12 +1476,12 @@ function fromEsbuildPlugin(plugin) {
1467
1476
  let EsbuildPluginCompat = _EsbuildPluginCompat;
1468
1477
  return EsbuildPluginCompat;
1469
1478
  }
1470
- var import_promises2, pattern, _CompilerPluginRuntime, CompilerPluginRuntime;
1479
+ var import_promises, pattern, _CompilerPluginRuntime, CompilerPluginRuntime;
1471
1480
  var init_CompilerPluginRuntime = __esm({
1472
1481
  "src/plugins/runtime/CompilerPluginRuntime.ts"() {
1473
1482
  "use strict";
1474
1483
  init_cjs_shims();
1475
- import_promises2 = require("fs/promises");
1484
+ import_promises = require("fs/promises");
1476
1485
  init_plugins();
1477
1486
  pattern = /\.(c|m)?(t|j)sx?$/;
1478
1487
  _CompilerPluginRuntime = class _CompilerPluginRuntime {
@@ -1485,7 +1494,7 @@ var init_CompilerPluginRuntime = __esm({
1485
1494
  }
1486
1495
  async onLoad(args) {
1487
1496
  var _a;
1488
- const source = await (0, import_promises2.readFile)(args.path, "utf8");
1497
+ const source = await (0, import_promises.readFile)(args.path, "utf8");
1489
1498
  let contents = source, loader = args.path.split(".").pop();
1490
1499
  for (const plugin of this.plugins) {
1491
1500
  try {
@@ -1956,6 +1965,134 @@ var init_config = __esm({
1956
1965
  }
1957
1966
  });
1958
1967
 
1968
+ // src/app/i18n/DefaultLocalizationStrategy.ts
1969
+ var import_promises2, import_node_path, import_node_fs, _DefaultLocalizationStrategy, DefaultLocalizationStrategy;
1970
+ var init_DefaultLocalizationStrategy = __esm({
1971
+ "src/app/i18n/DefaultLocalizationStrategy.ts"() {
1972
+ "use strict";
1973
+ init_cjs_shims();
1974
+ import_promises2 = require("fs/promises");
1975
+ import_node_path = require("path");
1976
+ init_config();
1977
+ import_node_fs = require("fs");
1978
+ _DefaultLocalizationStrategy = class _DefaultLocalizationStrategy {
1979
+ constructor(commandkit) {
1980
+ this.commandkit = commandkit;
1981
+ }
1982
+ translations = /* @__PURE__ */ new Map();
1983
+ async locateTranslation(scope, locale) {
1984
+ const localesPath = this.commandkit.getPath("locales");
1985
+ if (!localesPath) return null;
1986
+ const path3 = (0, import_node_path.join)(localesPath, locale, `${scope}.json`);
1987
+ try {
1988
+ const data = await (0, import_promises2.readFile)(path3, "utf-8");
1989
+ const localeData = JSON.parse(data);
1990
+ await this.generateLocaleTypes(localeData);
1991
+ return localeData;
1992
+ } catch {
1993
+ return null;
1994
+ }
1995
+ }
1996
+ async generateLocaleTypes(localeData) {
1997
+ const { typedLocales } = getConfig();
1998
+ if (!typedLocales) return;
1999
+ const file = (0, import_node_path.join)(
2000
+ process.cwd(),
2001
+ "node_modules",
2002
+ "commandkit-types",
2003
+ "locale_types.d.ts"
2004
+ );
2005
+ const header = `// auto generated file do not edit
2006
+ declare module 'commandkit' {
2007
+ export interface CommandLocalizationTypeData {
2008
+ `;
2009
+ const footer = ` }
2010
+ }`;
2011
+ const generateType = /* @__PURE__ */ __name((locale) => {
2012
+ return `"${locale.command}": ${JSON.stringify(
2013
+ Object.entries(locale.translations).map(([key, value]) => {
2014
+ const args = value.match(/{([^}]+)}/g);
2015
+ if (!args) return `${JSON.stringify(key)}: null`;
2016
+ return `${JSON.stringify(key)}: ${args.map((arg) => arg.slice(1, -1)).join(" | ")}`;
2017
+ }),
2018
+ null,
2019
+ 2
2020
+ )}`;
2021
+ }, "generateType");
2022
+ if (!(0, import_node_fs.existsSync)(file)) {
2023
+ const generated = generateType(localeData);
2024
+ await (0, import_promises2.writeFile)(file, `${header}${generated}${footer}`);
2025
+ } else {
2026
+ const data = await (0, import_promises2.readFile)(file, "utf-8");
2027
+ const lines = data.split("\n");
2028
+ const index = lines.findIndex(
2029
+ (line) => line.includes("CommandLocalizationTypeData")
2030
+ );
2031
+ if (index === -1) {
2032
+ for (const locale of this.translations.values()) {
2033
+ const generated2 = generateType(locale);
2034
+ await (0, import_promises2.writeFile)(file, `${header}${generated2}${footer}`);
2035
+ }
2036
+ return;
2037
+ }
2038
+ const start = index + 2;
2039
+ const end = lines.findIndex((line) => line.includes("}"));
2040
+ const generated = generateType(localeData);
2041
+ lines.splice(start, end - start, generated);
2042
+ await (0, import_promises2.writeFile)(file, lines.join("\n"));
2043
+ }
2044
+ }
2045
+ async getTranslationStrict(scope, locale) {
2046
+ const key = `${scope}:${locale}`;
2047
+ if (!this.translations.has(key)) {
2048
+ const translation = await this.locateTranslation(scope, locale);
2049
+ if (!translation) {
2050
+ throw new Error(`Translation not found for ${key}`);
2051
+ }
2052
+ this.translations.set(key, translation);
2053
+ return translation;
2054
+ }
2055
+ return this.translations.get(key);
2056
+ }
2057
+ async getTranslation(scope, locale) {
2058
+ try {
2059
+ return this.getTranslationStrict(scope, locale);
2060
+ } catch (e) {
2061
+ return null;
2062
+ }
2063
+ }
2064
+ async translate(request) {
2065
+ const { scope, key, args, locale } = request;
2066
+ const translation = await this.getTranslation(scope, locale);
2067
+ if (!translation) return `${scope}.${key}`;
2068
+ const value = translation.translations[key];
2069
+ const translated = this.applyTranslation(value, args);
2070
+ return translated || `${scope}.${key}`;
2071
+ }
2072
+ applyTranslation(translation, args) {
2073
+ if (!translation || !args) return translation;
2074
+ return translation.replace(/{([^}]+)}/g, (_, key) => {
2075
+ return String(args[key] ?? `{${key}}`);
2076
+ });
2077
+ }
2078
+ };
2079
+ __name(_DefaultLocalizationStrategy, "DefaultLocalizationStrategy");
2080
+ DefaultLocalizationStrategy = _DefaultLocalizationStrategy;
2081
+ }
2082
+ });
2083
+
2084
+ // src/utils/constants.ts
2085
+ var COMMANDKIT_CACHE_TAG, COMMANDKIT_IS_DEV, COMMANDKIT_IS_TEST;
2086
+ var init_constants = __esm({
2087
+ "src/utils/constants.ts"() {
2088
+ "use strict";
2089
+ init_cjs_shims();
2090
+ COMMANDKIT_CACHE_TAG = Symbol("kCommandKitCacheTag");
2091
+ COMMANDKIT_IS_DEV = !!process.env.COMMANDKIT_IS_DEV;
2092
+ COMMANDKIT_IS_TEST = process.env.COMMANDKIT_IS_TEST === "true";
2093
+ }
2094
+ });
2095
+
1959
2096
  // src/utils/utilities.ts
1960
2097
  function findAppDirectory() {
1961
2098
  if (appDir) return appDir;
@@ -1963,10 +2100,10 @@ function findAppDirectory() {
1963
2100
  process.cwd(),
1964
2101
  COMMANDKIT_IS_DEV ? ".commandkit" : getConfig().distDir
1965
2102
  );
1966
- if (!(0, import_node_fs.existsSync)(root)) root = process.cwd();
2103
+ if (!(0, import_node_fs2.existsSync)(root)) root = process.cwd();
1967
2104
  const dirs = ["app"].map((dir) => (0, import_node_path2.join)(root, dir));
1968
2105
  for (const dir of dirs) {
1969
- if ((0, import_node_fs.existsSync)(dir)) {
2106
+ if ((0, import_node_fs2.existsSync)(dir)) {
1970
2107
  appDir = dir;
1971
2108
  return dir;
1972
2109
  }
@@ -1975,22 +2112,31 @@ function findAppDirectory() {
1975
2112
  }
1976
2113
  function debounce(fn, ms2) {
1977
2114
  let timer = null;
2115
+ let resolve = null;
1978
2116
  return (...args) => {
1979
2117
  if (timer) {
1980
2118
  clearTimeout(timer);
2119
+ if (resolve) {
2120
+ resolve(null);
2121
+ }
1981
2122
  }
1982
- timer = setTimeout(() => {
1983
- fn(...args);
1984
- timer = null;
1985
- }, ms2);
2123
+ return new Promise((res) => {
2124
+ resolve = res;
2125
+ timer = setTimeout(() => {
2126
+ const result = fn(...args);
2127
+ res(result);
2128
+ timer = null;
2129
+ resolve = null;
2130
+ }, ms2);
2131
+ });
1986
2132
  };
1987
2133
  }
1988
- var import_node_fs, import_node_path2, appDir;
2134
+ var import_node_fs2, import_node_path2, appDir;
1989
2135
  var init_utilities = __esm({
1990
2136
  "src/utils/utilities.ts"() {
1991
2137
  "use strict";
1992
2138
  init_cjs_shims();
1993
- import_node_fs = require("fs");
2139
+ import_node_fs2 = require("fs");
1994
2140
  import_node_path2 = require("path");
1995
2141
  init_constants();
1996
2142
  init_config();
@@ -2946,6 +3092,9 @@ var init_CommandRegistrar = __esm({
2946
3092
  const commands = this.commandkit.commandHandler.getCommandsArray();
2947
3093
  return commands.flatMap((cmd) => {
2948
3094
  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);
3097
+ }
2949
3098
  const collections = [json];
2950
3099
  if (cmd.data.userContextMenu && json.type !== import_discord9.ApplicationCommandType.User) {
2951
3100
  collections.push({
@@ -2970,6 +3119,70 @@ var init_CommandRegistrar = __esm({
2970
3119
  return collections;
2971
3120
  });
2972
3121
  }
3122
+ /**
3123
+ * Process and merge subcommands into the parent command's options
3124
+ */
3125
+ processSubcommands(commandData, subcommands) {
3126
+ var _a, _b, _c;
3127
+ if (!commandData.options) {
3128
+ commandData.options = [];
3129
+ }
3130
+ const groupedSubcommands = /* @__PURE__ */ new Map();
3131
+ for (const subcommand of subcommands) {
3132
+ const group = subcommand.group || null;
3133
+ if (!groupedSubcommands.has(group)) {
3134
+ groupedSubcommands.set(group, []);
3135
+ }
3136
+ (_a = groupedSubcommands.get(group)) == null ? void 0 : _a.push(subcommand);
3137
+ }
3138
+ const directSubcommands = groupedSubcommands.get(null) || [];
3139
+ for (const subcommand of directSubcommands) {
3140
+ const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3141
+ subcommand.id
3142
+ );
3143
+ if (subcommandData) {
3144
+ const subcommandOption = {
3145
+ type: 1,
3146
+ // SUB_COMMAND
3147
+ name: subcommand.name,
3148
+ description: subcommandData.description || "No description provided",
3149
+ options: subcommandData.options || [],
3150
+ name_localizations: subcommandData.name_localizations,
3151
+ description_localizations: subcommandData.description_localizations
3152
+ };
3153
+ commandData.options.push(subcommandOption);
3154
+ }
3155
+ }
3156
+ for (const [groupName, groupSubcommands] of groupedSubcommands.entries()) {
3157
+ if (groupName === null) continue;
3158
+ const subcommandGroupOption = {
3159
+ type: import_discord9.ApplicationCommandOptionType.SubcommandGroup,
3160
+ // SUB_COMMAND_GROUP
3161
+ name: groupName,
3162
+ description: `${groupName} commands`,
3163
+ options: []
3164
+ };
3165
+ for (const subcommand of groupSubcommands) {
3166
+ const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3167
+ subcommand.id
3168
+ );
3169
+ if (subcommandData) {
3170
+ (_b = subcommandGroupOption.options) == null ? void 0 : _b.push({
3171
+ type: import_discord9.ApplicationCommandOptionType.Subcommand,
3172
+ // SUB_COMMAND
3173
+ name: subcommand.name,
3174
+ description: subcommandData.description || "No description provided",
3175
+ options: subcommandData.options || [],
3176
+ name_localizations: subcommandData.name_localizations,
3177
+ description_localizations: subcommandData.description_localizations
3178
+ });
3179
+ }
3180
+ }
3181
+ if ((((_c = subcommandGroupOption.options) == null ? void 0 : _c.length) || 0) > 0) {
3182
+ commandData.options.push(subcommandGroupOption);
3183
+ }
3184
+ }
3185
+ }
2973
3186
  /**
2974
3187
  * Registers loaded commands.
2975
3188
  */
@@ -3085,14 +3298,26 @@ var init_AppCommandHandler = __esm({
3085
3298
  this.registrar = new CommandRegistrar(this.commandkit);
3086
3299
  }
3087
3300
  loadedCommands = new import_discord10.Collection();
3301
+ loadedSubCommands = new import_discord10.Collection();
3088
3302
  loadedMiddlewares = new import_discord10.Collection();
3303
+ // Name-to-ID mapping for easier lookup
3304
+ commandNameToId = /* @__PURE__ */ new Map();
3305
+ subcommandPathToId = /* @__PURE__ */ new Map();
3089
3306
  registrar;
3090
3307
  onInteraction = null;
3091
3308
  onMessageCreate = null;
3092
3309
  onMessageUpdate = null;
3093
3310
  getCommandsArray() {
3094
- const loaded = Array.from(this.loadedCommands.values());
3095
- return loaded;
3311
+ return Array.from(this.loadedCommands.values());
3312
+ }
3313
+ /**
3314
+ * Get subcommand data by ID for the command registrar
3315
+ */
3316
+ getSubcommandData(id) {
3317
+ const subcommand = this.loadedSubCommands.get(id);
3318
+ if (!subcommand) return null;
3319
+ const commandData = subcommand.data.command;
3320
+ return "toJSON" in commandData ? commandData.toJSON() : commandData;
3096
3321
  }
3097
3322
  registerCommandHandler() {
3098
3323
  this.onInteraction ??= async (interaction) => {
@@ -3104,9 +3329,9 @@ var init_AppCommandHandler = __esm({
3104
3329
  if (success) return;
3105
3330
  const isCommandLike = interaction.isCommand() || interaction.isAutocomplete() || interaction.isUserContextMenuCommand() || interaction.isMessageContextMenuCommand();
3106
3331
  if (!isCommandLike) return;
3107
- const command = await this.prepareCommandRun(interaction);
3108
- if (!command) return;
3109
- return this.runCommand(command, interaction);
3332
+ const prepared = await this.prepareCommandRun(interaction);
3333
+ if (!prepared) return;
3334
+ return this.runCommand(prepared, interaction);
3110
3335
  };
3111
3336
  this.onMessageCreate ??= async (message) => {
3112
3337
  const success = await this.commandkit.plugins.execute(
@@ -3116,9 +3341,9 @@ var init_AppCommandHandler = __esm({
3116
3341
  );
3117
3342
  if (success) return;
3118
3343
  if (message.author.bot) return;
3119
- const command = await this.prepareCommandRun(message);
3120
- if (!command) return;
3121
- return this.runCommand(command, message);
3344
+ const prepared = await this.prepareCommandRun(message);
3345
+ if (!prepared) return;
3346
+ return this.runCommand(prepared, message);
3122
3347
  };
3123
3348
  this.onMessageUpdate ??= async (oldMessage, newMessage) => {
3124
3349
  const success = await this.commandkit.plugins.execute(
@@ -3133,9 +3358,9 @@ var init_AppCommandHandler = __esm({
3133
3358
  if (success) return;
3134
3359
  if (oldMessage.partial || newMessage.partial) return;
3135
3360
  if (oldMessage.author.bot) return;
3136
- const command = await this.prepareCommandRun(newMessage);
3137
- if (!command) return;
3138
- return this.runCommand(command, newMessage);
3361
+ const prepared = await this.prepareCommandRun(newMessage);
3362
+ if (!prepared) return;
3363
+ return this.runCommand(prepared, newMessage);
3139
3364
  };
3140
3365
  this.commandkit.client.on(import_discord10.Events.InteractionCreate, this.onInteraction);
3141
3366
  this.commandkit.client.on(import_discord10.Events.MessageCreate, this.onMessageCreate);
@@ -3155,7 +3380,7 @@ var init_AppCommandHandler = __esm({
3155
3380
  }
3156
3381
  return null;
3157
3382
  }
3158
- async runCommand(command, source) {
3383
+ async runCommand(prepared, source) {
3159
3384
  if (source instanceof import_discord10.Message && (source.editedTimestamp || source.partial)) {
3160
3385
  return;
3161
3386
  }
@@ -3166,13 +3391,14 @@ var init_AppCommandHandler = __esm({
3166
3391
  message: source instanceof import_discord10.Message ? source : null,
3167
3392
  forwarded: false
3168
3393
  });
3169
- for (const middleware of command.middlewares) {
3394
+ for (const middleware of prepared.middlewares) {
3170
3395
  await middleware.data.beforeExecute(ctx);
3171
3396
  }
3172
- const fn = command.command.data[executionMode];
3397
+ const targetData = prepared.subcommand ? prepared.subcommand.data : prepared.command.data;
3398
+ const fn = targetData[executionMode];
3173
3399
  if (!fn) {
3174
3400
  Logger.warn(
3175
- `Command ${command.command.command.name} has no handler for ${executionMode}`
3401
+ `Command ${prepared.command.command.name}${prepared.subcommand ? "/" + prepared.subcommand.subcommand.name : ""} has no handler for ${executionMode}`
3176
3402
  );
3177
3403
  }
3178
3404
  if (fn) {
@@ -3180,7 +3406,7 @@ var init_AppCommandHandler = __esm({
3180
3406
  const executeCommand = /* @__PURE__ */ __name(async () => fn(ctx.clone()), "executeCommand");
3181
3407
  const res = await this.commandkit.plugins.execute(
3182
3408
  async (ctx2, plugin) => {
3183
- return plugin.executeCommand(ctx2, source, command, executeCommand);
3409
+ return plugin.executeCommand(ctx2, source, prepared, executeCommand);
3184
3410
  }
3185
3411
  );
3186
3412
  if (!res) {
@@ -3190,12 +3416,15 @@ var init_AppCommandHandler = __esm({
3190
3416
  Logger.error(e);
3191
3417
  }
3192
3418
  }
3193
- for (const middleware of command.middlewares) {
3419
+ for (const middleware of prepared.middlewares) {
3194
3420
  await middleware.data.afterExecute(ctx);
3195
3421
  }
3196
3422
  }
3197
3423
  async prepareCommandRun(source) {
3198
- let cmd;
3424
+ var _a;
3425
+ let cmdName;
3426
+ let subcommandGroupName = null;
3427
+ let subcommandName = null;
3199
3428
  let parser2;
3200
3429
  if (source instanceof import_discord10.Message) {
3201
3430
  if (source.author.bot) return null;
@@ -3204,13 +3433,14 @@ var init_AppCommandHandler = __esm({
3204
3433
  source,
3205
3434
  Array.isArray(prefix) ? prefix : [prefix],
3206
3435
  (command) => {
3207
- var _a, _b;
3208
- const loadedCommand2 = this.loadedCommands.find((c) => {
3209
- return c.data.command.name === command;
3210
- });
3436
+ var _a2, _b;
3437
+ const commandId2 = this.commandNameToId.get(command);
3438
+ if (!commandId2) return null;
3439
+ const loadedCommand2 = this.loadedCommands.get(commandId2);
3211
3440
  if (!loadedCommand2) return null;
3212
- if (source.guildId && ((_a = loadedCommand2.guilds) == null ? void 0 : _a.length) && !loadedCommand2.guilds.includes(source.guildId))
3441
+ if (source.guildId && ((_a2 = loadedCommand2.guilds) == null ? void 0 : _a2.length) && !loadedCommand2.guilds.includes(source.guildId)) {
3213
3442
  return null;
3443
+ }
3214
3444
  const json = "toJSON" in loadedCommand2.data.command ? loadedCommand2.data.command.toJSON() : loadedCommand2.data.command;
3215
3445
  return ((_b = json.options) == null ? void 0 : _b.reduce(
3216
3446
  (acc, opt) => {
@@ -3222,7 +3452,17 @@ var init_AppCommandHandler = __esm({
3222
3452
  }
3223
3453
  );
3224
3454
  try {
3225
- cmd = parser2.getFullCommand();
3455
+ const fullCommand = parser2.getFullCommand();
3456
+ const parts = fullCommand.split(" ");
3457
+ cmdName = parts[0];
3458
+ if (parts.length > 1) {
3459
+ if (parts.length === 3) {
3460
+ subcommandGroupName = parts[1];
3461
+ subcommandName = parts[2];
3462
+ } else {
3463
+ subcommandName = parts[1];
3464
+ }
3465
+ }
3226
3466
  } catch (e) {
3227
3467
  if (isErrorType(e, CommandKitErrorCodes.InvalidCommandPrefix)) {
3228
3468
  return null;
@@ -3232,31 +3472,63 @@ var init_AppCommandHandler = __esm({
3232
3472
  }
3233
3473
  } else {
3234
3474
  if (!source.isCommand()) return null;
3235
- cmd = source.commandName;
3475
+ cmdName = source.commandName;
3236
3476
  if (source.isChatInputCommand()) {
3237
- const subcommandGroup = source.options.getSubcommandGroup(false);
3238
- const subcommand = source.options.getSubcommand(false);
3239
- if (subcommandGroup) {
3240
- cmd += ` ${subcommandGroup}`;
3241
- }
3242
- if (subcommand) {
3243
- cmd += ` ${subcommand}`;
3244
- }
3477
+ subcommandGroupName = source.options.getSubcommandGroup(false);
3478
+ subcommandName = source.options.getSubcommand(false);
3245
3479
  }
3246
3480
  }
3247
- const loadedCommand = this.loadedCommands.find((c) => {
3248
- return c.data.command.name === cmd;
3249
- });
3481
+ const commandId = this.commandNameToId.get(cmdName);
3482
+ if (!commandId) return null;
3483
+ const loadedCommand = this.loadedCommands.get(commandId);
3250
3484
  if (!loadedCommand) return null;
3485
+ if (source instanceof import_discord10.CommandInteraction && source.guildId && ((_a = loadedCommand.guilds) == null ? void 0 : _a.length) && !loadedCommand.guilds.includes(source.guildId)) {
3486
+ return null;
3487
+ }
3488
+ let loadedSubCommand = null;
3489
+ if (subcommandName) {
3490
+ let subcommandPath = `${loadedCommand.command.id}/${subcommandName}`;
3491
+ if (subcommandGroupName) {
3492
+ subcommandPath = `${loadedCommand.command.id}/${subcommandGroupName}/${subcommandName}`;
3493
+ }
3494
+ const subCommandId = this.subcommandPathToId.get(subcommandPath);
3495
+ if (subCommandId) {
3496
+ loadedSubCommand = this.loadedSubCommands.get(subCommandId) || null;
3497
+ }
3498
+ }
3499
+ const middlewares = [];
3500
+ for (const middlewareId of loadedCommand.command.middlewares) {
3501
+ const middleware = this.loadedMiddlewares.get(middlewareId);
3502
+ if (middleware) {
3503
+ middlewares.push(middleware);
3504
+ }
3505
+ }
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
+ }
3251
3519
  return {
3252
3520
  command: loadedCommand,
3253
- middlewares: loadedCommand.command.middlewares.map((m) => this.loadedMiddlewares.get(m)).filter((m) => !!m),
3521
+ subcommand: loadedSubCommand,
3522
+ middlewares,
3254
3523
  messageCommandParser: parser2
3255
3524
  };
3256
3525
  }
3257
3526
  async reloadCommands() {
3258
3527
  this.loadedCommands.clear();
3528
+ this.loadedSubCommands.clear();
3259
3529
  this.loadedMiddlewares.clear();
3530
+ this.commandNameToId.clear();
3531
+ this.subcommandPathToId.clear();
3260
3532
  await this.loadCommands();
3261
3533
  }
3262
3534
  async loadCommands() {
@@ -3264,9 +3536,33 @@ var init_AppCommandHandler = __esm({
3264
3536
  if (!commandsRouter) {
3265
3537
  throw new Error("Commands router has not yet initialized");
3266
3538
  }
3267
- const { commands, middleware } = commandsRouter.getData();
3268
- for (const [id, md] of middleware) {
3269
- const data = await import(`${toFileURL(md.fullPath)}?t=${Date.now()}`);
3539
+ const { commands, subcommands, middlewares } = commandsRouter.getData();
3540
+ for (const [id, middleware] of middlewares) {
3541
+ await this.loadMiddleware(id, middleware);
3542
+ }
3543
+ for (const [id, command] of commands) {
3544
+ await this.loadCommand(id, command);
3545
+ }
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;
3559
+ }
3560
+ }
3561
+ }
3562
+ }
3563
+ async loadMiddleware(id, middleware) {
3564
+ try {
3565
+ const data = await import(`${toFileURL(middleware.path)}?t=${Date.now()}`);
3270
3566
  let handlerCount = 0;
3271
3567
  for (const [key, validator] of Object.entries(middlewareDataSchema)) {
3272
3568
  if (data[key] && !await validator(data[key])) {
@@ -3281,13 +3577,35 @@ var init_AppCommandHandler = __esm({
3281
3577
  `Invalid export for middleware ${id}: at least one handler function must be provided`
3282
3578
  );
3283
3579
  }
3284
- this.loadedMiddlewares.set(id, { middleware: md, data });
3580
+ this.loadedMiddlewares.set(id, { middleware, data });
3581
+ } catch (error) {
3582
+ Logger.error(
3583
+ `Failed to load middleware ${middleware.name} (${id})`,
3584
+ error
3585
+ );
3285
3586
  }
3286
- for (const [name, command] of commands) {
3287
- const data = await import(`${toFileURL(command.fullPath)}?t=${Date.now()}`);
3587
+ }
3588
+ async loadCommand(id, command) {
3589
+ try {
3590
+ if (command.path === null) {
3591
+ this.loadedCommands.set(id, {
3592
+ command,
3593
+ data: {
3594
+ command: {
3595
+ name: command.name,
3596
+ description: `${command.name} commands`,
3597
+ type: 1
3598
+ // CHAT_INPUT
3599
+ }
3600
+ }
3601
+ });
3602
+ this.commandNameToId.set(command.name, id);
3603
+ return;
3604
+ }
3605
+ const data = await import(`${toFileURL(command.path)}?t=${Date.now()}`);
3288
3606
  if (!data.command) {
3289
3607
  throw new Error(
3290
- `Invalid export for command ${name}: no command definition found`
3608
+ `Invalid export for command ${command.name}: no command definition found`
3291
3609
  );
3292
3610
  }
3293
3611
  let handlerCount = 0;
@@ -3295,19 +3613,19 @@ var init_AppCommandHandler = __esm({
3295
3613
  if (key !== "command" && data[key]) handlerCount++;
3296
3614
  if (data[key] && !await validator(data[key])) {
3297
3615
  throw new Error(
3298
- `Invalid export for command ${name}: ${key} does not match expected value`
3616
+ `Invalid export for command ${command.name}: ${key} does not match expected value`
3299
3617
  );
3300
3618
  }
3301
3619
  }
3302
3620
  if (handlerCount === 0) {
3303
3621
  throw new Error(
3304
- `Invalid export for command ${name}: at least one handler function must be provided`
3622
+ `Invalid export for command ${command.name}: at least one handler function must be provided`
3305
3623
  );
3306
3624
  }
3307
3625
  const localizedCommand = await this.applyLocalizations({
3308
3626
  ...data.command
3309
3627
  });
3310
- this.loadedCommands.set(name, {
3628
+ this.loadedCommands.set(id, {
3311
3629
  command,
3312
3630
  guilds: data.guilds,
3313
3631
  data: {
@@ -3315,6 +3633,60 @@ var init_AppCommandHandler = __esm({
3315
3633
  command: localizedCommand
3316
3634
  }
3317
3635
  });
3636
+ this.commandNameToId.set(command.name, id);
3637
+ } catch (error) {
3638
+ Logger.error(`Failed to load command ${command.name} (${id})`, error);
3639
+ }
3640
+ }
3641
+ async loadSubcommand(id, subcommand) {
3642
+ try {
3643
+ const data = await import(`${toFileURL(subcommand.path)}?t=${Date.now()}`);
3644
+ if (!data.command) {
3645
+ throw new Error(
3646
+ `Invalid export for subcommand ${subcommand.name}: no command definition found`
3647
+ );
3648
+ }
3649
+ let handlerCount = 0;
3650
+ for (const [key, validator] of Object.entries(commandDataSchema)) {
3651
+ if (key !== "command" && data[key]) handlerCount++;
3652
+ if (data[key] && !await validator(data[key])) {
3653
+ throw new Error(
3654
+ `Invalid export for subcommand ${subcommand.name}: ${key} does not match expected value`
3655
+ );
3656
+ }
3657
+ }
3658
+ if (handlerCount === 0) {
3659
+ throw new Error(
3660
+ `Invalid export for subcommand ${subcommand.name}: at least one handler function must be provided`
3661
+ );
3662
+ }
3663
+ const localizedCommand = await this.applyLocalizations({
3664
+ ...data.command
3665
+ });
3666
+ this.loadedSubCommands.set(id, {
3667
+ subcommand,
3668
+ data: {
3669
+ ...data,
3670
+ command: localizedCommand
3671
+ }
3672
+ });
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
+ }
3685
+ } catch (error) {
3686
+ Logger.error(
3687
+ `Failed to load subcommand ${subcommand.name} (${id})`,
3688
+ error
3689
+ );
3318
3690
  }
3319
3691
  }
3320
3692
  async applyLocalizations(command) {
@@ -3400,248 +3772,243 @@ var init_AppCommandHandler = __esm({
3400
3772
  });
3401
3773
 
3402
3774
  // src/app/router/CommandsRouter.ts
3403
- var import_node_fs2, import_promises3, import_node_path3, _CommandsRouter, CommandsRouter;
3775
+ var import_discord11, import_node_fs3, import_promises3, import_posix, _CommandsRouter, CommandsRouter;
3404
3776
  var init_CommandsRouter = __esm({
3405
3777
  "src/app/router/CommandsRouter.ts"() {
3406
3778
  "use strict";
3407
3779
  init_cjs_shims();
3408
- import_node_fs2 = require("fs");
3780
+ import_discord11 = require("discord.js");
3781
+ import_node_fs3 = require("fs");
3409
3782
  import_promises3 = require("fs/promises");
3410
- import_node_path3 = __toESM(require("path"));
3783
+ import_posix = __toESM(require("path/posix"));
3411
3784
  _CommandsRouter = class _CommandsRouter {
3412
- /**
3413
- * Creates a new CommandsRouter instance
3414
- * @param options - Configuration options for the router
3415
- */
3416
3785
  constructor(options) {
3417
3786
  this.options = options;
3418
- if (!options.entrypoint) {
3419
- throw new Error("Entrypoint directory must be provided");
3420
- }
3421
- options.matcher ??= {};
3422
- options.matcher.command ??= /command\.(m|c)?(j|t)sx?$/;
3423
- options.matcher.middleware ??= /middleware\.(m|c)?(j|t)sx?$/;
3424
3787
  }
3425
- commands = /* @__PURE__ */ new Map();
3426
- middlewares = /* @__PURE__ */ new Map();
3427
- /**
3428
- * Gets the configured entrypoint directory
3429
- */
3788
+ commands = new import_discord11.Collection();
3789
+ middlewares = new import_discord11.Collection();
3790
+ subcommands = new import_discord11.Collection();
3791
+ isValidPath() {
3792
+ return (0, import_node_fs3.existsSync)(this.entrypoint);
3793
+ }
3430
3794
  get entrypoint() {
3431
3795
  return this.options.entrypoint;
3432
3796
  }
3433
- /**
3434
- * Gets the configured matchers for command and middleware files
3435
- */
3436
- get matchers() {
3437
- return this.options.matcher;
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();
3805
+ }
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;
3438
3861
  }
3439
- /**
3440
- * Returns the cached data of the commands and middleware
3441
- */
3442
3862
  getData() {
3443
3863
  return {
3444
3864
  commands: this.commands,
3445
- middleware: this.middlewares
3865
+ middlewares: this.middlewares,
3866
+ subcommands: this.subcommands
3446
3867
  };
3447
3868
  }
3448
- /**
3449
- * Checks if the entrypoint path is valid
3450
- */
3451
- isValidPath() {
3452
- return (0, import_node_fs2.existsSync)(this.entrypoint);
3453
- }
3454
- /**
3455
- * Executes a matcher against a file path
3456
- * @param matcher - The matcher to use
3457
- * @param path - The file path to test
3458
- * @returns boolean indicating if the path matches
3459
- */
3460
- execMatcher(matcher, path3) {
3461
- if (typeof matcher === "string") {
3462
- return path3.endsWith(matcher);
3463
- }
3464
- if (matcher instanceof RegExp) {
3465
- return matcher.test(path3);
3466
- }
3467
- return matcher(path3);
3468
- }
3469
- /**
3470
- * Converts an absolute path to a path relative to the entrypoint
3471
- * @param path - The absolute path to convert
3472
- */
3473
- resolveRelativePath(path3) {
3474
- const regex = new RegExp(`^${this.entrypoint}`);
3475
- return path3.replace(regex, "");
3476
- }
3477
- /**
3478
- * Matches a command by name or path segments
3479
- * @param commandOrSegment - Command name or array of path segments
3480
- * @returns Matched command and its middlewares, or null if no match
3481
- */
3482
- match(commandOrSegment) {
3483
- if (!(commandOrSegment == null ? void 0 : commandOrSegment.length)) return null;
3484
- if (Array.isArray(commandOrSegment) && commandOrSegment.length === 1) {
3485
- commandOrSegment = commandOrSegment[0];
3486
- }
3487
- if (!Array.isArray(commandOrSegment) && !commandOrSegment.includes(" ")) {
3488
- const command2 = this.commands.get(commandOrSegment);
3489
- if (!command2) return null;
3490
- const middlewares2 = command2.middlewares.map((id) => this.middlewares.get(id)).filter((m) => !!m);
3491
- return {
3492
- command: command2,
3493
- middlewares: middlewares2
3494
- };
3495
- }
3496
- const segments = Array.isArray(commandOrSegment) ? commandOrSegment : commandOrSegment.split(" ");
3497
- const command = Array.from(this.commands.values()).find((cmd) => {
3498
- const commandSegments = cmd.parentSegments;
3499
- if (commandSegments.length !== segments.length) return false;
3500
- return commandSegments.every((segment, index) => {
3501
- if (/^\[.+\]$/.test(segment)) return true;
3502
- return segment === segments[index];
3503
- });
3504
- });
3505
- if (!command) return null;
3506
- const middlewares = command.middlewares.map((id) => this.middlewares.get(id)).filter((m) => !!m);
3869
+ toJSON() {
3507
3870
  return {
3508
- command,
3509
- middlewares
3871
+ commands: Object.fromEntries(this.commands.entries()),
3872
+ middlewares: Object.fromEntries(this.middlewares.entries()),
3873
+ subcommands: Object.fromEntries(this.subcommands.entries())
3510
3874
  };
3511
3875
  }
3512
- /**
3513
- * Reloads the commands tree by re-scanning the entrypoint directory
3514
- */
3515
- async reload() {
3516
- this.clear();
3517
- return this.scan();
3518
- }
3519
- /**
3520
- * Clears the internal commands and middleware maps
3521
- */
3522
- clear() {
3523
- this.commands.clear();
3524
- this.middlewares.clear();
3525
- }
3526
- /**
3527
- * Scans the entrypoint directory for commands and middleware
3528
- * @returns Promise resolving to the complete commands tree
3529
- */
3530
3876
  async scan() {
3531
- this.clear();
3532
- const files = await this.scanDirectory(this.entrypoint, []);
3533
- const commandFiles = files.filter((file) => {
3534
- const basename = import_node_path3.default.basename(file);
3535
- return !this.isIgnoredFile(basename) && this.isCommandFile(file);
3536
- });
3537
- const middlewareFiles = files.filter(
3538
- (file) => this.execMatcher(this.matchers.middleware, file)
3539
- );
3540
- for (const file of commandFiles) {
3541
- const parsedPath = this.parseCommandPath(file);
3542
- const location = this.resolveRelativePath(file);
3543
- const command = {
3544
- name: parsedPath.name,
3545
- path: location,
3546
- fullPath: file,
3547
- parent: parsedPath.parent,
3548
- parentSegments: parsedPath.parentSegments,
3549
- category: parsedPath.category,
3550
- middlewares: []
3551
- };
3552
- this.commands.set(parsedPath.name, command);
3553
- }
3554
- for (const file of middlewareFiles) {
3555
- const location = this.resolveRelativePath(file);
3556
- const dirname = import_node_path3.default.dirname(location);
3557
- const id = crypto.randomUUID();
3558
- const parts = location.split(import_node_path3.default.sep).filter((p) => p);
3559
- const categories = this.parseCategories(parts);
3560
- const middleware = {
3561
- id,
3562
- name: dirname,
3563
- path: location,
3564
- fullPath: file,
3565
- category: categories.length ? categories.join("/") : null
3566
- };
3567
- this.middlewares.set(id, middleware);
3568
- const isGlobalMiddleware = import_node_path3.default.parse(file).name === "middleware";
3569
- const commands = Array.from(this.commands.values());
3570
- for (const command of commands) {
3571
- const commandDir = import_node_path3.default.dirname(command.path);
3572
- if (isGlobalMiddleware) {
3573
- if (commandDir === dirname || commandDir.startsWith(dirname + import_node_path3.default.sep)) {
3574
- command.middlewares.push(id);
3575
- }
3877
+ if (!this.isValidPath()) return this.toJSON();
3878
+ const root = this.entrypoint;
3879
+ await this.scanDeep(root);
3880
+ return this.toJSON();
3881
+ }
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);
3893
+ }
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
+ );
3576
3909
  } else {
3577
- const commandName = command.name;
3578
- const middlewareName = import_node_path3.default.basename(file).replace(/\.middleware\.(m|c)?(j|t)sx?$/, "");
3579
- if (commandName === middlewareName && commandDir === dirname) {
3580
- command.middlewares.push(id);
3581
- }
3910
+ this.processCommand(
3911
+ itemPath,
3912
+ category,
3913
+ isIndexFile ? normalizedPath : null
3914
+ );
3582
3915
  }
3583
3916
  }
3584
3917
  }
3585
- return this.toJSON();
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);
3586
3953
  }
3587
3954
  /**
3588
- * Converts the internal maps to a serializable object
3589
- * @returns CommandsTree containing all commands and middleware
3955
+ * Gets the appropriate file name, handling index files specially
3956
+ * For index files, it returns the parent directory name (excluding category markers)
3590
3957
  */
3591
- toJSON() {
3592
- return {
3593
- commands: Object.fromEntries(this.commands),
3594
- middleware: Object.fromEntries(this.middlewares)
3595
- };
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);
3962
+ }
3963
+ return fileName;
3596
3964
  }
3597
3965
  /**
3598
- * Recursively scans a directory for files
3599
- * @param dir - Directory to scan
3600
- * @param entries - Accumulator for found files
3601
- * @returns Promise resolving to array of file paths
3966
+ * Extract the clean directory name, removing any category markers
3602
3967
  */
3603
- async scanDirectory(dir, entries) {
3604
- const files = await (0, import_promises3.readdir)(dir, {
3605
- withFileTypes: true
3606
- });
3607
- for (const file of files) {
3608
- if (file.name === "node_modules" || file.parentPath.includes("node_modules")) {
3609
- continue;
3610
- }
3611
- if (file.isDirectory()) {
3612
- const next = (0, import_node_path3.join)(dir, file.name);
3613
- await this.scanDirectory(next, entries);
3614
- continue;
3615
- }
3616
- entries.push((0, import_node_path3.join)(dir, file.name));
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);
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);
3617
3983
  }
3618
- return entries;
3619
3984
  }
3620
- isIgnoredFile(filename) {
3621
- return filename.startsWith("_");
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);
3990
+ }
3622
3991
  }
3623
- isCommandFile(path3) {
3624
- if (this.execMatcher(this.matchers.middleware, path3)) return false;
3625
- return /index\.(m|c)?(j|t)sx?$/.test(path3) || /\.(m|c)?(j|t)sx?$/.test(path3);
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(":");
3626
3997
  }
3627
- parseCategories(parts) {
3628
- return parts.filter((part) => part.startsWith("(") && part.endsWith(")")).map((part) => part.slice(1, -1));
3998
+ getRelativePath(entry) {
3999
+ return import_posix.default.relative(this.entrypoint, entry);
3629
4000
  }
3630
- parseCommandPath(filepath) {
3631
- const location = this.resolveRelativePath(filepath);
3632
- const parts = location.split(import_node_path3.default.sep).filter((p) => p);
3633
- const categories = this.parseCategories(parts);
3634
- const segments = parts.filter(
3635
- (part) => !(part.startsWith("(") && part.endsWith(")"))
3636
- );
3637
- let name = segments.pop() || "";
3638
- name = name.replace(/\.(m|c)?(j|t)sx?$/, "").replace(/^index$/, "");
3639
- return {
3640
- name,
3641
- category: categories.length ? categories.join("/") : null,
3642
- parent: segments.length ? segments.join(" ") : null,
3643
- parentSegments: segments
3644
- };
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;
4009
+ }
4010
+ extractName(entry) {
4011
+ return import_posix.default.basename(entry).replace(/\.(c|m)?(j|t)sx?$/, "");
3645
4012
  }
3646
4013
  };
3647
4014
  __name(_CommandsRouter, "CommandsRouter");
@@ -3650,14 +4017,14 @@ var init_CommandsRouter = __esm({
3650
4017
  });
3651
4018
 
3652
4019
  // src/app/router/EventsRouter.ts
3653
- var import_node_fs3, import_promises4, import_node_path4, _EventsRouter, EventsRouter;
4020
+ var import_node_fs4, import_promises4, import_node_path3, _EventsRouter, EventsRouter;
3654
4021
  var init_EventsRouter = __esm({
3655
4022
  "src/app/router/EventsRouter.ts"() {
3656
4023
  "use strict";
3657
4024
  init_cjs_shims();
3658
- import_node_fs3 = require("fs");
4025
+ import_node_fs4 = require("fs");
3659
4026
  import_promises4 = require("fs/promises");
3660
- import_node_path4 = require("path");
4027
+ import_node_path3 = require("path");
3661
4028
  _EventsRouter = class _EventsRouter {
3662
4029
  /**
3663
4030
  * Creates a new EventsRouter instance
@@ -3691,7 +4058,7 @@ var init_EventsRouter = __esm({
3691
4058
  * Checks if the entrypoint path is valid
3692
4059
  */
3693
4060
  isValidPath() {
3694
- return (0, import_node_fs3.existsSync)(this.entrypoint);
4061
+ return (0, import_node_fs4.existsSync)(this.entrypoint);
3695
4062
  }
3696
4063
  /**
3697
4064
  * Clear all parsed events
@@ -3715,7 +4082,7 @@ var init_EventsRouter = __esm({
3715
4082
  const dirs = await (0, import_promises4.readdir)(this.entrypoint, { withFileTypes: true });
3716
4083
  for (const dir of dirs) {
3717
4084
  if (dir.isDirectory()) {
3718
- const path3 = (0, import_node_path4.join)(this.entrypoint, dir.name);
4085
+ const path3 = (0, import_node_path3.join)(this.entrypoint, dir.name);
3719
4086
  const event = await this.scanEvent(dir.name, path3);
3720
4087
  this.events.set(event.event, event);
3721
4088
  }
@@ -3742,12 +4109,12 @@ var init_EventsRouter = __esm({
3742
4109
  for (const file of files) {
3743
4110
  if (/node_modules/.test(file.name)) continue;
3744
4111
  if (file.isDirectory()) {
3745
- const nextPath = (0, import_node_path4.join)(path3, file.name);
4112
+ const nextPath = (0, import_node_path3.join)(path3, file.name);
3746
4113
  await this.scanEvent(event, nextPath, listeners);
3747
4114
  continue;
3748
4115
  }
3749
4116
  if (file.isFile() && /\.(m|c)?(j|t)sx?$/.test(file.name)) {
3750
- listeners.push((0, import_node_path4.join)(file.parentPath, file.name));
4117
+ listeners.push((0, import_node_path3.join)(file.parentPath, file.name));
3751
4118
  }
3752
4119
  }
3753
4120
  const maybeNamespace = path3.replace(this.entrypoint, "").replaceAll("\\", "/").split("/").shift();
@@ -3799,7 +4166,10 @@ var init_AppEventsHandler = __esm({
3799
4166
  `Event handler for ${event.event}${event.namespace ? ` of namespace ${event.namespace}` : ""} does not have a default export or is not a function`
3800
4167
  );
3801
4168
  }
3802
- listeners.push(handler.default);
4169
+ listeners.push({
4170
+ handler: handler.default,
4171
+ once: !!handler.once
4172
+ });
3803
4173
  }
3804
4174
  const len = listeners.length;
3805
4175
  if (!len) {
@@ -3827,11 +4197,28 @@ var init_AppEventsHandler = __esm({
3827
4197
  registerAllClientEvents() {
3828
4198
  const client = this.commandkit.client;
3829
4199
  for (const [key, data] of this.loadedEvents.entries()) {
3830
- const { name, listeners, namespace, mainListener } = data;
3831
- const main = mainListener || (async (...args) => {
3832
- for (const listener of listeners) {
4200
+ const { name, listeners, namespace } = data;
4201
+ const onceListeners = listeners.filter((listener) => listener.once);
4202
+ const onListeners = listeners.filter((listener) => !listener.once);
4203
+ const executedOnceListeners = /* @__PURE__ */ new Set();
4204
+ const mainHandler = /* @__PURE__ */ __name(async (...args) => {
4205
+ for (const listener of onListeners) {
4206
+ try {
4207
+ await listener.handler(...args);
4208
+ } catch (e) {
4209
+ Logger.error(
4210
+ `Error handling event ${name}${namespace ? ` of namespace ${namespace}` : ""}`,
4211
+ e
4212
+ );
4213
+ }
4214
+ }
4215
+ }, "mainHandler");
4216
+ const onceHandler = /* @__PURE__ */ __name(async (...args) => {
4217
+ for (const listener of onceListeners) {
3833
4218
  try {
3834
- await listener(...args);
4219
+ if (executedOnceListeners.has(listener.handler)) continue;
4220
+ await listener.handler(...args);
4221
+ executedOnceListeners.add(listener.handler);
3835
4222
  } catch (e) {
3836
4223
  Logger.error(
3837
4224
  `Error handling event ${name}${namespace ? ` of namespace ${namespace}` : ""}`,
@@ -3839,16 +4226,35 @@ var init_AppEventsHandler = __esm({
3839
4226
  );
3840
4227
  }
3841
4228
  }
4229
+ if (executedOnceListeners.size === onceListeners.length && onListeners.length === 0) {
4230
+ this.loadedEvents.delete(key);
4231
+ Logger.info(
4232
+ `\u{1F9F9} Cleaned up completed once-only event ${name}${namespace ? ` of namespace ${namespace}` : ""}`
4233
+ );
4234
+ }
4235
+ }, "onceHandler");
4236
+ this.loadedEvents.set(key, {
4237
+ ...data,
4238
+ mainListener: onListeners.length > 0 ? { handler: mainHandler, once: false } : void 0,
4239
+ executedOnceListeners
3842
4240
  });
3843
- if (!mainListener) {
3844
- this.loadedEvents.set(key, {
3845
- ...data,
3846
- mainListener: main
3847
- });
4241
+ if (namespace) {
4242
+ if (onListeners.length > 0) {
4243
+ this.commandkit.events.on(namespace, name, mainHandler);
4244
+ }
4245
+ if (onceListeners.length > 0) {
4246
+ this.commandkit.events.once(namespace, name, onceHandler);
4247
+ }
4248
+ } else {
4249
+ if (onListeners.length > 0) {
4250
+ client.on(name, mainHandler);
4251
+ }
4252
+ if (onceListeners.length > 0) {
4253
+ client.once(name, onceHandler);
4254
+ }
3848
4255
  }
3849
- client.on(name, main);
3850
4256
  Logger.info(
3851
- `\u{1F50C} Registered event ${name}${namespace ? ` of namespace ${namespace}` : ""}`
4257
+ `\u{1F50C} Registered event ${name}${namespace ? ` of namespace ${namespace}` : ""} (${onListeners.length} regular, ${onceListeners.length} once-only)`
3852
4258
  );
3853
4259
  }
3854
4260
  }
@@ -3859,9 +4265,17 @@ var init_AppEventsHandler = __esm({
3859
4265
  { name, mainListener, namespace }
3860
4266
  ] of this.loadedEvents.entries()) {
3861
4267
  if (mainListener) {
3862
- client.off(name, mainListener);
4268
+ if (namespace) {
4269
+ this.commandkit.events.off(namespace, name, mainListener.handler);
4270
+ } else {
4271
+ client.off(name, mainListener.handler);
4272
+ }
3863
4273
  } else {
3864
- client.removeAllListeners(name);
4274
+ if (namespace) {
4275
+ this.commandkit.events.removeAllListeners(namespace, name);
4276
+ } else {
4277
+ client.removeAllListeners(name);
4278
+ }
3865
4279
  }
3866
4280
  this.loadedEvents.delete(key);
3867
4281
  Logger.info(
@@ -3875,6 +4289,54 @@ var init_AppEventsHandler = __esm({
3875
4289
  }
3876
4290
  });
3877
4291
 
4292
+ // src/utils/types-package.ts
4293
+ 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");
4300
+ const exists = (0, import_node_fs5.existsSync)(packageJSON);
4301
+ if (exists) return location;
4302
+ const packageJSONContent = {
4303
+ name: "commandkit-types",
4304
+ version: "1.0.0",
4305
+ description: "CommandKit types package",
4306
+ type: "commonjs",
4307
+ main: "index.js",
4308
+ types: "index.d.ts"
4309
+ };
4310
+ const indexContent = `module.exports = {};`;
4311
+ const typesContent = `import { CommandLocalizationTypeData } from './locale.d.ts';
4312
+ import { CommandTypeData } from './command.d.ts';
4313
+
4314
+ declare module 'commandkit' {
4315
+ export interface CommandKitTypeReferences {
4316
+ locale: CommandLocalizationTypeData;
4317
+ command: CommandTypeData;
4318
+ }
4319
+ }`;
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, "");
4326
+ return location;
4327
+ }
4328
+ var import_node_fs5, import_promises5, import_node_path4;
4329
+ var init_types_package = __esm({
4330
+ "src/utils/types-package.ts"() {
4331
+ "use strict";
4332
+ init_cjs_shims();
4333
+ import_node_fs5 = require("fs");
4334
+ import_promises5 = require("fs/promises");
4335
+ import_node_path4 = require("path");
4336
+ __name(generateTypesPackage, "generateTypesPackage");
4337
+ }
4338
+ });
4339
+
3878
4340
  // src/cli/common.ts
3879
4341
  function write(message) {
3880
4342
  process.stdout.write(message);
@@ -3902,7 +4364,7 @@ async function loadConfigFileFromPath(target) {
3902
4364
  const isTs = await ensureTypeScript(target);
3903
4365
  if (isTs && ts) {
3904
4366
  const { transpileModule } = ts;
3905
- const src = import_node_fs4.default.readFileSync(target, "utf8");
4367
+ const src = import_node_fs6.default.readFileSync(target, "utf8");
3906
4368
  const { outputText } = transpileModule(src, {
3907
4369
  compilerOptions: {
3908
4370
  module: ts.ModuleKind.ESNext,
@@ -3911,14 +4373,9 @@ async function loadConfigFileFromPath(target) {
3911
4373
  },
3912
4374
  fileName: target
3913
4375
  });
3914
- const nodeModulesPath = (0, import_node_path5.join)(
3915
- process.cwd(),
3916
- "node_modules",
3917
- ".commandkit_tmp"
3918
- );
3919
- import_node_fs4.default.mkdirSync(nodeModulesPath, { recursive: true });
4376
+ const nodeModulesPath = await generateTypesPackage();
3920
4377
  const tmpFile = (0, import_node_path5.join)(nodeModulesPath, "compiled-commandkit.config.mjs");
3921
- import_node_fs4.default.writeFileSync(tmpFile, outputText);
4378
+ import_node_fs6.default.writeFileSync(tmpFile, outputText);
3922
4379
  target = tmpFile;
3923
4380
  }
3924
4381
  const config = await import(`file://${target}`).then(
@@ -3927,20 +4384,21 @@ async function loadConfigFileFromPath(target) {
3927
4384
  return config;
3928
4385
  }
3929
4386
  async function ensureExists(loc) {
3930
- const exists = import_node_fs4.default.existsSync(loc);
4387
+ const exists = import_node_fs6.default.existsSync(loc);
3931
4388
  if (!exists) {
3932
4389
  throw new Error(`File not found: ${loc}`);
3933
4390
  }
3934
4391
  }
3935
- var import_rimraf, import_node_path5, import_node_fs4, ts;
4392
+ var import_rimraf, import_node_path5, import_node_fs6, ts;
3936
4393
  var init_common = __esm({
3937
4394
  "src/cli/common.ts"() {
3938
4395
  "use strict";
3939
4396
  init_cjs_shims();
3940
4397
  import_rimraf = require("rimraf");
3941
4398
  import_node_path5 = require("path");
3942
- import_node_fs4 = __toESM(require("fs"));
4399
+ import_node_fs6 = __toESM(require("fs"));
3943
4400
  init_colors();
4401
+ init_types_package();
3944
4402
  __name(write, "write");
3945
4403
  __name(panic, "panic");
3946
4404
  __name(ensureTypeScript, "ensureTypeScript");
@@ -3953,7 +4411,7 @@ var init_common = __esm({
3953
4411
  function findConfigFile(cwd) {
3954
4412
  const locations = CONFIG_FILE_NAMES.map((name) => (0, import_node_path6.join)(cwd, name));
3955
4413
  for (const location of locations) {
3956
- if ((0, import_node_fs5.existsSync)(location)) {
4414
+ if ((0, import_node_fs7.existsSync)(location)) {
3957
4415
  return {
3958
4416
  path: location,
3959
4417
  isTypeScript: /\.ts$/.test(location)
@@ -3970,12 +4428,12 @@ async function loadConfigFile(entrypoint = process.cwd()) {
3970
4428
  loadedConfig = config;
3971
4429
  return config;
3972
4430
  }
3973
- var import_node_fs5, import_node_path6, CONFIG_FILE_NAMES, loadedConfig;
4431
+ var import_node_fs7, import_node_path6, CONFIG_FILE_NAMES, loadedConfig;
3974
4432
  var init_loader = __esm({
3975
4433
  "src/config/loader.ts"() {
3976
4434
  "use strict";
3977
4435
  init_cjs_shims();
3978
- import_node_fs5 = require("fs");
4436
+ import_node_fs7 = require("fs");
3979
4437
  import_node_path6 = require("path");
3980
4438
  init_common();
3981
4439
  init_config();
@@ -3994,12 +4452,13 @@ var init_loader = __esm({
3994
4452
  // src/utils/dev-hooks.ts
3995
4453
  function registerDevHooks(commandkit) {
3996
4454
  if (!COMMANDKIT_IS_DEV) return;
3997
- process.stdin.on("data", (chunk) => {
3998
- const input = chunk.toString().trim();
3999
- const match = input.match(EVENT_PATTERN);
4000
- if (!match) return;
4001
- const [, event, , path3] = match;
4002
- Logger.info(`Received HMR event: ${event}${path3 ? ` for ${path3}` : ""}`);
4455
+ process.on("message", (message) => {
4456
+ if (typeof message !== "object" || message === null) return;
4457
+ const { event, path: path3 } = message;
4458
+ if (!event) return;
4459
+ if (process.env.COMMANDKIT_DEBUG_HMR === "true") {
4460
+ Logger.info(`Received HMR event: ${event}${path3 ? ` for ${path3}` : ""}`);
4461
+ }
4003
4462
  switch (event) {
4004
4463
  case "reload-commands":
4005
4464
  commandkit.commandHandler.reloadCommands();
@@ -4013,31 +4472,75 @@ function registerDevHooks(commandkit) {
4013
4472
  }
4014
4473
  });
4015
4474
  }
4016
- var EVENT_PATTERN;
4017
4475
  var init_dev_hooks = __esm({
4018
4476
  "src/utils/dev-hooks.ts"() {
4019
4477
  "use strict";
4020
4478
  init_cjs_shims();
4021
4479
  init_Logger();
4022
4480
  init_constants();
4023
- EVENT_PATTERN = /^COMMANDKIT_EVENT=(\w+)(\|(.+))?$/;
4024
4481
  __name(registerDevHooks, "registerDevHooks");
4025
4482
  }
4026
4483
  });
4027
4484
 
4485
+ // src/events/CommandKitEventsChannel.ts
4486
+ var import_node_events, _CommandKitEventsChannel, CommandKitEventsChannel;
4487
+ var init_CommandKitEventsChannel = __esm({
4488
+ "src/events/CommandKitEventsChannel.ts"() {
4489
+ "use strict";
4490
+ init_cjs_shims();
4491
+ import_node_events = __toESM(require("events"));
4492
+ _CommandKitEventsChannel = class _CommandKitEventsChannel {
4493
+ constructor(commandkit) {
4494
+ this.commandkit = commandkit;
4495
+ }
4496
+ emitter = new import_node_events.default();
4497
+ to(namespace) {
4498
+ return {
4499
+ on: this.on.bind(this, namespace),
4500
+ off: this.off.bind(this, namespace),
4501
+ once: this.once.bind(this, namespace),
4502
+ emit: this.emit.bind(this, namespace),
4503
+ removeAllListeners: this.removeAllListeners.bind(this, namespace)
4504
+ };
4505
+ }
4506
+ on(namespace, event, listener) {
4507
+ this.emitter.on(`${namespace}:${event}`, listener);
4508
+ }
4509
+ off(namespace, event, listener) {
4510
+ this.emitter.off(`${namespace}:${event}`, listener);
4511
+ }
4512
+ once(namespace, event, listener) {
4513
+ this.emitter.once(`${namespace}:${event}`, listener);
4514
+ }
4515
+ emit(namespace, event, ...args) {
4516
+ return this.emitter.emit(`${namespace}:${event}`, ...args);
4517
+ }
4518
+ removeAllListeners(namespace, event) {
4519
+ if (event) {
4520
+ this.emitter.removeAllListeners(`${namespace}:${event}`);
4521
+ } else {
4522
+ this.emitter.removeAllListeners(namespace);
4523
+ }
4524
+ }
4525
+ };
4526
+ __name(_CommandKitEventsChannel, "CommandKitEventsChannel");
4527
+ CommandKitEventsChannel = _CommandKitEventsChannel;
4528
+ }
4529
+ });
4530
+
4028
4531
  // src/CommandKit.ts
4029
- var import_node_events, import_discord11, import_node_path7, _started, _CommandKit_instances, init_fn, initCommands_fn, initEvents_fn, _CommandKit, CommandKit;
4532
+ var import_node_events2, import_discord12, import_node_path7, _started, _CommandKit_instances, init_fn, initCommands_fn, initEvents_fn, _CommandKit, CommandKit;
4030
4533
  var init_CommandKit = __esm({
4031
4534
  "src/CommandKit.ts"() {
4032
4535
  "use strict";
4033
4536
  init_cjs_shims();
4034
- import_node_events = __toESM(require("events"));
4537
+ import_node_events2 = __toESM(require("events"));
4035
4538
  init_colors();
4036
4539
  init_CacheProvider();
4037
4540
  init_MemoryCache();
4038
4541
  init_components();
4039
4542
  init_EventInterceptor();
4040
- import_discord11 = require("discord.js");
4543
+ import_discord12 = require("discord.js");
4041
4544
  init_DefaultLocalizationStrategy();
4042
4545
  init_utilities();
4043
4546
  import_node_path7 = require("path");
@@ -4048,7 +4551,11 @@ var init_CommandKit = __esm({
4048
4551
  init_loader();
4049
4552
  init_constants();
4050
4553
  init_dev_hooks();
4051
- _CommandKit = class _CommandKit extends import_node_events.default {
4554
+ init_CommandKitEventsChannel();
4555
+ init_plugins();
4556
+ init_types_package();
4557
+ init_Logger();
4558
+ _CommandKit = class _CommandKit extends import_node_events2.default {
4052
4559
  /**
4053
4560
  * Create a new command and event handler with CommandKit.
4054
4561
  *
@@ -4080,7 +4587,7 @@ var init_CommandKit = __esm({
4080
4587
  __privateAdd(this, _started, false);
4081
4588
  __publicField(this, "eventInterceptor");
4082
4589
  __publicField(this, "config", {
4083
- defaultLocale: import_discord11.Locale.EnglishUS,
4590
+ defaultLocale: import_discord12.Locale.EnglishUS,
4084
4591
  localizationStrategy: new DefaultLocalizationStrategy(this),
4085
4592
  getMessageCommandPrefix: /* @__PURE__ */ __name(() => "!", "getMessageCommandPrefix")
4086
4593
  });
@@ -4089,6 +4596,7 @@ var init_CommandKit = __esm({
4089
4596
  __publicField(this, "commandHandler", new AppCommandHandler(this));
4090
4597
  __publicField(this, "eventHandler", new AppEventsHandler(this));
4091
4598
  __publicField(this, "plugins");
4599
+ __publicField(this, "events", new CommandKitEventsChannel(this));
4092
4600
  options.debugCommands ??= process.env.NODE_ENV !== "production";
4093
4601
  if (options.cacheProvider !== null && (!options.cacheProvider || !(options.cacheProvider instanceof CacheProvider))) {
4094
4602
  options.cacheProvider = new MemoryCache();
@@ -4104,8 +4612,18 @@ var init_CommandKit = __esm({
4104
4612
  * @param token The application token to connect to the discord gateway. If not provided, it will use the `TOKEN` or `DISCORD_TOKEN` environment variable. If set to `false`, it will not login.
4105
4613
  */
4106
4614
  async start(token) {
4107
- await loadConfigFile();
4108
4615
  if (__privateGet(this, _started)) return;
4616
+ if (COMMANDKIT_IS_DEV) {
4617
+ try {
4618
+ registerDevHooks(this);
4619
+ await generateTypesPackage();
4620
+ } catch (e) {
4621
+ if (process.env.COMMANDKIT_DEBUG_TYPEGEN) {
4622
+ Logger.error(e);
4623
+ }
4624
+ }
4625
+ }
4626
+ await this.loadPlugins();
4109
4627
  await __privateMethod(this, _CommandKit_instances, init_fn).call(this);
4110
4628
  this.incrementClientListenersCount();
4111
4629
  if (token !== false && !this.options.client.isReady()) {
@@ -4114,11 +4632,19 @@ var init_CommandKit = __esm({
4114
4632
  );
4115
4633
  }
4116
4634
  __privateSet(this, _started, true);
4117
- if (COMMANDKIT_IS_DEV) {
4118
- registerDevHooks(this);
4119
- }
4120
4635
  await this.commandHandler.registrar.register();
4121
4636
  }
4637
+ /**
4638
+ * Loads all the plugins.
4639
+ */
4640
+ async loadPlugins() {
4641
+ const config = await loadConfigFile();
4642
+ const plugins = config.plugins.filter((p) => isRuntimePlugin(p));
4643
+ if (!plugins.length) return;
4644
+ for (const plugin of plugins) {
4645
+ await this.plugins.softRegisterPlugin(plugin);
4646
+ }
4647
+ }
4122
4648
  /**
4123
4649
  * Whether or not the commandkit application has started.
4124
4650
  */
@@ -4275,6 +4801,10 @@ var init_CommandKit = __esm({
4275
4801
  initCommands_fn = /* @__PURE__ */ __name(async function() {
4276
4802
  if (this.commandsRouter.isValidPath()) {
4277
4803
  await this.commandsRouter.scan();
4804
+ if (COMMANDKIT_IS_DEV) {
4805
+ const visual = this.commandsRouter.visualize();
4806
+ console.log(visual);
4807
+ }
4278
4808
  }
4279
4809
  await this.commandHandler.loadCommands();
4280
4810
  }, "#initCommands");
@@ -4303,7 +4833,7 @@ var init_version = __esm({
4303
4833
  "use strict";
4304
4834
  init_cjs_shims();
4305
4835
  version = /* @__MACRO__ $version */
4306
- "0.1.11-dev.20250306101654";
4836
+ "0.1.11-dev.20250307192025";
4307
4837
  }
4308
4838
  });
4309
4839
 
@@ -4337,11 +4867,18 @@ var init_env = __esm({
4337
4867
  });
4338
4868
 
4339
4869
  // src/cli/app-process.ts
4870
+ function getStdio(supportsCommands) {
4871
+ if (supportsCommands) {
4872
+ return ["pipe", "pipe", "pipe", "ipc"];
4873
+ }
4874
+ return ["pipe", "pipe", "pipe"];
4875
+ }
4340
4876
  function createAppProcess(fileName, cwd, isDev) {
4341
4877
  var _a, _b;
4342
- if (!(0, import_node_fs6.existsSync)((0, import_node_path8.join)(cwd, fileName))) {
4878
+ if (!(0, import_node_fs8.existsSync)((0, import_node_path8.join)(cwd, fileName))) {
4343
4879
  panic(`Could not locate the entrypoint file: ${fileName}`);
4344
4880
  }
4881
+ const stdio = getStdio(isDev);
4345
4882
  const ps = (0, import_node_child_process.spawn)(
4346
4883
  "node",
4347
4884
  [
@@ -4353,14 +4890,14 @@ function createAppProcess(fileName, cwd, isDev) {
4353
4890
  cwd,
4354
4891
  windowsHide: true,
4355
4892
  env: DevEnv(),
4356
- stdio: ["pipe", "pipe", "pipe"]
4893
+ stdio
4357
4894
  }
4358
4895
  );
4359
4896
  (_a = ps.stdout) == null ? void 0 : _a.pipe(process.stdout);
4360
4897
  (_b = ps.stderr) == null ? void 0 : _b.pipe(process.stderr);
4361
4898
  return ps;
4362
4899
  }
4363
- var import_node_child_process, import_node_path8, import_node_fs6;
4900
+ var import_node_child_process, import_node_path8, import_node_fs8;
4364
4901
  var init_app_process = __esm({
4365
4902
  "src/cli/app-process.ts"() {
4366
4903
  "use strict";
@@ -4368,8 +4905,9 @@ var init_app_process = __esm({
4368
4905
  import_node_child_process = require("child_process");
4369
4906
  init_env();
4370
4907
  import_node_path8 = require("path");
4371
- import_node_fs6 = require("fs");
4908
+ import_node_fs8 = require("fs");
4372
4909
  init_common();
4910
+ __name(getStdio, "getStdio");
4373
4911
  __name(createAppProcess, "createAppProcess");
4374
4912
  }
4375
4913
  });
@@ -4454,9 +4992,9 @@ async function main() {
4454
4992
  await main();
4455
4993
  `;
4456
4994
  const dist = isDev ? ".commandkit" : distDir || "dist";
4457
- await (0, import_promises5.writeFile)((0, import_node_path9.join)(configPath, dist, "index.js"), code);
4995
+ await (0, import_promises6.writeFile)((0, import_node_path9.join)(configPath, dist, "index.js"), code);
4458
4996
  }
4459
- var import_tsup, import_promises5, import_node_path9, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4997
+ var import_tsup, import_promises6, import_node_path9, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4460
4998
  var init_build = __esm({
4461
4999
  "src/cli/build.ts"() {
4462
5000
  "use strict";
@@ -4464,7 +5002,7 @@ var init_build = __esm({
4464
5002
  import_tsup = require("tsup");
4465
5003
  init_plugins();
4466
5004
  init_loader();
4467
- import_promises5 = require("fs/promises");
5005
+ import_promises6 = require("fs/promises");
4468
5006
  import_node_path9 = require("path");
4469
5007
  init_env();
4470
5008
  __name(buildApplication, "buildApplication");
@@ -4531,7 +5069,11 @@ async function buildAndStart(configPath, skipStart = false) {
4531
5069
  esbuildPlugins: config.esbuildPlugins
4532
5070
  });
4533
5071
  if (skipStart) return null;
4534
- return createAppProcess(mainFile, configPath, true);
5072
+ const ps = createAppProcess(mainFile, configPath, true);
5073
+ ps.on("message", (message) => {
5074
+ console.log(`Received message from child process: ${message}`);
5075
+ });
5076
+ return ps;
4535
5077
  }
4536
5078
  async function bootstrapDevelopmentServer(configPath) {
4537
5079
  const start = performance.now();
@@ -4542,13 +5084,13 @@ async function bootstrapDevelopmentServer(configPath) {
4542
5084
  let ps = null;
4543
5085
  const performHMR = debounce(async (path3) => {
4544
5086
  if (!path3 || !ps) return false;
5087
+ if (!ps.send) return false;
4545
5088
  if (isCommandSource(path3)) {
4546
5089
  console.log(
4547
5090
  `${colors_default.cyanBright("Reloading command(s) at ")} ${colors_default.yellowBright(path3)}`
4548
5091
  );
4549
5092
  await buildAndStart(cwd, true);
4550
- ps.stdin.write(`COMMANDKIT_EVENT=reload-commands|${path3}
4551
- `);
5093
+ ps.send({ event: "reload-commands", path: path3 });
4552
5094
  return true;
4553
5095
  }
4554
5096
  if (isEventSource(path3)) {
@@ -4556,8 +5098,7 @@ async function bootstrapDevelopmentServer(configPath) {
4556
5098
  `${colors_default.cyanBright("Reloading event(s) at ")} ${colors_default.yellowBright(path3)}`
4557
5099
  );
4558
5100
  await buildAndStart(cwd, true);
4559
- ps.stdin.write(`COMMANDKIT_EVENT=reload-events|${path3}
4560
- `);
5101
+ ps.send({ event: "reload-events", path: path3 });
4561
5102
  return true;
4562
5103
  }
4563
5104
  if (isLocaleSource(path3)) {
@@ -4565,14 +5106,17 @@ async function bootstrapDevelopmentServer(configPath) {
4565
5106
  `${colors_default.cyanBright("Reloading locale(s) at ")} ${colors_default.yellowBright(path3)}`
4566
5107
  );
4567
5108
  await buildAndStart(cwd, true);
4568
- ps.stdin.write(`COMMANDKIT_EVENT=reload-locales|${path3}
4569
- `);
5109
+ ps.send({ event: "reload-locales", path: path3 });
4570
5110
  return true;
4571
5111
  }
4572
5112
  return false;
4573
5113
  }, 300);
4574
5114
  const hmrHandler = /* @__PURE__ */ __name(async (path3) => {
4575
- if (await performHMR(path3)) return;
5115
+ const hmr = await performHMR(path3);
5116
+ if (hmr) return;
5117
+ console.log(
5118
+ `${colors_default.yellowBright("\u26A1\uFE0F Performing full restart due to the changes in")} ${colors_default.cyanBright(path3)}`
5119
+ );
4576
5120
  ps == null ? void 0 : ps.kill();
4577
5121
  ps = await buildAndStart(cwd);
4578
5122
  }, "hmrHandler");
@@ -4587,18 +5131,15 @@ async function bootstrapDevelopmentServer(configPath) {
4587
5131
  break;
4588
5132
  case "rc":
4589
5133
  console.log(`Received reload commands command, reloading...`);
4590
- ps == null ? void 0 : ps.stdin.write(`COMMANDKIT_EVENT=reload-commands
4591
- `);
5134
+ ps == null ? void 0 : ps.send({ event: "reload-commands" });
4592
5135
  break;
4593
5136
  case "re":
4594
5137
  console.log(`Received reload events command, reloading...`);
4595
- ps == null ? void 0 : ps.stdin.write(`COMMANDKIT_EVENT=reload-events
4596
- `);
5138
+ ps == null ? void 0 : ps.send({ event: "reload-events" });
4597
5139
  break;
4598
5140
  case "rl":
4599
5141
  console.log(`Received reload locales command, reloading...`);
4600
- ps == null ? void 0 : ps.stdin.write(`COMMANDKIT_EVENT=reload-locales
4601
- `);
5142
+ ps == null ? void 0 : ps.send({ event: "reload-locales" });
4602
5143
  break;
4603
5144
  }
4604
5145
  });
@@ -4606,7 +5147,7 @@ async function bootstrapDevelopmentServer(configPath) {
4606
5147
  watcher.on("add", hmrHandler);
4607
5148
  watcher.on("unlink", hmrHandler);
4608
5149
  watcher.on("unlinkDir", (path3) => {
4609
- const hasChild = (0, import_node_fs7.readdirSync)(path3).length > 0;
5150
+ const hasChild = (0, import_node_fs9.readdirSync)(path3).length > 0;
4610
5151
  if (hasChild) return hmrHandler(path3);
4611
5152
  });
4612
5153
  watcher.on("error", (e) => {
@@ -4625,7 +5166,7 @@ ${colors_default.yellowBright("re")} - Reload all events
4625
5166
  ${colors_default.yellowBright("rl")} - Reload all locales`
4626
5167
  );
4627
5168
  }
4628
- var import_path2, import_chokidar, import_node_fs7, isCommandSource, isEventSource, isLocaleSource;
5169
+ var import_path2, import_chokidar, import_node_fs9, isCommandSource, isEventSource, isLocaleSource;
4629
5170
  var init_development = __esm({
4630
5171
  "src/cli/development.ts"() {
4631
5172
  "use strict";
@@ -4636,7 +5177,7 @@ var init_development = __esm({
4636
5177
  init_app_process();
4637
5178
  init_build();
4638
5179
  import_chokidar = require("chokidar");
4639
- import_node_fs7 = require("fs");
5180
+ import_node_fs9 = require("fs");
4640
5181
  init_utilities();
4641
5182
  init_colors();
4642
5183
  __name(buildAndStart, "buildAndStart");
@@ -4723,7 +5264,7 @@ __export(generators_exports, {
4723
5264
  });
4724
5265
  async function generateCommand(name, customPath) {
4725
5266
  const cmdPath = (0, import_path4.join)(customPath || COMMANDS_DIR, name);
4726
- if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises6.mkdir)(cmdPath, { recursive: true });
5267
+ if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises7.mkdir)(cmdPath, { recursive: true });
4727
5268
  if ((0, import_fs2.existsSync)((0, import_path4.join)(cmdPath, "command.ts"))) {
4728
5269
  panic(`Command ${name} already exists.`);
4729
5270
  }
@@ -4743,7 +5284,7 @@ export const message: MessageCommand = async (ctx) => {
4743
5284
  await ctx.message.reply('Hello from ${name}!');
4744
5285
  };
4745
5286
  `.trim();
4746
- await (0, import_promises6.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5287
+ await (0, import_promises7.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
4747
5288
  console.log(
4748
5289
  colors_default.green(
4749
5290
  `Command ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(cmdPath))}/command.ts`
@@ -4752,10 +5293,10 @@ export const message: MessageCommand = async (ctx) => {
4752
5293
  }
4753
5294
  async function generateEvent(name, customPath) {
4754
5295
  const eventPath = (0, import_path4.join)(customPath || EVENTS_DIR, name);
4755
- if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises6.mkdir)(eventPath, { recursive: true });
5296
+ if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises7.mkdir)(eventPath, { recursive: true });
4756
5297
  let filename = "event.ts";
4757
5298
  if ((0, import_fs2.existsSync)((0, import_path4.join)(eventPath, filename))) {
4758
- const count = (await (0, import_promises6.readdir)(eventPath)).length;
5299
+ const count = (await (0, import_promises7.readdir)(eventPath)).length;
4759
5300
  filename = `${String(count).padStart(2, "0")}_${filename}`;
4760
5301
  }
4761
5302
  const eventFile = `
@@ -4763,7 +5304,7 @@ export default async function on${name[0].toUpperCase() + name.slice(1)}() {
4763
5304
  console.log('${name} event fired!');
4764
5305
  };
4765
5306
  `.trim();
4766
- await (0, import_promises6.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5307
+ await (0, import_promises7.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
4767
5308
  console.log(
4768
5309
  colors_default.green(
4769
5310
  `Event ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(eventPath))}/${colors_default.magenta(filename)}`
@@ -4772,7 +5313,7 @@ export default async function on${name[0].toUpperCase() + name.slice(1)}() {
4772
5313
  }
4773
5314
  async function generateLocale(locale, commandName, customPath) {
4774
5315
  const localeNames = Object.fromEntries(
4775
- Object.entries(import_discord12.Locale).map(([k, v]) => [v, k])
5316
+ Object.entries(import_discord13.Locale).map(([k, v]) => [v, k])
4776
5317
  );
4777
5318
  if (!localeNames[locale]) {
4778
5319
  panic(`Invalid locale: ${locale}`);
@@ -4781,7 +5322,7 @@ async function generateLocale(locale, commandName, customPath) {
4781
5322
  panic("Command name is required.");
4782
5323
  }
4783
5324
  const localePath = (0, import_path4.join)(customPath || LOCALES_DIR, locale);
4784
- if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises6.mkdir)(localePath, { recursive: true });
5325
+ if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises7.mkdir)(localePath, { recursive: true });
4785
5326
  if ((0, import_fs2.existsSync)((0, import_path4.join)(localePath, `${commandName}.json`))) {
4786
5327
  panic(`Locale file for ${commandName} already exists.`);
4787
5328
  }
@@ -4792,7 +5333,7 @@ async function generateLocale(locale, commandName, customPath) {
4792
5333
  },
4793
5334
  translations: {}
4794
5335
  };
4795
- await (0, import_promises6.writeFile)(
5336
+ await (0, import_promises7.writeFile)(
4796
5337
  (0, import_path4.join)(localePath, `${commandName}.json`),
4797
5338
  JSON.stringify(localeFile, null, 2)
4798
5339
  );
@@ -4804,14 +5345,14 @@ async function generateLocale(locale, commandName, customPath) {
4804
5345
  )
4805
5346
  );
4806
5347
  }
4807
- var import_promises6, import_path4, import_discord12, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5348
+ var import_promises7, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
4808
5349
  var init_generators = __esm({
4809
5350
  "src/cli/generators.ts"() {
4810
5351
  "use strict";
4811
5352
  init_cjs_shims();
4812
- import_promises6 = require("fs/promises");
5353
+ import_promises7 = require("fs/promises");
4813
5354
  import_path4 = require("path");
4814
- import_discord12 = require("discord.js");
5355
+ import_discord13 = require("discord.js");
4815
5356
  init_common();
4816
5357
  import_fs2 = require("fs");
4817
5358
  init_colors();