commandkit 0.1.11-dev.20250314022547 → 0.1.11-dev.20250328083250

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
@@ -1493,12 +1493,12 @@ var init_CompilerPluginRuntime = __esm({
1493
1493
  return !this.plugins.length;
1494
1494
  }
1495
1495
  async onLoad(args) {
1496
- var _a;
1496
+ var _a, _b;
1497
1497
  const source = await (0, import_promises.readFile)(args.path, "utf8");
1498
- let contents = source, loader = args.path.split(".").pop();
1498
+ let contents = source, loader = (_a = args.path) == null ? void 0 : _a.split(".").pop();
1499
1499
  for (const plugin of this.plugins) {
1500
1500
  try {
1501
- const res = await ((_a = plugin.transform) == null ? void 0 : _a.call(plugin, {
1501
+ const res = await ((_b = plugin.transform) == null ? void 0 : _b.call(plugin, {
1502
1502
  contents,
1503
1503
  path: args.path,
1504
1504
  loader,
@@ -1695,6 +1695,7 @@ var init_UseCacheTransformer = __esm({
1695
1695
  ).join("");
1696
1696
  }, "generateRandomString");
1697
1697
  cacheDirectivePlugin = /* @__PURE__ */ __name(async (source, args) => {
1698
+ var _a;
1698
1699
  const ast = parser.parse(source, {
1699
1700
  sourceType: "module",
1700
1701
  plugins: ["typescript", "jsx"]
@@ -1707,22 +1708,22 @@ var init_UseCacheTransformer = __esm({
1707
1708
  };
1708
1709
  traverse(ast, {
1709
1710
  Program: {
1710
- enter(path3) {
1711
- const binding = path3.scope.getBinding(CACHE_IDENTIFIER);
1711
+ enter(path2) {
1712
+ const binding = path2.scope.getBinding(CACHE_IDENTIFIER);
1712
1713
  if (binding) {
1713
1714
  state.cacheIdentifierName = `${CACHE_IDENTIFIER}_${generateRandomString()}`;
1714
1715
  }
1715
1716
  }
1716
1717
  },
1717
- ImportDeclaration(path3) {
1718
- if (path3.node.source.value === IMPORT_PATH && path3.node.specifiers.some(
1718
+ ImportDeclaration(path2) {
1719
+ if (path2.node.source.value === IMPORT_PATH && path2.node.specifiers.some(
1719
1720
  (spec) => t.isImportSpecifier(spec) && // @ts-ignore
1720
1721
  spec.imported.name === CACHE_IDENTIFIER
1721
1722
  )) {
1722
1723
  state.hasExistingImport = true;
1723
1724
  if (state.cacheIdentifierName !== CACHE_IDENTIFIER) {
1724
1725
  state.modifications.push(() => {
1725
- path3.node.specifiers.forEach((spec) => {
1726
+ path2.node.specifiers.forEach((spec) => {
1726
1727
  if (t.isImportSpecifier(spec) && // @ts-ignore
1727
1728
  spec.imported.name === CACHE_IDENTIFIER) {
1728
1729
  spec.local.name = state.cacheIdentifierName;
@@ -1732,14 +1733,14 @@ var init_UseCacheTransformer = __esm({
1732
1733
  }
1733
1734
  }
1734
1735
  },
1735
- "FunctionDeclaration|FunctionExpression|ArrowFunctionExpression|ObjectMethod"(path3) {
1736
- var _a, _b, _c;
1737
- const body = t.isBlockStatement(path3.node.body) ? path3.node.body : null;
1738
- const hasUseCache = (_a = body == null ? void 0 : body.directives) == null ? void 0 : _a.some(
1736
+ "FunctionDeclaration|FunctionExpression|ArrowFunctionExpression|ObjectMethod"(path2) {
1737
+ var _a2, _b, _c;
1738
+ const body = t.isBlockStatement(path2.node.body) ? path2.node.body : null;
1739
+ const hasUseCache = (_a2 = body == null ? void 0 : body.directives) == null ? void 0 : _a2.some(
1739
1740
  (d) => d.value.value === DIRECTIVE
1740
1741
  );
1741
- if (!hasUseCache && !t.isBlockStatement(path3.node.body)) {
1742
- const parentFunction = path3.findParent(
1742
+ if (!hasUseCache && !t.isBlockStatement(path2.node.body)) {
1743
+ const parentFunction = path2.findParent(
1743
1744
  (p) => (p.isFunction() || p.isProgram()) && "directives" in p.node
1744
1745
  );
1745
1746
  if (!((_b = parentFunction == null ? void 0 : parentFunction.node.directives) == null ? void 0 : _b.some(
@@ -1748,35 +1749,35 @@ var init_UseCacheTransformer = __esm({
1748
1749
  return;
1749
1750
  }
1750
1751
  }
1751
- if (hasUseCache || !t.isBlockStatement(path3.node.body)) {
1752
- if (!path3.node.async) {
1752
+ if (hasUseCache || !t.isBlockStatement(path2.node.body)) {
1753
+ if (!path2.node.async) {
1753
1754
  throw new Error(
1754
1755
  `"${DIRECTIVE}" directive may only be used in async functions at ${args.path}
1755
1756
 
1756
- ${path3.toString()}
1757
+ ${path2.toString()}
1757
1758
  ^^^^${"-".repeat(6)} This function must be async`
1758
1759
  );
1759
1760
  }
1760
1761
  state.needsImport = true;
1761
- const isDeclaration = t.isFunctionDeclaration(path3.node);
1762
- const name = isDeclaration ? (_c = path3.node.id) == null ? void 0 : _c.name : void 0;
1763
- const newBody = t.isBlockStatement(path3.node.body) ? t.blockStatement(
1764
- path3.node.body.body,
1765
- path3.node.body.directives.filter(
1762
+ const isDeclaration = t.isFunctionDeclaration(path2.node);
1763
+ const name = isDeclaration ? (_c = path2.node.id) == null ? void 0 : _c.name : void 0;
1764
+ const newBody = t.isBlockStatement(path2.node.body) ? t.blockStatement(
1765
+ path2.node.body.body,
1766
+ path2.node.body.directives.filter(
1766
1767
  (d) => d.value.value !== DIRECTIVE
1767
1768
  )
1768
- ) : path3.node.body;
1769
+ ) : path2.node.body;
1769
1770
  const wrapped = t.callExpression(
1770
1771
  t.identifier(state.cacheIdentifierName),
1771
- [t.arrowFunctionExpression(path3.node.params, newBody, true)]
1772
+ [t.arrowFunctionExpression(path2.node.params, newBody, true)]
1772
1773
  );
1773
1774
  state.modifications.push(() => {
1774
- if (t.isObjectMethod(path3.node)) {
1775
- path3.replaceWith(
1776
- t.objectProperty(t.identifier(path3.node.key.name), wrapped)
1775
+ if (t.isObjectMethod(path2.node)) {
1776
+ path2.replaceWith(
1777
+ t.objectProperty(t.identifier(path2.node.key.name), wrapped)
1777
1778
  );
1778
1779
  } else if (name) {
1779
- path3.replaceWith(
1780
+ path2.replaceWith(
1780
1781
  t.variableDeclaration(
1781
1782
  "const",
1782
1783
  [
@@ -1784,10 +1785,10 @@ ${path3.toString()}
1784
1785
  ]
1785
1786
  )
1786
1787
  );
1787
- } else if (!t.isVariableDeclarator(path3.parent)) {
1788
- path3.replaceWith(wrapped);
1788
+ } else if (!t.isVariableDeclarator(path2.parent)) {
1789
+ path2.replaceWith(wrapped);
1789
1790
  } else {
1790
- path3.parent.init = wrapped;
1791
+ path2.parent.init = wrapped;
1791
1792
  }
1792
1793
  });
1793
1794
  }
@@ -1812,7 +1813,7 @@ ${path3.toString()}
1812
1813
  const { code } = generate(ast);
1813
1814
  return {
1814
1815
  contents: code,
1815
- loader: args.path.split(".").pop()
1816
+ loader: (_a = args.path) == null ? void 0 : _a.split(".").pop()
1816
1817
  };
1817
1818
  }, "cacheDirectivePlugin");
1818
1819
  }
@@ -1888,7 +1889,10 @@ var init_default = __esm({
1888
1889
  init_CachePlugin();
1889
1890
  init_MacroPlugin();
1890
1891
  defaultConfig = {
1891
- plugins: [new CachePlugin({}), new MacroPlugin({})],
1892
+ plugins: [
1893
+ new CachePlugin({ enabled: true }),
1894
+ new MacroPlugin({ enabled: true })
1895
+ ],
1892
1896
  esbuildPlugins: [],
1893
1897
  compilerOptions: {
1894
1898
  macro: {
@@ -1914,42 +1918,45 @@ var init_default = __esm({
1914
1918
  }
1915
1919
  });
1916
1920
 
1917
- // src/config/utils.ts
1918
- var mergeDeep;
1919
- var init_utils = __esm({
1920
- "src/config/utils.ts"() {
1921
- "use strict";
1922
- init_cjs_shims();
1923
- mergeDeep = /* @__PURE__ */ __name((target, source) => {
1924
- const isObject = /* @__PURE__ */ __name((obj) => obj && typeof obj === "object" && !Array.isArray(obj), "isObject");
1925
- const output = { ...target };
1926
- if (isObject(target) && isObject(source)) {
1927
- Object.keys(source).forEach((key) => {
1928
- if (isObject(source[key])) {
1929
- if (!(key in target)) {
1930
- Object.assign(output, { [key]: source[key] });
1931
- } else {
1932
- output[key] = mergeDeep(target[key], source[key]);
1933
- }
1934
- } else {
1935
- Object.assign(output, { [key]: source[key] });
1936
- }
1937
- });
1938
- }
1939
- return output;
1940
- }, "mergeDeep");
1941
- }
1942
- });
1943
-
1944
1921
  // src/config/config.ts
1945
1922
  function getConfig() {
1946
1923
  return defined;
1947
1924
  }
1948
1925
  function defineConfig(config = {}) {
1949
- defined = mergeDeep(
1950
- config,
1951
- mergeDeep({}, defaultConfig)
1952
- );
1926
+ var _a, _b;
1927
+ defined = {
1928
+ compilerOptions: {
1929
+ cache: {
1930
+ ...defaultConfig.compilerOptions.cache,
1931
+ ...(_a = config.compilerOptions) == null ? void 0 : _a.cache
1932
+ },
1933
+ macro: {
1934
+ ...defaultConfig.compilerOptions.macro,
1935
+ ...(_b = config.compilerOptions) == null ? void 0 : _b.macro
1936
+ }
1937
+ },
1938
+ distDir: config.distDir ?? defaultConfig.distDir,
1939
+ env: {
1940
+ ...defaultConfig.env,
1941
+ ...config.env
1942
+ },
1943
+ esbuildPlugins: [
1944
+ ...config.esbuildPlugins ?? [],
1945
+ ...defaultConfig.esbuildPlugins ?? []
1946
+ ],
1947
+ plugins: [...config.plugins ?? [], ...defaultConfig.plugins ?? []],
1948
+ sourceMap: {
1949
+ ...defaultConfig.sourceMap,
1950
+ ...config.sourceMap
1951
+ },
1952
+ static: config.static ?? defaultConfig.static,
1953
+ typedCommands: config.typedCommands ?? defaultConfig.typedCommands,
1954
+ typedLocales: config.typedLocales ?? defaultConfig.typedLocales,
1955
+ typescript: {
1956
+ ...defaultConfig.typescript,
1957
+ ...config.typescript
1958
+ }
1959
+ };
1953
1960
  return defined;
1954
1961
  }
1955
1962
  var defined;
@@ -1958,13 +1965,24 @@ var init_config = __esm({
1958
1965
  "use strict";
1959
1966
  init_cjs_shims();
1960
1967
  init_default();
1961
- init_utils();
1962
1968
  defined = defaultConfig;
1963
1969
  __name(getConfig, "getConfig");
1964
1970
  __name(defineConfig, "defineConfig");
1965
1971
  }
1966
1972
  });
1967
1973
 
1974
+ // src/utils/constants.ts
1975
+ var COMMANDKIT_CACHE_TAG, COMMANDKIT_IS_DEV, COMMANDKIT_IS_TEST;
1976
+ var init_constants = __esm({
1977
+ "src/utils/constants.ts"() {
1978
+ "use strict";
1979
+ init_cjs_shims();
1980
+ COMMANDKIT_CACHE_TAG = Symbol("kCommandKitCacheTag");
1981
+ COMMANDKIT_IS_DEV = !!process.env.COMMANDKIT_IS_DEV;
1982
+ COMMANDKIT_IS_TEST = process.env.COMMANDKIT_IS_TEST === "true";
1983
+ }
1984
+ });
1985
+
1968
1986
  // src/app/i18n/DefaultLocalizationStrategy.ts
1969
1987
  var import_promises2, import_node_path, import_node_fs, _DefaultLocalizationStrategy, DefaultLocalizationStrategy;
1970
1988
  var init_DefaultLocalizationStrategy = __esm({
@@ -1975,6 +1993,7 @@ var init_DefaultLocalizationStrategy = __esm({
1975
1993
  import_node_path = require("path");
1976
1994
  init_config();
1977
1995
  import_node_fs = require("fs");
1996
+ init_constants();
1978
1997
  _DefaultLocalizationStrategy = class _DefaultLocalizationStrategy {
1979
1998
  constructor(commandkit2) {
1980
1999
  this.commandkit = commandkit2;
@@ -1983,17 +2002,38 @@ var init_DefaultLocalizationStrategy = __esm({
1983
2002
  async locateTranslation(scope, locale) {
1984
2003
  const localesPath = this.commandkit.getPath("locales");
1985
2004
  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;
2005
+ const paths = [".js", ".json", ".mjs", ".cjs"].map(
2006
+ (e) => (0, import_node_path.join)(localesPath, locale, scope) + e
2007
+ );
2008
+ for (const path2 of paths) {
2009
+ if (!(0, import_node_fs.existsSync)(path2)) {
2010
+ continue;
2011
+ }
2012
+ try {
2013
+ let localeData;
2014
+ try {
2015
+ if (path2.endsWith(".json")) {
2016
+ const data = await (0, import_promises2.readFile)(path2, "utf-8");
2017
+ localeData = JSON.parse(data);
2018
+ } else {
2019
+ const { default: data } = await import(`file://${path2}`);
2020
+ localeData = data;
2021
+ }
2022
+ } catch {
2023
+ continue;
2024
+ }
2025
+ if (!localeData) continue;
2026
+ await this.generateLocaleTypes(localeData).catch(() => {
2027
+ });
2028
+ return localeData;
2029
+ } catch {
2030
+ return null;
2031
+ }
1994
2032
  }
2033
+ return null;
1995
2034
  }
1996
2035
  async generateLocaleTypes(localeData) {
2036
+ if (!COMMANDKIT_IS_DEV) return;
1997
2037
  const { typedLocales } = getConfig();
1998
2038
  if (!typedLocales) return;
1999
2039
  const file = (0, import_node_path.join)(
@@ -2003,43 +2043,58 @@ var init_DefaultLocalizationStrategy = __esm({
2003
2043
  "locale_types.d.ts"
2004
2044
  );
2005
2045
  const header = `// auto generated file do not edit
2046
+ export {};
2006
2047
  declare module 'commandkit' {
2007
2048
  export interface CommandLocalizationTypeData {
2008
2049
  `;
2009
- const footer = ` }
2050
+ const footer = ` type TranslatableCommandName = keyof CommandLocalizationTypeData
2051
+ }
2010
2052
  }`;
2011
2053
  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
- )}`;
2054
+ const commandName = locale.command.name;
2055
+ const translationTypes = Object.entries(locale.translations).map(([key, value]) => {
2056
+ const args = value.match(/{([^}]+)}/g);
2057
+ if (!args) {
2058
+ return ` "${key}": null`;
2059
+ }
2060
+ const argUnion = args.map((arg) => `"${arg.slice(1, -1)}"`).join(" | ");
2061
+ return ` "${key}": ${argUnion}`;
2062
+ }).join(",\n");
2063
+ return ` "${commandName}": {
2064
+ ${translationTypes}
2065
+ }`;
2021
2066
  }, "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}`);
2067
+ try {
2068
+ let commandDefinitions = /* @__PURE__ */ new Map();
2069
+ if ((0, import_node_fs.existsSync)(file)) {
2070
+ try {
2071
+ const data = await (0, import_promises2.readFile)(file, "utf-8");
2072
+ const content = data.toString();
2073
+ const regex = /"([^"]+)":\s*\{([^}]*)\}/gs;
2074
+ let match;
2075
+ while ((match = regex.exec(content)) !== null) {
2076
+ const [fullMatch, commandName] = match;
2077
+ if (commandName !== localeData.command.name) {
2078
+ commandDefinitions.set(commandName, fullMatch);
2079
+ }
2080
+ }
2081
+ } catch (err) {
2082
+ console.warn("Could not parse existing type file, creating new one");
2035
2083
  }
2036
- return;
2037
2084
  }
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"));
2085
+ const newCommandType = generateType(localeData);
2086
+ commandDefinitions.set(localeData.command.name, newCommandType);
2087
+ let fileContent = header;
2088
+ const entries = Array.from(commandDefinitions.values());
2089
+ fileContent += entries.join(",\n");
2090
+ fileContent += "\n" + footer;
2091
+ const dir = (0, import_node_path.join)(process.cwd(), "node_modules", "commandkit-types");
2092
+ if (!(0, import_node_fs.existsSync)(dir)) {
2093
+ await (0, import_promises2.mkdir)(dir, { recursive: true });
2094
+ }
2095
+ await (0, import_promises2.writeFile)(file, fileContent);
2096
+ } catch (error) {
2097
+ console.error("Failed to generate locale types:", error);
2043
2098
  }
2044
2099
  }
2045
2100
  async getTranslationStrict(scope, locale) {
@@ -2081,18 +2136,6 @@ declare module 'commandkit' {
2081
2136
  }
2082
2137
  });
2083
2138
 
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
-
2096
2139
  // src/utils/utilities.ts
2097
2140
  function findAppDirectory() {
2098
2141
  if (appDir) return appDir;
@@ -2146,160 +2189,471 @@ var init_utilities = __esm({
2146
2189
  }
2147
2190
  });
2148
2191
 
2149
- // src/app/i18n/Localization.ts
2150
- var _Localization, Localization;
2151
- var init_Localization = __esm({
2152
- "src/app/i18n/Localization.ts"() {
2192
+ // src/utils/resolve-file-url.ts
2193
+ function toFileURL(filePath, withTs = false) {
2194
+ const resolvedPath = import_path.default.resolve(filePath);
2195
+ return `${"file://" + resolvedPath.replace(/\\\\|\\/g, "/")}${withTs ? `?ts=${Date.now()}` : ""}`;
2196
+ }
2197
+ var import_path;
2198
+ var init_resolve_file_url = __esm({
2199
+ "src/utils/resolve-file-url.ts"() {
2153
2200
  "use strict";
2154
2201
  init_cjs_shims();
2155
- _Localization = class _Localization {
2156
- /**
2157
- * Creates a new localization instance.
2158
- * @param commandkit The command kit instance.
2159
- * @param config The localization configuration.
2160
- */
2161
- constructor(commandkit2, config) {
2162
- this.commandkit = commandkit2;
2163
- this.config = config;
2164
- const strategy = this.commandkit.config.localizationStrategy;
2165
- const { locale, target } = this.config;
2166
- this.t = (translatable, args) => {
2167
- return strategy.translate({
2168
- args,
2169
- key: translatable,
2170
- locale,
2171
- scope: target
2172
- });
2173
- };
2174
- }
2175
- /**
2176
- * Translates the given translatable object.
2177
- * @param translatable The translatable object to translate.
2178
- */
2179
- t;
2180
- /**
2181
- * Get the localization strategy.
2182
- */
2183
- getStrategy() {
2184
- return this.commandkit.config.localizationStrategy;
2185
- }
2186
- /**
2187
- * Get the default locale
2188
- */
2189
- getDefaultLocale() {
2190
- return this.commandkit.config.defaultLocale;
2191
- }
2192
- /**
2193
- * Get the current locale
2194
- */
2195
- getLocale() {
2196
- return this.config.locale;
2197
- }
2198
- /**
2199
- * Get the localization target
2200
- */
2201
- getTarget() {
2202
- return this.config.target;
2203
- }
2204
- };
2205
- __name(_Localization, "Localization");
2206
- Localization = _Localization;
2202
+ import_path = __toESM(require("path"));
2203
+ __name(toFileURL, "toFileURL");
2207
2204
  }
2208
2205
  });
2209
2206
 
2210
- // src/context/environment.ts
2211
- function afterCommand(fn) {
2212
- const env = getContext();
2213
- if (!env) {
2214
- throw new Error("after must be called inside commandkit handler.");
2215
- }
2216
- return env.registerDeferredFunction(fn);
2217
- }
2218
- function cancelAfterCommand(id) {
2219
- const env = getContext();
2220
- if (!env) {
2221
- throw new Error("cancelAfter must be called inside commandkit handler.");
2222
- }
2223
- env.clearDeferredFunction(id);
2224
- }
2225
- var import_node_crypto, _data, _CommandKitEnvironment, CommandKitEnvironment, CommandKitEnvironmentType;
2226
- var init_environment = __esm({
2227
- "src/context/environment.ts"() {
2207
+ // src/app/commands/MessageCommandParser.ts
2208
+ var import_discord8, _parsed, _options, _args, _MessageCommandParser, MessageCommandParser, _MessageCommandOptions, MessageCommandOptions;
2209
+ var init_MessageCommandParser = __esm({
2210
+ "src/app/commands/MessageCommandParser.ts"() {
2228
2211
  "use strict";
2229
2212
  init_cjs_shims();
2230
- import_node_crypto = require("crypto");
2231
- init_async_context();
2232
- _CommandKitEnvironment = class _CommandKitEnvironment {
2233
- /**
2234
- * Creates the commandkit execution environment.
2235
- * @param commandkit - The commandkit instance.
2236
- */
2237
- constructor(commandkit2) {
2238
- this.commandkit = commandkit2;
2239
- __privateAdd(this, _data, {
2240
- executionError: null,
2241
- type: null,
2242
- variables: /* @__PURE__ */ new Map(),
2243
- deferredFunctions: /* @__PURE__ */ new Map(),
2244
- marker: "",
2245
- markStart: 0,
2246
- markEnd: 0
2247
- });
2213
+ import_discord8 = require("discord.js");
2214
+ init_error_codes();
2215
+ _MessageCommandParser = class _MessageCommandParser {
2216
+ constructor(message, prefix, schema) {
2217
+ this.message = message;
2218
+ this.prefix = prefix;
2219
+ this.schema = schema;
2220
+ __privateAdd(this, _parsed, null);
2221
+ __privateAdd(this, _options, null);
2222
+ __privateAdd(this, _args, []);
2248
2223
  }
2249
- /**
2250
- * Get the execution error.
2251
- * @internal
2252
- */
2253
- getExecutionError() {
2254
- return __privateGet(this, _data).executionError;
2224
+ getArgs() {
2225
+ void this.parse();
2226
+ return __privateGet(this, _args);
2255
2227
  }
2256
- /**
2257
- * Set the execution error.
2258
- * @param error - The error to set.
2259
- * @internal
2260
- */
2261
- setExecutionError(error) {
2262
- if (__privateGet(this, _data).executionError) {
2263
- throw new Error("Execution error already set.");
2228
+ get options() {
2229
+ if (!__privateGet(this, _options)) {
2230
+ __privateSet(this, _options, new MessageCommandOptions(this));
2264
2231
  }
2265
- __privateGet(this, _data).executionError = error;
2232
+ return __privateGet(this, _options);
2266
2233
  }
2267
- /**
2268
- * Get the environment type.
2269
- */
2270
- getType() {
2271
- const type = __privateGet(this, _data).type;
2272
- if (!type) {
2273
- throw new Error("Environment type not set.");
2274
- }
2275
- return type;
2234
+ getOption(name) {
2235
+ var _a;
2236
+ return (_a = this.parse().options.find((o) => o.name === name)) == null ? void 0 : _a.value;
2276
2237
  }
2277
- /**
2278
- * Set the environment type.
2279
- * @param type - The environment type to set.
2280
- * @internal
2281
- */
2282
- setType(type) {
2283
- __privateGet(this, _data).type = type;
2238
+ getCommand() {
2239
+ return this.parse().command;
2284
2240
  }
2285
- /**
2286
- * The variables store for this environment.
2287
- */
2288
- get variables() {
2289
- return __privateGet(this, _data).variables;
2241
+ getSubcommand() {
2242
+ return this.parse().subcommand;
2290
2243
  }
2291
- /**
2292
- * Register a deferred function.
2293
- * @param fn - The deferred function to register.
2294
- * @returns The deferred function id.
2295
- * @internal
2296
- */
2297
- registerDeferredFunction(fn) {
2298
- const id = (0, import_node_crypto.randomUUID)();
2299
- __privateGet(this, _data).deferredFunctions.set(id, fn);
2300
- return id;
2244
+ getSubcommandGroup() {
2245
+ return this.parse().subcommandGroup;
2301
2246
  }
2302
- /**
2247
+ getPrefix() {
2248
+ for (const p of this.prefix) {
2249
+ if (this.message.content.startsWith(p)) {
2250
+ return p;
2251
+ }
2252
+ }
2253
+ }
2254
+ getFullCommand() {
2255
+ return [this.getCommand(), this.getSubcommandGroup(), this.getSubcommand()].filter((v) => v).join(" ");
2256
+ }
2257
+ parse() {
2258
+ if (__privateGet(this, _parsed)) {
2259
+ return __privateGet(this, _parsed);
2260
+ }
2261
+ const content = this.message.content;
2262
+ const prefix = this.getPrefix();
2263
+ if (!prefix) {
2264
+ throw createCommandKitError(CommandKitErrorCodes.InvalidCommandPrefix);
2265
+ }
2266
+ const parts = content.slice(prefix.length).trim().split(" ");
2267
+ const command = parts.shift();
2268
+ __privateSet(this, _args, parts);
2269
+ let subcommandGroup;
2270
+ let subcommand;
2271
+ if (command == null ? void 0 : command.includes(":")) {
2272
+ const [, group, cmd] = command.split(":");
2273
+ if (!cmd && group) {
2274
+ subcommand = group;
2275
+ } else if (cmd && group) {
2276
+ subcommandGroup = group;
2277
+ subcommand = cmd;
2278
+ }
2279
+ }
2280
+ const schema = this.schema(
2281
+ [command, subcommandGroup, subcommand].filter(Boolean).join(" ").trim()
2282
+ );
2283
+ const options = parts.map((part) => {
2284
+ try {
2285
+ const [name, value] = part.split(":");
2286
+ if (!(name in schema)) return null;
2287
+ switch (schema[name]) {
2288
+ case import_discord8.ApplicationCommandOptionType.Boolean:
2289
+ return { name, value: value === "true" };
2290
+ case import_discord8.ApplicationCommandOptionType.Integer:
2291
+ return { name, value: parseInt(value, 10) };
2292
+ case import_discord8.ApplicationCommandOptionType.Number:
2293
+ return { name, value: parseFloat(value) };
2294
+ case import_discord8.ApplicationCommandOptionType.String:
2295
+ return { name, value };
2296
+ case import_discord8.ApplicationCommandOptionType.User:
2297
+ return {
2298
+ name,
2299
+ value: this.message.mentions.users.find((u) => {
2300
+ return u.id === value.replace(/[<@!>]/g, "");
2301
+ })
2302
+ };
2303
+ case import_discord8.ApplicationCommandOptionType.Channel:
2304
+ return {
2305
+ name,
2306
+ value: this.message.mentions.channels.find((c) => {
2307
+ return c.id === value.replace(/[<#>]/g, "");
2308
+ })
2309
+ };
2310
+ case import_discord8.ApplicationCommandOptionType.Role:
2311
+ return {
2312
+ name,
2313
+ value: this.message.mentions.roles.find((r) => {
2314
+ return r.id === value.replace(/[<@&>]/g, "");
2315
+ })
2316
+ };
2317
+ case import_discord8.ApplicationCommandOptionType.Attachment:
2318
+ return {
2319
+ name,
2320
+ value: this.message.attachments.find((a) => {
2321
+ return a.name === value;
2322
+ })
2323
+ };
2324
+ default:
2325
+ return null;
2326
+ }
2327
+ } catch {
2328
+ return null;
2329
+ }
2330
+ }).filter((v) => v !== null);
2331
+ __privateSet(this, _parsed, {
2332
+ command,
2333
+ options,
2334
+ subcommand,
2335
+ subcommandGroup
2336
+ });
2337
+ return __privateGet(this, _parsed);
2338
+ }
2339
+ };
2340
+ _parsed = new WeakMap();
2341
+ _options = new WeakMap();
2342
+ _args = new WeakMap();
2343
+ __name(_MessageCommandParser, "MessageCommandParser");
2344
+ MessageCommandParser = _MessageCommandParser;
2345
+ _MessageCommandOptions = class _MessageCommandOptions {
2346
+ constructor(parser2) {
2347
+ this.parser = parser2;
2348
+ }
2349
+ assertOption(name, required = false) {
2350
+ const option = this.parser.getOption(name);
2351
+ if (required && option === void 0) {
2352
+ throw new Error(`Option "${name}" is required.`);
2353
+ }
2354
+ return option ?? null;
2355
+ }
2356
+ getMember(name, required = false) {
2357
+ var _a;
2358
+ const user = this.assertOption(name, required);
2359
+ const member = (_a = this.parser.message.guild) == null ? void 0 : _a.members.cache.get(user == null ? void 0 : user.id);
2360
+ if (required && !member) {
2361
+ throw new Error(`Member "${name}" is required.`);
2362
+ }
2363
+ return member ?? null;
2364
+ }
2365
+ getAttachment(name, required = false) {
2366
+ return this.assertOption(name, required);
2367
+ }
2368
+ getBoolean(name, required = false) {
2369
+ return this.assertOption(name, required);
2370
+ }
2371
+ getNumber(name, required = false) {
2372
+ return this.assertOption(name, required);
2373
+ }
2374
+ getString(name, required = false) {
2375
+ return this.assertOption(name, required);
2376
+ }
2377
+ getInteger(name, required = false) {
2378
+ return this.assertOption(name, required);
2379
+ }
2380
+ getUser(name, required = false) {
2381
+ return this.assertOption(name, required);
2382
+ }
2383
+ getChannel(name, required = false) {
2384
+ return this.assertOption(name, required);
2385
+ }
2386
+ getRole(name, required = false) {
2387
+ return this.assertOption(name, required);
2388
+ }
2389
+ getMentionable(name, required = false) {
2390
+ const target = this.assertOption(name, required);
2391
+ if (target instanceof import_discord8.GuildMember || target instanceof import_discord8.User || target instanceof import_discord8.Role) {
2392
+ return target;
2393
+ }
2394
+ if (required) {
2395
+ throw new Error(`Mentionable "${name}" is required.`);
2396
+ }
2397
+ return null;
2398
+ }
2399
+ getSubcommand(required = false) {
2400
+ const sub = this.parser.getSubcommand();
2401
+ if (required && sub === void 0) {
2402
+ throw new Error("Subcommand is required.");
2403
+ }
2404
+ return sub ?? null;
2405
+ }
2406
+ getSubcommandGroup(required = false) {
2407
+ const sub = this.parser.getSubcommandGroup();
2408
+ if (required && sub === void 0) {
2409
+ throw new Error("Subcommand group is required.");
2410
+ }
2411
+ return sub ?? null;
2412
+ }
2413
+ };
2414
+ __name(_MessageCommandOptions, "MessageCommandOptions");
2415
+ MessageCommandOptions = _MessageCommandOptions;
2416
+ }
2417
+ });
2418
+
2419
+ // src/app/register/CommandRegistrar.ts
2420
+ var import_discord9, _CommandRegistrar, CommandRegistrar;
2421
+ var init_CommandRegistrar = __esm({
2422
+ "src/app/register/CommandRegistrar.ts"() {
2423
+ "use strict";
2424
+ init_cjs_shims();
2425
+ import_discord9 = require("discord.js");
2426
+ init_Logger();
2427
+ _CommandRegistrar = class _CommandRegistrar {
2428
+ /**
2429
+ * Creates an instance of CommandRegistrar.
2430
+ * @param commandkit The commandkit instance.
2431
+ */
2432
+ constructor(commandkit2) {
2433
+ this.commandkit = commandkit2;
2434
+ this.api.setToken(
2435
+ this.commandkit.client.token ?? process.env.DISCORD_TOKEN ?? process.env.TOKEN ?? ""
2436
+ );
2437
+ }
2438
+ api = new import_discord9.REST();
2439
+ /**
2440
+ * Gets the commands data.
2441
+ */
2442
+ getCommandsData() {
2443
+ const handler = this.commandkit.commandHandler;
2444
+ const commands = handler.getCommandsArray();
2445
+ return commands.flatMap((cmd) => {
2446
+ const json = "toJSON" in cmd.data.command ? cmd.data.command.toJSON() : cmd.data.command;
2447
+ const collections = [json];
2448
+ if (cmd.data.userContextMenu && json.type !== import_discord9.ApplicationCommandType.User) {
2449
+ collections.push({
2450
+ ...json,
2451
+ type: import_discord9.ApplicationCommandType.User,
2452
+ options: void 0,
2453
+ description_localizations: void 0,
2454
+ // @ts-ignore
2455
+ description: void 0
2456
+ });
2457
+ }
2458
+ if (cmd.data.messageContextMenu && json.type !== import_discord9.ApplicationCommandType.Message) {
2459
+ collections.push({
2460
+ ...json,
2461
+ type: import_discord9.ApplicationCommandType.Message,
2462
+ description_localizations: void 0,
2463
+ // @ts-ignore
2464
+ description: void 0,
2465
+ options: void 0
2466
+ });
2467
+ }
2468
+ return collections;
2469
+ });
2470
+ }
2471
+ /**
2472
+ * Registers loaded commands.
2473
+ */
2474
+ async register() {
2475
+ if (!this.commandkit.client.isReady()) {
2476
+ throw new Error("Cannot register commands before the client is ready");
2477
+ }
2478
+ const commands = this.getCommandsData();
2479
+ const guildCommands = commands.filter((command) => {
2480
+ var _a;
2481
+ return (_a = command.guilds) == null ? void 0 : _a.filter(Boolean).length;
2482
+ }).map((c) => {
2483
+ var _a;
2484
+ return {
2485
+ ...c,
2486
+ guilds: Array.from(new Set((_a = c.guilds) == null ? void 0 : _a.filter(Boolean)))
2487
+ };
2488
+ });
2489
+ const globalCommands = commands.filter(
2490
+ (command) => {
2491
+ var _a;
2492
+ return !((_a = command.guilds) == null ? void 0 : _a.filter(Boolean).length);
2493
+ }
2494
+ );
2495
+ await this.updateGlobalCommands(globalCommands);
2496
+ await this.updateGuildCommands(guildCommands);
2497
+ }
2498
+ /**
2499
+ * Updates the global commands.
2500
+ */
2501
+ async updateGlobalCommands(commands) {
2502
+ if (!commands.length) return;
2503
+ try {
2504
+ const data = await this.api.put(
2505
+ import_discord9.Routes.applicationCommands(this.commandkit.client.user.id),
2506
+ {
2507
+ body: commands.map((c) => ({
2508
+ ...c,
2509
+ guilds: void 0
2510
+ }))
2511
+ }
2512
+ );
2513
+ Logger.info(
2514
+ `\u2728 Refreshed ${data.length} global application (/) commands`
2515
+ );
2516
+ } catch (e) {
2517
+ Logger.error("Failed to update global application (/) commands", e);
2518
+ }
2519
+ }
2520
+ /**
2521
+ * Updates the guild commands.
2522
+ */
2523
+ async updateGuildCommands(commands) {
2524
+ try {
2525
+ const guildCommandsMap = /* @__PURE__ */ new Map();
2526
+ commands.forEach((command) => {
2527
+ var _a;
2528
+ if (!((_a = command.guilds) == null ? void 0 : _a.length)) return;
2529
+ command.guilds.forEach((guild) => {
2530
+ if (!guildCommandsMap.has(guild)) {
2531
+ guildCommandsMap.set(guild, []);
2532
+ }
2533
+ guildCommandsMap.get(guild).push(command);
2534
+ });
2535
+ });
2536
+ if (!guildCommandsMap.size) return;
2537
+ let count = 0;
2538
+ for (const [guild, guildCommands] of guildCommandsMap) {
2539
+ const data = await this.api.put(
2540
+ import_discord9.Routes.applicationGuildCommands(
2541
+ this.commandkit.client.user.id,
2542
+ guild
2543
+ ),
2544
+ {
2545
+ body: guildCommands.map((b) => ({
2546
+ ...b,
2547
+ guilds: void 0
2548
+ }))
2549
+ }
2550
+ );
2551
+ count += data.length;
2552
+ }
2553
+ Logger.info(`\u2728 Refreshed ${count} guild application (/) commands`);
2554
+ } catch (e) {
2555
+ Logger.error("Failed to update guild application (/) commands", e);
2556
+ }
2557
+ }
2558
+ };
2559
+ __name(_CommandRegistrar, "CommandRegistrar");
2560
+ CommandRegistrar = _CommandRegistrar;
2561
+ }
2562
+ });
2563
+
2564
+ // src/context/environment.ts
2565
+ function afterCommand(fn) {
2566
+ const env = getContext();
2567
+ if (!env) {
2568
+ throw new Error("after must be called inside commandkit handler.");
2569
+ }
2570
+ return env.registerDeferredFunction(fn);
2571
+ }
2572
+ function cancelAfterCommand(id) {
2573
+ const env = getContext();
2574
+ if (!env) {
2575
+ throw new Error("cancelAfter must be called inside commandkit handler.");
2576
+ }
2577
+ env.clearDeferredFunction(id);
2578
+ }
2579
+ var import_node_crypto, _data, _CommandKitEnvironment, CommandKitEnvironment, CommandKitEnvironmentType;
2580
+ var init_environment = __esm({
2581
+ "src/context/environment.ts"() {
2582
+ "use strict";
2583
+ init_cjs_shims();
2584
+ import_node_crypto = require("crypto");
2585
+ init_async_context();
2586
+ _CommandKitEnvironment = class _CommandKitEnvironment {
2587
+ /**
2588
+ * Creates the commandkit execution environment.
2589
+ * @param commandkit - The commandkit instance.
2590
+ */
2591
+ constructor(commandkit2) {
2592
+ this.commandkit = commandkit2;
2593
+ __privateAdd(this, _data, {
2594
+ executionError: null,
2595
+ type: null,
2596
+ variables: /* @__PURE__ */ new Map(),
2597
+ deferredFunctions: /* @__PURE__ */ new Map(),
2598
+ marker: "",
2599
+ markStart: 0,
2600
+ markEnd: 0
2601
+ });
2602
+ }
2603
+ /**
2604
+ * Get the execution error.
2605
+ * @internal
2606
+ */
2607
+ getExecutionError() {
2608
+ return __privateGet(this, _data).executionError;
2609
+ }
2610
+ /**
2611
+ * Set the execution error.
2612
+ * @param error - The error to set.
2613
+ * @internal
2614
+ */
2615
+ setExecutionError(error) {
2616
+ if (__privateGet(this, _data).executionError) {
2617
+ throw new Error("Execution error already set.");
2618
+ }
2619
+ __privateGet(this, _data).executionError = error;
2620
+ }
2621
+ /**
2622
+ * Get the environment type.
2623
+ */
2624
+ getType() {
2625
+ const type = __privateGet(this, _data).type;
2626
+ if (!type) {
2627
+ throw new Error("Environment type not set.");
2628
+ }
2629
+ return type;
2630
+ }
2631
+ /**
2632
+ * Set the environment type.
2633
+ * @param type - The environment type to set.
2634
+ * @internal
2635
+ */
2636
+ setType(type) {
2637
+ __privateGet(this, _data).type = type;
2638
+ }
2639
+ /**
2640
+ * The variables store for this environment.
2641
+ */
2642
+ get variables() {
2643
+ return __privateGet(this, _data).variables;
2644
+ }
2645
+ /**
2646
+ * Register a deferred function.
2647
+ * @param fn - The deferred function to register.
2648
+ * @returns The deferred function id.
2649
+ * @internal
2650
+ */
2651
+ registerDeferredFunction(fn) {
2652
+ const id = (0, import_node_crypto.randomUUID)();
2653
+ __privateGet(this, _data).deferredFunctions.set(id, fn);
2654
+ return id;
2655
+ }
2656
+ /**
2303
2657
  * Clear a deferred function by id.
2304
2658
  * @param id - The deferred function id to clear.
2305
2659
  * @internal
@@ -2360,15 +2714,76 @@ var init_environment = __esm({
2360
2714
  return Math.abs(__privateGet(this, _data).markEnd - __privateGet(this, _data).markStart);
2361
2715
  }
2362
2716
  };
2363
- _data = new WeakMap();
2364
- __name(_CommandKitEnvironment, "CommandKitEnvironment");
2365
- CommandKitEnvironment = _CommandKitEnvironment;
2366
- CommandKitEnvironmentType = /* @__PURE__ */ ((CommandKitEnvironmentType2) => {
2367
- CommandKitEnvironmentType2["CommandHandler"] = "COMMAND_HANDLER";
2368
- return CommandKitEnvironmentType2;
2369
- })(CommandKitEnvironmentType || {});
2370
- __name(afterCommand, "afterCommand");
2371
- __name(cancelAfterCommand, "cancelAfterCommand");
2717
+ _data = new WeakMap();
2718
+ __name(_CommandKitEnvironment, "CommandKitEnvironment");
2719
+ CommandKitEnvironment = _CommandKitEnvironment;
2720
+ CommandKitEnvironmentType = /* @__PURE__ */ ((CommandKitEnvironmentType2) => {
2721
+ CommandKitEnvironmentType2["CommandHandler"] = "COMMAND_HANDLER";
2722
+ return CommandKitEnvironmentType2;
2723
+ })(CommandKitEnvironmentType || {});
2724
+ __name(afterCommand, "afterCommand");
2725
+ __name(cancelAfterCommand, "cancelAfterCommand");
2726
+ }
2727
+ });
2728
+
2729
+ // src/app/i18n/Localization.ts
2730
+ var _Localization, Localization;
2731
+ var init_Localization = __esm({
2732
+ "src/app/i18n/Localization.ts"() {
2733
+ "use strict";
2734
+ init_cjs_shims();
2735
+ _Localization = class _Localization {
2736
+ /**
2737
+ * Creates a new localization instance.
2738
+ * @param commandkit The command kit instance.
2739
+ * @param config The localization configuration.
2740
+ */
2741
+ constructor(commandkit2, config) {
2742
+ this.commandkit = commandkit2;
2743
+ this.config = config;
2744
+ const strategy = this.commandkit.config.localizationStrategy;
2745
+ const { locale, target } = this.config;
2746
+ this.t = (translatable, args) => {
2747
+ return strategy.translate({
2748
+ args,
2749
+ key: translatable,
2750
+ locale,
2751
+ scope: target
2752
+ });
2753
+ };
2754
+ }
2755
+ /**
2756
+ * Translates the given translatable object.
2757
+ * @param translatable The translatable object to translate.
2758
+ */
2759
+ t;
2760
+ /**
2761
+ * Get the localization strategy.
2762
+ */
2763
+ getStrategy() {
2764
+ return this.commandkit.config.localizationStrategy;
2765
+ }
2766
+ /**
2767
+ * Get the default locale
2768
+ */
2769
+ getDefaultLocale() {
2770
+ return this.commandkit.config.defaultLocale;
2771
+ }
2772
+ /**
2773
+ * Get the current locale
2774
+ */
2775
+ getLocale() {
2776
+ return this.config.locale;
2777
+ }
2778
+ /**
2779
+ * Get the localization target
2780
+ */
2781
+ getTarget() {
2782
+ return this.config.target;
2783
+ }
2784
+ };
2785
+ __name(_Localization, "Localization");
2786
+ Localization = _Localization;
2372
2787
  }
2373
2788
  });
2374
2789
 
@@ -2750,13 +3165,17 @@ var init_Context = __esm({
2750
3165
  /**
2751
3166
  * Returns the i18n api for this command.
2752
3167
  * @param locale The locale to use for the i18n api.
3168
+ * @template T The command name for type-safe translations. Will provide autocomplete from available translations.
2753
3169
  */
2754
3170
  locale(locale) {
2755
3171
  const selectedLocale = locale ?? this.getLocale();
2756
- return new Localization(this.commandkit, {
2757
- locale: selectedLocale,
2758
- target: this.getCommandIdentifier()
2759
- });
3172
+ return new Localization(
3173
+ this.commandkit,
3174
+ {
3175
+ locale: selectedLocale,
3176
+ target: this.getCommandIdentifier()
3177
+ }
3178
+ );
2760
3179
  }
2761
3180
  /**
2762
3181
  * Creates a clone of this context
@@ -2817,496 +3236,248 @@ var init_Context = __esm({
2817
3236
  _MiddlewareContext = class _MiddlewareContext extends Context {
2818
3237
  constructor() {
2819
3238
  super(...arguments);
2820
- __privateAdd(this, _cancel, false);
2821
- }
2822
- /**
2823
- * Whether the command execution was cancelled.
2824
- */
2825
- get cancelled() {
2826
- return __privateGet(this, _cancel);
2827
- }
2828
- /**
2829
- * Cancels the command execution.
2830
- */
2831
- cancel() {
2832
- __privateSet(this, _cancel, true);
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
- }
2847
- };
2848
- _cancel = new WeakMap();
2849
- __name(_MiddlewareContext, "MiddlewareContext");
2850
- MiddlewareContext = _MiddlewareContext;
2851
- }
2852
- });
2853
-
2854
- // src/utils/resolve-file-url.ts
2855
- function toFileURL(filePath, withTs = false) {
2856
- const resolvedPath = import_path.default.resolve(filePath);
2857
- return `${"file://" + resolvedPath.replace(/\\\\|\\/g, "/")}${withTs ? `?ts=${Date.now()}` : ""}`;
2858
- }
2859
- var import_path;
2860
- var init_resolve_file_url = __esm({
2861
- "src/utils/resolve-file-url.ts"() {
2862
- "use strict";
2863
- init_cjs_shims();
2864
- import_path = __toESM(require("path"));
2865
- __name(toFileURL, "toFileURL");
2866
- }
2867
- });
2868
-
2869
- // src/app/commands/MessageCommandParser.ts
2870
- var import_discord8, _parsed, _options, _args, _MessageCommandParser, MessageCommandParser, _MessageCommandOptions, MessageCommandOptions;
2871
- var init_MessageCommandParser = __esm({
2872
- "src/app/commands/MessageCommandParser.ts"() {
2873
- "use strict";
2874
- init_cjs_shims();
2875
- import_discord8 = require("discord.js");
2876
- init_error_codes();
2877
- _MessageCommandParser = class _MessageCommandParser {
2878
- constructor(message, prefix, schema) {
2879
- this.message = message;
2880
- this.prefix = prefix;
2881
- this.schema = schema;
2882
- __privateAdd(this, _parsed, null);
2883
- __privateAdd(this, _options, null);
2884
- __privateAdd(this, _args, []);
2885
- }
2886
- getArgs() {
2887
- void this.parse();
2888
- return __privateGet(this, _args);
2889
- }
2890
- get options() {
2891
- if (!__privateGet(this, _options)) {
2892
- __privateSet(this, _options, new MessageCommandOptions(this));
2893
- }
2894
- return __privateGet(this, _options);
2895
- }
2896
- getOption(name) {
2897
- var _a;
2898
- return (_a = this.parse().options.find((o) => o.name === name)) == null ? void 0 : _a.value;
2899
- }
2900
- getCommand() {
2901
- return this.parse().command;
2902
- }
2903
- getSubcommand() {
2904
- return this.parse().subcommand;
2905
- }
2906
- getSubcommandGroup() {
2907
- return this.parse().subcommandGroup;
2908
- }
2909
- getPrefix() {
2910
- for (const p of this.prefix) {
2911
- if (this.message.content.startsWith(p)) {
2912
- return p;
2913
- }
2914
- }
2915
- }
2916
- getFullCommand() {
2917
- return [this.getCommand(), this.getSubcommandGroup(), this.getSubcommand()].filter((v) => v).join(" ");
2918
- }
2919
- parse() {
2920
- if (__privateGet(this, _parsed)) {
2921
- return __privateGet(this, _parsed);
2922
- }
2923
- const content = this.message.content;
2924
- const prefix = this.getPrefix();
2925
- if (!prefix) {
2926
- throw createCommandKitError(CommandKitErrorCodes.InvalidCommandPrefix);
2927
- }
2928
- const parts = content.slice(prefix.length).trim().split(" ");
2929
- const command = parts.shift();
2930
- __privateSet(this, _args, parts);
2931
- let subcommandGroup;
2932
- let subcommand;
2933
- if (command == null ? void 0 : command.includes(":")) {
2934
- const [, group, cmd] = command.split(":");
2935
- if (!cmd && group) {
2936
- subcommand = group;
2937
- } else if (cmd && group) {
2938
- subcommandGroup = group;
2939
- subcommand = cmd;
2940
- }
2941
- }
2942
- const schema = this.schema(
2943
- [command, subcommandGroup, subcommand].filter(Boolean).join(" ").trim()
2944
- );
2945
- const options = parts.map((part) => {
2946
- try {
2947
- const [name, value] = part.split(":");
2948
- if (!(name in schema)) return null;
2949
- switch (schema[name]) {
2950
- case import_discord8.ApplicationCommandOptionType.Boolean:
2951
- return { name, value: value === "true" };
2952
- case import_discord8.ApplicationCommandOptionType.Integer:
2953
- return { name, value: parseInt(value, 10) };
2954
- case import_discord8.ApplicationCommandOptionType.Number:
2955
- return { name, value: parseFloat(value) };
2956
- case import_discord8.ApplicationCommandOptionType.String:
2957
- return { name, value };
2958
- case import_discord8.ApplicationCommandOptionType.User:
2959
- return {
2960
- name,
2961
- value: this.message.mentions.users.find((u) => {
2962
- return u.id === value.replace(/[<@!>]/g, "");
2963
- })
2964
- };
2965
- case import_discord8.ApplicationCommandOptionType.Channel:
2966
- return {
2967
- name,
2968
- value: this.message.mentions.channels.find((c) => {
2969
- return c.id === value.replace(/[<#>]/g, "");
2970
- })
2971
- };
2972
- case import_discord8.ApplicationCommandOptionType.Role:
2973
- return {
2974
- name,
2975
- value: this.message.mentions.roles.find((r) => {
2976
- return r.id === value.replace(/[<@&>]/g, "");
2977
- })
2978
- };
2979
- case import_discord8.ApplicationCommandOptionType.Attachment:
2980
- return {
2981
- name,
2982
- value: this.message.attachments.find((a) => {
2983
- return a.name === value;
2984
- })
2985
- };
2986
- default:
2987
- return null;
2988
- }
2989
- } catch {
2990
- return null;
2991
- }
2992
- }).filter((v) => v !== null);
2993
- __privateSet(this, _parsed, {
2994
- command,
2995
- options,
2996
- subcommand,
2997
- subcommandGroup
2998
- });
2999
- return __privateGet(this, _parsed);
3000
- }
3001
- };
3002
- _parsed = new WeakMap();
3003
- _options = new WeakMap();
3004
- _args = new WeakMap();
3005
- __name(_MessageCommandParser, "MessageCommandParser");
3006
- MessageCommandParser = _MessageCommandParser;
3007
- _MessageCommandOptions = class _MessageCommandOptions {
3008
- constructor(parser2) {
3009
- this.parser = parser2;
3010
- }
3011
- assertOption(name, required = false) {
3012
- const option = this.parser.getOption(name);
3013
- if (required && option === void 0) {
3014
- throw new Error(`Option "${name}" is required.`);
3015
- }
3016
- return option ?? null;
3017
- }
3018
- getMember(name, required = false) {
3019
- var _a;
3020
- const user = this.assertOption(name, required);
3021
- const member = (_a = this.parser.message.guild) == null ? void 0 : _a.members.cache.get(user == null ? void 0 : user.id);
3022
- if (required && !member) {
3023
- throw new Error(`Member "${name}" is required.`);
3024
- }
3025
- return member ?? null;
3026
- }
3027
- getAttachment(name, required = false) {
3028
- return this.assertOption(name, required);
3029
- }
3030
- getBoolean(name, required = false) {
3031
- return this.assertOption(name, required);
3032
- }
3033
- getNumber(name, required = false) {
3034
- return this.assertOption(name, required);
3035
- }
3036
- getString(name, required = false) {
3037
- return this.assertOption(name, required);
3038
- }
3039
- getInteger(name, required = false) {
3040
- return this.assertOption(name, required);
3041
- }
3042
- getUser(name, required = false) {
3043
- return this.assertOption(name, required);
3044
- }
3045
- getChannel(name, required = false) {
3046
- return this.assertOption(name, required);
3047
- }
3048
- getRole(name, required = false) {
3049
- return this.assertOption(name, required);
3050
- }
3051
- getMentionable(name, required = false) {
3052
- const target = this.assertOption(name, required);
3053
- if (target instanceof import_discord8.GuildMember || target instanceof import_discord8.User || target instanceof import_discord8.Role) {
3054
- return target;
3055
- }
3056
- if (required) {
3057
- throw new Error(`Mentionable "${name}" is required.`);
3058
- }
3059
- return null;
3239
+ __privateAdd(this, _cancel, false);
3060
3240
  }
3061
- getSubcommand(required = false) {
3062
- const sub = this.parser.getSubcommand();
3063
- if (required && sub === void 0) {
3064
- throw new Error("Subcommand is required.");
3065
- }
3066
- return sub ?? null;
3241
+ /**
3242
+ * Whether the command execution was cancelled.
3243
+ */
3244
+ get cancelled() {
3245
+ return __privateGet(this, _cancel);
3067
3246
  }
3068
- getSubcommandGroup(required = false) {
3069
- const sub = this.parser.getSubcommandGroup();
3070
- if (required && sub === void 0) {
3071
- throw new Error("Subcommand group is required.");
3072
- }
3073
- return sub ?? null;
3247
+ /**
3248
+ * Cancels the command execution.
3249
+ */
3250
+ cancel() {
3251
+ __privateSet(this, _cancel, true);
3252
+ }
3253
+ /**
3254
+ * Sets command runner function to wrap the command execution.
3255
+ * @param fn The function to set.
3256
+ * @example ctx.setCommandRunner(async (execute) => {
3257
+ * // do something before command execution
3258
+ * await execute();
3259
+ * // do something after command execution
3260
+ * })
3261
+ */
3262
+ setCommandRunner(fn) {
3263
+ var _a, _b;
3264
+ (_b = (_a = this.config.customArgs) == null ? void 0 : _a.setCommandRunner) == null ? void 0 : _b.call(_a, fn);
3074
3265
  }
3075
3266
  };
3076
- __name(_MessageCommandOptions, "MessageCommandOptions");
3077
- MessageCommandOptions = _MessageCommandOptions;
3267
+ _cancel = new WeakMap();
3268
+ __name(_MiddlewareContext, "MiddlewareContext");
3269
+ MiddlewareContext = _MiddlewareContext;
3078
3270
  }
3079
3271
  });
3080
3272
 
3081
- // src/app/register/CommandRegistrar.ts
3082
- var import_discord9, _CommandRegistrar, CommandRegistrar;
3083
- var init_CommandRegistrar = __esm({
3084
- "src/app/register/CommandRegistrar.ts"() {
3273
+ // src/app/commands/AppCommandRunner.ts
3274
+ var import_discord10, _AppCommandRunner_instances, finalizer_fn, _AppCommandRunner, AppCommandRunner;
3275
+ var init_AppCommandRunner = __esm({
3276
+ "src/app/commands/AppCommandRunner.ts"() {
3085
3277
  "use strict";
3086
3278
  init_cjs_shims();
3087
- import_discord9 = require("discord.js");
3279
+ import_discord10 = require("discord.js");
3280
+ init_environment();
3088
3281
  init_Logger();
3089
- _CommandRegistrar = class _CommandRegistrar {
3090
- /**
3091
- * Creates an instance of CommandRegistrar.
3092
- * @param commandkit The commandkit instance.
3093
- */
3094
- constructor(commandkit2) {
3095
- this.commandkit = commandkit2;
3096
- this.api.setToken(
3097
- this.commandkit.client.token ?? process.env.DISCORD_TOKEN ?? process.env.TOKEN ?? ""
3098
- );
3099
- }
3100
- api = new import_discord9.REST();
3101
- /**
3102
- * Gets the commands data.
3103
- */
3104
- getCommandsData() {
3105
- const handler = this.commandkit.commandHandler;
3106
- const commands = handler.getCommandsArray();
3107
- return commands.flatMap((cmd) => {
3108
- var _a;
3109
- const json = "toJSON" in cmd.data.command ? cmd.data.command.toJSON() : cmd.data.command;
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);
3112
- }
3113
- const collections = [json];
3114
- if (cmd.data.userContextMenu && json.type !== import_discord9.ApplicationCommandType.User) {
3115
- collections.push({
3116
- ...json,
3117
- type: import_discord9.ApplicationCommandType.User,
3118
- options: void 0,
3119
- description_localizations: void 0,
3120
- // @ts-ignore
3121
- description: void 0
3122
- });
3123
- }
3124
- if (cmd.data.messageContextMenu && json.type !== import_discord9.ApplicationCommandType.Message) {
3125
- collections.push({
3126
- ...json,
3127
- type: import_discord9.ApplicationCommandType.Message,
3128
- description_localizations: void 0,
3129
- // @ts-ignore
3130
- description: void 0,
3131
- options: void 0
3132
- });
3133
- }
3134
- return collections;
3135
- });
3282
+ init_Context();
3283
+ init_async_context();
3284
+ _AppCommandRunner = class _AppCommandRunner {
3285
+ constructor(handler) {
3286
+ this.handler = handler;
3287
+ __privateAdd(this, _AppCommandRunner_instances);
3136
3288
  }
3137
- /**
3138
- * Process and merge subcommands into the parent command's options
3139
- */
3140
- processSubcommands(commandData, subcommands) {
3141
- var _a, _b, _c;
3142
- if (!commandData.options) {
3143
- commandData.options = [];
3289
+ async runCommand(prepared, source) {
3290
+ if (source instanceof import_discord10.Message && (source.editedTimestamp || source.partial)) {
3291
+ return;
3144
3292
  }
3145
- const groupedSubcommands = /* @__PURE__ */ new Map();
3146
- for (const subcommand of subcommands) {
3147
- const group = subcommand.group || null;
3148
- if (!groupedSubcommands.has(group)) {
3149
- groupedSubcommands.set(group, []);
3293
+ const { commandkit: commandkit2 } = this.handler;
3294
+ const executionMode = this.getExecutionMode(source);
3295
+ let runCommand = null;
3296
+ const env = new CommandKitEnvironment(commandkit2);
3297
+ env.setType("COMMAND_HANDLER" /* CommandHandler */);
3298
+ env.variables.set("commandHandlerType", "app");
3299
+ env.variables.set("currentCommandName", prepared.command.command.name);
3300
+ env.variables.set("execHandlerKind", executionMode);
3301
+ const ctx = new MiddlewareContext(commandkit2, {
3302
+ environment: env,
3303
+ executionMode,
3304
+ interaction: !(source instanceof import_discord10.Message) ? source : null,
3305
+ message: source instanceof import_discord10.Message ? source : null,
3306
+ forwarded: false,
3307
+ customArgs: {
3308
+ setCommandRunner: /* @__PURE__ */ __name((fn2) => {
3309
+ runCommand = fn2;
3310
+ }, "setCommandRunner")
3150
3311
  }
3151
- (_a = groupedSubcommands.get(group)) == null ? void 0 : _a.push(subcommand);
3312
+ });
3313
+ for (const middleware of prepared.middlewares) {
3314
+ await middleware.data.beforeExecute(ctx);
3152
3315
  }
3153
- const directSubcommands = groupedSubcommands.get(null) || [];
3154
- for (const subcommand of directSubcommands) {
3155
- const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3156
- subcommand.command,
3157
- subcommand.name
3316
+ const targetData = prepared.command.data;
3317
+ const fn = targetData[executionMode];
3318
+ if (!fn) {
3319
+ Logger.warn(
3320
+ `Command ${prepared.command.command.name} has no handler for ${executionMode}`
3158
3321
  );
3159
- if (subcommandData) {
3160
- const subcommandOption = {
3161
- type: import_discord9.ApplicationCommandOptionType.Subcommand,
3162
- name: subcommand.name,
3163
- description: subcommandData.description || "No description provided",
3164
- options: subcommandData.options || [],
3165
- name_localizations: subcommandData.name_localizations,
3166
- description_localizations: subcommandData.description_localizations
3167
- };
3168
- commandData.options.push(subcommandOption);
3169
- }
3170
3322
  }
3171
- for (const [groupName, groupSubcommands] of groupedSubcommands.entries()) {
3172
- if (groupName === null) continue;
3173
- const subcommandGroupOption = {
3174
- type: import_discord9.ApplicationCommandOptionType.SubcommandGroup,
3175
- name: groupName,
3176
- description: `${groupName} commands`,
3177
- options: []
3178
- };
3179
- for (const subcommand of groupSubcommands) {
3180
- const subcommandData = this.commandkit.commandHandler.getSubcommandData(
3181
- subcommand.command,
3182
- subcommand.name
3323
+ if (fn) {
3324
+ try {
3325
+ const _executeCommand = makeContextAwareFunction(
3326
+ env,
3327
+ async () => {
3328
+ afterCommand((env2) => {
3329
+ const error = env2.getExecutionError();
3330
+ const marker = env2.getMarker();
3331
+ const time = `${env2.getExecutionTime().toFixed(2)}ms`;
3332
+ if (error) {
3333
+ Logger.error(
3334
+ `[${marker} - ${time}] Error executing command: ${error.stack || error}`
3335
+ );
3336
+ return;
3337
+ }
3338
+ Logger.info(
3339
+ `[${marker} - ${time}] Command executed successfully`
3340
+ );
3341
+ });
3342
+ return fn(ctx.clone());
3343
+ },
3344
+ __privateMethod(this, _AppCommandRunner_instances, finalizer_fn).bind(this)
3183
3345
  );
3184
- if (subcommandData) {
3185
- (_b = subcommandGroupOption.options) == null ? void 0 : _b.push({
3186
- type: import_discord9.ApplicationCommandOptionType.Subcommand,
3187
- name: subcommand.name,
3188
- description: subcommandData.description || "No description provided",
3189
- options: subcommandData.options || [],
3190
- name_localizations: subcommandData.name_localizations,
3191
- description_localizations: subcommandData.description_localizations
3192
- });
3346
+ const executeCommand = runCommand != null ? runCommand(_executeCommand) : _executeCommand;
3347
+ env.markStart(prepared.command.command.name);
3348
+ const res = await commandkit2.plugins.execute(async (ctx2, plugin) => {
3349
+ return plugin.executeCommand(ctx2, source, prepared, executeCommand);
3350
+ });
3351
+ if (!res) {
3352
+ await executeCommand();
3193
3353
  }
3354
+ } catch (e) {
3355
+ Logger.error(e);
3194
3356
  }
3195
- if ((((_c = subcommandGroupOption.options) == null ? void 0 : _c.length) || 0) > 0) {
3196
- commandData.options.push(subcommandGroupOption);
3357
+ }
3358
+ try {
3359
+ for (const middleware of prepared.middlewares) {
3360
+ await middleware.data.afterExecute(ctx);
3197
3361
  }
3362
+ } finally {
3363
+ env.markEnd();
3198
3364
  }
3199
3365
  }
3200
- /**
3201
- * Registers loaded commands.
3202
- */
3203
- async register() {
3204
- if (!this.commandkit.client.isReady()) {
3205
- throw new Error("Cannot register commands before the client is ready");
3366
+ getExecutionMode(source) {
3367
+ if (source instanceof import_discord10.Message) return CommandExecutionMode.Message;
3368
+ if (source.isChatInputCommand()) return CommandExecutionMode.SlashCommand;
3369
+ if (source.isAutocomplete()) {
3370
+ return CommandExecutionMode.Autocomplete;
3206
3371
  }
3207
- const commands = this.getCommandsData();
3208
- const guildCommands = commands.filter((command) => {
3209
- var _a;
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
- };
3217
- });
3218
- const globalCommands = commands.filter(
3219
- (command) => {
3220
- var _a;
3221
- return !((_a = command.guilds) == null ? void 0 : _a.filter(Boolean).length);
3222
- }
3223
- );
3224
- await this.updateGlobalCommands(globalCommands);
3225
- await this.updateGuildCommands(guildCommands);
3226
- }
3227
- /**
3228
- * Updates the global commands.
3229
- */
3230
- async updateGlobalCommands(commands) {
3231
- if (!commands.length) return;
3232
- try {
3233
- const data = await this.api.put(
3234
- import_discord9.Routes.applicationCommands(this.commandkit.client.user.id),
3235
- {
3236
- body: commands.map((c) => ({
3237
- ...c,
3238
- guilds: void 0
3239
- }))
3240
- }
3241
- );
3242
- Logger.info(
3243
- `\u2728 Refreshed ${data.length} global application (/) commands`
3244
- );
3245
- } catch (e) {
3246
- Logger.error("Failed to update global application (/) commands", e);
3372
+ if (source.isMessageContextMenuCommand()) {
3373
+ return CommandExecutionMode.MessageContextMenu;
3247
3374
  }
3248
- }
3249
- /**
3250
- * Updates the guild commands.
3251
- */
3252
- async updateGuildCommands(commands) {
3253
- try {
3254
- const guildCommandsMap = /* @__PURE__ */ new Map();
3255
- commands.forEach((command) => {
3256
- var _a;
3257
- if (!((_a = command.guilds) == null ? void 0 : _a.length)) return;
3258
- command.guilds.forEach((guild) => {
3259
- if (!guildCommandsMap.has(guild)) {
3260
- guildCommandsMap.set(guild, []);
3261
- }
3262
- guildCommandsMap.get(guild).push(command);
3263
- });
3264
- });
3265
- if (!guildCommandsMap.size) return;
3266
- let count = 0;
3267
- for (const [guild, guildCommands] of guildCommandsMap) {
3268
- const data = await this.api.put(
3269
- import_discord9.Routes.applicationGuildCommands(
3270
- this.commandkit.client.user.id,
3271
- guild
3272
- ),
3273
- {
3274
- body: guildCommands.map((b) => ({
3275
- ...b,
3276
- guilds: void 0
3277
- }))
3278
- }
3279
- );
3280
- count += data.length;
3281
- }
3282
- Logger.info(`\u2728 Refreshed ${count} guild application (/) commands`);
3283
- } catch (e) {
3284
- Logger.error("Failed to update guild application (/) commands", e);
3375
+ if (source.isUserContextMenuCommand()) {
3376
+ return CommandExecutionMode.UserContextMenu;
3285
3377
  }
3378
+ return null;
3286
3379
  }
3287
3380
  };
3288
- __name(_CommandRegistrar, "CommandRegistrar");
3289
- CommandRegistrar = _CommandRegistrar;
3381
+ _AppCommandRunner_instances = new WeakSet();
3382
+ finalizer_fn = /* @__PURE__ */ __name(async function() {
3383
+ const env = useEnvironment();
3384
+ await env.runDeferredFunctions();
3385
+ env.clearAllDeferredFunctions();
3386
+ }, "#finalizer");
3387
+ __name(_AppCommandRunner, "AppCommandRunner");
3388
+ AppCommandRunner = _AppCommandRunner;
3389
+ }
3390
+ });
3391
+
3392
+ // src/utils/types-package.ts
3393
+ async function generateTypesPackage() {
3394
+ const location = (0, import_node_path3.join)(process.cwd(), "node_modules", "commandkit-types");
3395
+ if (!COMMANDKIT_IS_DEV) return location;
3396
+ const packageJSON = (0, import_node_path3.join)(location, "package.json");
3397
+ const index = (0, import_node_path3.join)(location, "index.js");
3398
+ const types = (0, import_node_path3.join)(location, "index.d.ts");
3399
+ const locale = (0, import_node_path3.join)(location, "locale_types.d.ts");
3400
+ const command = (0, import_node_path3.join)(location, "command.d.ts");
3401
+ const packageJSONContent = {
3402
+ name: "commandkit-types",
3403
+ version: "1.0.0",
3404
+ description: "CommandKit types package",
3405
+ type: "commonjs",
3406
+ main: "index.js",
3407
+ types: "index.d.ts"
3408
+ };
3409
+ const indexContent = `module.exports = {};`;
3410
+ const typesContent = `// Main types index file - imports all type declarations
3411
+ import './locale_types';
3412
+ import './command';
3413
+ export {};
3414
+ `;
3415
+ const localeTypesContent = `// Auto-generated localization types
3416
+ export {};
3417
+ declare module 'commandkit' {
3418
+ interface CommandLocalizationTypeData {
3419
+ // This interface will be populated with localizations
3420
+ }
3421
+
3422
+ type TranslatableCommandName = keyof CommandLocalizationTypeData
3423
+ }`;
3424
+ const commandTypesContent = `// Auto-generated command types
3425
+ export {};
3426
+ declare module 'commandkit' {
3427
+ type CommandTypeData = string
3428
+ }`;
3429
+ await (0, import_promises3.mkdir)(location, { recursive: true }).catch(() => {
3430
+ });
3431
+ await (0, import_promises3.writeFile)(packageJSON, JSON.stringify(packageJSONContent, null, 2));
3432
+ await (0, import_promises3.writeFile)(index, indexContent);
3433
+ await (0, import_promises3.writeFile)(types, typesContent);
3434
+ await (0, import_promises3.writeFile)(locale, localeTypesContent);
3435
+ await (0, import_promises3.writeFile)(command, commandTypesContent);
3436
+ return location;
3437
+ }
3438
+ async function rewriteCommandDeclaration(data) {
3439
+ const commandTypesContent = `// Auto-generated command types
3440
+ declare module 'commandkit' {
3441
+ ${data}
3442
+ }
3443
+ export {};
3444
+ `;
3445
+ const location = (0, import_node_path3.join)(process.cwd(), "node_modules", "commandkit-types");
3446
+ if (!(0, import_node_fs3.existsSync)(location)) return;
3447
+ const type = (0, import_node_path3.join)(location, "command.d.ts");
3448
+ await (0, import_promises3.writeFile)(type, commandTypesContent, { encoding: "utf-8" });
3449
+ }
3450
+ var import_promises3, import_node_path3, import_node_fs3;
3451
+ var init_types_package = __esm({
3452
+ "src/utils/types-package.ts"() {
3453
+ "use strict";
3454
+ init_cjs_shims();
3455
+ import_promises3 = require("fs/promises");
3456
+ import_node_path3 = require("path");
3457
+ init_constants();
3458
+ import_node_fs3 = require("fs");
3459
+ __name(generateTypesPackage, "generateTypesPackage");
3460
+ __name(rewriteCommandDeclaration, "rewriteCommandDeclaration");
3290
3461
  }
3291
3462
  });
3292
3463
 
3293
3464
  // src/app/handlers/AppCommandHandler.ts
3294
- var import_discord10, commandDataSchema, middlewareDataSchema, _AppCommandHandler_instances, finalizer_fn, _AppCommandHandler, AppCommandHandler;
3465
+ var import_discord11, commandDataSchema, middlewareDataSchema, _AppCommandHandler, AppCommandHandler;
3295
3466
  var init_AppCommandHandler = __esm({
3296
3467
  "src/app/handlers/AppCommandHandler.ts"() {
3297
3468
  "use strict";
3298
3469
  init_cjs_shims();
3299
- import_discord10 = require("discord.js");
3300
- init_Context();
3470
+ import_discord11 = require("discord.js");
3301
3471
  init_resolve_file_url();
3302
3472
  init_MessageCommandParser();
3303
3473
  init_error_codes();
3304
3474
  init_CommandRegistrar();
3305
- init_async_context();
3306
3475
  init_Logger();
3307
- init_environment();
3476
+ init_AppCommandRunner();
3477
+ init_constants();
3478
+ init_types_package();
3308
3479
  commandDataSchema = {
3309
- command: /* @__PURE__ */ __name((c) => c instanceof import_discord10.SlashCommandBuilder || c instanceof import_discord10.ContextMenuCommandBuilder || c && typeof c === "object", "command"),
3480
+ command: /* @__PURE__ */ __name((c) => c instanceof import_discord11.SlashCommandBuilder || c instanceof import_discord11.ContextMenuCommandBuilder || c && typeof c === "object", "command"),
3310
3481
  chatInput: /* @__PURE__ */ __name((c) => typeof c === "function", "chatInput"),
3311
3482
  autocomplete: /* @__PURE__ */ __name((c) => typeof c === "function", "autocomplete"),
3312
3483
  message: /* @__PURE__ */ __name((c) => typeof c === "function", "message"),
@@ -3320,33 +3491,21 @@ var init_AppCommandHandler = __esm({
3320
3491
  _AppCommandHandler = class _AppCommandHandler {
3321
3492
  constructor(commandkit2) {
3322
3493
  this.commandkit = commandkit2;
3323
- __privateAdd(this, _AppCommandHandler_instances);
3324
- __publicField(this, "loadedCommands", new import_discord10.Collection());
3325
- __publicField(this, "loadedSubCommands", new import_discord10.Collection());
3326
- __publicField(this, "loadedMiddlewares", new import_discord10.Collection());
3327
- // Name-to-ID mapping for easier lookup
3328
- __publicField(this, "commandNameToId", /* @__PURE__ */ new Map());
3329
- __publicField(this, "subcommandPathToId", /* @__PURE__ */ new Map());
3330
- __publicField(this, "registrar");
3331
- __publicField(this, "onInteraction", null);
3332
- __publicField(this, "onMessageCreate", null);
3333
- __publicField(this, "onMessageUpdate", null);
3334
3494
  this.registrar = new CommandRegistrar(this.commandkit);
3335
3495
  }
3496
+ loadedCommands = new import_discord11.Collection();
3497
+ loadedMiddlewares = new import_discord11.Collection();
3498
+ // Name-to-ID mapping for easier lookup
3499
+ commandNameToId = /* @__PURE__ */ new Map();
3500
+ subcommandPathToId = /* @__PURE__ */ new Map();
3501
+ registrar;
3502
+ onInteraction = null;
3503
+ onMessageCreate = null;
3504
+ onMessageUpdate = null;
3505
+ commandRunner = new AppCommandRunner(this);
3336
3506
  getCommandsArray() {
3337
3507
  return Array.from(this.loadedCommands.values());
3338
3508
  }
3339
- /**
3340
- * Get subcommand data by command ID and subcommand name
3341
- */
3342
- getSubcommandData(commandId, subcommandName) {
3343
- const subcommand = Array.from(this.loadedSubCommands.values()).find(
3344
- (sub) => sub.subcommand.command === commandId && sub.subcommand.name === subcommandName
3345
- );
3346
- if (!subcommand) return null;
3347
- const commandData = subcommand.data.command;
3348
- return "toJSON" in commandData ? commandData.toJSON() : commandData;
3349
- }
3350
3509
  registerCommandHandler() {
3351
3510
  this.onInteraction ??= async (interaction) => {
3352
3511
  const success = await this.commandkit.plugins.execute(
@@ -3359,7 +3518,7 @@ var init_AppCommandHandler = __esm({
3359
3518
  if (!isCommandLike) return;
3360
3519
  const prepared = await this.prepareCommandRun(interaction);
3361
3520
  if (!prepared) return;
3362
- return this.runCommand(prepared, interaction);
3521
+ return this.commandRunner.runCommand(prepared, interaction);
3363
3522
  };
3364
3523
  this.onMessageCreate ??= async (message) => {
3365
3524
  const success = await this.commandkit.plugins.execute(
@@ -3371,7 +3530,7 @@ var init_AppCommandHandler = __esm({
3371
3530
  if (message.author.bot) return;
3372
3531
  const prepared = await this.prepareCommandRun(message);
3373
3532
  if (!prepared) return;
3374
- return this.runCommand(prepared, message);
3533
+ return this.commandRunner.runCommand(prepared, message);
3375
3534
  };
3376
3535
  this.onMessageUpdate ??= async (oldMessage, newMessage) => {
3377
3536
  const success = await this.commandkit.plugins.execute(
@@ -3388,107 +3547,17 @@ var init_AppCommandHandler = __esm({
3388
3547
  if (oldMessage.author.bot) return;
3389
3548
  const prepared = await this.prepareCommandRun(newMessage);
3390
3549
  if (!prepared) return;
3391
- return this.runCommand(prepared, newMessage);
3550
+ return this.commandRunner.runCommand(prepared, newMessage);
3392
3551
  };
3393
- this.commandkit.client.on(import_discord10.Events.InteractionCreate, this.onInteraction);
3394
- this.commandkit.client.on(import_discord10.Events.MessageCreate, this.onMessageCreate);
3395
- this.commandkit.client.on(import_discord10.Events.MessageUpdate, this.onMessageUpdate);
3396
- }
3397
- getExecutionMode(source) {
3398
- if (source instanceof import_discord10.Message) return CommandExecutionMode.Message;
3399
- if (source.isChatInputCommand()) return CommandExecutionMode.SlashCommand;
3400
- if (source.isAutocomplete()) {
3401
- return CommandExecutionMode.Autocomplete;
3402
- }
3403
- if (source.isMessageContextMenuCommand()) {
3404
- return CommandExecutionMode.MessageContextMenu;
3405
- }
3406
- if (source.isUserContextMenuCommand()) {
3407
- return CommandExecutionMode.UserContextMenu;
3408
- }
3409
- return null;
3410
- }
3411
- async runCommand(prepared, source) {
3412
- if (source instanceof import_discord10.Message && (source.editedTimestamp || source.partial)) {
3413
- return;
3414
- }
3415
- const executionMode = this.getExecutionMode(source);
3416
- let runCommand = null;
3417
- const env = new CommandKitEnvironment(this.commandkit);
3418
- env.setType("COMMAND_HANDLER" /* CommandHandler */);
3419
- env.variables.set("commandHandlerType", "app");
3420
- env.variables.set("currentCommandName", prepared.command.command.name);
3421
- env.variables.set("execHandlerKind", executionMode);
3422
- const ctx = new MiddlewareContext(this.commandkit, {
3423
- environment: env,
3424
- executionMode,
3425
- interaction: !(source instanceof import_discord10.Message) ? source : null,
3426
- message: source instanceof import_discord10.Message ? source : null,
3427
- forwarded: false,
3428
- customArgs: {
3429
- setCommandRunner: /* @__PURE__ */ __name((fn2) => {
3430
- runCommand = fn2;
3431
- }, "setCommandRunner")
3432
- }
3433
- });
3434
- for (const middleware of prepared.middlewares) {
3435
- await middleware.data.beforeExecute(ctx);
3436
- }
3437
- const targetData = prepared.subcommand ? prepared.subcommand.data : prepared.command.data;
3438
- const fn = targetData[executionMode];
3439
- if (!fn) {
3440
- Logger.warn(
3441
- `Command ${prepared.command.command.name}${prepared.subcommand ? "/" + prepared.subcommand.subcommand.name : ""} has no handler for ${executionMode}`
3442
- );
3443
- }
3444
- if (fn) {
3445
- try {
3446
- const _executeCommand = makeContextAwareFunction(
3447
- env,
3448
- async () => fn(ctx.clone()),
3449
- __privateMethod(this, _AppCommandHandler_instances, finalizer_fn).bind(this)
3450
- );
3451
- const executeCommand = runCommand != null ? runCommand(_executeCommand) : _executeCommand;
3452
- afterCommand((env2) => {
3453
- const error = env2.getExecutionError();
3454
- const marker = env2.getMarker();
3455
- const time = `${env2.getExecutionTime().toFixed(2)}ms`;
3456
- if (error) {
3457
- Logger.error(
3458
- `[${marker} - ${time}] Error executing command: ${error.stack || error}`
3459
- );
3460
- return;
3461
- }
3462
- Logger.info(`[${marker} - ${time}] Command executed successfully`);
3463
- });
3464
- env.markStart(prepared.command.command.name);
3465
- const res = await this.commandkit.plugins.execute(
3466
- async (ctx2, plugin) => {
3467
- return plugin.executeCommand(ctx2, source, prepared, executeCommand);
3468
- }
3469
- );
3470
- if (!res) {
3471
- await executeCommand();
3472
- }
3473
- } catch (e) {
3474
- Logger.error(e);
3475
- }
3476
- }
3477
- try {
3478
- for (const middleware of prepared.middlewares) {
3479
- await middleware.data.afterExecute(ctx);
3480
- }
3481
- } finally {
3482
- env.markEnd();
3483
- }
3552
+ this.commandkit.client.on(import_discord11.Events.InteractionCreate, this.onInteraction);
3553
+ this.commandkit.client.on(import_discord11.Events.MessageCreate, this.onMessageCreate);
3554
+ this.commandkit.client.on(import_discord11.Events.MessageUpdate, this.onMessageUpdate);
3484
3555
  }
3485
3556
  async prepareCommandRun(source) {
3486
3557
  var _a;
3487
3558
  let cmdName;
3488
- let subcommandGroupName = null;
3489
- let subcommandName = null;
3490
3559
  let parser2;
3491
- if (source instanceof import_discord10.Message) {
3560
+ if (source instanceof import_discord11.Message) {
3492
3561
  if (source.author.bot) return null;
3493
3562
  const prefix = await this.commandkit.config.getMessageCommandPrefix(source);
3494
3563
  parser2 = new MessageCommandParser(
@@ -3517,14 +3586,6 @@ var init_AppCommandHandler = __esm({
3517
3586
  const fullCommand = parser2.getFullCommand();
3518
3587
  const parts = fullCommand.split(" ");
3519
3588
  cmdName = parts[0];
3520
- if (parts.length > 1) {
3521
- if (parts.length === 3) {
3522
- subcommandGroupName = parts[1];
3523
- subcommandName = parts[2];
3524
- } else {
3525
- subcommandName = parts[1];
3526
- }
3527
- }
3528
3589
  } catch (e) {
3529
3590
  if (isErrorType(e, CommandKitErrorCodes.InvalidCommandPrefix)) {
3530
3591
  return null;
@@ -3535,31 +3596,16 @@ var init_AppCommandHandler = __esm({
3535
3596
  } else {
3536
3597
  if (!source.isCommand()) return null;
3537
3598
  cmdName = source.commandName;
3538
- if (source.isChatInputCommand()) {
3539
- subcommandGroupName = source.options.getSubcommandGroup(false);
3540
- subcommandName = source.options.getSubcommand(false);
3541
- }
3542
3599
  }
3543
3600
  const commandId = this.commandNameToId.get(cmdName);
3544
3601
  if (!commandId) return null;
3545
3602
  const loadedCommand = this.loadedCommands.get(commandId);
3546
3603
  if (!loadedCommand) return null;
3547
- if (source instanceof import_discord10.CommandInteraction && source.guildId && ((_a = loadedCommand.guilds) == null ? void 0 : _a.length) && !loadedCommand.guilds.includes(source.guildId)) {
3604
+ if (source instanceof import_discord11.CommandInteraction && source.guildId && ((_a = loadedCommand.guilds) == null ? void 0 : _a.length) && !loadedCommand.guilds.includes(source.guildId)) {
3548
3605
  return null;
3549
3606
  }
3550
- let loadedSubCommand = null;
3551
- if (subcommandName) {
3552
- let subcommandPath = `${loadedCommand.command.id}/${subcommandName}`;
3553
- if (subcommandGroupName) {
3554
- subcommandPath = `${loadedCommand.command.id}/${subcommandGroupName}/${subcommandName}`;
3555
- }
3556
- const subCommandId = this.subcommandPathToId.get(subcommandPath);
3557
- if (subCommandId) {
3558
- loadedSubCommand = this.loadedSubCommands.get(subCommandId) || null;
3559
- }
3560
- }
3561
3607
  const middlewares = [];
3562
- for (const middlewareId of loadedCommand.command.middlewareIds) {
3608
+ for (const middlewareId of loadedCommand.command.middlewares) {
3563
3609
  const middleware = this.loadedMiddlewares.get(middlewareId);
3564
3610
  if (middleware) {
3565
3611
  middlewares.push(middleware);
@@ -3567,14 +3613,12 @@ var init_AppCommandHandler = __esm({
3567
3613
  }
3568
3614
  return {
3569
3615
  command: loadedCommand,
3570
- subcommand: loadedSubCommand,
3571
3616
  middlewares,
3572
3617
  messageCommandParser: parser2
3573
3618
  };
3574
3619
  }
3575
3620
  async reloadCommands() {
3576
3621
  this.loadedCommands.clear();
3577
- this.loadedSubCommands.clear();
3578
3622
  this.loadedMiddlewares.clear();
3579
3623
  this.commandNameToId.clear();
3580
3624
  this.subcommandPathToId.clear();
@@ -3592,12 +3636,12 @@ var init_AppCommandHandler = __esm({
3592
3636
  for (const [id, command] of commands) {
3593
3637
  await this.loadCommand(id, command);
3594
3638
  }
3595
- for (const loadedCommand of this.loadedCommands.values()) {
3596
- if (loadedCommand.command.subcommands) {
3597
- for (const subcommand of loadedCommand.command.subcommands) {
3598
- await this.loadSubcommand(subcommand);
3599
- }
3600
- }
3639
+ if (COMMANDKIT_IS_DEV) {
3640
+ await rewriteCommandDeclaration(
3641
+ `type CommandTypeData = ${Array.from(
3642
+ this.loadedCommands.mapValues((v) => JSON.stringify(v.command.name)).values()
3643
+ ).join(" | ")}`
3644
+ );
3601
3645
  }
3602
3646
  }
3603
3647
  async loadMiddleware(id, middleware) {
@@ -3673,59 +3717,20 @@ var init_AppCommandHandler = __esm({
3673
3717
  Logger.error(`Failed to load command ${command.name} (${id})`, error);
3674
3718
  }
3675
3719
  }
3676
- async loadSubcommand(subcommand) {
3677
- try {
3678
- const data = await import(`${toFileURL(subcommand.path)}?t=${Date.now()}`);
3679
- if (!data.command) {
3680
- throw new Error(
3681
- `Invalid export for subcommand ${subcommand.name}: no command definition found`
3682
- );
3683
- }
3684
- let handlerCount = 0;
3685
- for (const [key, validator] of Object.entries(commandDataSchema)) {
3686
- if (key !== "command" && data[key]) handlerCount++;
3687
- if (data[key] && !await validator(data[key])) {
3688
- throw new Error(
3689
- `Invalid export for subcommand ${subcommand.name}: ${key} does not match expected value`
3690
- );
3691
- }
3692
- }
3693
- if (handlerCount === 0) {
3694
- throw new Error(
3695
- `Invalid export for subcommand ${subcommand.name}: at least one handler function must be provided`
3696
- );
3697
- }
3698
- const localizedCommand = await this.applyLocalizations(
3699
- { ...data.command },
3700
- subcommand
3701
- );
3702
- const subcommandId = subcommand.command + "/" + subcommand.name;
3703
- this.loadedSubCommands.set(subcommandId, {
3704
- subcommand,
3705
- data: {
3706
- ...data,
3707
- command: localizedCommand
3708
- }
3709
- });
3710
- this.subcommandPathToId.set(subcommandId, subcommandId);
3711
- } catch (error) {
3712
- Logger.error(`Failed to load subcommand ${subcommand.name}`, error);
3713
- }
3714
- }
3715
- async applyLocalizations(command, subcommand) {
3720
+ async applyLocalizations(command) {
3716
3721
  var _a, _b, _c, _d, _e;
3717
3722
  const localization = this.commandkit.config.localizationStrategy;
3718
- const validLocales = Object.values(import_discord10.Locale).filter(
3723
+ const validLocales = Object.values(import_discord11.Locale).filter(
3719
3724
  (v) => typeof v === "string"
3720
3725
  );
3721
- const localizationKey = subcommand ? command.name.split("/")[0] : command.name;
3726
+ const localizationKey = command.name;
3722
3727
  for (const locale of validLocales) {
3723
3728
  const translation = await localization.locateTranslation(
3724
3729
  localizationKey,
3725
3730
  locale
3726
3731
  );
3727
3732
  if (!(translation == null ? void 0 : translation.command)) continue;
3728
- if (command instanceof import_discord10.SlashCommandBuilder) {
3733
+ if (command instanceof import_discord11.SlashCommandBuilder) {
3729
3734
  if (translation.command.name) {
3730
3735
  command.setNameLocalization(locale, translation.command.name);
3731
3736
  }
@@ -3742,7 +3747,6 @@ var init_AppCommandHandler = __esm({
3742
3747
  while (o = opt.shift()) {
3743
3748
  (_c = raw.options) == null ? void 0 : _c.forEach((option) => {
3744
3749
  var _a2;
3745
- if (subcommand && option.name !== subcommand.name) return;
3746
3750
  if (option.name === o.ref) {
3747
3751
  if (option.name) {
3748
3752
  option.name_localizations ??= {};
@@ -3772,14 +3776,14 @@ var init_AppCommandHandler = __esm({
3772
3776
  });
3773
3777
  }
3774
3778
  }
3775
- } else if (command instanceof import_discord10.ContextMenuCommandBuilder) {
3779
+ } else if (command instanceof import_discord11.ContextMenuCommandBuilder) {
3776
3780
  if (translation.command.name) {
3777
3781
  command.setNameLocalization(locale, translation.command.name);
3778
3782
  }
3779
3783
  } else {
3780
3784
  command.name_localizations ??= {};
3781
3785
  command.name_localizations[locale] = translation.command.name;
3782
- if (!subcommand && command.description) {
3786
+ if (command.description) {
3783
3787
  command.description_localizations ??= {};
3784
3788
  command.description_localizations[locale] = translation.command.description;
3785
3789
  }
@@ -3789,7 +3793,6 @@ var init_AppCommandHandler = __esm({
3789
3793
  while (o = opt.shift()) {
3790
3794
  command.options.forEach((option) => {
3791
3795
  var _a2;
3792
- if (subcommand && option.name !== subcommand.name) return;
3793
3796
  if (option.name === o.ref) {
3794
3797
  option.name_localizations ??= {};
3795
3798
  option.name_localizations[locale] = o.name;
@@ -3822,49 +3825,69 @@ var init_AppCommandHandler = __esm({
3822
3825
  return command;
3823
3826
  }
3824
3827
  };
3825
- _AppCommandHandler_instances = new WeakSet();
3826
- finalizer_fn = /* @__PURE__ */ __name(async function() {
3827
- const env = useEnvironment();
3828
- await env.runDeferredFunctions();
3829
- env.clearAllDeferredFunctions();
3830
- }, "#finalizer");
3831
3828
  __name(_AppCommandHandler, "AppCommandHandler");
3832
3829
  AppCommandHandler = _AppCommandHandler;
3833
3830
  }
3834
3831
  });
3835
3832
 
3836
3833
  // src/app/router/CommandsRouter.ts
3837
- var import_discord11, import_node_fs3, import_node_crypto3, import_walk, import_node_path3, _CommandsRouter, CommandsRouter;
3834
+ var import_node_fs4, import_promises4, import_node_path4, MIDDLEWARE_PATTERN, COMMAND_PATTERN, CATEGORY_PATTERN, _CommandsRouter, CommandsRouter;
3838
3835
  var init_CommandsRouter = __esm({
3839
3836
  "src/app/router/CommandsRouter.ts"() {
3840
3837
  "use strict";
3841
3838
  init_cjs_shims();
3842
- import_discord11 = require("discord.js");
3843
- import_node_fs3 = require("fs");
3844
- import_node_crypto3 = __toESM(require("crypto"));
3845
- import_walk = __toESM(require("@root/walk"));
3846
- import_node_path3 = __toESM(require("path"));
3839
+ import_node_fs4 = require("fs");
3840
+ import_promises4 = require("fs/promises");
3841
+ import_node_path4 = require("path");
3842
+ MIDDLEWARE_PATTERN = /^\+middleware\.(m|c)?(j|t)sx?$/;
3843
+ COMMAND_PATTERN = /^(\w+)\.(m|c)?(j|t)sx?$/;
3844
+ CATEGORY_PATTERN = /^\(\w+\)$/;
3847
3845
  _CommandsRouter = class _CommandsRouter {
3848
3846
  constructor(options) {
3849
3847
  this.options = options;
3850
3848
  }
3851
- commands = new import_discord11.Collection();
3852
- middlewares = new import_discord11.Collection();
3853
- fromData(data) {
3854
- this.commands = new import_discord11.Collection(
3855
- Object.entries(data.commands).map(([id, command]) => [id, command])
3856
- );
3857
- this.middlewares = new import_discord11.Collection(
3858
- Object.entries(data.middlewares).map(
3859
- ([id, middleware]) => [
3860
- id,
3861
- middleware
3862
- ]
3863
- )
3864
- );
3849
+ commands = /* @__PURE__ */ new Map();
3850
+ middlewares = /* @__PURE__ */ new Map();
3851
+ populate(data) {
3852
+ for (const [id, command] of Object.entries(data.commands)) {
3853
+ this.commands.set(id, command);
3854
+ }
3855
+ for (const [id, middleware] of Object.entries(data.middlewares)) {
3856
+ this.middlewares.set(id, middleware);
3857
+ }
3865
3858
  }
3866
3859
  isValidPath() {
3867
- return (0, import_node_fs3.existsSync)(this.options.entrypoint);
3860
+ return (0, import_node_fs4.existsSync)(this.options.entrypoint);
3861
+ }
3862
+ isCommand(name) {
3863
+ return COMMAND_PATTERN.test(name);
3864
+ }
3865
+ isMiddleware(name) {
3866
+ return MIDDLEWARE_PATTERN.test(name);
3867
+ }
3868
+ isCategory(name) {
3869
+ return CATEGORY_PATTERN.test(name);
3870
+ }
3871
+ clear() {
3872
+ this.commands.clear();
3873
+ this.middlewares.clear();
3874
+ }
3875
+ async scan() {
3876
+ const entries = await (0, import_promises4.readdir)(this.options.entrypoint, {
3877
+ withFileTypes: true
3878
+ });
3879
+ for (const entry of entries) {
3880
+ if (entry.name.startsWith("_")) continue;
3881
+ const fullPath = (0, import_node_path4.join)(this.options.entrypoint, entry.name);
3882
+ if (entry.isDirectory()) {
3883
+ const category = this.isCategory(entry.name) ? entry.name.slice(1, -1) : null;
3884
+ await this.traverse(fullPath, category);
3885
+ } else {
3886
+ await this.handle(entry);
3887
+ }
3888
+ }
3889
+ await this.applyMiddlewares();
3890
+ return this.toJSON();
3868
3891
  }
3869
3892
  getData() {
3870
3893
  return {
@@ -3878,164 +3901,58 @@ var init_CommandsRouter = __esm({
3878
3901
  middlewares: Object.fromEntries(this.middlewares.entries())
3879
3902
  };
3880
3903
  }
3881
- clear() {
3882
- this.commands.clear();
3883
- this.middlewares.clear();
3884
- }
3885
- reload() {
3886
- this.clear();
3887
- return this.scan();
3888
- }
3889
- async scan() {
3890
- if (!this.isValidPath()) {
3891
- throw new Error("Invalid path");
3892
- }
3893
- await this.traverse();
3894
- this.applyBindings();
3895
- return this.toJSON();
3896
- }
3897
- async traverse() {
3898
- const validFile = /\.(c|m)?(j|t)sx?$/;
3899
- const middleware = /^(\w+\.)?middleware\.(c|m)?(j|t)sx?$/;
3900
- const categoryDir = /^\((\w+)\)$/;
3901
- const isCategory = /* @__PURE__ */ __name((name) => categoryDir.test(name), "isCategory");
3902
- const isMiddleware = /* @__PURE__ */ __name((name) => middleware.test(name), "isMiddleware");
3903
- const isCommand = /* @__PURE__ */ __name((name) => validFile.test(name) && !isMiddleware(name), "isCommand");
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()) {
3910
- if (isCategory(name) && this.distanceFromRoot(pathname) > 1) {
3911
- throw new Error(
3912
- `Category directories must be at the root. Found "${name}" at "${pathname}"`
3913
- );
3914
- }
3915
- return;
3916
- }
3917
- if (this.distanceFromRoot(pathname, true) > 1) return;
3918
- if (isMiddleware(name)) {
3919
- const middleware2 = {
3920
- id: import_node_crypto3.default.randomUUID(),
3921
- path: pathname,
3922
- relativePath: this.toRelativePath(pathname)
3923
- };
3924
- this.middlewares.set(middleware2.id, middleware2);
3925
- return;
3926
- }
3927
- if (!isCommand(name)) return;
3928
- const command = {
3929
- id: import_node_crypto3.default.randomUUID(),
3930
- name: this.parseFileName(name),
3931
- category: this.parseCategory(pathname),
3932
- middlewareIds: [],
3933
- path: pathname,
3934
- relativePath: this.toRelativePath(pathname),
3935
- subcommands: []
3936
- };
3937
- this.commands.set(command.id, command);
3938
- }
3939
- );
3940
- await import_walk.default.walk(
3941
- this.options.entrypoint,
3942
- async (error, pathname, dirent) => {
3943
- if (error) throw error;
3944
- const name = dirent.name;
3945
- if (dirent.isDirectory()) return;
3946
- if (this.distanceFromRoot(pathname, true) <= 1) return;
3947
- if (isMiddleware(name)) {
3948
- const middleware2 = {
3949
- id: import_node_crypto3.default.randomUUID(),
3950
- path: pathname,
3951
- relativePath: this.toRelativePath(pathname)
3952
- };
3953
- this.middlewares.set(middleware2.id, middleware2);
3954
- return;
3955
- }
3956
- if (!isCommand(name)) return;
3957
- let currentDir = import_node_path3.default.dirname(pathname);
3958
- let parentCommand;
3959
- while (currentDir !== this.options.entrypoint) {
3960
- const dirName = import_node_path3.default.basename(currentDir);
3961
- parentCommand = Array.from(this.commands.values()).find(
3962
- (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
3963
- );
3964
- if (parentCommand) break;
3965
- currentDir = import_node_path3.default.dirname(currentDir);
3966
- }
3967
- if (parentCommand) {
3968
- const subcommand = {
3969
- name: this.parseFileName(name),
3970
- group: this.parseGroup(pathname),
3971
- path: pathname,
3972
- relativePath: this.toRelativePath(pathname),
3973
- command: parentCommand.id
3974
- };
3975
- parentCommand.subcommands.push(subcommand);
3976
- }
3977
- }
3978
- );
3979
- }
3980
- applyBindings() {
3981
- for (const command of this.commands.values()) {
3982
- const commandName = command.name;
3983
- const commandDir = import_node_path3.default.dirname(command.path);
3984
- for (const middleware of this.middlewares.values()) {
3985
- const middlewareDir = import_node_path3.default.dirname(middleware.path);
3986
- const middlewareFileName = import_node_path3.default.basename(middleware.path);
3987
- const isCommandSpecificMiddleware = middlewareFileName.startsWith(
3988
- commandName + "."
3989
- );
3990
- const isSharedMiddleware = middlewareFileName === "middleware.ts" || middlewareFileName === "middleware.js";
3991
- if (isCommandSpecificMiddleware && middlewareFileName.startsWith(commandName + ".")) {
3992
- command.middlewareIds.push(middleware.id);
3993
- continue;
3994
- }
3995
- if (isSharedMiddleware) {
3996
- const relPath = import_node_path3.default.relative(middlewareDir, commandDir);
3997
- if (!relPath.startsWith("..") && !import_node_path3.default.isAbsolute(relPath)) {
3998
- command.middlewareIds.push(middleware.id);
3999
- }
3904
+ async traverse(path2, category) {
3905
+ const entries = await (0, import_promises4.readdir)(path2, {
3906
+ withFileTypes: true
3907
+ });
3908
+ for (const entry of entries) {
3909
+ if (entry.name.startsWith("_")) continue;
3910
+ if (entry.isFile()) {
3911
+ if (this.isCommand(entry.name) || this.isMiddleware(entry.name)) {
3912
+ await this.handle(entry, category);
4000
3913
  }
4001
3914
  }
4002
3915
  }
4003
3916
  }
4004
- distanceFromRoot(pathname, isFile = false) {
4005
- const entrypointParts = this.options.entrypoint.split(import_node_path3.default.sep);
4006
- const pathParts = (!isFile ? pathname : import_node_path3.default.dirname(pathname)).split(
4007
- import_node_path3.default.sep
4008
- );
4009
- const relativeParts = pathParts.slice(entrypointParts.length);
4010
- return relativeParts.filter((part) => !part.match(/^\(.*\)$/)).length;
4011
- }
4012
- parseGroup(pathname) {
4013
- const parts = pathname.split(import_node_path3.default.sep);
4014
- const parentDirIndex = parts.findIndex(
4015
- (part) => this.commands.some((cmd) => cmd.name === part)
4016
- );
4017
- if (parentDirIndex === -1) return null;
4018
- const groupName = parts[parts.length - 2];
4019
- if (!groupName || groupName === parts[parentDirIndex] || groupName.match(/^\(.*\)$/)) {
4020
- return null;
4021
- }
4022
- return groupName;
4023
- }
4024
- parseCategory(pathname) {
4025
- const parts = pathname.split(import_node_path3.default.sep);
4026
- const entrypointParts = this.options.entrypoint.split(import_node_path3.default.sep);
4027
- const relativeIndex = entrypointParts.length;
4028
- const categoryDir = parts[relativeIndex];
4029
- if (!categoryDir || !/^\((\w+)\)$/.test(categoryDir)) {
4030
- return null;
3917
+ async handle(entry, category = null) {
3918
+ const name = entry.name;
3919
+ const path2 = (0, import_node_path4.join)(entry.parentPath, entry.name);
3920
+ if (this.isCommand(name)) {
3921
+ const command = {
3922
+ id: crypto.randomUUID(),
3923
+ name: (0, import_node_path4.basename)(path2, (0, import_node_path4.extname)(path2)),
3924
+ path: path2,
3925
+ category,
3926
+ parentPath: entry.parentPath,
3927
+ relativePath: this.replaceEntrypoint(path2),
3928
+ middlewares: []
3929
+ };
3930
+ this.commands.set(command.id, command);
3931
+ } else if (this.isMiddleware(name)) {
3932
+ const middleware = {
3933
+ id: crypto.randomUUID(),
3934
+ name: (0, import_node_path4.basename)(path2, (0, import_node_path4.extname)(path2)),
3935
+ path: path2,
3936
+ relativePath: this.replaceEntrypoint(path2),
3937
+ parentPath: entry.parentPath
3938
+ };
3939
+ this.middlewares.set(middleware.id, middleware);
4031
3940
  }
4032
- return categoryDir.slice(1, -1);
4033
3941
  }
4034
- parseFileName(filename) {
4035
- return import_node_path3.default.basename(filename, import_node_path3.default.extname(filename));
3942
+ applyMiddlewares() {
3943
+ this.commands.forEach((command) => {
3944
+ const commandPath = command.parentPath;
3945
+ const samePathMiddlewares = Array.from(this.middlewares.values()).filter((middleware) => {
3946
+ return middleware.parentPath === commandPath;
3947
+ }).map((middleware) => middleware.id);
3948
+ command.middlewares = Array.from(
3949
+ /* @__PURE__ */ new Set([...command.middlewares, ...samePathMiddlewares])
3950
+ );
3951
+ });
4036
3952
  }
4037
- toRelativePath(pathname) {
4038
- return import_node_path3.default.relative(this.options.entrypoint, pathname);
3953
+ replaceEntrypoint(path2) {
3954
+ const normalized = (0, import_node_path4.normalize)(path2);
3955
+ return normalized.replace(this.options.entrypoint, "");
4039
3956
  }
4040
3957
  };
4041
3958
  __name(_CommandsRouter, "CommandsRouter");
@@ -4044,14 +3961,14 @@ var init_CommandsRouter = __esm({
4044
3961
  });
4045
3962
 
4046
3963
  // src/app/router/EventsRouter.ts
4047
- var import_node_fs4, import_promises3, import_node_path4, _EventsRouter, EventsRouter;
3964
+ var import_node_fs5, import_promises5, import_node_path5, _EventsRouter, EventsRouter;
4048
3965
  var init_EventsRouter = __esm({
4049
3966
  "src/app/router/EventsRouter.ts"() {
4050
3967
  "use strict";
4051
3968
  init_cjs_shims();
4052
- import_node_fs4 = require("fs");
4053
- import_promises3 = require("fs/promises");
4054
- import_node_path4 = require("path");
3969
+ import_node_fs5 = require("fs");
3970
+ import_promises5 = require("fs/promises");
3971
+ import_node_path5 = require("path");
4055
3972
  _EventsRouter = class _EventsRouter {
4056
3973
  /**
4057
3974
  * Creates a new EventsRouter instance
@@ -4085,7 +4002,7 @@ var init_EventsRouter = __esm({
4085
4002
  * Checks if the entrypoint path is valid
4086
4003
  */
4087
4004
  isValidPath() {
4088
- return (0, import_node_fs4.existsSync)(this.entrypoint);
4005
+ return (0, import_node_fs5.existsSync)(this.entrypoint);
4089
4006
  }
4090
4007
  /**
4091
4008
  * Clear all parsed events
@@ -4106,12 +4023,11 @@ var init_EventsRouter = __esm({
4106
4023
  * @returns Promise resolving to the events tree
4107
4024
  */
4108
4025
  async scan() {
4109
- const dirs = await (0, import_promises3.readdir)(this.entrypoint, { withFileTypes: true });
4026
+ const dirs = await (0, import_promises5.readdir)(this.entrypoint, { withFileTypes: true });
4110
4027
  for (const dir of dirs) {
4111
4028
  if (dir.isDirectory()) {
4112
- const path3 = (0, import_node_path4.join)(this.entrypoint, dir.name);
4113
- const event = await this.scanEvent(dir.name, path3);
4114
- this.events.set(event.event, event);
4029
+ const path2 = (0, import_node_path5.join)(this.entrypoint, dir.name);
4030
+ await this.scanEvent(dir.name, path2, null, [], true);
4115
4031
  }
4116
4032
  }
4117
4033
  return Object.fromEntries(this.events);
@@ -4130,23 +4046,24 @@ var init_EventsRouter = __esm({
4130
4046
  * @param listeners - Array to collect listener file paths
4131
4047
  * @returns Promise resolving to the parsed event metadata
4132
4048
  */
4133
- async scanEvent(event, path3, listeners = []) {
4134
- var _a;
4135
- const files = await (0, import_promises3.readdir)(path3, { withFileTypes: true });
4049
+ async scanEvent(event, path2, _namespace = null, listeners = [], isRoot = false) {
4050
+ const files = await (0, import_promises5.readdir)(path2, { withFileTypes: true });
4051
+ const isNamespace = isRoot && /^\(.+\)$/.test(event);
4052
+ const namespace = isNamespace ? event.slice(1, -1) : _namespace ?? null;
4136
4053
  for (const file of files) {
4137
- if (/node_modules/.test(file.name)) continue;
4054
+ if (file.name.includes("_")) continue;
4138
4055
  if (file.isDirectory()) {
4139
- const nextPath = (0, import_node_path4.join)(path3, file.name);
4140
- await this.scanEvent(event, nextPath, listeners);
4056
+ const nextPath = (0, import_node_path5.join)(path2, file.name);
4057
+ await this.scanEvent(file.name, nextPath, namespace, listeners);
4141
4058
  continue;
4142
4059
  }
4143
4060
  if (file.isFile() && /\.(m|c)?(j|t)sx?$/.test(file.name)) {
4144
- listeners.push((0, import_node_path4.join)(file.parentPath, file.name));
4061
+ listeners.push((0, import_node_path5.join)(file.parentPath, file.name));
4145
4062
  }
4146
4063
  }
4147
- const maybeNamespace = path3.replace(this.entrypoint, "").replaceAll("\\", "/").split("/").shift();
4148
- const namespace = maybeNamespace && ((_a = /\(([^)]+)\)/.exec(maybeNamespace)) == null ? void 0 : _a[1]) || null;
4149
- return { event, path: path3, listeners, namespace };
4064
+ if (!isNamespace) {
4065
+ this.events.set(event, { event, path: path2, listeners, namespace });
4066
+ }
4150
4067
  }
4151
4068
  };
4152
4069
  __name(_EventsRouter, "EventsRouter");
@@ -4316,54 +4233,6 @@ var init_AppEventsHandler = __esm({
4316
4233
  }
4317
4234
  });
4318
4235
 
4319
- // src/utils/types-package.ts
4320
- async function generateTypesPackage() {
4321
- const location = (0, import_node_path5.join)(process.cwd(), "node_modules", "commandkit-types");
4322
- const packageJSON = (0, import_node_path5.join)(location, "package.json");
4323
- const index = (0, import_node_path5.join)(location, "index.js");
4324
- const types = (0, import_node_path5.join)(location, "index.d.ts");
4325
- const locale = (0, import_node_path5.join)(location, "locale.d.ts");
4326
- const command = (0, import_node_path5.join)(location, "command.d.ts");
4327
- const exists = (0, import_node_fs5.existsSync)(packageJSON);
4328
- if (exists) return location;
4329
- const packageJSONContent = {
4330
- name: "commandkit-types",
4331
- version: "1.0.0",
4332
- description: "CommandKit types package",
4333
- type: "commonjs",
4334
- main: "index.js",
4335
- types: "index.d.ts"
4336
- };
4337
- const indexContent = `module.exports = {};`;
4338
- const typesContent = `import { CommandLocalizationTypeData } from './locale.d.ts';
4339
- import { CommandTypeData } from './command.d.ts';
4340
-
4341
- declare module 'commandkit' {
4342
- export interface CommandKitTypeReferences {
4343
- locale: CommandLocalizationTypeData;
4344
- command: CommandTypeData;
4345
- }
4346
- }`;
4347
- await (0, import_promises4.mkdir)(location, { recursive: true });
4348
- await (0, import_promises4.writeFile)(packageJSON, JSON.stringify(packageJSONContent, null, 2));
4349
- await (0, import_promises4.writeFile)(index, indexContent);
4350
- await (0, import_promises4.writeFile)(types, typesContent);
4351
- await (0, import_promises4.writeFile)(locale, "");
4352
- await (0, import_promises4.writeFile)(command, "");
4353
- return location;
4354
- }
4355
- var import_node_fs5, import_promises4, import_node_path5;
4356
- var init_types_package = __esm({
4357
- "src/utils/types-package.ts"() {
4358
- "use strict";
4359
- init_cjs_shims();
4360
- import_node_fs5 = require("fs");
4361
- import_promises4 = require("fs/promises");
4362
- import_node_path5 = require("path");
4363
- __name(generateTypesPackage, "generateTypesPackage");
4364
- }
4365
- });
4366
-
4367
4236
  // src/cli/common.ts
4368
4237
  function write(message) {
4369
4238
  process.stdout.write(message);
@@ -4481,10 +4350,10 @@ function registerDevHooks(commandkit2) {
4481
4350
  if (!COMMANDKIT_IS_DEV) return;
4482
4351
  process.on("message", (message) => {
4483
4352
  if (typeof message !== "object" || message === null) return;
4484
- const { event, path: path3 } = message;
4353
+ const { event, path: path2 } = message;
4485
4354
  if (!event) return;
4486
4355
  if (process.env.COMMANDKIT_DEBUG_HMR === "true") {
4487
- Logger.info(`Received HMR event: ${event}${path3 ? ` for ${path3}` : ""}`);
4356
+ Logger.info(`Received HMR event: ${event}${path2 ? ` for ${path2}` : ""}`);
4488
4357
  }
4489
4358
  switch (event) {
4490
4359
  case "reload-commands":
@@ -4869,7 +4738,7 @@ var init_version = __esm({
4869
4738
  "use strict";
4870
4739
  init_cjs_shims();
4871
4740
  version = /* @__MACRO__ $version */
4872
- "0.1.11-dev.20250314022547";
4741
+ "0.1.11-dev.20250328083250";
4873
4742
  }
4874
4743
  });
4875
4744
 
@@ -4962,6 +4831,8 @@ async function buildApplication({
4962
4831
  esbuildPluginList.push(...esbuildPlugins.map(fromEsbuildPlugin));
4963
4832
  }
4964
4833
  try {
4834
+ const dest = isDev ? ".commandkit" : config.distDir;
4835
+ await (0, import_rimraf2.rimraf)(dest);
4965
4836
  await (0, import_tsup.build)({
4966
4837
  esbuildPlugins: esbuildPluginList,
4967
4838
  watch: false,
@@ -4985,7 +4856,7 @@ async function buildApplication({
4985
4856
  name: "CommandKit",
4986
4857
  sourcemap: true,
4987
4858
  target: "node16",
4988
- outDir: isDev ? ".commandkit" : config.distDir,
4859
+ outDir: dest,
4989
4860
  entry: [
4990
4861
  "src",
4991
4862
  `!${config.distDir}`,
@@ -5028,9 +4899,9 @@ async function main() {
5028
4899
  await main();
5029
4900
  `;
5030
4901
  const dist = isDev ? ".commandkit" : distDir || "dist";
5031
- await (0, import_promises5.writeFile)((0, import_node_path10.join)(configPath, dist, "index.js"), code);
4902
+ await (0, import_promises6.writeFile)((0, import_node_path10.join)(configPath, dist, "index.js"), code);
5032
4903
  }
5033
- var import_tsup, import_promises5, import_node_path10, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
4904
+ var import_tsup, import_promises6, import_node_path10, import_rimraf2, envScript, requireScript, antiCrashScript, wrapInAsyncIIFE;
5034
4905
  var init_build = __esm({
5035
4906
  "src/cli/build.ts"() {
5036
4907
  "use strict";
@@ -5038,9 +4909,10 @@ var init_build = __esm({
5038
4909
  import_tsup = require("tsup");
5039
4910
  init_plugins();
5040
4911
  init_loader();
5041
- import_promises5 = require("fs/promises");
4912
+ import_promises6 = require("fs/promises");
5042
4913
  import_node_path10 = require("path");
5043
4914
  init_env();
4915
+ import_rimraf2 = require("rimraf");
5044
4916
  __name(buildApplication, "buildApplication");
5045
4917
  envScript = /* @__PURE__ */ __name((dev) => `// --- Environment Variables Loader ---
5046
4918
  const $env = [${(dev ? devEnvFileArgs : prodEnvFileArgs).map((p) => `"${p}"`).join(", ")}];
@@ -5118,40 +4990,40 @@ async function bootstrapDevelopmentServer(configPath) {
5118
4990
  ignoreInitial: true
5119
4991
  });
5120
4992
  let ps = null;
5121
- const performHMR = debounce(async (path3) => {
5122
- if (!path3 || !ps) return false;
4993
+ const performHMR = debounce(async (path2) => {
4994
+ if (!path2 || !ps) return false;
5123
4995
  if (!ps.send) return false;
5124
- if (isCommandSource(path3)) {
4996
+ if (isCommandSource(path2)) {
5125
4997
  console.log(
5126
- `${colors_default.cyanBright("Reloading command(s) at ")} ${colors_default.yellowBright(path3)}`
4998
+ `${colors_default.cyanBright("Reloading command(s) at ")} ${colors_default.yellowBright(path2)}`
5127
4999
  );
5128
5000
  await buildAndStart(cwd, true);
5129
- ps.send({ event: "reload-commands", path: path3 });
5001
+ ps.send({ event: "reload-commands", path: path2 });
5130
5002
  return true;
5131
5003
  }
5132
- if (isEventSource(path3)) {
5004
+ if (isEventSource(path2)) {
5133
5005
  console.log(
5134
- `${colors_default.cyanBright("Reloading event(s) at ")} ${colors_default.yellowBright(path3)}`
5006
+ `${colors_default.cyanBright("Reloading event(s) at ")} ${colors_default.yellowBright(path2)}`
5135
5007
  );
5136
5008
  await buildAndStart(cwd, true);
5137
- ps.send({ event: "reload-events", path: path3 });
5009
+ ps.send({ event: "reload-events", path: path2 });
5138
5010
  return true;
5139
5011
  }
5140
- if (isLocaleSource(path3)) {
5012
+ if (isLocaleSource(path2)) {
5141
5013
  console.log(
5142
- `${colors_default.cyanBright("Reloading locale(s) at ")} ${colors_default.yellowBright(path3)}`
5014
+ `${colors_default.cyanBright("Reloading locale(s) at ")} ${colors_default.yellowBright(path2)}`
5143
5015
  );
5144
5016
  await buildAndStart(cwd, true);
5145
- ps.send({ event: "reload-locales", path: path3 });
5017
+ ps.send({ event: "reload-locales", path: path2 });
5146
5018
  return true;
5147
5019
  }
5148
5020
  return false;
5149
5021
  }, 300);
5150
- const hmrHandler = /* @__PURE__ */ __name(async (path3) => {
5151
- const hmr = await performHMR(path3);
5022
+ const hmrHandler = /* @__PURE__ */ __name(async (path2) => {
5023
+ const hmr = await performHMR(path2);
5152
5024
  if (hmr) return;
5153
5025
  console.log(
5154
- `${colors_default.yellowBright("\u26A1\uFE0F Performing full restart due to the changes in")} ${colors_default.cyanBright(path3)}`
5026
+ `${colors_default.yellowBright("\u26A1\uFE0F Performing full restart due to the changes in")} ${colors_default.cyanBright(path2)}`
5155
5027
  );
5156
5028
  ps == null ? void 0 : ps.kill();
5157
5029
  ps = await buildAndStart(cwd);
@@ -5231,7 +5103,7 @@ async function createSpinner(text) {
5231
5103
  });
5232
5104
  }
5233
5105
  var ora;
5234
- var init_utils2 = __esm({
5106
+ var init_utils = __esm({
5235
5107
  "src/cli/utils.ts"() {
5236
5108
  "use strict";
5237
5109
  init_cjs_shims();
@@ -5281,7 +5153,7 @@ var init_production = __esm({
5281
5153
  init_common();
5282
5154
  init_build();
5283
5155
  init_plugins();
5284
- init_utils2();
5156
+ init_utils();
5285
5157
  __name(bootstrapProductionServer, "bootstrapProductionServer");
5286
5158
  __name(createProductionBuild, "createProductionBuild");
5287
5159
  }
@@ -5296,7 +5168,7 @@ __export(generators_exports, {
5296
5168
  });
5297
5169
  async function generateCommand(name, customPath) {
5298
5170
  const cmdPath = (0, import_path4.join)(customPath || COMMANDS_DIR, name);
5299
- if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises6.mkdir)(cmdPath, { recursive: true });
5171
+ if (!(0, import_fs2.existsSync)(cmdPath)) await (0, import_promises7.mkdir)(cmdPath, { recursive: true });
5300
5172
  if ((0, import_fs2.existsSync)((0, import_path4.join)(cmdPath, "command.ts"))) {
5301
5173
  panic(`Command ${name} already exists.`);
5302
5174
  }
@@ -5316,7 +5188,7 @@ export const message: MessageCommand = async (ctx) => {
5316
5188
  await ctx.message.reply('Hello from ${name}!');
5317
5189
  };
5318
5190
  `.trim();
5319
- await (0, import_promises6.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5191
+ await (0, import_promises7.writeFile)((0, import_path4.join)(cmdPath, "command.ts"), commandFile);
5320
5192
  console.log(
5321
5193
  colors_default.green(
5322
5194
  `Command ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(cmdPath))}/command.ts`
@@ -5325,10 +5197,10 @@ export const message: MessageCommand = async (ctx) => {
5325
5197
  }
5326
5198
  async function generateEvent(name, customPath) {
5327
5199
  const eventPath = (0, import_path4.join)(customPath || EVENTS_DIR, name);
5328
- if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises6.mkdir)(eventPath, { recursive: true });
5200
+ if (!(0, import_fs2.existsSync)(eventPath)) await (0, import_promises7.mkdir)(eventPath, { recursive: true });
5329
5201
  let filename = "event.ts";
5330
5202
  if ((0, import_fs2.existsSync)((0, import_path4.join)(eventPath, filename))) {
5331
- const count = (await (0, import_promises6.readdir)(eventPath)).length;
5203
+ const count = (await (0, import_promises7.readdir)(eventPath)).length;
5332
5204
  filename = `${String(count).padStart(2, "0")}_${filename}`;
5333
5205
  }
5334
5206
  const eventFile = `
@@ -5336,7 +5208,7 @@ export default async function on${name[0].toUpperCase() + name.slice(1)}() {
5336
5208
  console.log('${name} event fired!');
5337
5209
  };
5338
5210
  `.trim();
5339
- await (0, import_promises6.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5211
+ await (0, import_promises7.writeFile)((0, import_path4.join)(eventPath, filename), eventFile);
5340
5212
  console.log(
5341
5213
  colors_default.green(
5342
5214
  `Event ${colors_default.magenta(name)} created at ${colors_default.blue(formatPath(eventPath))}/${colors_default.magenta(filename)}`
@@ -5354,7 +5226,7 @@ async function generateLocale(locale, commandName, customPath) {
5354
5226
  panic("Command name is required.");
5355
5227
  }
5356
5228
  const localePath = (0, import_path4.join)(customPath || LOCALES_DIR, locale);
5357
- if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises6.mkdir)(localePath, { recursive: true });
5229
+ if (!(0, import_fs2.existsSync)(localePath)) await (0, import_promises7.mkdir)(localePath, { recursive: true });
5358
5230
  if ((0, import_fs2.existsSync)((0, import_path4.join)(localePath, `${commandName}.json`))) {
5359
5231
  panic(`Locale file for ${commandName} already exists.`);
5360
5232
  }
@@ -5365,7 +5237,7 @@ async function generateLocale(locale, commandName, customPath) {
5365
5237
  },
5366
5238
  translations: {}
5367
5239
  };
5368
- await (0, import_promises6.writeFile)(
5240
+ await (0, import_promises7.writeFile)(
5369
5241
  (0, import_path4.join)(localePath, `${commandName}.json`),
5370
5242
  JSON.stringify(localeFile, null, 2)
5371
5243
  );
@@ -5377,12 +5249,12 @@ async function generateLocale(locale, commandName, customPath) {
5377
5249
  )
5378
5250
  );
5379
5251
  }
5380
- var import_promises6, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5252
+ var import_promises7, import_path4, import_discord13, import_fs2, BASE_PATH, COMMANDS_DIR, EVENTS_DIR, LOCALES_DIR, formatPath;
5381
5253
  var init_generators = __esm({
5382
5254
  "src/cli/generators.ts"() {
5383
5255
  "use strict";
5384
5256
  init_cjs_shims();
5385
- import_promises6 = require("fs/promises");
5257
+ import_promises7 = require("fs/promises");
5386
5258
  import_path4 = require("path");
5387
5259
  import_discord13 = require("discord.js");
5388
5260
  init_common();
@@ -5392,7 +5264,7 @@ var init_generators = __esm({
5392
5264
  COMMANDS_DIR = (0, import_path4.join)(BASE_PATH, "src/app/commands");
5393
5265
  EVENTS_DIR = (0, import_path4.join)(BASE_PATH, "src/app/events");
5394
5266
  LOCALES_DIR = (0, import_path4.join)(BASE_PATH, "src/app/locales");
5395
- formatPath = /* @__PURE__ */ __name((path3) => path3.replace(process.cwd(), ".").replace(/\\/g, "/"), "formatPath");
5267
+ formatPath = /* @__PURE__ */ __name((path2) => path2.replace(process.cwd(), ".").replace(/\\/g, "/"), "formatPath");
5396
5268
  __name(generateCommand, "generateCommand");
5397
5269
  __name(generateEvent, "generateEvent");
5398
5270
  __name(generateLocale, "generateLocale");
@@ -5411,7 +5283,10 @@ __export(index_exports, {
5411
5283
  CommandKit: () => CommandKit,
5412
5284
  CommandKitEnvironment: () => CommandKitEnvironment,
5413
5285
  CommandKitEnvironmentType: () => CommandKitEnvironmentType,
5286
+ CommandKitPluginRuntime: () => CommandKitPluginRuntime,
5414
5287
  CommandsRouter: () => CommandsRouter,
5288
+ CompilerPlugin: () => CompilerPlugin,
5289
+ CompilerPluginRuntime: () => CompilerPluginRuntime,
5415
5290
  Context: () => Context,
5416
5291
  DefaultLocalizationStrategy: () => DefaultLocalizationStrategy,
5417
5292
  DefaultLogger: () => DefaultLogger,
@@ -5428,6 +5303,7 @@ __export(index_exports, {
5428
5303
  Modal: () => Modal,
5429
5304
  ModalKit: () => ModalKit,
5430
5305
  ParagraphInput: () => ParagraphInput,
5306
+ RuntimePlugin: () => RuntimePlugin,
5431
5307
  ShortInput: () => ShortInput,
5432
5308
  TextInput: () => TextInput,
5433
5309
  afterCommand: () => afterCommand,
@@ -5444,6 +5320,7 @@ __export(index_exports, {
5444
5320
  dmOnly: () => dmOnly,
5445
5321
  exitContext: () => exitContext,
5446
5322
  exitMiddleware: () => exitMiddleware,
5323
+ fromEsbuildPlugin: () => fromEsbuildPlugin,
5447
5324
  getCommandKit: () => getCommandKit,
5448
5325
  getConfig: () => getConfig,
5449
5326
  getContext: () => getContext,
@@ -5452,6 +5329,8 @@ __export(index_exports, {
5452
5329
  invalidate: () => invalidate,
5453
5330
  isCachedFunction: () => isCachedFunction,
5454
5331
  isCommandKitElement: () => isCommandKitElement,
5332
+ isCompilerPlugin: () => isCompilerPlugin,
5333
+ isRuntimePlugin: () => isRuntimePlugin,
5455
5334
  makeContextAwareFunction: () => makeContextAwareFunction,
5456
5335
  redirect: () => redirect,
5457
5336
  rethrow: () => rethrow,
@@ -5497,9 +5376,13 @@ init_cjs_shims();
5497
5376
  init_Logger();
5498
5377
  init_router();
5499
5378
  init_version();
5379
+ init_plugins();
5500
5380
 
5501
5381
  // src/cli/init.ts
5502
5382
  init_cjs_shims();
5383
+ var import_node_fs10 = require("fs");
5384
+ var import_promises8 = require("fs/promises");
5385
+ var import_node_path11 = require("path");
5503
5386
  async function bootstrapCommandkitCLI(argv, options) {
5504
5387
  process.title = "CommandKit CLI";
5505
5388
  const { Command } = await import("commander");
@@ -5547,6 +5430,11 @@ async function bootstrapCommandkitCLI(argv, options) {
5547
5430
  }
5548
5431
  });
5549
5432
  await program.parseAsync(argv, options);
5433
+ const types = (0, import_node_path11.join)(process.cwd(), "node_modules", "commandkit-types");
5434
+ if (!(0, import_node_fs10.existsSync)(types)) {
5435
+ await (0, import_promises8.mkdir)(types, { recursive: true }).catch(() => {
5436
+ });
5437
+ }
5550
5438
  }
5551
5439
  __name(bootstrapCommandkitCLI, "bootstrapCommandkitCLI");
5552
5440
 
@@ -5563,7 +5451,10 @@ var index_default = CommandKit;
5563
5451
  CommandKit,
5564
5452
  CommandKitEnvironment,
5565
5453
  CommandKitEnvironmentType,
5454
+ CommandKitPluginRuntime,
5566
5455
  CommandsRouter,
5456
+ CompilerPlugin,
5457
+ CompilerPluginRuntime,
5567
5458
  Context,
5568
5459
  DefaultLocalizationStrategy,
5569
5460
  DefaultLogger,
@@ -5580,6 +5471,7 @@ var index_default = CommandKit;
5580
5471
  Modal,
5581
5472
  ModalKit,
5582
5473
  ParagraphInput,
5474
+ RuntimePlugin,
5583
5475
  ShortInput,
5584
5476
  TextInput,
5585
5477
  afterCommand,
@@ -5595,6 +5487,7 @@ var index_default = CommandKit;
5595
5487
  dmOnly,
5596
5488
  exitContext,
5597
5489
  exitMiddleware,
5490
+ fromEsbuildPlugin,
5598
5491
  getCommandKit,
5599
5492
  getConfig,
5600
5493
  getContext,
@@ -5603,6 +5496,8 @@ var index_default = CommandKit;
5603
5496
  invalidate,
5604
5497
  isCachedFunction,
5605
5498
  isCommandKitElement,
5499
+ isCompilerPlugin,
5500
+ isRuntimePlugin,
5606
5501
  makeContextAwareFunction,
5607
5502
  redirect,
5608
5503
  rethrow,