@wolfstar/plugin-subcommands-advanced 2.0.3 → 2.0.4

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/README.md CHANGED
@@ -1,4 +1,18 @@
1
- # `@wolfstar/plugin-subcommands-advanced`
1
+ <div align="center">
2
+
3
+ <img src="https://cdn.wolfstar.rocks/wolfstar-assets/wolfstar.png" alt="WolfStar" width="100" />
4
+
5
+ # @wolfstar/plugin-subcommands-advanced
6
+
7
+ **Modular slash subcommands for `@wolfstar/http-framework`.**
8
+
9
+ [![version](https://npmx.dev/api/registry/badge/version/@wolfstar/plugin-subcommands-advanced)](https://npmx.dev/package/@wolfstar/plugin-subcommands-advanced)
10
+ [![downloads](https://npmx.dev/api/registry/badge/downloads/@wolfstar/plugin-subcommands-advanced)](https://npmx.dev/package/@wolfstar/plugin-subcommands-advanced)
11
+ [![license](https://img.shields.io/github/license/wolfstar-project/plugins?style=flat-square&color=informational)](https://github.com/wolfstar-project/plugins/blob/main/LICENSE)
12
+
13
+ </div>
14
+
15
+ ## Description
2
16
 
3
17
  Plugin for [`@wolfstar/http-framework`](https://www.npmjs.com/package/@wolfstar/http-framework) that lets you split slash **subcommands** (and subcommand groups) into **separate command classes**, instead of putting every handler method on the parent.
4
18
 
@@ -238,8 +238,9 @@ declare const RegisterSubcommandsHooks: {
238
238
  * Loader strategy that wires modular subcommands onto parent commands before
239
239
  * chat-input mappings are published to {@link CommandStore.router}.
240
240
  *
241
- * {@link CommandStore.loadAll} constructs every piece first (children populate the
242
- * registries), then inserts them — {@link onLoad} therefore sees a complete registry.
241
+ * {@link CommandStore.loadAll} constructs every piece first, then inserts them. The
242
+ * first {@link onLoad} resolves all deferred children, so every parent sees a complete
243
+ * registry while builders avoid the construction phase.
243
244
  */
244
245
  declare class SubcommandsAdvancedLoaderStrategy extends CommandLoaderStrategy {
245
246
  onLoad(store: CommandStore, piece: Command): Command<import("@sapphire/pieces").PieceOptions>;
@@ -277,4 +278,4 @@ declare module "@wolfstar/http-framework" {
277
278
  }
278
279
  //#endregion
279
280
  export { SubcommandMappingCollection as S, PluginSubcommandOptions as _, RegisterSubcommandsHooks as a, SlashSubcommandResolvable as b, parseSlashSubcommand as c, subcommandGroupMethodName as d, subcommandMethodName as f, Subcommand as g, Command$1 as h, SubcommandsAdvancedLoaderStrategy as i, subCommandsGroupRegistry as l, RegisterAsSubcommandGroup as m, hasRegisteredSubcommands as n, analyzeSubCommandParsed as o, RegisterAsSubcommand as p, wireParentSubcommands as r, analyzeSubcommandGroupParsed as s, clearSubcommandRegistries as t, subCommandsRegistry as u, RegisterSubCommandGroupOptions as v, SubcommandCommandOptions as x, RegisterSubCommandOptions as y };
280
- //# sourceMappingURL=index-BuJfV_kf.d.ts.map
281
+ //# sourceMappingURL=index-B0SPGeCJ.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-BuJfV_kf.d.ts","names":[],"sources":["../../src/lib/utils/types.ts","../../src/lib/structures/command.ts","../../src/lib/utils/decorators.ts","../../src/lib/utils/functions.ts","../../src/lib/utils/hooks.ts","../../src/lib/utils/strategy.ts","../../src/lib/utils/wiring.ts","../../src/index.ts"],"mappings":";;;;;;;;KAOY,4BACR;EACE,UAAU,KAAK;IACjB,KAAK,mEAEH,SAAS,+BACT,kBAAkB,cACf;;;;UAKQ;;;;EAIf;;;;EAIA,iBAAiB;;;;;UAMF;;;;EAIf;;;;EAIA;;;;EAIA,iBAAiB;;;;;UAMF;EACf,qBAAqB;EACrB,4BAA4B;;;;;UAMb;EACf,cAAc;EACd,cAAc;EACd;;;;;UAMe;;;;;;;EAOf;;;;KClEU,yBAAyB,QAAiB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;cA2BnD,UACX,gBAAgB,yBAAyB,gCACjC,QAAiB;EACzB,YAAmB,SAAS,QAAiB,eAAe,UAAS;;kBA8BtD;OACH,UAAU;OACV,OAAO,QAAiB;;OAExB,UAAU;OACV,gBAAgB,QAAiB;OACjC,uBAAuB,QAAiB;OACxC,0BAA0B,QAAiB;OAC3C,gCAAgC,QAAiB;OACjD,WAAW,QAAiB;;;;;;;;;;;;;;;;;;;;;cAsB7B,WACX,gBAAgB,QAAiB,UAAU,QAAiB,iBACpD,QAAiB;;;;WAIT;;;;;kBAGD;OACH,UAAU,QAAiB;OAC3B,OAAO,QAAiB;;OAExB,UAAU;OACV,gBAAgB,QAAiB;OACjC,uBAAuB,QAAiB;OACxC,0BAA0B,QAAiB;OAC3C,gCAAgC,QAAiB;OACjD,WAAW,QAAiB;;;;KC1GrC,6BAA6B,gBAAgB;;;;;;;;;;;;;;;;iBAiBlC,qBACd,2BACA,iBAAiB,6BAEQ,UAAU,oBAAkB,QAAU,MAAI;;;;;;;;;;;;;;;;;;iBAyCrD,0BACd,2BACA,mBACA,iBAAiB,6BAEQ,UAAU,oBAAkB,QAAU,MAAI;;;;;;cCvExD,qBAAqB,mBAEhC,mBAAmB;;;;cAMR,0BAA0B,mBAErC,mBAAmB,mBAAmB;;;;iBAMxB,qBACd,YAAY,4BACX;;;;iBA2Ba,qBAAqB;;;;iBAOrB,0BAA0B,mBAAmB;;;;iBAO7C,wBACd,OAAO,SACP,2BACA,YAAY,4BACX;;;;iBAmBa,6BACd,OAAO,SACP,2BACA,mBACA,YAAY,4BACX;;;;;;;;;cCrFU;;;;EAIX,YAAW,OAAQ,SAAO,UAAY;;;;EAmBtC,OAAM,OAAQ,SAAO,UAAY;;;;;;;;;;;cCvBtB,0CAA0C;EACrC,OAAO,OAAO,cAAc,OAAO,UAAO,mCAAA;;;;;;;iBCG5C,yBAAyB;;;;;;;;;;;iBAczB,sBAAsB,QAAQ;;;;iBAyI9B;;;;YCvIJ;;;;IAIR,sBAAsB"}
1
+ {"version":3,"file":"index-B0SPGeCJ.d.ts","names":[],"sources":["../../src/lib/utils/types.ts","../../src/lib/structures/command.ts","../../src/lib/utils/decorators.ts","../../src/lib/utils/functions.ts","../../src/lib/utils/hooks.ts","../../src/lib/utils/strategy.ts","../../src/lib/utils/wiring.ts","../../src/index.ts"],"mappings":";;;;;;;;KAOY,4BACR;EACE,UAAU,KAAK;IACjB,KAAK,mEAEH,SAAS,+BACT,kBAAkB,cACf;;;;UAKQ;;;;EAIf;;;;EAIA,iBAAiB;;;;;UAMF;;;;EAIf;;;;EAIA;;;;EAIA,iBAAiB;;;;;UAMF;EACf,qBAAqB;EACrB,4BAA4B;;;;;UAMb;EACf,cAAc;EACd,cAAc;EACd;;;;;UAMe;;;;;;;EAOf;;;;KCtEU,yBAAyB,QAAiB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;cA2BnD,UACX,gBAAgB,yBAAyB,gCACjC,QAAiB;EACzB,YAAmB,SAAS,QAAiB,eAAe,UAAS;;kBAyBtD;OACH,UAAU;OACV,OAAO,QAAiB;;OAExB,UAAU;OACV,gBAAgB,QAAiB;OACjC,uBAAuB,QAAiB;OACxC,0BAA0B,QAAiB;OAC3C,gCAAgC,QAAiB;OACjD,WAAW,QAAiB;;;;;;;;;;;;;;;;;;;;;cAsB7B,WACX,gBAAgB,QAAiB,UAAU,QAAiB,iBACpD,QAAiB;;;;WAIT;;;;;kBAGD;OACH,UAAU,QAAiB;OAC3B,OAAO,QAAiB;;OAExB,UAAU;OACV,gBAAgB,QAAiB;OACjC,uBAAuB,QAAiB;OACxC,0BAA0B,QAAiB;OAC3C,gCAAgC,QAAiB;OACjD,WAAW,QAAiB;;;;KCrGrC,6BAA6B,gBAAgB;;;;;;;;;;;;;;;;iBAiBlC,qBACd,2BACA,iBAAiB,6BAEQ,UAAU,oBAAkB,QAAU,MAAI;;;;;;;;;;;;;;;;;;iBAwCrD,0BACd,2BACA,mBACA,iBAAiB,6BAEQ,UAAU,oBAAkB,QAAU,MAAI;;;;;;cClExD,qBAAqB,mBAEhC,mBAAmB;;;;cAMR,0BAA0B,mBAErC,mBAAmB,mBAAmB;;;;iBAexB,qBACd,YAAY,4BACX;;;;iBAsFa,qBAAqB;;;;iBAOrB,0BAA0B,mBAAmB;;;;iBAO7C,wBACd,OAAO,SACP,2BACA,YAAY,4BACX;;;;iBAUa,6BACd,OAAO,SACP,2BACA,mBACA,YAAY,4BACX;;;;;;;;;cChJU;;;;EAIX,YAAW,OAAQ,SAAO,UAAY;;;;EAmBtC,OAAM,OAAQ,SAAO,UAAY;;;;;;;;;;;;cCrBtB,0CAA0C;EACrC,OAAO,OAAO,cAAc,OAAO,UAAO,mCAAA;;;;;;;iBCM5C,yBAAyB;;;;;;;;;;;iBAczB,sBAAsB,QAAQ;;;;iBA2I9B;;;;YC9IJ;;;;IAIR,sBAAsB"}
@@ -1,2 +1,2 @@
1
- import { S as SubcommandMappingCollection, _ as PluginSubcommandOptions, a as RegisterSubcommandsHooks, b as SlashSubcommandResolvable, c as parseSlashSubcommand, d as subcommandGroupMethodName, f as subcommandMethodName, g as Subcommand, h as Command, i as SubcommandsAdvancedLoaderStrategy, l as subCommandsGroupRegistry, m as RegisterAsSubcommandGroup, n as hasRegisteredSubcommands, o as analyzeSubCommandParsed, p as RegisterAsSubcommand, r as wireParentSubcommands, s as analyzeSubcommandGroupParsed, t as clearSubcommandRegistries, u as subCommandsRegistry, v as RegisterSubCommandGroupOptions, x as SubcommandCommandOptions, y as RegisterSubCommandOptions } from "./index-BuJfV_kf.js";
1
+ import { S as SubcommandMappingCollection, _ as PluginSubcommandOptions, a as RegisterSubcommandsHooks, b as SlashSubcommandResolvable, c as parseSlashSubcommand, d as subcommandGroupMethodName, f as subcommandMethodName, g as Subcommand, h as Command, i as SubcommandsAdvancedLoaderStrategy, l as subCommandsGroupRegistry, m as RegisterAsSubcommandGroup, n as hasRegisteredSubcommands, o as analyzeSubCommandParsed, p as RegisterAsSubcommand, r as wireParentSubcommands, s as analyzeSubcommandGroupParsed, t as clearSubcommandRegistries, u as subCommandsRegistry, v as RegisterSubCommandGroupOptions, x as SubcommandCommandOptions, y as RegisterSubCommandOptions } from "./index-B0SPGeCJ.js";
2
2
  export { Command, type PluginSubcommandOptions, RegisterAsSubcommand, RegisterAsSubcommandGroup, type RegisterSubCommandGroupOptions, type RegisterSubCommandOptions, RegisterSubcommandsHooks, type SlashSubcommandResolvable, Subcommand, type SubcommandCommandOptions, type SubcommandMappingCollection, SubcommandsAdvancedLoaderStrategy, analyzeSubCommandParsed, analyzeSubcommandGroupParsed, clearSubcommandRegistries, hasRegisteredSubcommands, parseSlashSubcommand, subCommandsGroupRegistry, subCommandsRegistry, subcommandGroupMethodName, subcommandMethodName, wireParentSubcommands };
package/dist/esm/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as RegisterAsSubcommand, c as Subcommand, d as analyzeSubcommandGroupParsed, f as parseSlashSubcommand, g as subcommandMethodName, h as subcommandGroupMethodName, i as wireParentSubcommands, l as RegisterSubcommandsHooks, m as subCommandsRegistry, n as clearSubcommandRegistries, o as RegisterAsSubcommandGroup, p as subCommandsGroupRegistry, r as hasRegisteredSubcommands, s as Command, t as SubcommandsAdvancedLoaderStrategy, u as analyzeSubCommandParsed } from "./src-DNdsrn4L.js";
1
+ import { a as RegisterAsSubcommand, c as Subcommand, d as analyzeSubcommandGroupParsed, f as parseSlashSubcommand, g as subcommandMethodName, h as subcommandGroupMethodName, i as wireParentSubcommands, l as RegisterSubcommandsHooks, m as subCommandsRegistry, n as clearSubcommandRegistries, o as RegisterAsSubcommandGroup, p as subCommandsGroupRegistry, r as hasRegisteredSubcommands, s as Command, t as SubcommandsAdvancedLoaderStrategy, u as analyzeSubCommandParsed } from "./src-C5fgASI3.js";
2
2
 
3
3
  export { Command, RegisterAsSubcommand, RegisterAsSubcommandGroup, RegisterSubcommandsHooks, Subcommand, SubcommandsAdvancedLoaderStrategy, analyzeSubCommandParsed, analyzeSubcommandGroupParsed, clearSubcommandRegistries, hasRegisteredSubcommands, parseSlashSubcommand, subCommandsGroupRegistry, subCommandsRegistry, subcommandGroupMethodName, subcommandMethodName, wireParentSubcommands };
@@ -1,4 +1,4 @@
1
- import "./index-BuJfV_kf.js";
1
+ import "./index-B0SPGeCJ.js";
2
2
  import { Client, ClientOptions, Plugin, postInitialization } from "@wolfstar/http-framework";
3
3
  //#region src/register.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as SubcommandsAdvancedLoaderStrategy } from "./src-DNdsrn4L.js";
1
+ import { t as SubcommandsAdvancedLoaderStrategy } from "./src-C5fgASI3.js";
2
2
  import { Client, Plugin, container, postInitialization } from "@wolfstar/http-framework";
3
3
 
4
4
  //#region src/register.ts
@@ -12,6 +12,7 @@ const subCommandsRegistry = new Collection();
12
12
  * Registry of grouped subcommands keyed by parent → group → subcommand name.
13
13
  */
14
14
  const subCommandsGroupRegistry = new Collection();
15
+ const deferredSubcommands = /* @__PURE__ */ new Map();
15
16
  /**
16
17
  * Normalize slash subcommand input into a builder.
17
18
  */
@@ -29,6 +30,49 @@ function parseSlashSubcommand(subcommand) {
29
30
  return new SlashCommandSubcommandBuilder().setName(data.name).setDescription(data.description);
30
31
  }
31
32
  /**
33
+ * Defer parsing a subcommand until the command store starts inserting pieces.
34
+ *
35
+ * Sapphire constructs every piece before inserting any of them during `loadAll`.
36
+ * Keeping the builder callback untouched here prevents it from observing partially
37
+ * initialized services during piece construction.
38
+ *
39
+ * @internal
40
+ */
41
+ function deferSubcommand(piece, parentCommandName, slashSubcommand, nameCommandsAutogenerated, groupName) {
42
+ const deferred = {
43
+ parentCommandName,
44
+ groupName,
45
+ slashSubcommand,
46
+ nameCommandsAutogenerated
47
+ };
48
+ const registrations = deferredSubcommands.get(piece);
49
+ if (registrations) registrations.push(deferred);
50
+ else deferredSubcommands.set(piece, [deferred]);
51
+ }
52
+ /** @internal */
53
+ function resolveDeferredSubcommands() {
54
+ for (const [piece, registrations] of deferredSubcommands) {
55
+ const resolved = registrations.map((deferred) => ({
56
+ deferred,
57
+ parsed: parseSlashSubcommand(deferred.slashSubcommand)
58
+ }));
59
+ for (const { deferred, parsed } of resolved) {
60
+ if (deferred.nameCommandsAutogenerated) Object.defineProperty(piece, "name", {
61
+ configurable: true,
62
+ enumerable: true,
63
+ writable: true,
64
+ value: deferred.groupName ? `${deferred.parentCommandName}/${deferred.groupName}/${parsed.name}` : `${deferred.parentCommandName}/${parsed.name}`
65
+ });
66
+ registerParsedSubcommand(piece, deferred.parentCommandName, parsed, deferred.groupName);
67
+ }
68
+ deferredSubcommands.delete(piece);
69
+ }
70
+ }
71
+ /** @internal */
72
+ function clearDeferredSubcommands() {
73
+ deferredSubcommands.clear();
74
+ }
75
+ /**
32
76
  * Stable method name linked on the parent command for a direct subcommand.
33
77
  */
34
78
  function subcommandMethodName(subcommandName) {
@@ -44,29 +88,28 @@ function subcommandGroupMethodName(groupName, subcommandName) {
44
88
  * Register a command piece as a direct subcommand of `parentCommandName`.
45
89
  */
46
90
  function analyzeSubCommandParsed(piece, parentCommandName, subcommand) {
47
- const subcommandParsed = parseSlashSubcommand(subcommand);
48
- const subcommandName = subcommandParsed.name;
49
- const entry = {
50
- slashCommand: subcommandParsed,
51
- commandPiece: piece,
52
- methodName: subcommandMethodName(subcommandName)
53
- };
54
- subCommandsRegistry.ensure(parentCommandName, () => new Collection()).set(subcommandName, entry);
91
+ registerParsedSubcommand(piece, parentCommandName, parseSlashSubcommand(subcommand));
55
92
  return piece;
56
93
  }
57
94
  /**
58
95
  * Register a command piece as a subcommand inside a group of `parentCommandName`.
59
96
  */
60
97
  function analyzeSubcommandGroupParsed(piece, parentCommandName, groupName, subcommand) {
61
- const subcommandParsed = parseSlashSubcommand(subcommand);
98
+ registerParsedSubcommand(piece, parentCommandName, parseSlashSubcommand(subcommand), groupName);
99
+ return piece;
100
+ }
101
+ function registerParsedSubcommand(piece, parentCommandName, subcommandParsed, groupName) {
62
102
  const subcommandName = subcommandParsed.name;
63
103
  const entry = {
64
104
  slashCommand: subcommandParsed,
65
105
  commandPiece: piece,
66
- methodName: subcommandGroupMethodName(groupName, subcommandName)
106
+ methodName: groupName ? subcommandGroupMethodName(groupName, subcommandName) : subcommandMethodName(subcommandName)
67
107
  };
108
+ if (!groupName) {
109
+ subCommandsRegistry.ensure(parentCommandName, () => new Collection()).set(subcommandName, entry);
110
+ return;
111
+ }
68
112
  subCommandsGroupRegistry.ensure(parentCommandName, () => new Collection()).ensure(groupName, () => new Collection()).set(subcommandName, entry);
69
- return piece;
70
113
  }
71
114
 
72
115
  //#endregion
@@ -140,27 +183,15 @@ const RegisterSubcommandsHooks = {
140
183
  */
141
184
  var Command$1 = class extends Command {
142
185
  constructor(context, options = {}) {
186
+ super(context, options);
143
187
  const nameCommandsAutogenerated = container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true;
144
- let name = options.name;
145
- if (options.registerSubCommand && nameCommandsAutogenerated) {
146
- const parsed = parseSlashSubcommand(options.registerSubCommand.slashSubcommand);
147
- name = `${options.registerSubCommand.parentCommandName}/${parsed.name}`;
148
- }
149
- if (options.registerSubcommandInGroup && nameCommandsAutogenerated) {
150
- const parsed = parseSlashSubcommand(options.registerSubcommandInGroup.slashSubcommand);
151
- name = `${options.registerSubcommandInGroup.parentCommandName}/${options.registerSubcommandInGroup.groupName}/${parsed.name}`;
152
- }
153
- super(context, {
154
- ...options,
155
- name
156
- });
157
188
  if (this.options.registerSubCommand) {
158
189
  const { parentCommandName, slashSubcommand } = this.options.registerSubCommand;
159
- analyzeSubCommandParsed(this, parentCommandName, slashSubcommand);
190
+ deferSubcommand(this, parentCommandName, slashSubcommand, nameCommandsAutogenerated);
160
191
  }
161
192
  if (this.options.registerSubcommandInGroup) {
162
193
  const { parentCommandName, groupName, slashSubcommand } = this.options.registerSubcommandInGroup;
163
- analyzeSubcommandGroupParsed(this, parentCommandName, groupName, slashSubcommand);
194
+ deferSubcommand(this, parentCommandName, slashSubcommand, nameCommandsAutogenerated, groupName);
164
195
  }
165
196
  }
166
197
  };
@@ -212,13 +243,8 @@ function RegisterAsSubcommand(parentCommandName, slashSubcommand) {
212
243
  const decorated = class extends target {
213
244
  constructor(...args) {
214
245
  const [context, baseOptions = {}] = args;
215
- const parsed = parseSlashSubcommand(slashSubcommand);
216
- const name = container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true ? `${parentCommandName}/${parsed.name}` : baseOptions.name;
217
- super(context, {
218
- ...baseOptions,
219
- name
220
- });
221
- analyzeSubCommandParsed(this, parentCommandName, slashSubcommand);
246
+ super(context, baseOptions);
247
+ deferSubcommand(this, parentCommandName, slashSubcommand, container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true);
222
248
  }
223
249
  };
224
250
  applicationCommandRegistry.ensure(decorated);
@@ -247,13 +273,8 @@ function RegisterAsSubcommandGroup(parentCommandName, groupName, slashSubcommand
247
273
  const decorated = class extends target {
248
274
  constructor(...args) {
249
275
  const [context, baseOptions = {}] = args;
250
- const parsed = parseSlashSubcommand(slashSubcommand);
251
- const name = container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true ? `${parentCommandName}/${groupName}/${parsed.name}` : baseOptions.name;
252
- super(context, {
253
- ...baseOptions,
254
- name
255
- });
256
- analyzeSubcommandGroupParsed(this, parentCommandName, groupName, slashSubcommand);
276
+ super(context, baseOptions);
277
+ deferSubcommand(this, parentCommandName, slashSubcommand, container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true, groupName);
257
278
  }
258
279
  };
259
280
  applicationCommandRegistry.ensure(decorated);
@@ -281,6 +302,7 @@ function hasRegisteredSubcommands(parentName) {
281
302
  * (Store `loadAll` rebuilds pieces) still satisfy {@link CommandRouter}'s method checks.
282
303
  */
283
304
  function wireParentSubcommands(parent) {
305
+ resolveDeferredSubcommands();
284
306
  const parentName = parent.router.chatInputName;
285
307
  if (!parentName || !hasRegisteredSubcommands(parentName)) return;
286
308
  if (wiredParents.has(parent)) return;
@@ -362,6 +384,7 @@ function lookupEntry(parentName, methodName) {
362
384
  * Reset subcommand registries (useful between tests).
363
385
  */
364
386
  function clearSubcommandRegistries() {
387
+ clearDeferredSubcommands();
365
388
  subCommandsRegistry.clear();
366
389
  subCommandsGroupRegistry.clear();
367
390
  }
@@ -372,11 +395,13 @@ function clearSubcommandRegistries() {
372
395
  * Loader strategy that wires modular subcommands onto parent commands before
373
396
  * chat-input mappings are published to {@link CommandStore.router}.
374
397
  *
375
- * {@link CommandStore.loadAll} constructs every piece first (children populate the
376
- * registries), then inserts them — {@link onLoad} therefore sees a complete registry.
398
+ * {@link CommandStore.loadAll} constructs every piece first, then inserts them. The
399
+ * first {@link onLoad} resolves all deferred children, so every parent sees a complete
400
+ * registry while builders avoid the construction phase.
377
401
  */
378
402
  var SubcommandsAdvancedLoaderStrategy = class extends CommandLoaderStrategy {
379
403
  onLoad(store, piece) {
404
+ resolveDeferredSubcommands();
380
405
  const parentName = piece.router.chatInputName;
381
406
  if (parentName && hasRegisteredSubcommands(parentName)) wireParentSubcommands(piece);
382
407
  return super.onLoad(store, piece);
@@ -385,4 +410,4 @@ var SubcommandsAdvancedLoaderStrategy = class extends CommandLoaderStrategy {
385
410
 
386
411
  //#endregion
387
412
  export { RegisterAsSubcommand as a, Subcommand as c, analyzeSubcommandGroupParsed as d, parseSlashSubcommand as f, subcommandMethodName as g, subcommandGroupMethodName as h, wireParentSubcommands as i, RegisterSubcommandsHooks as l, subCommandsRegistry as m, clearSubcommandRegistries as n, RegisterAsSubcommandGroup as o, subCommandsGroupRegistry as p, hasRegisteredSubcommands as r, Command$1 as s, SubcommandsAdvancedLoaderStrategy as t, analyzeSubCommandParsed as u };
388
- //# sourceMappingURL=src-DNdsrn4L.js.map
413
+ //# sourceMappingURL=src-C5fgASI3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-C5fgASI3.js","names":["Command","FrameworkCommand"],"sources":["../../src/lib/utils/functions.ts","../../src/lib/utils/hooks.ts","../../src/lib/structures/command.ts","../../src/lib/utils/decorators.ts","../../src/lib/utils/wiring.ts","../../src/lib/utils/strategy.ts"],"sourcesContent":["import { SlashCommandSubcommandBuilder } from \"@discordjs/builders\";\nimport { Collection } from \"@discordjs/collection\";\nimport { container, type Command } from \"@wolfstar/http-framework\";\nimport type { SlashSubcommandResolvable, SubcommandMappingCollection } from \"./types.js\";\n\n/**\n * Registry of direct subcommands keyed by parent command name, then subcommand name.\n */\nexport const subCommandsRegistry: Collection<\n string,\n Collection<string, SubcommandMappingCollection>\n> = new Collection();\n\n/**\n * Registry of grouped subcommands keyed by parent → group → subcommand name.\n */\nexport const subCommandsGroupRegistry: Collection<\n string,\n Collection<string, Collection<string, SubcommandMappingCollection>>\n> = new Collection();\n\ninterface DeferredSubcommand {\n parentCommandName: string;\n groupName?: string;\n slashSubcommand: SlashSubcommandResolvable;\n nameCommandsAutogenerated: boolean;\n}\n\nconst deferredSubcommands = new Map<Command, DeferredSubcommand[]>();\n\n/**\n * Normalize slash subcommand input into a builder.\n */\nexport function parseSlashSubcommand(\n subcommand: SlashSubcommandResolvable,\n): SlashCommandSubcommandBuilder {\n if (typeof subcommand === \"function\") {\n const builder = new SlashCommandSubcommandBuilder();\n return subcommand(builder, container) ?? builder;\n }\n\n if (subcommand instanceof SlashCommandSubcommandBuilder) {\n return subcommand;\n }\n\n if (\n typeof subcommand === \"object\" &&\n subcommand !== null &&\n \"toJSON\" in subcommand &&\n typeof subcommand.toJSON === \"function\"\n ) {\n const json = (subcommand as { toJSON: () => { name: string; description: string } }).toJSON();\n return new SlashCommandSubcommandBuilder().setName(json.name).setDescription(json.description);\n }\n\n const data = subcommand as { name: string; description: string };\n return new SlashCommandSubcommandBuilder().setName(data.name).setDescription(data.description);\n}\n\n/**\n * Defer parsing a subcommand until the command store starts inserting pieces.\n *\n * Sapphire constructs every piece before inserting any of them during `loadAll`.\n * Keeping the builder callback untouched here prevents it from observing partially\n * initialized services during piece construction.\n *\n * @internal\n */\nexport function deferSubcommand(\n piece: Command,\n parentCommandName: string,\n slashSubcommand: SlashSubcommandResolvable,\n nameCommandsAutogenerated: boolean,\n groupName?: string,\n): void {\n const deferred = {\n parentCommandName,\n groupName,\n slashSubcommand,\n nameCommandsAutogenerated,\n };\n const registrations = deferredSubcommands.get(piece);\n if (registrations) registrations.push(deferred);\n else deferredSubcommands.set(piece, [deferred]);\n}\n\n/** @internal */\nexport function resolveDeferredSubcommands(): void {\n for (const [piece, registrations] of deferredSubcommands) {\n const resolved = registrations.map((deferred) => ({\n deferred,\n parsed: parseSlashSubcommand(deferred.slashSubcommand),\n }));\n\n for (const { deferred, parsed } of resolved) {\n if (deferred.nameCommandsAutogenerated) {\n Object.defineProperty(piece, \"name\", {\n configurable: true,\n enumerable: true,\n writable: true,\n value: deferred.groupName\n ? `${deferred.parentCommandName}/${deferred.groupName}/${parsed.name}`\n : `${deferred.parentCommandName}/${parsed.name}`,\n });\n }\n\n registerParsedSubcommand(piece, deferred.parentCommandName, parsed, deferred.groupName);\n }\n\n deferredSubcommands.delete(piece);\n }\n}\n\n/** @internal */\nexport function clearDeferredSubcommands(): void {\n deferredSubcommands.clear();\n}\n\n/**\n * Stable method name linked on the parent command for a direct subcommand.\n */\nexport function subcommandMethodName(subcommandName: string): string {\n return `__wolfstar_sc_${subcommandName}`;\n}\n\n/**\n * Stable method name linked on the parent command for a grouped subcommand.\n */\nexport function subcommandGroupMethodName(groupName: string, subcommandName: string): string {\n return `__wolfstar_sc_${groupName}_${subcommandName}`;\n}\n\n/**\n * Register a command piece as a direct subcommand of `parentCommandName`.\n */\nexport function analyzeSubCommandParsed(\n piece: Command,\n parentCommandName: string,\n subcommand: SlashSubcommandResolvable,\n): Command {\n const subcommandParsed = parseSlashSubcommand(subcommand);\n registerParsedSubcommand(piece, parentCommandName, subcommandParsed);\n\n return piece;\n}\n\n/**\n * Register a command piece as a subcommand inside a group of `parentCommandName`.\n */\nexport function analyzeSubcommandGroupParsed(\n piece: Command,\n parentCommandName: string,\n groupName: string,\n subcommand: SlashSubcommandResolvable,\n): Command {\n const subcommandParsed = parseSlashSubcommand(subcommand);\n registerParsedSubcommand(piece, parentCommandName, subcommandParsed, groupName);\n\n return piece;\n}\n\nfunction registerParsedSubcommand(\n piece: Command,\n parentCommandName: string,\n subcommandParsed: SlashCommandSubcommandBuilder,\n groupName?: string,\n): void {\n const subcommandName = subcommandParsed.name;\n const methodName = groupName\n ? subcommandGroupMethodName(groupName, subcommandName)\n : subcommandMethodName(subcommandName);\n const entry: SubcommandMappingCollection = {\n slashCommand: subcommandParsed,\n commandPiece: piece,\n methodName,\n };\n\n if (!groupName) {\n const registry = subCommandsRegistry.ensure(parentCommandName, () => new Collection());\n registry.set(subcommandName, entry);\n return;\n }\n\n const parentRegistry = subCommandsGroupRegistry.ensure(parentCommandName, () => new Collection());\n const groupRegistry = parentRegistry.ensure(groupName, () => new Collection());\n groupRegistry.set(subcommandName, entry);\n}\n","import type { SlashCommandBuilder } from \"@discordjs/builders\";\nimport type { Command } from \"@wolfstar/http-framework\";\nimport { subCommandsGroupRegistry, subCommandsRegistry } from \"./functions.js\";\n\n/**\n * Optional hooks for parent commands that register chat-input commands imperatively\n * via {@link Command.registerApplicationCommands}. Prefer relying on the automatic\n * wiring performed by {@link SubcommandsAdvancedLoaderStrategy}; these helpers are\n * useful when you want to inspect or manually attach builders during registration.\n */\nexport const RegisterSubcommandsHooks = {\n /**\n * Attach registered direct subcommands onto a {@link SlashCommandBuilder}.\n */\n subcommands(piece: Command, context?: SlashCommandBuilder): void {\n const subcommands = subCommandsRegistry.get(piece.router.chatInputName ?? piece.name);\n if (!subcommands) {\n console.warn(\n `[plugin-subcommands-advanced]: No direct subcommands registered for parent \"${piece.router.chatInputName ?? piece.name}\".`,\n );\n return;\n }\n\n if (!context) return;\n\n for (const { slashCommand } of subcommands.values()) {\n context.addSubcommand(slashCommand);\n }\n },\n\n /**\n * Attach registered grouped subcommands onto matching groups on a {@link SlashCommandBuilder}.\n */\n groups(piece: Command, context?: SlashCommandBuilder): void {\n const groups = subCommandsGroupRegistry.get(piece.router.chatInputName ?? piece.name);\n if (!groups) {\n console.warn(\n `[plugin-subcommands-advanced]: No subcommand groups registered for parent \"${piece.router.chatInputName ?? piece.name}\".`,\n );\n return;\n }\n\n if (!context) return;\n\n for (const [groupName, commands] of groups) {\n const group = context.options.find((option) => {\n const data =\n \"toJSON\" in option && typeof option.toJSON === \"function\" ? option.toJSON() : null;\n return data && typeof data === \"object\" && \"name\" in data && data.name === groupName;\n }) as { addSubcommand?(subcommand: unknown): unknown } | undefined;\n\n if (!group?.addSubcommand) continue;\n\n for (const { slashCommand } of commands.values()) {\n group.addSubcommand(slashCommand);\n }\n }\n },\n};\n","import { Command as FrameworkCommand, container } from \"@wolfstar/http-framework\";\nimport { deferSubcommand } from \"../utils/functions.js\";\nimport { RegisterSubcommandsHooks } from \"../utils/hooks.js\";\nimport type { SubcommandCommandOptions } from \"../utils/types.js\";\n\nexport type AdvancedCommandOptions = FrameworkCommand.Options & SubcommandCommandOptions;\n\n/**\n * Command class that can register itself as a modular subcommand (or grouped subcommand)\n * of a parent {@link Subcommand} / chat-input command.\n *\n * @example\n * ```typescript\n * import { Command } from '@wolfstar/plugin-subcommands-advanced';\n *\n * export class PingCommand extends Command {\n * public constructor(context: Command.LoaderContext, options: Command.Options) {\n * super(context, {\n * ...options,\n * registerSubCommand: {\n * parentCommandName: 'utils',\n * slashSubcommand: (builder) => builder.setName('ping').setDescription('Ping!')\n * }\n * });\n * }\n *\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Pong!' });\n * }\n * }\n * ```\n */\nexport class Command<\n Options extends AdvancedCommandOptions = AdvancedCommandOptions,\n> extends FrameworkCommand<Options> {\n public constructor(context: FrameworkCommand.LoaderContext, options: Options = {} as Options) {\n super(context, options);\n\n const nameCommandsAutogenerated =\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true;\n\n if (this.options.registerSubCommand) {\n const { parentCommandName, slashSubcommand } = this.options.registerSubCommand;\n deferSubcommand(this, parentCommandName, slashSubcommand, nameCommandsAutogenerated);\n }\n\n if (this.options.registerSubcommandInGroup) {\n const { parentCommandName, groupName, slashSubcommand } =\n this.options.registerSubcommandInGroup;\n deferSubcommand(\n this,\n parentCommandName,\n slashSubcommand,\n nameCommandsAutogenerated,\n groupName,\n );\n }\n }\n}\n\nexport namespace Command {\n export type Options = AdvancedCommandOptions;\n export type JSON = FrameworkCommand.JSON;\n /** @deprecated Use {@linkcode LoaderContext} instead. */\n export type Context = LoaderContext;\n export type LoaderContext = FrameworkCommand.LoaderContext;\n export type ChatInputInteraction = FrameworkCommand.ChatInputInteraction;\n export type AutocompleteInteraction = FrameworkCommand.AutocompleteInteraction;\n export type ApplicationCommandInteraction = FrameworkCommand.ApplicationCommandInteraction;\n export type Registry = FrameworkCommand.Registry;\n}\n\n/**\n * Parent command marker. Extend this for the chat-input command that owns modular\n * subcommands. Wiring of children is performed automatically by the plugin loader\n * strategy after all pieces are constructed.\n *\n * @example\n * ```typescript\n * import { RegisterCommand } from '@wolfstar/http-framework';\n * import { Subcommand } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterCommand((builder) =>\n * builder\n * .setName('utils')\n * .setDescription('Utility commands')\n * .addSubcommandGroup((group) => group.setName('poll').setDescription('Polls'))\n * )\n * export class UtilsCommand extends Subcommand {}\n * ```\n */\nexport class Subcommand<\n Options extends FrameworkCommand.Options = FrameworkCommand.Options,\n> extends FrameworkCommand<Options> {\n /**\n * Optional hooks for imperative {@link registerApplicationCommands} usage.\n */\n public readonly hooks = RegisterSubcommandsHooks;\n}\n\nexport namespace Subcommand {\n export type Options = FrameworkCommand.Options;\n export type JSON = FrameworkCommand.JSON;\n /** @deprecated Use {@linkcode LoaderContext} instead. */\n export type Context = LoaderContext;\n export type LoaderContext = FrameworkCommand.LoaderContext;\n export type ChatInputInteraction = FrameworkCommand.ChatInputInteraction;\n export type AutocompleteInteraction = FrameworkCommand.AutocompleteInteraction;\n export type ApplicationCommandInteraction = FrameworkCommand.ApplicationCommandInteraction;\n export type Registry = FrameworkCommand.Registry;\n}\n","import {\n applicationCommandRegistry,\n type Command as FrameworkCommand,\n container,\n} from \"@wolfstar/http-framework\";\nimport { deferSubcommand } from \"./functions.js\";\nimport type { SlashSubcommandResolvable } from \"./types.js\";\n\ntype CommandConstructor = new (...args: any[]) => FrameworkCommand;\n\n/**\n * Class decorator that registers the decorated command as a direct subcommand of `parentCommandName`.\n *\n * @example\n * ```typescript\n * import { Command, RegisterAsSubcommand } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterAsSubcommand('utils', (builder) => builder.setName('ping').setDescription('Ping!'))\n * export class PingCommand extends Command {\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Pong!' });\n * }\n * }\n * ```\n */\nexport function RegisterAsSubcommand(\n parentCommandName: string,\n slashSubcommand: SlashSubcommandResolvable,\n) {\n return function decorate<T extends CommandConstructor>(target: T): T {\n const decorated = class extends target {\n public constructor(...args: any[]) {\n const [context, baseOptions = {}] = args as [\n FrameworkCommand.LoaderContext,\n FrameworkCommand.Options,\n ];\n super(context, baseOptions);\n deferSubcommand(\n this,\n parentCommandName,\n slashSubcommand,\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true,\n );\n }\n } as T;\n\n applicationCommandRegistry.ensure(decorated as unknown as typeof FrameworkCommand);\n\n return decorated;\n };\n}\n\n/**\n * Class decorator that registers the decorated command as a subcommand inside a group.\n *\n * @example\n * ```typescript\n * import { Command, RegisterAsSubcommandGroup } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterAsSubcommandGroup('utils', 'poll', (builder) =>\n * builder.setName('create').setDescription('Create a poll')\n * )\n * export class PollCreateCommand extends Command {\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Created!' });\n * }\n * }\n * ```\n */\nexport function RegisterAsSubcommandGroup(\n parentCommandName: string,\n groupName: string,\n slashSubcommand: SlashSubcommandResolvable,\n) {\n return function decorate<T extends CommandConstructor>(target: T): T {\n const decorated = class extends target {\n public constructor(...args: any[]) {\n const [context, baseOptions = {}] = args as [\n FrameworkCommand.LoaderContext,\n FrameworkCommand.Options,\n ];\n super(context, baseOptions);\n deferSubcommand(\n this,\n parentCommandName,\n slashSubcommand,\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true,\n groupName,\n );\n }\n } as T;\n\n applicationCommandRegistry.ensure(decorated as unknown as typeof FrameworkCommand);\n\n return decorated;\n };\n}\n","import { applicationCommandRegistry, CommandRouter, type Command } from \"@wolfstar/http-framework\";\nimport {\n ApplicationCommandOptionType,\n type APIApplicationCommandSubcommandGroupOption,\n type RESTPostAPIChatInputApplicationCommandsJSONBody,\n} from \"discord-api-types/v10\";\nimport {\n clearDeferredSubcommands,\n resolveDeferredSubcommands,\n subCommandsGroupRegistry,\n subCommandsRegistry,\n} from \"./functions.js\";\nimport type { SubcommandMappingCollection } from \"./types.js\";\n\nconst wiredParents = new WeakSet<Command>();\n\n/**\n * Whether this piece is a parent that has registered modular subcommands.\n */\nexport function hasRegisteredSubcommands(parentName: string): boolean {\n return subCommandsRegistry.has(parentName) || subCommandsGroupRegistry.has(parentName);\n}\n\n/**\n * Install delegate methods on the parent and rebuild its chat-input resolver + router\n * so modular child command classes handle each subcommand.\n *\n * Must run after every command piece has been constructed (e.g. from\n * {@link CommandLoaderStrategy.onLoad}), so the registries contain every child.\n *\n * Delegates are installed on the parent **prototype** so reconstructed instances\n * (Store `loadAll` rebuilds pieces) still satisfy {@link CommandRouter}'s method checks.\n */\nexport function wireParentSubcommands(parent: Command): void {\n resolveDeferredSubcommands();\n\n const parentName = parent.router.chatInputName;\n if (!parentName || !hasRegisteredSubcommands(parentName)) return;\n if (wiredParents.has(parent)) return;\n\n const ctor = parent.constructor as typeof Command;\n const existing = applicationCommandRegistry.get(ctor);\n const chatInput = existing?.chatInput;\n if (!chatInput) {\n console.warn(\n `[plugin-subcommands-advanced]: Parent command \"${parentName}\" has no chat-input registration; skipping wiring.`,\n );\n return;\n }\n\n const snapshot = chatInput.toJSON();\n applicationCommandRegistry.delete(ctor);\n\n const resolver = applicationCommandRegistry.ensure(ctor).makeChatInput();\n resolver.setCommand(baseCommandData(snapshot));\n\n for (const option of snapshot.options ?? []) {\n if (option.type === ApplicationCommandOptionType.SubcommandGroup) {\n resolver.addSubcommandGroup(groupDataWithoutSubcommands(option), getLinkedMethod(option));\n for (const subcommand of option.options ?? []) {\n resolver.addSubcommand(subcommand, getLinkedMethod(subcommand), option.name);\n }\n } else if (option.type === ApplicationCommandOptionType.Subcommand) {\n resolver.addSubcommand(option, getLinkedMethod(option));\n }\n }\n\n const direct = subCommandsRegistry.get(parentName);\n if (direct) {\n for (const entry of direct.values()) {\n installDelegate(ctor, parentName, entry);\n resolver.addSubcommand(entry.slashCommand, entry.methodName);\n }\n }\n\n const groups = subCommandsGroupRegistry.get(parentName);\n if (groups) {\n for (const [groupName, commands] of groups) {\n for (const entry of commands.values()) {\n installDelegate(ctor, parentName, entry);\n resolver.addSubcommand(entry.slashCommand, entry.methodName, groupName);\n }\n }\n }\n\n Object.defineProperty(parent, \"router\", {\n value: new CommandRouter(parent),\n configurable: true,\n enumerable: true,\n writable: false,\n });\n\n wiredParents.add(parent);\n}\n\nfunction baseCommandData(snapshot: RESTPostAPIChatInputApplicationCommandsJSONBody) {\n const { options: _options, ...rest } = snapshot;\n return rest;\n}\n\nfunction groupDataWithoutSubcommands(group: APIApplicationCommandSubcommandGroupOption) {\n const { options: _options, type: _type, ...rest } = group;\n return rest;\n}\n\n/**\n * `http-framework` links a subcommand (or group) option to its handler method by\n * defining a non-enumerable symbol property on the resolved option object. The\n * symbol is not exported, so it is recovered here by its description to preserve\n * framework-native subcommand routing when the resolver is rebuilt.\n */\nconst LINKED_METHOD_SYMBOL_DESCRIPTION = \"decorated-command.method.link\";\n\nfunction getLinkedMethod(option: object): string | null {\n for (const symbol of Object.getOwnPropertySymbols(option)) {\n if (symbol.description === LINKED_METHOD_SYMBOL_DESCRIPTION) {\n return (Reflect.get(option, symbol) as string | undefined) ?? null;\n }\n }\n\n return null;\n}\n\nfunction installDelegate(\n parentCtor: typeof Command,\n parentName: string,\n entry: SubcommandMappingCollection,\n): void {\n const { methodName } = entry;\n\n Object.defineProperty(parentCtor.prototype, methodName, {\n configurable: true,\n enumerable: false,\n writable: true,\n value(this: Command, interaction: Command.ApplicationCommandInteraction, args: object) {\n const resolved = lookupEntry(parentName, methodName);\n if (!resolved) {\n throw new Error(\n `[plugin-subcommands-advanced]: No child command registered for parent \"${parentName}\" method \"${methodName}\".`,\n );\n }\n return resolved.commandPiece.chatInputRun(interaction, args);\n },\n });\n}\n\nfunction lookupEntry(\n parentName: string,\n methodName: string,\n): SubcommandMappingCollection | undefined {\n const direct = subCommandsRegistry.get(parentName);\n if (direct) {\n for (const entry of direct.values()) {\n if (entry.methodName === methodName) return entry;\n }\n }\n\n const groups = subCommandsGroupRegistry.get(parentName);\n if (groups) {\n for (const commands of groups.values()) {\n for (const entry of commands.values()) {\n if (entry.methodName === methodName) return entry;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Reset subcommand registries (useful between tests).\n */\nexport function clearSubcommandRegistries(): void {\n clearDeferredSubcommands();\n subCommandsRegistry.clear();\n subCommandsGroupRegistry.clear();\n}\n","import { CommandLoaderStrategy, type Command, type CommandStore } from \"@wolfstar/http-framework\";\nimport { resolveDeferredSubcommands } from \"./functions.js\";\nimport { hasRegisteredSubcommands, wireParentSubcommands } from \"./wiring.js\";\n\n/**\n * Loader strategy that wires modular subcommands onto parent commands before\n * chat-input mappings are published to {@link CommandStore.router}.\n *\n * {@link CommandStore.loadAll} constructs every piece first, then inserts them. The\n * first {@link onLoad} resolves all deferred children, so every parent sees a complete\n * registry while builders avoid the construction phase.\n */\nexport class SubcommandsAdvancedLoaderStrategy extends CommandLoaderStrategy {\n public override onLoad(store: CommandStore, piece: Command) {\n resolveDeferredSubcommands();\n\n const parentName = piece.router.chatInputName;\n if (parentName && hasRegisteredSubcommands(parentName)) {\n wireParentSubcommands(piece);\n }\n\n return super.onLoad(store, piece);\n }\n}\n"],"mappings":";;;;;;;;;AAQA,MAAa,sBAGT,IAAI,WAAW;;;;AAKnB,MAAa,2BAGT,IAAI,WAAW;AASnB,MAAM,sCAAsB,IAAI,IAAmC;;;;AAKnE,SAAgB,qBACd,YAC+B;CAC/B,IAAI,OAAO,eAAe,YAAY;EACpC,MAAM,UAAU,IAAI,8BAA8B;EAClD,OAAO,WAAW,SAAS,SAAS,KAAK;CAC3C;CAEA,IAAI,sBAAsB,+BACxB,OAAO;CAGT,IACE,OAAO,eAAe,YACtB,eAAe,QACf,YAAY,cACZ,OAAO,WAAW,WAAW,YAC7B;EACA,MAAM,OAAQ,WAAuE,OAAO;EAC5F,OAAO,IAAI,8BAA8B,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,eAAe,KAAK,WAAW;CAC/F;CAEA,MAAM,OAAO;CACb,OAAO,IAAI,8BAA8B,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,eAAe,KAAK,WAAW;AAC/F;;;;;;;;;;AAWA,SAAgB,gBACd,OACA,mBACA,iBACA,2BACA,WACM;CACN,MAAM,WAAW;EACf;EACA;EACA;EACA;CACF;CACA,MAAM,gBAAgB,oBAAoB,IAAI,KAAK;CACnD,IAAI,eAAe,cAAc,KAAK,QAAQ;MACzC,oBAAoB,IAAI,OAAO,CAAC,QAAQ,CAAC;AAChD;;AAGA,SAAgB,6BAAmC;CACjD,KAAK,MAAM,CAAC,OAAO,kBAAkB,qBAAqB;EACxD,MAAM,WAAW,cAAc,KAAK,cAAc;GAChD;GACA,QAAQ,qBAAqB,SAAS,eAAe;EACvD,EAAE;EAEF,KAAK,MAAM,EAAE,UAAU,YAAY,UAAU;GAC3C,IAAI,SAAS,2BACX,OAAO,eAAe,OAAO,QAAQ;IACnC,cAAc;IACd,YAAY;IACZ,UAAU;IACV,OAAO,SAAS,YACZ,GAAG,SAAS,kBAAkB,GAAG,SAAS,UAAU,GAAG,OAAO,SAC9D,GAAG,SAAS,kBAAkB,GAAG,OAAO;GAC9C,CAAC;GAGH,yBAAyB,OAAO,SAAS,mBAAmB,QAAQ,SAAS,SAAS;EACxF;EAEA,oBAAoB,OAAO,KAAK;CAClC;AACF;;AAGA,SAAgB,2BAAiC;CAC/C,oBAAoB,MAAM;AAC5B;;;;AAKA,SAAgB,qBAAqB,gBAAgC;CACnE,OAAO,iBAAiB;AAC1B;;;;AAKA,SAAgB,0BAA0B,WAAmB,gBAAgC;CAC3F,OAAO,iBAAiB,UAAU,GAAG;AACvC;;;;AAKA,SAAgB,wBACd,OACA,mBACA,YACS;CAET,yBAAyB,OAAO,mBADP,qBAAqB,UACoB,CAAC;CAEnE,OAAO;AACT;;;;AAKA,SAAgB,6BACd,OACA,mBACA,WACA,YACS;CAET,yBAAyB,OAAO,mBADP,qBAAqB,UACoB,GAAG,SAAS;CAE9E,OAAO;AACT;AAEA,SAAS,yBACP,OACA,mBACA,kBACA,WACM;CACN,MAAM,iBAAiB,iBAAiB;CAIxC,MAAM,QAAqC;EACzC,cAAc;EACd,cAAc;EACd,YANiB,YACf,0BAA0B,WAAW,cAAc,IACnD,qBAAqB,cAAc;CAKvC;CAEA,IAAI,CAAC,WAAW;EAEd,AADiB,oBAAoB,OAAO,yBAAyB,IAAI,WAAW,CAC7E,CAAC,CAAC,IAAI,gBAAgB,KAAK;EAClC;CACF;CAIA,AAFuB,yBAAyB,OAAO,yBAAyB,IAAI,WAAW,CAC5D,CAAC,CAAC,OAAO,iBAAiB,IAAI,WAAW,CAChE,CAAC,CAAC,IAAI,gBAAgB,KAAK;AACzC;;;;;;;;;;AChLA,MAAa,2BAA2B;;;;CAItC,YAAY,OAAgB,SAAqC;EAC/D,MAAM,cAAc,oBAAoB,IAAI,MAAM,OAAO,iBAAiB,MAAM,IAAI;EACpF,IAAI,CAAC,aAAa;GAChB,QAAQ,KACN,+EAA+E,MAAM,OAAO,iBAAiB,MAAM,KAAK,GAC1H;GACA;EACF;EAEA,IAAI,CAAC,SAAS;EAEd,KAAK,MAAM,EAAE,kBAAkB,YAAY,OAAO,GAChD,QAAQ,cAAc,YAAY;CAEtC;;;;CAKA,OAAO,OAAgB,SAAqC;EAC1D,MAAM,SAAS,yBAAyB,IAAI,MAAM,OAAO,iBAAiB,MAAM,IAAI;EACpF,IAAI,CAAC,QAAQ;GACX,QAAQ,KACN,8EAA8E,MAAM,OAAO,iBAAiB,MAAM,KAAK,GACzH;GACA;EACF;EAEA,IAAI,CAAC,SAAS;EAEd,KAAK,MAAM,CAAC,WAAW,aAAa,QAAQ;GAC1C,MAAM,QAAQ,QAAQ,QAAQ,MAAM,WAAW;IAC7C,MAAM,OACJ,YAAY,UAAU,OAAO,OAAO,WAAW,aAAa,OAAO,OAAO,IAAI;IAChF,OAAO,QAAQ,OAAO,SAAS,YAAY,UAAU,QAAQ,KAAK,SAAS;GAC7E,CAAC;GAED,IAAI,CAAC,OAAO,eAAe;GAE3B,KAAK,MAAM,EAAE,kBAAkB,SAAS,OAAO,GAC7C,MAAM,cAAc,YAAY;EAEpC;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1BA,IAAaA,YAAb,cAEUC,QAA0B;CAClC,AAAO,YAAY,SAAyC,UAAmB,CAAC,GAAc;EAC5F,MAAM,SAAS,OAAO;EAEtB,MAAM,4BACJ,UAAU,QAAQ,QAAQ,qBAAqB,8BAA8B;EAE/E,IAAI,KAAK,QAAQ,oBAAoB;GACnC,MAAM,EAAE,mBAAmB,oBAAoB,KAAK,QAAQ;GAC5D,gBAAgB,MAAM,mBAAmB,iBAAiB,yBAAyB;EACrF;EAEA,IAAI,KAAK,QAAQ,2BAA2B;GAC1C,MAAM,EAAE,mBAAmB,WAAW,oBACpC,KAAK,QAAQ;GACf,gBACE,MACA,mBACA,iBACA,2BACA,SACF;EACF;CACF;AACF;;;;;;;;;;;;;;;;;;;;AAiCA,IAAa,aAAb,cAEUA,QAA0B;;;;CAIlC,AAAgB,QAAQ;AAC1B;;;;;;;;;;;;;;;;;;;ACzEA,SAAgB,qBACd,mBACA,iBACA;CACA,OAAO,SAAS,SAAuC,QAAc;EACnE,MAAM,YAAY,cAAc,OAAO;GACrC,AAAO,YAAY,GAAG,MAAa;IACjC,MAAM,CAAC,SAAS,cAAc,CAAC,KAAK;IAIpC,MAAM,SAAS,WAAW;IAC1B,gBACE,MACA,mBACA,iBACA,UAAU,QAAQ,QAAQ,qBAAqB,8BAA8B,IAC/E;GACF;EACF;EAEA,2BAA2B,OAAO,SAA+C;EAEjF,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,0BACd,mBACA,WACA,iBACA;CACA,OAAO,SAAS,SAAuC,QAAc;EACnE,MAAM,YAAY,cAAc,OAAO;GACrC,AAAO,YAAY,GAAG,MAAa;IACjC,MAAM,CAAC,SAAS,cAAc,CAAC,KAAK;IAIpC,MAAM,SAAS,WAAW;IAC1B,gBACE,MACA,mBACA,iBACA,UAAU,QAAQ,QAAQ,qBAAqB,8BAA8B,MAC7E,SACF;GACF;EACF;EAEA,2BAA2B,OAAO,SAA+C;EAEjF,OAAO;CACT;AACF;;;;AClFA,MAAM,+BAAe,IAAI,QAAiB;;;;AAK1C,SAAgB,yBAAyB,YAA6B;CACpE,OAAO,oBAAoB,IAAI,UAAU,KAAK,yBAAyB,IAAI,UAAU;AACvF;;;;;;;;;;;AAYA,SAAgB,sBAAsB,QAAuB;CAC3D,2BAA2B;CAE3B,MAAM,aAAa,OAAO,OAAO;CACjC,IAAI,CAAC,cAAc,CAAC,yBAAyB,UAAU,GAAG;CAC1D,IAAI,aAAa,IAAI,MAAM,GAAG;CAE9B,MAAM,OAAO,OAAO;CAEpB,MAAM,YADW,2BAA2B,IAAI,IACvB,CAAC,EAAE;CAC5B,IAAI,CAAC,WAAW;EACd,QAAQ,KACN,kDAAkD,WAAW,mDAC/D;EACA;CACF;CAEA,MAAM,WAAW,UAAU,OAAO;CAClC,2BAA2B,OAAO,IAAI;CAEtC,MAAM,WAAW,2BAA2B,OAAO,IAAI,CAAC,CAAC,cAAc;CACvE,SAAS,WAAW,gBAAgB,QAAQ,CAAC;CAE7C,KAAK,MAAM,UAAU,SAAS,WAAW,CAAC,GACxC,IAAI,OAAO,SAAS,6BAA6B,iBAAiB;EAChE,SAAS,mBAAmB,4BAA4B,MAAM,GAAG,gBAAgB,MAAM,CAAC;EACxF,KAAK,MAAM,cAAc,OAAO,WAAW,CAAC,GAC1C,SAAS,cAAc,YAAY,gBAAgB,UAAU,GAAG,OAAO,IAAI;CAE/E,OAAO,IAAI,OAAO,SAAS,6BAA6B,YACtD,SAAS,cAAc,QAAQ,gBAAgB,MAAM,CAAC;CAI1D,MAAM,SAAS,oBAAoB,IAAI,UAAU;CACjD,IAAI,QACF,KAAK,MAAM,SAAS,OAAO,OAAO,GAAG;EACnC,gBAAgB,MAAM,YAAY,KAAK;EACvC,SAAS,cAAc,MAAM,cAAc,MAAM,UAAU;CAC7D;CAGF,MAAM,SAAS,yBAAyB,IAAI,UAAU;CACtD,IAAI,QACF,KAAK,MAAM,CAAC,WAAW,aAAa,QAClC,KAAK,MAAM,SAAS,SAAS,OAAO,GAAG;EACrC,gBAAgB,MAAM,YAAY,KAAK;EACvC,SAAS,cAAc,MAAM,cAAc,MAAM,YAAY,SAAS;CACxE;CAIJ,OAAO,eAAe,QAAQ,UAAU;EACtC,OAAO,IAAI,cAAc,MAAM;EAC/B,cAAc;EACd,YAAY;EACZ,UAAU;CACZ,CAAC;CAED,aAAa,IAAI,MAAM;AACzB;AAEA,SAAS,gBAAgB,UAA2D;CAClF,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;CACvC,OAAO;AACT;AAEA,SAAS,4BAA4B,OAAmD;CACtF,MAAM,EAAE,SAAS,UAAU,MAAM,OAAO,GAAG,SAAS;CACpD,OAAO;AACT;;;;;;;AAQA,MAAM,mCAAmC;AAEzC,SAAS,gBAAgB,QAA+B;CACtD,KAAK,MAAM,UAAU,OAAO,sBAAsB,MAAM,GACtD,IAAI,OAAO,gBAAgB,kCACzB,OAAQ,QAAQ,IAAI,QAAQ,MAAM,KAA4B;CAIlE,OAAO;AACT;AAEA,SAAS,gBACP,YACA,YACA,OACM;CACN,MAAM,EAAE,eAAe;CAEvB,OAAO,eAAe,WAAW,WAAW,YAAY;EACtD,cAAc;EACd,YAAY;EACZ,UAAU;EACV,MAAqB,aAAoD,MAAc;GACrF,MAAM,WAAW,YAAY,YAAY,UAAU;GACnD,IAAI,CAAC,UACH,MAAM,IAAI,MACR,0EAA0E,WAAW,YAAY,WAAW,GAC9G;GAEF,OAAO,SAAS,aAAa,aAAa,aAAa,IAAI;EAC7D;CACF,CAAC;AACH;AAEA,SAAS,YACP,YACA,YACyC;CACzC,MAAM,SAAS,oBAAoB,IAAI,UAAU;CACjD,IAAI,QACF;OAAK,MAAM,SAAS,OAAO,OAAO,GAChC,IAAI,MAAM,eAAe,YAAY,OAAO;CAC9C;CAGF,MAAM,SAAS,yBAAyB,IAAI,UAAU;CACtD,IAAI,QACF;OAAK,MAAM,YAAY,OAAO,OAAO,GACnC,KAAK,MAAM,SAAS,SAAS,OAAO,GAClC,IAAI,MAAM,eAAe,YAAY,OAAO;CAEhD;AAIJ;;;;AAKA,SAAgB,4BAAkC;CAChD,yBAAyB;CACzB,oBAAoB,MAAM;CAC1B,yBAAyB,MAAM;AACjC;;;;;;;;;;;;ACpKA,IAAa,oCAAb,cAAuD,sBAAsB;CAC3E,AAAgB,OAAO,OAAqB,OAAgB;EAC1D,2BAA2B;EAE3B,MAAM,aAAa,MAAM,OAAO;EAChC,IAAI,cAAc,yBAAyB,UAAU,GACnD,sBAAsB,KAAK;EAG7B,OAAO,MAAM,OAAO,OAAO,KAAK;CAClC;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wolfstar/plugin-subcommands-advanced",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "Plugin for @wolfstar/http-framework to modularize slash subcommands into separate command classes",
5
5
  "keywords": [
6
6
  "discord",
@@ -53,8 +53,8 @@
53
53
  "discord-api-types": "^0.38.33"
54
54
  },
55
55
  "devDependencies": {
56
- "@wolfstar/http-framework": "^3.1.3",
57
- "@wolfstar/http-framework-test-utils": "^3.0.4"
56
+ "@wolfstar/http-framework": "^3.2.1",
57
+ "@wolfstar/http-framework-test-utils": "^3.0.6"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@wolfstar/http-framework": "^3.1.0"
@@ -1 +0,0 @@
1
- {"version":3,"file":"src-DNdsrn4L.js","names":["Command","FrameworkCommand"],"sources":["../../src/lib/utils/functions.ts","../../src/lib/utils/hooks.ts","../../src/lib/structures/command.ts","../../src/lib/utils/decorators.ts","../../src/lib/utils/wiring.ts","../../src/lib/utils/strategy.ts"],"sourcesContent":["import { SlashCommandSubcommandBuilder } from \"@discordjs/builders\";\nimport { Collection } from \"@discordjs/collection\";\nimport { container, type Command } from \"@wolfstar/http-framework\";\nimport type { SlashSubcommandResolvable, SubcommandMappingCollection } from \"./types.js\";\n\n/**\n * Registry of direct subcommands keyed by parent command name, then subcommand name.\n */\nexport const subCommandsRegistry: Collection<\n string,\n Collection<string, SubcommandMappingCollection>\n> = new Collection();\n\n/**\n * Registry of grouped subcommands keyed by parent → group → subcommand name.\n */\nexport const subCommandsGroupRegistry: Collection<\n string,\n Collection<string, Collection<string, SubcommandMappingCollection>>\n> = new Collection();\n\n/**\n * Normalize slash subcommand input into a builder.\n */\nexport function parseSlashSubcommand(\n subcommand: SlashSubcommandResolvable,\n): SlashCommandSubcommandBuilder {\n if (typeof subcommand === \"function\") {\n const builder = new SlashCommandSubcommandBuilder();\n return subcommand(builder, container) ?? builder;\n }\n\n if (subcommand instanceof SlashCommandSubcommandBuilder) {\n return subcommand;\n }\n\n if (\n typeof subcommand === \"object\" &&\n subcommand !== null &&\n \"toJSON\" in subcommand &&\n typeof subcommand.toJSON === \"function\"\n ) {\n const json = (subcommand as { toJSON: () => { name: string; description: string } }).toJSON();\n return new SlashCommandSubcommandBuilder().setName(json.name).setDescription(json.description);\n }\n\n const data = subcommand as { name: string; description: string };\n return new SlashCommandSubcommandBuilder().setName(data.name).setDescription(data.description);\n}\n\n/**\n * Stable method name linked on the parent command for a direct subcommand.\n */\nexport function subcommandMethodName(subcommandName: string): string {\n return `__wolfstar_sc_${subcommandName}`;\n}\n\n/**\n * Stable method name linked on the parent command for a grouped subcommand.\n */\nexport function subcommandGroupMethodName(groupName: string, subcommandName: string): string {\n return `__wolfstar_sc_${groupName}_${subcommandName}`;\n}\n\n/**\n * Register a command piece as a direct subcommand of `parentCommandName`.\n */\nexport function analyzeSubCommandParsed(\n piece: Command,\n parentCommandName: string,\n subcommand: SlashSubcommandResolvable,\n): Command {\n const subcommandParsed = parseSlashSubcommand(subcommand);\n const subcommandName = subcommandParsed.name;\n const methodName = subcommandMethodName(subcommandName);\n const entry: SubcommandMappingCollection = {\n slashCommand: subcommandParsed,\n commandPiece: piece,\n methodName,\n };\n\n const registry = subCommandsRegistry.ensure(parentCommandName, () => new Collection());\n registry.set(subcommandName, entry);\n\n return piece;\n}\n\n/**\n * Register a command piece as a subcommand inside a group of `parentCommandName`.\n */\nexport function analyzeSubcommandGroupParsed(\n piece: Command,\n parentCommandName: string,\n groupName: string,\n subcommand: SlashSubcommandResolvable,\n): Command {\n const subcommandParsed = parseSlashSubcommand(subcommand);\n const subcommandName = subcommandParsed.name;\n const methodName = subcommandGroupMethodName(groupName, subcommandName);\n const entry: SubcommandMappingCollection = {\n slashCommand: subcommandParsed,\n commandPiece: piece,\n methodName,\n };\n\n const parentRegistry = subCommandsGroupRegistry.ensure(parentCommandName, () => new Collection());\n const groupRegistry = parentRegistry.ensure(groupName, () => new Collection());\n groupRegistry.set(subcommandName, entry);\n\n return piece;\n}\n","import type { SlashCommandBuilder } from \"@discordjs/builders\";\nimport type { Command } from \"@wolfstar/http-framework\";\nimport { subCommandsGroupRegistry, subCommandsRegistry } from \"./functions.js\";\n\n/**\n * Optional hooks for parent commands that register chat-input commands imperatively\n * via {@link Command.registerApplicationCommands}. Prefer relying on the automatic\n * wiring performed by {@link SubcommandsAdvancedLoaderStrategy}; these helpers are\n * useful when you want to inspect or manually attach builders during registration.\n */\nexport const RegisterSubcommandsHooks = {\n /**\n * Attach registered direct subcommands onto a {@link SlashCommandBuilder}.\n */\n subcommands(piece: Command, context?: SlashCommandBuilder): void {\n const subcommands = subCommandsRegistry.get(piece.router.chatInputName ?? piece.name);\n if (!subcommands) {\n console.warn(\n `[plugin-subcommands-advanced]: No direct subcommands registered for parent \"${piece.router.chatInputName ?? piece.name}\".`,\n );\n return;\n }\n\n if (!context) return;\n\n for (const { slashCommand } of subcommands.values()) {\n context.addSubcommand(slashCommand);\n }\n },\n\n /**\n * Attach registered grouped subcommands onto matching groups on a {@link SlashCommandBuilder}.\n */\n groups(piece: Command, context?: SlashCommandBuilder): void {\n const groups = subCommandsGroupRegistry.get(piece.router.chatInputName ?? piece.name);\n if (!groups) {\n console.warn(\n `[plugin-subcommands-advanced]: No subcommand groups registered for parent \"${piece.router.chatInputName ?? piece.name}\".`,\n );\n return;\n }\n\n if (!context) return;\n\n for (const [groupName, commands] of groups) {\n const group = context.options.find((option) => {\n const data =\n \"toJSON\" in option && typeof option.toJSON === \"function\" ? option.toJSON() : null;\n return data && typeof data === \"object\" && \"name\" in data && data.name === groupName;\n }) as { addSubcommand?(subcommand: unknown): unknown } | undefined;\n\n if (!group?.addSubcommand) continue;\n\n for (const { slashCommand } of commands.values()) {\n group.addSubcommand(slashCommand);\n }\n }\n },\n};\n","import { Command as FrameworkCommand, container } from \"@wolfstar/http-framework\";\nimport {\n analyzeSubCommandParsed,\n analyzeSubcommandGroupParsed,\n parseSlashSubcommand,\n} from \"../utils/functions.js\";\nimport { RegisterSubcommandsHooks } from \"../utils/hooks.js\";\nimport type { SubcommandCommandOptions } from \"../utils/types.js\";\n\nexport type AdvancedCommandOptions = FrameworkCommand.Options & SubcommandCommandOptions;\n\n/**\n * Command class that can register itself as a modular subcommand (or grouped subcommand)\n * of a parent {@link Subcommand} / chat-input command.\n *\n * @example\n * ```typescript\n * import { Command } from '@wolfstar/plugin-subcommands-advanced';\n *\n * export class PingCommand extends Command {\n * public constructor(context: Command.LoaderContext, options: Command.Options) {\n * super(context, {\n * ...options,\n * registerSubCommand: {\n * parentCommandName: 'utils',\n * slashSubcommand: (builder) => builder.setName('ping').setDescription('Ping!')\n * }\n * });\n * }\n *\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Pong!' });\n * }\n * }\n * ```\n */\nexport class Command<\n Options extends AdvancedCommandOptions = AdvancedCommandOptions,\n> extends FrameworkCommand<Options> {\n public constructor(context: FrameworkCommand.LoaderContext, options: Options = {} as Options) {\n const nameCommandsAutogenerated =\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true;\n let name = options.name;\n\n if (options.registerSubCommand && nameCommandsAutogenerated) {\n const parsed = parseSlashSubcommand(options.registerSubCommand.slashSubcommand);\n name = `${options.registerSubCommand.parentCommandName}/${parsed.name}`;\n }\n\n if (options.registerSubcommandInGroup && nameCommandsAutogenerated) {\n const parsed = parseSlashSubcommand(options.registerSubcommandInGroup.slashSubcommand);\n name = `${options.registerSubcommandInGroup.parentCommandName}/${options.registerSubcommandInGroup.groupName}/${parsed.name}`;\n }\n\n super(context, { ...options, name } as Options);\n\n if (this.options.registerSubCommand) {\n const { parentCommandName, slashSubcommand } = this.options.registerSubCommand;\n analyzeSubCommandParsed(this, parentCommandName, slashSubcommand);\n }\n\n if (this.options.registerSubcommandInGroup) {\n const { parentCommandName, groupName, slashSubcommand } =\n this.options.registerSubcommandInGroup;\n analyzeSubcommandGroupParsed(this, parentCommandName, groupName, slashSubcommand);\n }\n }\n}\n\nexport namespace Command {\n export type Options = AdvancedCommandOptions;\n export type JSON = FrameworkCommand.JSON;\n /** @deprecated Use {@linkcode LoaderContext} instead. */\n export type Context = LoaderContext;\n export type LoaderContext = FrameworkCommand.LoaderContext;\n export type ChatInputInteraction = FrameworkCommand.ChatInputInteraction;\n export type AutocompleteInteraction = FrameworkCommand.AutocompleteInteraction;\n export type ApplicationCommandInteraction = FrameworkCommand.ApplicationCommandInteraction;\n export type Registry = FrameworkCommand.Registry;\n}\n\n/**\n * Parent command marker. Extend this for the chat-input command that owns modular\n * subcommands. Wiring of children is performed automatically by the plugin loader\n * strategy after all pieces are constructed.\n *\n * @example\n * ```typescript\n * import { RegisterCommand } from '@wolfstar/http-framework';\n * import { Subcommand } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterCommand((builder) =>\n * builder\n * .setName('utils')\n * .setDescription('Utility commands')\n * .addSubcommandGroup((group) => group.setName('poll').setDescription('Polls'))\n * )\n * export class UtilsCommand extends Subcommand {}\n * ```\n */\nexport class Subcommand<\n Options extends FrameworkCommand.Options = FrameworkCommand.Options,\n> extends FrameworkCommand<Options> {\n /**\n * Optional hooks for imperative {@link registerApplicationCommands} usage.\n */\n public readonly hooks = RegisterSubcommandsHooks;\n}\n\nexport namespace Subcommand {\n export type Options = FrameworkCommand.Options;\n export type JSON = FrameworkCommand.JSON;\n /** @deprecated Use {@linkcode LoaderContext} instead. */\n export type Context = LoaderContext;\n export type LoaderContext = FrameworkCommand.LoaderContext;\n export type ChatInputInteraction = FrameworkCommand.ChatInputInteraction;\n export type AutocompleteInteraction = FrameworkCommand.AutocompleteInteraction;\n export type ApplicationCommandInteraction = FrameworkCommand.ApplicationCommandInteraction;\n export type Registry = FrameworkCommand.Registry;\n}\n","import {\n applicationCommandRegistry,\n type Command as FrameworkCommand,\n container,\n} from \"@wolfstar/http-framework\";\nimport {\n analyzeSubCommandParsed,\n analyzeSubcommandGroupParsed,\n parseSlashSubcommand,\n} from \"./functions.js\";\nimport type { SlashSubcommandResolvable } from \"./types.js\";\n\ntype CommandConstructor = new (...args: any[]) => FrameworkCommand;\n\n/**\n * Class decorator that registers the decorated command as a direct subcommand of `parentCommandName`.\n *\n * @example\n * ```typescript\n * import { Command, RegisterAsSubcommand } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterAsSubcommand('utils', (builder) => builder.setName('ping').setDescription('Ping!'))\n * export class PingCommand extends Command {\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Pong!' });\n * }\n * }\n * ```\n */\nexport function RegisterAsSubcommand(\n parentCommandName: string,\n slashSubcommand: SlashSubcommandResolvable,\n) {\n return function decorate<T extends CommandConstructor>(target: T): T {\n const decorated = class extends target {\n public constructor(...args: any[]) {\n const [context, baseOptions = {}] = args as [\n FrameworkCommand.LoaderContext,\n FrameworkCommand.Options,\n ];\n const parsed = parseSlashSubcommand(slashSubcommand);\n const name =\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true\n ? `${parentCommandName}/${parsed.name}`\n : baseOptions.name;\n\n super(context, { ...baseOptions, name });\n analyzeSubCommandParsed(this, parentCommandName, slashSubcommand);\n }\n } as T;\n\n applicationCommandRegistry.ensure(decorated as unknown as typeof FrameworkCommand);\n\n return decorated;\n };\n}\n\n/**\n * Class decorator that registers the decorated command as a subcommand inside a group.\n *\n * @example\n * ```typescript\n * import { Command, RegisterAsSubcommandGroup } from '@wolfstar/plugin-subcommands-advanced';\n *\n * @RegisterAsSubcommandGroup('utils', 'poll', (builder) =>\n * builder.setName('create').setDescription('Create a poll')\n * )\n * export class PollCreateCommand extends Command {\n * public override chatInputRun(interaction: Command.ChatInputInteraction) {\n * return interaction.reply({ content: 'Created!' });\n * }\n * }\n * ```\n */\nexport function RegisterAsSubcommandGroup(\n parentCommandName: string,\n groupName: string,\n slashSubcommand: SlashSubcommandResolvable,\n) {\n return function decorate<T extends CommandConstructor>(target: T): T {\n const decorated = class extends target {\n public constructor(...args: any[]) {\n const [context, baseOptions = {}] = args as [\n FrameworkCommand.LoaderContext,\n FrameworkCommand.Options,\n ];\n const parsed = parseSlashSubcommand(slashSubcommand);\n const name =\n container.client?.options.subcommandsAdvanced?.nameCommandsAutogenerated === true\n ? `${parentCommandName}/${groupName}/${parsed.name}`\n : baseOptions.name;\n\n super(context, { ...baseOptions, name });\n analyzeSubcommandGroupParsed(this, parentCommandName, groupName, slashSubcommand);\n }\n } as T;\n\n applicationCommandRegistry.ensure(decorated as unknown as typeof FrameworkCommand);\n\n return decorated;\n };\n}\n","import { applicationCommandRegistry, CommandRouter, type Command } from \"@wolfstar/http-framework\";\nimport {\n ApplicationCommandOptionType,\n type APIApplicationCommandSubcommandGroupOption,\n type RESTPostAPIChatInputApplicationCommandsJSONBody,\n} from \"discord-api-types/v10\";\nimport { subCommandsGroupRegistry, subCommandsRegistry } from \"./functions.js\";\nimport type { SubcommandMappingCollection } from \"./types.js\";\n\nconst wiredParents = new WeakSet<Command>();\n\n/**\n * Whether this piece is a parent that has registered modular subcommands.\n */\nexport function hasRegisteredSubcommands(parentName: string): boolean {\n return subCommandsRegistry.has(parentName) || subCommandsGroupRegistry.has(parentName);\n}\n\n/**\n * Install delegate methods on the parent and rebuild its chat-input resolver + router\n * so modular child command classes handle each subcommand.\n *\n * Must run after every command piece has been constructed (e.g. from\n * {@link CommandLoaderStrategy.onLoad}), so the registries contain every child.\n *\n * Delegates are installed on the parent **prototype** so reconstructed instances\n * (Store `loadAll` rebuilds pieces) still satisfy {@link CommandRouter}'s method checks.\n */\nexport function wireParentSubcommands(parent: Command): void {\n const parentName = parent.router.chatInputName;\n if (!parentName || !hasRegisteredSubcommands(parentName)) return;\n if (wiredParents.has(parent)) return;\n\n const ctor = parent.constructor as typeof Command;\n const existing = applicationCommandRegistry.get(ctor);\n const chatInput = existing?.chatInput;\n if (!chatInput) {\n console.warn(\n `[plugin-subcommands-advanced]: Parent command \"${parentName}\" has no chat-input registration; skipping wiring.`,\n );\n return;\n }\n\n const snapshot = chatInput.toJSON();\n applicationCommandRegistry.delete(ctor);\n\n const resolver = applicationCommandRegistry.ensure(ctor).makeChatInput();\n resolver.setCommand(baseCommandData(snapshot));\n\n for (const option of snapshot.options ?? []) {\n if (option.type === ApplicationCommandOptionType.SubcommandGroup) {\n resolver.addSubcommandGroup(groupDataWithoutSubcommands(option), getLinkedMethod(option));\n for (const subcommand of option.options ?? []) {\n resolver.addSubcommand(subcommand, getLinkedMethod(subcommand), option.name);\n }\n } else if (option.type === ApplicationCommandOptionType.Subcommand) {\n resolver.addSubcommand(option, getLinkedMethod(option));\n }\n }\n\n const direct = subCommandsRegistry.get(parentName);\n if (direct) {\n for (const entry of direct.values()) {\n installDelegate(ctor, parentName, entry);\n resolver.addSubcommand(entry.slashCommand, entry.methodName);\n }\n }\n\n const groups = subCommandsGroupRegistry.get(parentName);\n if (groups) {\n for (const [groupName, commands] of groups) {\n for (const entry of commands.values()) {\n installDelegate(ctor, parentName, entry);\n resolver.addSubcommand(entry.slashCommand, entry.methodName, groupName);\n }\n }\n }\n\n Object.defineProperty(parent, \"router\", {\n value: new CommandRouter(parent),\n configurable: true,\n enumerable: true,\n writable: false,\n });\n\n wiredParents.add(parent);\n}\n\nfunction baseCommandData(snapshot: RESTPostAPIChatInputApplicationCommandsJSONBody) {\n const { options: _options, ...rest } = snapshot;\n return rest;\n}\n\nfunction groupDataWithoutSubcommands(group: APIApplicationCommandSubcommandGroupOption) {\n const { options: _options, type: _type, ...rest } = group;\n return rest;\n}\n\n/**\n * `http-framework` links a subcommand (or group) option to its handler method by\n * defining a non-enumerable symbol property on the resolved option object. The\n * symbol is not exported, so it is recovered here by its description to preserve\n * framework-native subcommand routing when the resolver is rebuilt.\n */\nconst LINKED_METHOD_SYMBOL_DESCRIPTION = \"decorated-command.method.link\";\n\nfunction getLinkedMethod(option: object): string | null {\n for (const symbol of Object.getOwnPropertySymbols(option)) {\n if (symbol.description === LINKED_METHOD_SYMBOL_DESCRIPTION) {\n return (Reflect.get(option, symbol) as string | undefined) ?? null;\n }\n }\n\n return null;\n}\n\nfunction installDelegate(\n parentCtor: typeof Command,\n parentName: string,\n entry: SubcommandMappingCollection,\n): void {\n const { methodName } = entry;\n\n Object.defineProperty(parentCtor.prototype, methodName, {\n configurable: true,\n enumerable: false,\n writable: true,\n value(this: Command, interaction: Command.ApplicationCommandInteraction, args: object) {\n const resolved = lookupEntry(parentName, methodName);\n if (!resolved) {\n throw new Error(\n `[plugin-subcommands-advanced]: No child command registered for parent \"${parentName}\" method \"${methodName}\".`,\n );\n }\n return resolved.commandPiece.chatInputRun(interaction, args);\n },\n });\n}\n\nfunction lookupEntry(\n parentName: string,\n methodName: string,\n): SubcommandMappingCollection | undefined {\n const direct = subCommandsRegistry.get(parentName);\n if (direct) {\n for (const entry of direct.values()) {\n if (entry.methodName === methodName) return entry;\n }\n }\n\n const groups = subCommandsGroupRegistry.get(parentName);\n if (groups) {\n for (const commands of groups.values()) {\n for (const entry of commands.values()) {\n if (entry.methodName === methodName) return entry;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Reset subcommand registries (useful between tests).\n */\nexport function clearSubcommandRegistries(): void {\n subCommandsRegistry.clear();\n subCommandsGroupRegistry.clear();\n}\n","import { CommandLoaderStrategy, type Command, type CommandStore } from \"@wolfstar/http-framework\";\nimport { hasRegisteredSubcommands, wireParentSubcommands } from \"./wiring.js\";\n\n/**\n * Loader strategy that wires modular subcommands onto parent commands before\n * chat-input mappings are published to {@link CommandStore.router}.\n *\n * {@link CommandStore.loadAll} constructs every piece first (children populate the\n * registries), then inserts them — {@link onLoad} therefore sees a complete registry.\n */\nexport class SubcommandsAdvancedLoaderStrategy extends CommandLoaderStrategy {\n public override onLoad(store: CommandStore, piece: Command) {\n const parentName = piece.router.chatInputName;\n if (parentName && hasRegisteredSubcommands(parentName)) {\n wireParentSubcommands(piece);\n }\n\n return super.onLoad(store, piece);\n }\n}\n"],"mappings":"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"}