@@ -15,16 +15,107 @@ export function makePlugin<V extends unknown[]>(
15
15
export function EventInitPlugin ( execute : ( args : InitArgs ) => PluginResult ) {
16
16
return makePlugin ( PluginType . Init , execute ) ;
17
17
}
18
+
18
19
/**
20
+ * Creates an initialization plugin for command preprocessing and modification
21
+ *
19
22
* @since 2.5.0
23
+ * @template I - Extends CommandType to enforce type safety for command modules
24
+ *
25
+ * @param {function } execute - Function to execute during command initialization
26
+ * @param {InitArgs<T> } execute.args - The initialization arguments
27
+ * @param {T } execute.args.module - The command module being initialized
28
+ * @param {string } execute.args.absPath - The absolute path to the module file
29
+ * @param {Dependencies } execute.args.deps - Dependency injection container
30
+ *
31
+ * @returns {Plugin } A plugin that runs during command initialization
32
+ *
33
+ * @example
34
+ * // Plugin to update command description
35
+ * export const updateDescription = (description: string) => {
36
+ * return CommandInitPlugin(({ deps }) => {
37
+ * if(description.length > 100) {
38
+ * deps.logger?.info({ message: "Invalid description" })
39
+ * return controller.stop("From updateDescription: description is invalid");
40
+ * }
41
+ * module.description = description;
42
+ * return controller.next();
43
+ * });
44
+ * };
45
+ *
46
+ * @example
47
+ * // Plugin to store registration date in module locals
48
+ * export const dateRegistered = () => {
49
+ * return CommandInitPlugin(({ module }) => {
50
+ * module.locals.registered = Date.now()
51
+ * return controller.next();
52
+ * });
53
+ * };
54
+ *
55
+ * @remarks
56
+ * - Init plugins can modify how commands are loaded and perform preprocessing
57
+ * - The module.locals object can be used to store custom plugin-specific data
58
+ * - Be careful when modifying module fields as multiple plugins may interact with them
59
+ * - Use controller.next() to continue to the next plugin
60
+ * - Use controller.stop(reason) to halt plugin execution
20
61
*/
21
62
export function CommandInitPlugin < I extends CommandType > (
22
63
execute : ( args : InitArgs ) => PluginResult
23
- ) {
64
+ ) : Plugin {
24
65
return makePlugin ( PluginType . Init , execute ) ;
25
66
}
67
+
26
68
/**
69
+ * Creates a control plugin for command preprocessing, filtering, and state management
70
+ *
27
71
* @since 2.5.0
72
+ * @template I - Extends CommandType to enforce type safety for command modules
73
+ *
74
+ * @param {function } execute - Function to execute during command control flow
75
+ * @param {CommandArgs<I> } execute.args - The command arguments array
76
+ * @param {Context } execute.args[0] - The discord context (e.g., guild, channel, user info, interaction)
77
+ * @param {SDT } execute.args[1] - The State, Dependencies, Params, Module, and Type object
78
+ *
79
+ * @returns {Plugin } A plugin that runs during command execution flow
80
+ *
81
+ * @example
82
+ * // Plugin to restrict command to specific guild
83
+ * export const inGuild = (guildId: string) => {
84
+ * return CommandControlPlugin((ctx, sdt) => {
85
+ * if(ctx.guild.id !== guildId) {
86
+ * return controller.stop();
87
+ * }
88
+ * return controller.next();
89
+ * });
90
+ * };
91
+ *
92
+ * @example
93
+ * // Plugins passing state through the chain
94
+ * const plugin1 = CommandControlPlugin((ctx, sdt) => {
95
+ * return controller.next({ 'plugin1/data': 'from plugin1' });
96
+ * });
97
+ *
98
+ * const plugin2 = CommandControlPlugin((ctx, sdt) => {
99
+ * return controller.next({ 'plugin2/data': ctx.user.id });
100
+ * });
101
+ *
102
+ * export default commandModule({
103
+ * type: CommandType.Slash,
104
+ * plugins: [plugin1, plugin2],
105
+ * execute: (ctx, sdt) => {
106
+ * console.log(sdt.state); // Access accumulated state
107
+ * }
108
+ * });
109
+ *
110
+ * @remarks
111
+ * - Control plugins are executed in order when a discord.js event is emitted
112
+ * - Use controller.next() to continue to next plugin or controller.stop() to halt execution
113
+ * - State can be passed between plugins using controller.next({ key: value })
114
+ * - State keys should be namespaced to avoid collisions (e.g., 'plugin-name/key')
115
+ * - Final accumulated state is passed to the command's execute function
116
+ * - All plugins must succeed for the command to execute
117
+ * - Plugins have access to dependencies through the sdt.deps object
118
+ * - Useful for implementing preconditions, filters, and command preprocessing
28
119
*/
29
120
export function CommandControlPlugin < I extends CommandType > (
30
121
execute : ( ...args : CommandArgs < I > ) => PluginResult ,
0 commit comments