commandkit 1.2.1-dev.20260411010608 → 1.2.1-dev.20260411122819

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.
Files changed (142) hide show
  1. package/dist/CommandTree-DwfiCsOl.d.ts +55 -0
  2. package/dist/{CommandsRouter-DiNoF0dq.d.ts → CommandsRouter-D-b3xv38.d.ts} +102 -25
  3. package/dist/{EventsRouter-EuuSu6NH.d.ts → EventsRouter-Dyr_oJJD.d.ts} +1 -1
  4. package/dist/{MessageCommandParser-DPCbHXCS.d.ts → MessageCommandParser-UTKsRvb9.d.ts} +7 -1
  5. package/dist/analytics/analytics-engine.d.ts +1 -1
  6. package/dist/analytics/analytics-engine.js +1 -1
  7. package/dist/analytics/analytics-provider.d.ts +1 -1
  8. package/dist/analytics/utils.js +1 -1
  9. package/dist/{analytics-engine-uBNaD2CQ.d.ts → analytics-engine-BimOLPwO.d.ts} +109 -17
  10. package/dist/app/commands/AppCommandRunner.d.ts +1 -1
  11. package/dist/app/commands/AppCommandRunner.js +1 -1
  12. package/dist/app/commands/Context.d.ts +1 -1
  13. package/dist/app/commands/Context.js +1 -1
  14. package/dist/app/commands/MessageCommandParser.d.ts +1 -1
  15. package/dist/app/commands/MessageCommandParser.js +75 -70
  16. package/dist/app/commands/MessageCommandParser.js.map +1 -1
  17. package/dist/app/commands/helpers.d.ts +1 -1
  18. package/dist/app/events/EventWorkerContext.d.ts +2 -2
  19. package/dist/app/handlers/AppCommandHandler.d.ts +1 -1
  20. package/dist/app/handlers/AppCommandHandler.js +1 -1
  21. package/dist/app/handlers/AppEventsHandler.d.ts +1 -1
  22. package/dist/app/handlers/AppEventsHandler.js +1 -1
  23. package/dist/app/index.d.ts +4 -4
  24. package/dist/app/index.js +1 -1
  25. package/dist/app/interrupt/signals.d.ts +1 -1
  26. package/dist/app/middlewares/permissions.d.ts +1 -1
  27. package/dist/app/middlewares/permissions.js +1 -1
  28. package/dist/app/register/CommandRegistrar.d.ts +1 -1
  29. package/dist/app/register/CommandRegistrar.js +1 -1
  30. package/dist/app/router/CommandTree.d.ts +2 -0
  31. package/dist/app/router/CommandTree.js +1 -0
  32. package/dist/app/router/CommandsRouter.d.ts +1 -1
  33. package/dist/app/router/CommandsRouter.js +385 -23
  34. package/dist/app/router/CommandsRouter.js.map +1 -1
  35. package/dist/app/router/EventsRouter.d.ts +1 -1
  36. package/dist/app/router/index.d.ts +4 -3
  37. package/dist/checkbox-CvQGiyRe.d.ts +28 -0
  38. package/dist/cli/build.d.ts +1 -1
  39. package/dist/cli/build.js +1 -1
  40. package/dist/cli/common.d.ts +1 -1
  41. package/dist/cli/development.d.ts +1 -1
  42. package/dist/cli/development.js +1 -1
  43. package/dist/cli/init.js +1 -1
  44. package/dist/cli/production.js +1 -1
  45. package/dist/{commandkit-DNln6BAJ.js → commandkit-D2HMPuRQ.js} +548 -109
  46. package/dist/commandkit-D2HMPuRQ.js.map +1 -0
  47. package/dist/commandkit.d.ts +1 -1
  48. package/dist/commandkit.js +1 -1
  49. package/dist/components/common/element.js +1 -1
  50. package/dist/components/display/common.js +1 -1
  51. package/dist/components/display/container.d.ts +1 -1
  52. package/dist/components/display/container.js +1 -1
  53. package/dist/components/display/file.d.ts +1 -1
  54. package/dist/components/display/index.d.ts +8 -8
  55. package/dist/components/display/index.js +1 -1
  56. package/dist/components/display/label.d.ts +1 -1
  57. package/dist/components/display/label.js +1 -1
  58. package/dist/components/display/media-gallery.d.ts +1 -1
  59. package/dist/components/display/media-gallery.js +1 -1
  60. package/dist/components/display/poll.d.ts +1 -1
  61. package/dist/components/display/section.d.ts +1 -1
  62. package/dist/components/display/section.js +1 -1
  63. package/dist/components/display/separator.d.ts +1 -1
  64. package/dist/components/display/text-display.d.ts +1 -1
  65. package/dist/components/index.d.ts +11 -9
  66. package/dist/components/index.js +6 -1
  67. package/dist/components/interactive/button/Button.js +1 -1
  68. package/dist/components/interactive/button/ButtonKit.js +1 -1
  69. package/dist/components/interactive/checkbox/checkbox.d.ts +2 -0
  70. package/dist/components/interactive/checkbox/checkbox.js +6 -0
  71. package/dist/components/interactive/modal/Modal.js +1 -1
  72. package/dist/components/interactive/modal/ModalKit.js +1 -1
  73. package/dist/components/interactive/radio/radio.d.ts +2 -0
  74. package/dist/components/interactive/radio/radio.js +5 -0
  75. package/dist/components/interactive/select-menu/ChannelSelectMenuKit.js +1 -1
  76. package/dist/components/interactive/select-menu/MentionableSelectMenuKit.js +1 -1
  77. package/dist/components/interactive/select-menu/RoleSelectMenuKit.js +1 -1
  78. package/dist/components/interactive/select-menu/SelectMenu.js +1 -1
  79. package/dist/components/interactive/select-menu/StringSelectMenuKit.js +1 -1
  80. package/dist/components/interactive/select-menu/UserSelectMenuKit.js +1 -1
  81. package/dist/config/config.d.ts +1 -1
  82. package/dist/config/config.js +1 -1
  83. package/dist/config/default.d.ts +1 -1
  84. package/dist/config/default.js +1 -1
  85. package/dist/config/loader.d.ts +1 -1
  86. package/dist/config/loader.js +1 -1
  87. package/dist/config/types.d.ts +1 -1
  88. package/dist/config/utils.d.ts +1 -1
  89. package/dist/{constants-DqtJY0t-.d.ts → constants-D_sgdBHy.d.ts} +1 -1
  90. package/dist/{constants-DwxpkIeH.d.ts → constants-GWSfiS4h.d.ts} +1 -1
  91. package/dist/{container-CYojOA9d.d.ts → container-B7Kmw__R.d.ts} +1 -1
  92. package/dist/context/async-context.d.ts +1 -1
  93. package/dist/context/async-context.js +1 -1
  94. package/dist/context/environment.d.ts +1 -1
  95. package/dist/context/environment.js +1 -1
  96. package/dist/events/CommandKitEventsChannel.d.ts +1 -1
  97. package/dist/{file-DLO1zEcH.d.ts → file-BP8aoN3A.d.ts} +1 -1
  98. package/dist/flags/FlagProvider.d.ts +1 -1
  99. package/dist/flags/feature-flags.d.ts +1 -1
  100. package/dist/flags/feature-flags.js +1 -1
  101. package/dist/flags/store.d.ts +1 -1
  102. package/dist/{helpers-zmC44Mcu.d.ts → helpers-C5jRrAM1.d.ts} +1 -1
  103. package/dist/index.d.ts +19 -16
  104. package/dist/index.js +6 -1
  105. package/dist/kv/constants.d.ts +1 -1
  106. package/dist/kv/serde.d.ts +1 -1
  107. package/dist/{label-DqGRqodo.d.ts → label-CqHiBMXP.d.ts} +1 -1
  108. package/dist/logger/DefaultLogger.js +1 -1
  109. package/dist/logger/Logger.js +1 -1
  110. package/dist/{media-gallery-Ca8es-eB.d.ts → media-gallery-hFfa57Kd.d.ts} +1 -1
  111. package/dist/plugins/CompilerPlugin.d.ts +1 -1
  112. package/dist/plugins/PluginCommon.d.ts +1 -1
  113. package/dist/plugins/RuntimePlugin.d.ts +1 -1
  114. package/dist/plugins/index.d.ts +1 -1
  115. package/dist/plugins/index.js +1 -1
  116. package/dist/plugins/plugin-runtime/CommandKitPluginRuntime.d.ts +1 -1
  117. package/dist/plugins/plugin-runtime/CommandKitPluginRuntime.js +1 -1
  118. package/dist/plugins/plugin-runtime/CompilerPluginRuntime.d.ts +1 -1
  119. package/dist/plugins/plugin-runtime/CompilerPluginRuntime.js +1 -1
  120. package/dist/plugins/plugin-runtime/builtin/CommonDirectiveTransformer.d.ts +1 -1
  121. package/dist/plugins/plugin-runtime/builtin/CommonDirectiveTransformer.js +1 -1
  122. package/dist/plugins/plugin-runtime/builtin/MacroPlugin.d.ts +1 -1
  123. package/dist/plugins/plugin-runtime/builtin/MacroPlugin.js +1 -1
  124. package/dist/plugins/plugin-runtime/runtime.d.ts +1 -1
  125. package/dist/plugins/types.d.ts +1 -1
  126. package/dist/{poll-DQ6DX_Tt.d.ts → poll-ElAd5Z2K.d.ts} +1 -1
  127. package/dist/radio-Dcd4YIZx.d.ts +21 -0
  128. package/dist/{section-Q8nwx_-q.d.ts → section-BqDLXlp3.d.ts} +1 -1
  129. package/dist/{separator-B8P-kdIK.d.ts → separator-DSaCa1Tc.d.ts} +1 -1
  130. package/dist/{signals-CBXwugBW.d.ts → signals-DVOXPkQK.d.ts} +1 -1
  131. package/dist/{text-display-CL9C2yMc.d.ts → text-display-D-0dD7bR.d.ts} +1 -1
  132. package/dist/types.d.ts +1 -1
  133. package/dist/utils/constants.d.ts +1 -1
  134. package/dist/utils/dev-hooks.d.ts +1 -1
  135. package/dist/utils/dev-hooks.js +1 -1
  136. package/dist/utils/utilities.js +1 -1
  137. package/dist/version.js +1 -1
  138. package/package.json +3 -3
  139. package/dist/commandkit-DNln6BAJ.js.map +0 -1
  140. /package/dist/{index-BIsCUWAs.d.ts → index-CQiOqvUC.d.ts} +0 -0
  141. /package/dist/{index-CwHYpK-f.d.ts → index-CTLjHn5u.d.ts} +0 -0
  142. /package/dist/{index-DHrsNvX1.d.ts → index-LKrIp3Oo.d.ts} +0 -0
@@ -6,6 +6,7 @@ let node_path = require("node:path");
6
6
  let node_fs_promises = require("node:fs/promises");
7
7
 
8
8
  //#region src/app/router/CommandsRouter.ts
9
+ const ROOT_NODE_ID = "__commandkit_router_root__";
9
10
  /**
10
11
  * @private
11
12
  * @internal
@@ -32,6 +33,31 @@ const COMMAND_PATTERN = /^([^+().][^().]*)\.(m|c)?(j|t)sx?$/;
32
33
  */
33
34
  const CATEGORY_PATTERN = /^\(.+\)$/;
34
35
  /**
36
+ * @private
37
+ * @internal
38
+ */
39
+ const COMMAND_DIRECTORY_PATTERN = /^\[([^\][\\\/]+)\]$/;
40
+ /**
41
+ * @private
42
+ * @internal
43
+ */
44
+ const GROUP_DIRECTORY_PATTERN = /^\{([^}{\\\/]+)\}$/;
45
+ /**
46
+ * @private
47
+ * @internal
48
+ */
49
+ const COMMAND_DEFINITION_PATTERN = /^command\.(m|c)?(j|t)sx?$/;
50
+ /**
51
+ * @private
52
+ * @internal
53
+ */
54
+ const GROUP_DEFINITION_PATTERN = /^group\.(m|c)?(j|t)sx?$/;
55
+ /**
56
+ * @private
57
+ * @internal
58
+ */
59
+ const SUBCOMMAND_FILE_PATTERN = /^([^+().][^().]*)\.subcommand\.(m|c)?(j|t)sx?$/;
60
+ /**
35
61
  * Handles discovery and parsing of command and middleware files in the filesystem.
36
62
  */
37
63
  var CommandsRouter = class {
@@ -46,6 +72,21 @@ var CommandsRouter = class {
46
72
  */
47
73
  middlewares = new discord_js.Collection();
48
74
  /**
75
+ * @private
76
+ * @internal
77
+ */
78
+ treeNodes = new discord_js.Collection();
79
+ /**
80
+ * @private
81
+ * @internal
82
+ */
83
+ compiledRoutes = new discord_js.Collection();
84
+ /**
85
+ * @private
86
+ * @internal
87
+ */
88
+ diagnostics = [];
89
+ /**
49
90
  * Creates a new CommandsRouter instance.
50
91
  * @param options - Configuration options for the router
51
92
  */
@@ -53,12 +94,16 @@ var CommandsRouter = class {
53
94
  this.options = options;
54
95
  }
55
96
  /**
56
- * Populates the router with existing command and middleware data.
97
+ * Populates the router with existing command, middleware, and tree data.
57
98
  * @param data - Parsed command data to populate with
58
99
  */
59
100
  populate(data) {
101
+ this.clear();
60
102
  for (const [id, command] of Object.entries(data.commands)) this.commands.set(id, command);
61
103
  for (const [id, middleware] of Object.entries(data.middlewares)) this.middlewares.set(id, middleware);
104
+ for (const [id, node] of Object.entries(data.treeNodes ?? {})) this.treeNodes.set(id, node);
105
+ for (const [key, route] of Object.entries(data.compiledRoutes ?? {})) this.compiledRoutes.set(key, route);
106
+ this.diagnostics = [...data.diagnostics ?? []];
62
107
  }
63
108
  /**
64
109
  * Checks if the configured entrypoint path exists.
@@ -89,69 +134,380 @@ var CommandsRouter = class {
89
134
  return CATEGORY_PATTERN.test(name);
90
135
  }
91
136
  /**
92
- * Clears all loaded commands and middleware.
137
+ * @private
138
+ * @internal
139
+ */
140
+ isCommandDirectory(name) {
141
+ return COMMAND_DIRECTORY_PATTERN.test(name);
142
+ }
143
+ /**
144
+ * @private
145
+ * @internal
146
+ */
147
+ isGroupDirectory(name) {
148
+ return GROUP_DIRECTORY_PATTERN.test(name);
149
+ }
150
+ /**
151
+ * @private
152
+ * @internal
153
+ */
154
+ isCommandDefinition(name) {
155
+ return COMMAND_DEFINITION_PATTERN.test(name);
156
+ }
157
+ /**
158
+ * @private
159
+ * @internal
160
+ */
161
+ isGroupDefinition(name) {
162
+ return GROUP_DEFINITION_PATTERN.test(name);
163
+ }
164
+ /**
165
+ * @private
166
+ * @internal
167
+ */
168
+ isSubcommandFile(name) {
169
+ return SUBCOMMAND_FILE_PATTERN.test(name);
170
+ }
171
+ /**
172
+ * Clears all loaded commands, middleware, and compiled tree data.
93
173
  */
94
174
  clear() {
95
175
  this.commands.clear();
96
176
  this.middlewares.clear();
177
+ this.treeNodes.clear();
178
+ this.compiledRoutes.clear();
179
+ this.diagnostics = [];
97
180
  }
98
181
  /**
99
182
  * Scans the filesystem for commands and middleware files.
100
183
  * @returns Parsed command data
101
184
  */
102
185
  async scan() {
103
- const entries = await (0, node_fs_promises.readdir)(this.options.entrypoint, { withFileTypes: true });
104
- for (const entry of entries) {
105
- if (entry.name.startsWith("_")) continue;
106
- const fullPath = (0, node_path.join)(this.options.entrypoint, entry.name);
107
- if (entry.isDirectory()) {
108
- const category = this.isCategory(entry.name) ? entry.name.slice(1, -1) : null;
109
- await this.traverse(fullPath, category);
110
- } else await this.handle(entry);
111
- }
186
+ this.clear();
187
+ this.initializeRootNode();
188
+ await this.traverseDirectory(this.options.entrypoint, "normal", null, ROOT_NODE_ID);
112
189
  await this.applyMiddlewares();
190
+ this.compileTree();
113
191
  return this.toJSON();
114
192
  }
115
193
  /**
116
- * Gets the raw command and middleware collections.
117
- * @returns Object containing commands and middlewares collections
194
+ * Gets the raw command, middleware, and compiled tree collections.
195
+ * @returns Object containing router collections
118
196
  */
119
197
  getData() {
120
198
  return {
121
199
  commands: this.commands,
122
- middlewares: this.middlewares
200
+ middlewares: this.middlewares,
201
+ treeNodes: this.treeNodes,
202
+ compiledRoutes: this.compiledRoutes,
203
+ diagnostics: this.diagnostics
204
+ };
205
+ }
206
+ /**
207
+ * Gets only the internal command tree and compiled route data.
208
+ * @returns Object containing tree data
209
+ */
210
+ getTreeData() {
211
+ return {
212
+ treeNodes: this.treeNodes,
213
+ compiledRoutes: this.compiledRoutes,
214
+ diagnostics: this.diagnostics
123
215
  };
124
216
  }
125
217
  /**
126
218
  * Converts the loaded data to a JSON-serializable format.
127
- * @returns Plain object with commands and middlewares
219
+ * @returns Plain object with commands, middleware, and tree data
128
220
  */
129
221
  toJSON() {
130
222
  return {
131
223
  commands: Object.fromEntries(this.commands.entries()),
132
- middlewares: Object.fromEntries(this.middlewares.entries())
224
+ middlewares: Object.fromEntries(this.middlewares.entries()),
225
+ treeNodes: Object.fromEntries(this.treeNodes.entries()),
226
+ compiledRoutes: Object.fromEntries(this.compiledRoutes.entries()),
227
+ diagnostics: this.diagnostics
133
228
  };
134
229
  }
135
230
  /**
136
231
  * @private
137
232
  * @internal
138
233
  */
139
- async traverse(path, category) {
234
+ initializeRootNode() {
235
+ this.treeNodes.set(ROOT_NODE_ID, {
236
+ id: ROOT_NODE_ID,
237
+ source: "root",
238
+ kind: "root",
239
+ token: "",
240
+ route: [],
241
+ category: null,
242
+ parentId: null,
243
+ childIds: [],
244
+ directoryPath: this.options.entrypoint,
245
+ definitionPath: null,
246
+ relativePath: "",
247
+ shorthand: false,
248
+ executable: false
249
+ });
250
+ }
251
+ /**
252
+ * @private
253
+ * @internal
254
+ */
255
+ async traverseDirectory(path, state, category, parentId, token) {
256
+ let node = null;
257
+ if (state === "command") {
258
+ node = this.createTreeNode({
259
+ source: "directory",
260
+ token,
261
+ category,
262
+ parentId,
263
+ directoryPath: path,
264
+ definitionPath: null,
265
+ shorthand: false
266
+ });
267
+ if (!node) return;
268
+ } else if (state === "group") {
269
+ node = this.createTreeNode({
270
+ source: "group",
271
+ token,
272
+ category,
273
+ parentId,
274
+ directoryPath: path,
275
+ definitionPath: null,
276
+ shorthand: false
277
+ });
278
+ if (!node) return;
279
+ }
280
+ const currentNodeId = node ? node.id : parentId;
140
281
  const entries = await (0, node_fs_promises.readdir)(path, { withFileTypes: true });
141
282
  for (const entry of entries) {
142
283
  if (entry.name.startsWith("_")) continue;
284
+ const fullPath = (0, node_path.join)(path, entry.name);
143
285
  if (entry.isFile()) {
144
- if (this.isCommand(entry.name) || this.isMiddleware(entry.name)) await this.handle(entry, category);
145
- } else if (entry.isDirectory() && this.isCategory(entry.name) && category) {
146
- const nestedCategory = this.isCategory(entry.name) ? `${category}:${entry.name.slice(1, -1)}` : null;
147
- await this.traverse((0, node_path.join)(path, entry.name), nestedCategory);
286
+ if (state === "command") {
287
+ if (this.isCommandDefinition(entry.name)) {
288
+ node.definitionPath = fullPath;
289
+ node.relativePath = this.replaceEntrypoint(fullPath);
290
+ continue;
291
+ }
292
+ if (this.isSubcommandFile(entry.name)) {
293
+ this.createTreeNode({
294
+ source: "shorthand",
295
+ token: entry.name.match(SUBCOMMAND_FILE_PATTERN)[1],
296
+ category,
297
+ parentId: currentNodeId,
298
+ directoryPath: path,
299
+ definitionPath: fullPath,
300
+ shorthand: true
301
+ });
302
+ continue;
303
+ }
304
+ if (this.isMiddleware(entry.name)) {
305
+ await this.handle(entry, category);
306
+ continue;
307
+ }
308
+ if (this.isCommand(entry.name)) this.addDiagnostic("UNSUPPORTED_FILE_IN_COMMAND_DIRECTORY", "Only command.ts, middleware files, and subcommand shorthand files are supported inside a command directory.", fullPath);
309
+ } else if (state === "group") {
310
+ if (this.isGroupDefinition(entry.name)) {
311
+ node.definitionPath = fullPath;
312
+ node.relativePath = this.replaceEntrypoint(fullPath);
313
+ continue;
314
+ }
315
+ if (this.isSubcommandFile(entry.name)) {
316
+ this.createTreeNode({
317
+ source: "shorthand",
318
+ token: entry.name.match(SUBCOMMAND_FILE_PATTERN)[1],
319
+ category,
320
+ parentId: currentNodeId,
321
+ directoryPath: path,
322
+ definitionPath: fullPath,
323
+ shorthand: true
324
+ });
325
+ continue;
326
+ }
327
+ if (this.isMiddleware(entry.name)) {
328
+ await this.handle(entry, category);
329
+ continue;
330
+ }
331
+ if (this.isCommand(entry.name)) this.addDiagnostic("UNSUPPORTED_FILE_IN_GROUP_DIRECTORY", "Only group.ts, middleware files, and subcommand shorthand files are supported inside a group directory.", fullPath);
332
+ } else {
333
+ if (this.isSubcommandFile(entry.name)) {
334
+ if (currentNodeId === ROOT_NODE_ID) this.addDiagnostic("ORPHAN_SUBCOMMAND_FILE", "Subcommand shorthand files must be nested inside a command or group directory.", fullPath);
335
+ else this.createTreeNode({
336
+ source: "shorthand",
337
+ token: entry.name.match(SUBCOMMAND_FILE_PATTERN)[1],
338
+ category,
339
+ parentId: currentNodeId,
340
+ directoryPath: path,
341
+ definitionPath: fullPath,
342
+ shorthand: true
343
+ });
344
+ continue;
345
+ }
346
+ if (this.isCommand(entry.name) || this.isMiddleware(entry.name)) {
347
+ const result = await this.handle(entry, category);
348
+ if (result.command) this.createFlatCommandNode(result.command);
349
+ }
350
+ }
351
+ continue;
352
+ }
353
+ if (!entry.isDirectory()) continue;
354
+ if (this.isCommandDirectory(entry.name)) {
355
+ if (state === "command" || state === "group") await this.traverseDirectory(fullPath, "command", category, currentNodeId, entry.name.match(COMMAND_DIRECTORY_PATTERN)[1]);
356
+ else if (currentNodeId !== ROOT_NODE_ID) this.addDiagnostic("NESTED_COMMAND_NOT_ALLOWED", "Command directories cannot be nested under group or subcommand directories unless they are part of a hierarchical structure.", fullPath);
357
+ else await this.traverseDirectory(fullPath, "command", category, ROOT_NODE_ID, entry.name.match(COMMAND_DIRECTORY_PATTERN)[1]);
358
+ continue;
359
+ }
360
+ if (this.isGroupDirectory(entry.name)) {
361
+ if (currentNodeId === ROOT_NODE_ID) this.addDiagnostic("ROOT_GROUP_NOT_ALLOWED", "Group directories must be nested inside a command directory.", fullPath);
362
+ else await this.traverseDirectory(fullPath, "group", category, currentNodeId, entry.name.match(GROUP_DIRECTORY_PATTERN)[1]);
363
+ continue;
364
+ }
365
+ if (this.isCategory(entry.name)) {
366
+ const nestedCategory = category ? `${category}:${entry.name.slice(1, -1)}` : entry.name.slice(1, -1);
367
+ await this.traverseDirectory(fullPath, "normal", nestedCategory, currentNodeId);
368
+ continue;
369
+ }
370
+ await this.traverseDirectory(fullPath, "normal", category, currentNodeId);
371
+ }
372
+ if (state === "command" && node && !node.definitionPath) this.addDiagnostic("MISSING_COMMAND_DEFINITION", "Command directories must include a command.ts file.", path);
373
+ else if (state === "group" && node && !node.definitionPath) this.addDiagnostic("MISSING_GROUP_DEFINITION", "Group directories must include a group.ts file.", path);
374
+ }
375
+ /**
376
+ * @private
377
+ * @internal
378
+ */
379
+ createFlatCommandNode(command) {
380
+ this.createTreeNode({
381
+ id: command.id,
382
+ source: "flat",
383
+ token: command.name,
384
+ category: command.category,
385
+ parentId: ROOT_NODE_ID,
386
+ directoryPath: command.parentPath,
387
+ definitionPath: command.path,
388
+ shorthand: false
389
+ });
390
+ }
391
+ /**
392
+ * @private
393
+ * @internal
394
+ */
395
+ createTreeNode(options) {
396
+ const parent = this.treeNodes.get(options.parentId);
397
+ if (!parent) {
398
+ this.addDiagnostic("MISSING_PARENT_NODE", `Unable to create command tree node "${options.token}" because its parent node was not found.`, options.directoryPath);
399
+ return null;
400
+ }
401
+ if (parent.childIds.some((childId) => {
402
+ var _this$treeNodes$get;
403
+ return ((_this$treeNodes$get = this.treeNodes.get(childId)) === null || _this$treeNodes$get === void 0 ? void 0 : _this$treeNodes$get.token) === options.token;
404
+ })) {
405
+ this.addDiagnostic("DUPLICATE_SIBLING_TOKEN", `Duplicate command token "${options.token}" found under the same parent.`, options.definitionPath ?? options.directoryPath);
406
+ return null;
407
+ }
408
+ const route = [...parent.route, options.token];
409
+ const node = {
410
+ id: options.id ?? crypto.randomUUID(),
411
+ source: options.source,
412
+ kind: this.resolveNodeKind(options.source, route.length),
413
+ token: options.token,
414
+ route,
415
+ category: options.category,
416
+ parentId: options.parentId,
417
+ childIds: [],
418
+ directoryPath: options.directoryPath,
419
+ definitionPath: options.definitionPath,
420
+ relativePath: this.replaceEntrypoint(options.definitionPath ?? options.directoryPath),
421
+ shorthand: options.shorthand,
422
+ executable: false
423
+ };
424
+ this.treeNodes.set(node.id, node);
425
+ parent.childIds.push(node.id);
426
+ return node;
427
+ }
428
+ /**
429
+ * @private
430
+ * @internal
431
+ */
432
+ resolveNodeKind(source, depth) {
433
+ switch (source) {
434
+ case "root": return "root";
435
+ case "flat": return "flat";
436
+ case "group": return "group";
437
+ case "shorthand": return "subcommand";
438
+ case "directory": return depth === 1 ? "command" : "subcommand";
439
+ default: return source;
440
+ }
441
+ }
442
+ /**
443
+ * @private
444
+ * @internal
445
+ */
446
+ compileTree() {
447
+ this.compiledRoutes.clear();
448
+ for (const node of this.treeNodes.values()) {
449
+ if (node.id === ROOT_NODE_ID) continue;
450
+ const hasChildren = node.childIds.length > 0;
451
+ node.executable = !!node.definitionPath && node.kind !== "group" && !hasChildren;
452
+ if (node.kind === "subcommand" && hasChildren) this.addDiagnostic("SUBCOMMAND_CANNOT_HAVE_CHILDREN", `Subcommand "${node.route.join(".")}" cannot contain child command nodes.`, node.definitionPath ?? node.directoryPath);
453
+ if (node.kind === "command") {
454
+ const childKinds = new Set(node.childIds.map((childId) => {
455
+ var _this$treeNodes$get2;
456
+ return (_this$treeNodes$get2 = this.treeNodes.get(childId)) === null || _this$treeNodes$get2 === void 0 ? void 0 : _this$treeNodes$get2.kind;
457
+ }).filter(Boolean));
458
+ if (childKinds.has("group") && childKinds.has("subcommand")) this.addDiagnostic("MIXED_ROOT_CHILDREN", `Command "${node.route.join(".")}" cannot mix direct subcommands and subcommand groups.`, node.definitionPath ?? node.directoryPath);
148
459
  }
460
+ if (!node.executable || !node.definitionPath) continue;
461
+ const key = node.route.join(".");
462
+ const routeKind = node.kind;
463
+ this.compiledRoutes.set(key, {
464
+ id: node.id,
465
+ key,
466
+ kind: routeKind,
467
+ token: node.token,
468
+ route: node.route,
469
+ category: node.category,
470
+ definitionPath: node.definitionPath,
471
+ relativePath: this.replaceEntrypoint(node.definitionPath),
472
+ nodeId: node.id,
473
+ middlewares: this.collectCompiledMiddlewares(node)
474
+ });
149
475
  }
150
476
  }
151
477
  /**
152
478
  * @private
153
479
  * @internal
154
480
  */
481
+ collectCompiledMiddlewares(node) {
482
+ const allMiddlewares = Array.from(this.middlewares.values());
483
+ const globalMiddlewares = allMiddlewares.filter((middleware) => middleware.global).map((middleware) => middleware.id);
484
+ const directoryMiddlewares = allMiddlewares.filter((middleware) => {
485
+ return !middleware.global && !middleware.command && middleware.parentPath === node.directoryPath;
486
+ }).map((middleware) => middleware.id);
487
+ const commandSpecificMiddlewares = allMiddlewares.filter((middleware) => {
488
+ return middleware.command === node.token && middleware.parentPath === node.directoryPath;
489
+ }).map((middleware) => middleware.id);
490
+ return [
491
+ ...globalMiddlewares,
492
+ ...directoryMiddlewares,
493
+ ...commandSpecificMiddlewares
494
+ ];
495
+ }
496
+ /**
497
+ * @private
498
+ * @internal
499
+ */
500
+ addDiagnostic(code, message, path) {
501
+ this.diagnostics.push({
502
+ code,
503
+ message,
504
+ path: (0, node_path.normalize)(path)
505
+ });
506
+ }
507
+ /**
508
+ * @private
509
+ * @internal
510
+ */
155
511
  async handle(entry, category = null) {
156
512
  const name = entry.name;
157
513
  const path = (0, node_path.join)(entry.parentPath, entry.name);
@@ -166,7 +522,9 @@ var CommandsRouter = class {
166
522
  middlewares: []
167
523
  };
168
524
  this.commands.set(command.id, command);
169
- } else if (this.isMiddleware(name)) {
525
+ return { command };
526
+ }
527
+ if (this.isMiddleware(name)) {
170
528
  var _name$match;
171
529
  const middleware = {
172
530
  id: crypto.randomUUID(),
@@ -178,7 +536,9 @@ var CommandsRouter = class {
178
536
  command: COMMAND_MIDDLEWARE_PATTERN.test(name) ? ((_name$match = name.match(COMMAND_MIDDLEWARE_PATTERN)) === null || _name$match === void 0 ? void 0 : _name$match[1]) || null : null
179
537
  };
180
538
  this.middlewares.set(middleware.id, middleware);
539
+ return { middleware };
181
540
  }
541
+ return {};
182
542
  }
183
543
  /**
184
544
  * @private
@@ -189,7 +549,9 @@ var CommandsRouter = class {
189
549
  const commandPath = command.parentPath;
190
550
  const allMiddlewares = Array.from(this.middlewares.values());
191
551
  const commandSpecificMiddlewares = allMiddlewares.filter((middleware) => middleware.command === command.name).map((middleware) => middleware.id);
192
- const directorySpecificMiddlewares = allMiddlewares.filter((middleware) => !middleware.global && !middleware.command && middleware.parentPath === commandPath).map((middleware) => middleware.id);
552
+ const directorySpecificMiddlewares = allMiddlewares.filter((middleware) => {
553
+ return !middleware.global && !middleware.command && middleware.parentPath === commandPath;
554
+ }).map((middleware) => middleware.id);
193
555
  command.middlewares = [
194
556
  ...allMiddlewares.filter((middleware) => middleware.global).map((middleware) => middleware.id),
195
557
  ...directorySpecificMiddlewares,
@@ -1 +1 @@
1
- {"version":3,"file":"CommandsRouter.js","names":[],"sources":["../../../src/app/router/CommandsRouter.ts"],"sourcesContent":["import { Collection } from 'discord.js';\nimport { Dirent, existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { basename, extname, join, normalize } from 'node:path';\n\n/**\n * Represents a command with its metadata and middleware associations.\n */\nexport interface Command {\n id: string;\n name: string;\n path: string;\n relativePath: string;\n parentPath: string;\n middlewares: Array<string>;\n category: string | null;\n}\n\n/**\n * Represents a middleware with its metadata and scope.\n */\nexport interface Middleware {\n id: string;\n name: string;\n path: string;\n relativePath: string;\n parentPath: string;\n global: boolean;\n command: string | null;\n}\n\n/**\n * Data structure containing parsed commands and middleware.\n */\nexport interface ParsedCommandData {\n commands: Record<string, Command>;\n middlewares: Record<string, Middleware>;\n}\n\n/**\n * Configuration options for the commands router.\n */\nexport interface CommandsRouterOptions {\n entrypoint: string;\n}\n\n/**\n * @private\n * @internal\n */\nconst MIDDLEWARE_PATTERN = /^\\+middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_MIDDLEWARE_PATTERN =\n /^\\+([^+().][^().]*)\\.middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst GLOBAL_MIDDLEWARE_PATTERN = /^\\+global-middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_PATTERN = /^([^+().][^().]*)\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst CATEGORY_PATTERN = /^\\(.+\\)$/;\n\n/**\n * Handles discovery and parsing of command and middleware files in the filesystem.\n */\nexport class CommandsRouter {\n /**\n * @private\n * @internal\n */\n private commands = new Collection<string, Command>();\n\n /**\n * @private\n * @internal\n */\n private middlewares = new Collection<string, Middleware>();\n\n /**\n * Creates a new CommandsRouter instance.\n * @param options - Configuration options for the router\n */\n public constructor(private readonly options: CommandsRouterOptions) {}\n\n /**\n * Populates the router with existing command and middleware data.\n * @param data - Parsed command data to populate with\n */\n public populate(data: ParsedCommandData) {\n for (const [id, command] of Object.entries(data.commands)) {\n this.commands.set(id, command);\n }\n\n for (const [id, middleware] of Object.entries(data.middlewares)) {\n this.middlewares.set(id, middleware);\n }\n }\n\n /**\n * Checks if the configured entrypoint path exists.\n * @returns True if the path exists\n */\n public isValidPath(): boolean {\n return existsSync(this.options.entrypoint);\n }\n\n /**\n * @private\n * @internal\n */\n private isCommand(name: string): boolean {\n return COMMAND_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isMiddleware(name: string): boolean {\n return (\n MIDDLEWARE_PATTERN.test(name) ||\n GLOBAL_MIDDLEWARE_PATTERN.test(name) ||\n COMMAND_MIDDLEWARE_PATTERN.test(name)\n );\n }\n\n /**\n * @private\n * @internal\n */\n private isCategory(name: string): boolean {\n return CATEGORY_PATTERN.test(name);\n }\n\n /**\n * Clears all loaded commands and middleware.\n */\n public clear() {\n this.commands.clear();\n this.middlewares.clear();\n }\n\n /**\n * Scans the filesystem for commands and middleware files.\n * @returns Parsed command data\n */\n public async scan() {\n const entries = await readdir(this.options.entrypoint, {\n withFileTypes: true,\n });\n\n for (const entry of entries) {\n // ignore _ prefixed files\n if (entry.name.startsWith('_')) continue;\n\n const fullPath = join(this.options.entrypoint, entry.name);\n\n if (entry.isDirectory()) {\n const category = this.isCategory(entry.name)\n ? entry.name.slice(1, -1)\n : null;\n\n await this.traverse(fullPath, category);\n } else {\n await this.handle(entry);\n }\n }\n\n await this.applyMiddlewares();\n\n return this.toJSON();\n }\n\n /**\n * Gets the raw command and middleware collections.\n * @returns Object containing commands and middlewares collections\n */\n public getData() {\n return {\n commands: this.commands,\n middlewares: this.middlewares,\n };\n }\n\n /**\n * Converts the loaded data to a JSON-serializable format.\n * @returns Plain object with commands and middlewares\n */\n public toJSON() {\n return {\n commands: Object.fromEntries(this.commands.entries()),\n middlewares: Object.fromEntries(this.middlewares.entries()),\n };\n }\n\n /**\n * @private\n * @internal\n */\n private async traverse(path: string, category: string | null) {\n const entries = await readdir(path, {\n withFileTypes: true,\n });\n\n for (const entry of entries) {\n // ignore _ prefixed files\n if (entry.name.startsWith('_')) continue;\n\n if (entry.isFile()) {\n if (this.isCommand(entry.name) || this.isMiddleware(entry.name)) {\n await this.handle(entry, category);\n }\n } else if (\n entry.isDirectory() &&\n this.isCategory(entry.name) &&\n category\n ) {\n // nested category\n const nestedCategory = this.isCategory(entry.name)\n ? `${category}:${entry.name.slice(1, -1)}`\n : null;\n await this.traverse(join(path, entry.name), nestedCategory);\n }\n\n // TODO: handle subcommands\n }\n }\n\n /**\n * @private\n * @internal\n */\n private async handle(entry: Dirent, category: string | null = null) {\n const name = entry.name;\n const path = join(entry.parentPath, entry.name);\n\n if (this.isCommand(name)) {\n const command: Command = {\n id: crypto.randomUUID(),\n name: basename(path, extname(path)),\n path,\n category,\n parentPath: entry.parentPath,\n relativePath: this.replaceEntrypoint(path),\n middlewares: [],\n };\n\n this.commands.set(command.id, command);\n } else if (this.isMiddleware(name)) {\n const middleware: Middleware = {\n id: crypto.randomUUID(),\n name: basename(path, extname(path)),\n path,\n relativePath: this.replaceEntrypoint(path),\n parentPath: entry.parentPath,\n global: GLOBAL_MIDDLEWARE_PATTERN.test(name),\n command: COMMAND_MIDDLEWARE_PATTERN.test(name)\n ? name.match(COMMAND_MIDDLEWARE_PATTERN)?.[1] || null\n : null,\n };\n\n this.middlewares.set(middleware.id, middleware);\n }\n }\n\n /**\n * @private\n * @internal\n */\n private applyMiddlewares() {\n this.commands.forEach((command) => {\n const commandPath = command.parentPath;\n const allMiddlewares = Array.from(this.middlewares.values());\n\n const commandSpecificMiddlewares = allMiddlewares\n .filter((middleware) => middleware.command === command.name)\n .map((middleware) => middleware.id);\n\n const directorySpecificMiddlewares = allMiddlewares\n .filter(\n (middleware) =>\n !middleware.global &&\n !middleware.command &&\n middleware.parentPath === commandPath,\n )\n .map((middleware) => middleware.id);\n\n const globalMiddlewares = allMiddlewares\n .filter((middleware) => middleware.global)\n .map((middleware) => middleware.id);\n\n command.middlewares = [\n ...globalMiddlewares,\n ...directorySpecificMiddlewares,\n ...commandSpecificMiddlewares,\n ];\n });\n }\n\n /**\n * @private\n * @internal\n */\n private replaceEntrypoint(path: string) {\n const normalized = normalize(path);\n return normalized.replace(this.options.entrypoint, '');\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommandsRouter.js","names":[],"sources":["../../../src/app/router/CommandsRouter.ts"],"sourcesContent":["import { Collection } from 'discord.js';\nimport { Dirent, existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { basename, extname, join, normalize } from 'node:path';\nimport {\n CommandRouteDiagnostic,\n CommandTreeNode,\n CommandTreeNodeKind,\n CompiledCommandRoute,\n} from './CommandTree';\n\n/**\n * Represents a command with its metadata and middleware associations.\n */\nexport interface Command {\n id: string;\n name: string;\n path: string;\n relativePath: string;\n parentPath: string;\n middlewares: Array<string>;\n category: string | null;\n}\n\n/**\n * Represents a middleware with its metadata and scope.\n */\nexport interface Middleware {\n id: string;\n name: string;\n path: string;\n relativePath: string;\n parentPath: string;\n global: boolean;\n command: string | null;\n}\n\n/**\n * Data structure containing parsed commands, middleware, and tree data.\n */\nexport interface ParsedCommandData {\n commands: Record<string, Command>;\n middlewares: Record<string, Middleware>;\n treeNodes?: Record<string, CommandTreeNode>;\n compiledRoutes?: Record<string, CompiledCommandRoute>;\n diagnostics?: CommandRouteDiagnostic[];\n}\n\n/**\n * Configuration options for the commands router.\n */\nexport interface CommandsRouterOptions {\n entrypoint: string;\n}\n\nconst ROOT_NODE_ID = '__commandkit_router_root__';\n\n/**\n * @private\n * @internal\n */\nconst MIDDLEWARE_PATTERN = /^\\+middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_MIDDLEWARE_PATTERN =\n /^\\+([^+().][^().]*)\\.middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst GLOBAL_MIDDLEWARE_PATTERN = /^\\+global-middleware\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_PATTERN = /^([^+().][^().]*)\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst CATEGORY_PATTERN = /^\\(.+\\)$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_DIRECTORY_PATTERN = /^\\[([^\\][\\\\\\/]+)\\]$/;\n\n/**\n * @private\n * @internal\n */\nconst GROUP_DIRECTORY_PATTERN = /^\\{([^}{\\\\\\/]+)\\}$/;\n\n/**\n * @private\n * @internal\n */\nconst COMMAND_DEFINITION_PATTERN = /^command\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst GROUP_DEFINITION_PATTERN = /^group\\.(m|c)?(j|t)sx?$/;\n\n/**\n * @private\n * @internal\n */\nconst SUBCOMMAND_FILE_PATTERN =\n /^([^+().][^().]*)\\.subcommand\\.(m|c)?(j|t)sx?$/;\n\n/**\n * Handles discovery and parsing of command and middleware files in the filesystem.\n */\nexport class CommandsRouter {\n /**\n * @private\n * @internal\n */\n private commands = new Collection<string, Command>();\n\n /**\n * @private\n * @internal\n */\n private middlewares = new Collection<string, Middleware>();\n\n /**\n * @private\n * @internal\n */\n private treeNodes = new Collection<string, CommandTreeNode>();\n\n /**\n * @private\n * @internal\n */\n private compiledRoutes = new Collection<string, CompiledCommandRoute>();\n\n /**\n * @private\n * @internal\n */\n private diagnostics: CommandRouteDiagnostic[] = [];\n\n /**\n * Creates a new CommandsRouter instance.\n * @param options - Configuration options for the router\n */\n public constructor(private readonly options: CommandsRouterOptions) {}\n\n /**\n * Populates the router with existing command, middleware, and tree data.\n * @param data - Parsed command data to populate with\n */\n public populate(data: ParsedCommandData): void {\n this.clear();\n\n for (const [id, command] of Object.entries(data.commands)) {\n this.commands.set(id, command);\n }\n\n for (const [id, middleware] of Object.entries(data.middlewares)) {\n this.middlewares.set(id, middleware);\n }\n\n for (const [id, node] of Object.entries(data.treeNodes ?? {})) {\n this.treeNodes.set(id, node);\n }\n\n for (const [key, route] of Object.entries(data.compiledRoutes ?? {})) {\n this.compiledRoutes.set(key, route);\n }\n\n this.diagnostics = [...(data.diagnostics ?? [])];\n }\n\n /**\n * Checks if the configured entrypoint path exists.\n * @returns True if the path exists\n */\n public isValidPath(): boolean {\n return existsSync(this.options.entrypoint);\n }\n\n /**\n * @private\n * @internal\n */\n private isCommand(name: string): boolean {\n return COMMAND_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isMiddleware(name: string): boolean {\n return (\n MIDDLEWARE_PATTERN.test(name) ||\n GLOBAL_MIDDLEWARE_PATTERN.test(name) ||\n COMMAND_MIDDLEWARE_PATTERN.test(name)\n );\n }\n\n /**\n * @private\n * @internal\n */\n private isCategory(name: string): boolean {\n return CATEGORY_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isCommandDirectory(name: string): boolean {\n return COMMAND_DIRECTORY_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isGroupDirectory(name: string): boolean {\n return GROUP_DIRECTORY_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isCommandDefinition(name: string): boolean {\n return COMMAND_DEFINITION_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isGroupDefinition(name: string): boolean {\n return GROUP_DEFINITION_PATTERN.test(name);\n }\n\n /**\n * @private\n * @internal\n */\n private isSubcommandFile(name: string): boolean {\n return SUBCOMMAND_FILE_PATTERN.test(name);\n }\n\n /**\n * Clears all loaded commands, middleware, and compiled tree data.\n */\n public clear(): void {\n this.commands.clear();\n this.middlewares.clear();\n this.treeNodes.clear();\n this.compiledRoutes.clear();\n this.diagnostics = [];\n }\n\n /**\n * Scans the filesystem for commands and middleware files.\n * @returns Parsed command data\n */\n public async scan(): Promise<ParsedCommandData> {\n this.clear();\n this.initializeRootNode();\n\n await this.traverseDirectory(\n this.options.entrypoint,\n 'normal',\n null,\n ROOT_NODE_ID,\n );\n\n await this.applyMiddlewares();\n this.compileTree();\n\n return this.toJSON();\n }\n\n /**\n * Gets the raw command, middleware, and compiled tree collections.\n * @returns Object containing router collections\n */\n public getData(): {\n commands: Collection<string, Command>;\n middlewares: Collection<string, Middleware>;\n treeNodes: Collection<string, CommandTreeNode>;\n compiledRoutes: Collection<string, CompiledCommandRoute>;\n diagnostics: CommandRouteDiagnostic[];\n } {\n return {\n commands: this.commands,\n middlewares: this.middlewares,\n treeNodes: this.treeNodes,\n compiledRoutes: this.compiledRoutes,\n diagnostics: this.diagnostics,\n };\n }\n\n /**\n * Gets only the internal command tree and compiled route data.\n * @returns Object containing tree data\n */\n public getTreeData(): {\n treeNodes: Collection<string, CommandTreeNode>;\n compiledRoutes: Collection<string, CompiledCommandRoute>;\n diagnostics: CommandRouteDiagnostic[];\n } {\n return {\n treeNodes: this.treeNodes,\n compiledRoutes: this.compiledRoutes,\n diagnostics: this.diagnostics,\n };\n }\n\n /**\n * Converts the loaded data to a JSON-serializable format.\n * @returns Plain object with commands, middleware, and tree data\n */\n public toJSON(): ParsedCommandData {\n return {\n commands: Object.fromEntries(this.commands.entries()),\n middlewares: Object.fromEntries(this.middlewares.entries()),\n treeNodes: Object.fromEntries(this.treeNodes.entries()),\n compiledRoutes: Object.fromEntries(this.compiledRoutes.entries()),\n diagnostics: this.diagnostics,\n };\n }\n\n /**\n * @private\n * @internal\n */\n private initializeRootNode() {\n this.treeNodes.set(ROOT_NODE_ID, {\n id: ROOT_NODE_ID,\n source: 'root',\n kind: 'root',\n token: '',\n route: [],\n category: null,\n parentId: null,\n childIds: [],\n directoryPath: this.options.entrypoint,\n definitionPath: null,\n relativePath: '',\n shorthand: false,\n executable: false,\n });\n }\n\n /**\n * @private\n * @internal\n */\n private async traverseDirectory(\n path: string,\n state: 'normal' | 'command' | 'group',\n category: string | null,\n parentId: string,\n token?: string,\n ) {\n let node: CommandTreeNode | null = null;\n\n if (state === 'command') {\n node = this.createTreeNode({\n source: 'directory',\n token: token!,\n category,\n parentId,\n directoryPath: path,\n definitionPath: null,\n shorthand: false,\n });\n if (!node) return;\n } else if (state === 'group') {\n node = this.createTreeNode({\n source: 'group',\n token: token!,\n category,\n parentId,\n directoryPath: path,\n definitionPath: null,\n shorthand: false,\n });\n if (!node) return;\n }\n\n const currentNodeId = node ? node.id : parentId;\n\n const entries = await readdir(path, {\n withFileTypes: true,\n });\n\n for (const entry of entries) {\n if (entry.name.startsWith('_')) continue;\n\n const fullPath = join(path, entry.name);\n\n if (entry.isFile()) {\n if (state === 'command') {\n if (this.isCommandDefinition(entry.name)) {\n node!.definitionPath = fullPath;\n node!.relativePath = this.replaceEntrypoint(fullPath);\n continue;\n }\n if (this.isSubcommandFile(entry.name)) {\n this.createTreeNode({\n source: 'shorthand',\n token: entry.name.match(SUBCOMMAND_FILE_PATTERN)![1],\n category,\n parentId: currentNodeId,\n directoryPath: path,\n definitionPath: fullPath,\n shorthand: true,\n });\n continue;\n }\n if (this.isMiddleware(entry.name)) {\n await this.handle(entry, category);\n continue;\n }\n if (this.isCommand(entry.name)) {\n this.addDiagnostic(\n 'UNSUPPORTED_FILE_IN_COMMAND_DIRECTORY',\n 'Only command.ts, middleware files, and subcommand shorthand files are supported inside a command directory.',\n fullPath,\n );\n }\n } else if (state === 'group') {\n if (this.isGroupDefinition(entry.name)) {\n node!.definitionPath = fullPath;\n node!.relativePath = this.replaceEntrypoint(fullPath);\n continue;\n }\n if (this.isSubcommandFile(entry.name)) {\n this.createTreeNode({\n source: 'shorthand',\n token: entry.name.match(SUBCOMMAND_FILE_PATTERN)![1],\n category,\n parentId: currentNodeId,\n directoryPath: path,\n definitionPath: fullPath,\n shorthand: true,\n });\n continue;\n }\n if (this.isMiddleware(entry.name)) {\n await this.handle(entry, category);\n continue;\n }\n if (this.isCommand(entry.name)) {\n this.addDiagnostic(\n 'UNSUPPORTED_FILE_IN_GROUP_DIRECTORY',\n 'Only group.ts, middleware files, and subcommand shorthand files are supported inside a group directory.',\n fullPath,\n );\n }\n } else {\n if (this.isSubcommandFile(entry.name)) {\n if (currentNodeId === ROOT_NODE_ID) {\n this.addDiagnostic(\n 'ORPHAN_SUBCOMMAND_FILE',\n 'Subcommand shorthand files must be nested inside a command or group directory.',\n fullPath,\n );\n } else {\n this.createTreeNode({\n source: 'shorthand',\n token: entry.name.match(SUBCOMMAND_FILE_PATTERN)![1],\n category,\n parentId: currentNodeId,\n directoryPath: path,\n definitionPath: fullPath,\n shorthand: true,\n });\n }\n continue;\n }\n if (this.isCommand(entry.name) || this.isMiddleware(entry.name)) {\n const result = await this.handle(entry, category);\n if (result.command) {\n this.createFlatCommandNode(result.command);\n }\n }\n }\n continue;\n }\n\n if (!entry.isDirectory()) continue;\n\n if (this.isCommandDirectory(entry.name)) {\n if (state === 'command' || state === 'group') {\n await this.traverseDirectory(\n fullPath,\n 'command',\n category,\n currentNodeId,\n entry.name.match(COMMAND_DIRECTORY_PATTERN)![1],\n );\n } else if (currentNodeId !== ROOT_NODE_ID) {\n this.addDiagnostic(\n 'NESTED_COMMAND_NOT_ALLOWED',\n 'Command directories cannot be nested under group or subcommand directories unless they are part of a hierarchical structure.',\n fullPath,\n );\n } else {\n await this.traverseDirectory(\n fullPath,\n 'command',\n category,\n ROOT_NODE_ID,\n entry.name.match(COMMAND_DIRECTORY_PATTERN)![1],\n );\n }\n continue;\n }\n\n if (this.isGroupDirectory(entry.name)) {\n if (currentNodeId === ROOT_NODE_ID) {\n this.addDiagnostic(\n 'ROOT_GROUP_NOT_ALLOWED',\n 'Group directories must be nested inside a command directory.',\n fullPath,\n );\n } else {\n await this.traverseDirectory(\n fullPath,\n 'group',\n category,\n currentNodeId,\n entry.name.match(GROUP_DIRECTORY_PATTERN)![1],\n );\n }\n continue;\n }\n\n if (this.isCategory(entry.name)) {\n const nestedCategory = category\n ? `${category}:${entry.name.slice(1, -1)}`\n : entry.name.slice(1, -1);\n await this.traverseDirectory(\n fullPath,\n 'normal',\n nestedCategory,\n currentNodeId,\n );\n continue;\n }\n\n await this.traverseDirectory(fullPath, 'normal', category, currentNodeId);\n }\n\n if (state === 'command' && node && !node.definitionPath) {\n this.addDiagnostic(\n 'MISSING_COMMAND_DEFINITION',\n 'Command directories must include a command.ts file.',\n path,\n );\n } else if (state === 'group' && node && !node.definitionPath) {\n this.addDiagnostic(\n 'MISSING_GROUP_DEFINITION',\n 'Group directories must include a group.ts file.',\n path,\n );\n }\n }\n\n /**\n * @private\n * @internal\n */\n private createFlatCommandNode(command: Command) {\n this.createTreeNode({\n id: command.id,\n source: 'flat',\n token: command.name,\n category: command.category,\n parentId: ROOT_NODE_ID,\n directoryPath: command.parentPath,\n definitionPath: command.path,\n shorthand: false,\n });\n }\n\n /**\n * @private\n * @internal\n */\n private createTreeNode(options: {\n id?: string;\n source: Exclude<CommandTreeNode['source'], 'root'>;\n token: string;\n category: string | null;\n parentId: string;\n directoryPath: string;\n definitionPath: string | null;\n shorthand: boolean;\n }) {\n const parent = this.treeNodes.get(options.parentId);\n\n if (!parent) {\n this.addDiagnostic(\n 'MISSING_PARENT_NODE',\n `Unable to create command tree node \"${options.token}\" because its parent node was not found.`,\n options.directoryPath,\n );\n return null;\n }\n\n const duplicate = parent.childIds.some((childId) => {\n return this.treeNodes.get(childId)?.token === options.token;\n });\n\n if (duplicate) {\n this.addDiagnostic(\n 'DUPLICATE_SIBLING_TOKEN',\n `Duplicate command token \"${options.token}\" found under the same parent.`,\n options.definitionPath ?? options.directoryPath,\n );\n return null;\n }\n\n const route = [...parent.route, options.token];\n const node: CommandTreeNode = {\n id: options.id ?? crypto.randomUUID(),\n source: options.source,\n kind: this.resolveNodeKind(options.source, route.length),\n token: options.token,\n route,\n category: options.category,\n parentId: options.parentId,\n childIds: [],\n directoryPath: options.directoryPath,\n definitionPath: options.definitionPath,\n relativePath: this.replaceEntrypoint(\n options.definitionPath ?? options.directoryPath,\n ),\n shorthand: options.shorthand,\n executable: false,\n };\n\n this.treeNodes.set(node.id, node);\n parent.childIds.push(node.id);\n\n return node;\n }\n\n /**\n * @private\n * @internal\n */\n private resolveNodeKind(\n source: CommandTreeNode['source'],\n depth: number,\n ): CommandTreeNodeKind {\n switch (source) {\n case 'root':\n return 'root';\n case 'flat':\n return 'flat';\n case 'group':\n return 'group';\n case 'shorthand':\n return 'subcommand';\n case 'directory':\n return depth === 1 ? 'command' : 'subcommand';\n default:\n return source satisfies never;\n }\n }\n\n /**\n * @private\n * @internal\n */\n private compileTree() {\n this.compiledRoutes.clear();\n\n for (const node of this.treeNodes.values()) {\n if (node.id === ROOT_NODE_ID) continue;\n\n const hasChildren = node.childIds.length > 0;\n node.executable =\n !!node.definitionPath && node.kind !== 'group' && !hasChildren;\n\n if (node.kind === 'subcommand' && hasChildren) {\n this.addDiagnostic(\n 'SUBCOMMAND_CANNOT_HAVE_CHILDREN',\n `Subcommand \"${node.route.join('.')}\" cannot contain child command nodes.`,\n node.definitionPath ?? node.directoryPath,\n );\n }\n\n if (node.kind === 'command') {\n const childKinds = new Set(\n node.childIds\n .map((childId) => this.treeNodes.get(childId)?.kind)\n .filter(Boolean),\n );\n\n if (childKinds.has('group') && childKinds.has('subcommand')) {\n this.addDiagnostic(\n 'MIXED_ROOT_CHILDREN',\n `Command \"${node.route.join('.')}\" cannot mix direct subcommands and subcommand groups.`,\n node.definitionPath ?? node.directoryPath,\n );\n }\n }\n\n if (!node.executable || !node.definitionPath) continue;\n\n const key = node.route.join('.');\n const routeKind = node.kind as Exclude<\n CommandTreeNodeKind,\n 'root' | 'group'\n >;\n this.compiledRoutes.set(key, {\n id: node.id,\n key,\n kind: routeKind,\n token: node.token,\n route: node.route,\n category: node.category,\n definitionPath: node.definitionPath,\n relativePath: this.replaceEntrypoint(node.definitionPath),\n nodeId: node.id,\n middlewares: this.collectCompiledMiddlewares(node),\n });\n }\n }\n\n /**\n * @private\n * @internal\n */\n private collectCompiledMiddlewares(node: CommandTreeNode) {\n const allMiddlewares = Array.from(this.middlewares.values());\n const globalMiddlewares = allMiddlewares\n .filter((middleware) => middleware.global)\n .map((middleware) => middleware.id);\n\n const directoryMiddlewares = allMiddlewares\n .filter((middleware) => {\n return (\n !middleware.global &&\n !middleware.command &&\n middleware.parentPath === node.directoryPath\n );\n })\n .map((middleware) => middleware.id);\n\n const commandSpecificMiddlewares = allMiddlewares\n .filter((middleware) => {\n return (\n middleware.command === node.token &&\n middleware.parentPath === node.directoryPath\n );\n })\n .map((middleware) => middleware.id);\n\n return [\n ...globalMiddlewares,\n ...directoryMiddlewares,\n ...commandSpecificMiddlewares,\n ];\n }\n\n /**\n * @private\n * @internal\n */\n private addDiagnostic(code: string, message: string, path: string) {\n this.diagnostics.push({\n code,\n message,\n path: normalize(path),\n });\n }\n\n /**\n * @private\n * @internal\n */\n private async handle(entry: Dirent, category: string | null = null) {\n const name = entry.name;\n const path = join(entry.parentPath, entry.name);\n\n if (this.isCommand(name)) {\n const command: Command = {\n id: crypto.randomUUID(),\n name: basename(path, extname(path)),\n path,\n category,\n parentPath: entry.parentPath,\n relativePath: this.replaceEntrypoint(path),\n middlewares: [],\n };\n\n this.commands.set(command.id, command);\n return { command };\n }\n\n if (this.isMiddleware(name)) {\n const middleware: Middleware = {\n id: crypto.randomUUID(),\n name: basename(path, extname(path)),\n path,\n relativePath: this.replaceEntrypoint(path),\n parentPath: entry.parentPath,\n global: GLOBAL_MIDDLEWARE_PATTERN.test(name),\n command: COMMAND_MIDDLEWARE_PATTERN.test(name)\n ? name.match(COMMAND_MIDDLEWARE_PATTERN)?.[1] || null\n : null,\n };\n\n this.middlewares.set(middleware.id, middleware);\n return { middleware };\n }\n\n return {};\n }\n\n /**\n * @private\n * @internal\n */\n private applyMiddlewares() {\n this.commands.forEach((command) => {\n const commandPath = command.parentPath;\n const allMiddlewares = Array.from(this.middlewares.values());\n\n const commandSpecificMiddlewares = allMiddlewares\n .filter((middleware) => middleware.command === command.name)\n .map((middleware) => middleware.id);\n\n const directorySpecificMiddlewares = allMiddlewares\n .filter((middleware) => {\n return (\n !middleware.global &&\n !middleware.command &&\n middleware.parentPath === commandPath\n );\n })\n .map((middleware) => middleware.id);\n\n const globalMiddlewares = allMiddlewares\n .filter((middleware) => middleware.global)\n .map((middleware) => middleware.id);\n\n command.middlewares = [\n ...globalMiddlewares,\n ...directorySpecificMiddlewares,\n ...commandSpecificMiddlewares,\n ];\n });\n }\n\n /**\n * @private\n * @internal\n */\n private replaceEntrypoint(path: string) {\n const normalized = normalize(path);\n return normalized.replace(this.options.entrypoint, '');\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { i as ParsedEvent, n as EventsRouterOptions, r as EventsTree, t as EventsRouter } from "../../EventsRouter-EuuSu6NH.js";
1
+ import { i as ParsedEvent, n as EventsRouterOptions, r as EventsTree, t as EventsRouter } from "../../EventsRouter-Dyr_oJJD.js";
2
2
  export { EventsRouter, EventsRouterOptions, EventsTree, ParsedEvent };
@@ -1,3 +1,4 @@
1
- import { a as ParsedCommandData, i as Middleware, n as CommandsRouter, r as CommandsRouterOptions, t as Command } from "../../CommandsRouter-DiNoF0dq.js";
2
- import { i as ParsedEvent, n as EventsRouterOptions, r as EventsTree, t as EventsRouter } from "../../EventsRouter-EuuSu6NH.js";
3
- export { Command, CommandsRouter, CommandsRouterOptions, EventsRouter, EventsRouterOptions, EventsTree, Middleware, ParsedCommandData, ParsedEvent };
1
+ import { a as CompiledCommandRoute, i as CommandTreeNodeSource, n as CommandTreeNode, r as CommandTreeNodeKind, t as CommandRouteDiagnostic } from "../../CommandTree-DwfiCsOl.js";
2
+ import { a as ParsedCommandData, i as Middleware, n as CommandsRouter, r as CommandsRouterOptions, t as Command } from "../../CommandsRouter-D-b3xv38.js";
3
+ import { i as ParsedEvent, n as EventsRouterOptions, r as EventsTree, t as EventsRouter } from "../../EventsRouter-Dyr_oJJD.js";
4
+ export { Command, CommandRouteDiagnostic, CommandTreeNode, CommandTreeNodeKind, CommandTreeNodeSource, CommandsRouter, CommandsRouterOptions, CompiledCommandRoute, EventsRouter, EventsRouterOptions, EventsTree, Middleware, ParsedCommandData, ParsedEvent };
@@ -0,0 +1,28 @@
1
+ import { t as MaybeArray } from "./types-DZy7U-Ld.js";
2
+ import { CheckboxBuilder, CheckboxComponentData, CheckboxGroupBuilder, CheckboxGroupComponentData, CheckboxGroupOptionBuilder } from "discord.js";
3
+
4
+ //#region src/components/interactive/checkbox/checkbox.d.ts
5
+ interface CheckboxProps extends Omit<CheckboxComponentData, 'type' | 'required'> {
6
+ id?: number;
7
+ default?: boolean;
8
+ }
9
+ declare function Checkbox(props: CheckboxProps): CheckboxBuilder;
10
+ interface CheckboxGroupOptionProps {
11
+ label: string;
12
+ value: string;
13
+ description?: string;
14
+ default?: boolean;
15
+ }
16
+ declare function CheckboxGroupOption(props: CheckboxGroupOptionProps): CheckboxGroupOptionBuilder;
17
+ interface CheckboxGroupProps extends Omit<CheckboxGroupComponentData, 'type' | 'options'> {
18
+ id?: number;
19
+ customId: string;
20
+ children?: MaybeArray<CheckboxGroupOptionBuilder>;
21
+ minValues?: number;
22
+ maxValues?: number;
23
+ required?: boolean;
24
+ }
25
+ declare function CheckboxGroup(props: CheckboxGroupProps): CheckboxGroupBuilder;
26
+ //#endregion
27
+ export { CheckboxGroupProps as a, CheckboxGroupOptionProps as i, CheckboxGroup as n, CheckboxProps as o, CheckboxGroupOption as r, Checkbox as t };
28
+ //# sourceMappingURL=checkbox-CvQGiyRe.d.ts.map
@@ -1,4 +1,4 @@
1
- import { W as CompilerPlugin } from "../analytics-engine-uBNaD2CQ.js";
1
+ import { W as CompilerPlugin } from "../analytics-engine-BimOLPwO.js";
2
2
  import { t as MaybeArray } from "../types-DZy7U-Ld.js";
3
3
 
4
4
  //#region src/cli/build.d.ts