@spatulox/discord-module 0.2.0 → 0.2.2

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
@@ -16,6 +16,8 @@ Turn your Discord bot into independent modules that can be enabled or disabled a
16
16
 
17
17
  🔄 Hot reload : Enable/Disable problematic modules without restarting the bot !
18
18
 
19
+ ✅ Automatic Interactions Binding (name <-> function/method) : No more mess between interactions detection, dispatch and function/method call
20
+
19
21
  Discordjs : Always up to date and completely compatible
20
22
 
21
23
  ## 🎮 Usage (2 minutes)
@@ -44,6 +46,10 @@ Turn your Discord bot into independent modules that can be enabled or disabled a
44
46
  async handleMessageUpdate2(message: Message) {
45
47
  message.reply("Update 2 !")
46
48
  }
49
+
50
+ static async pong_interaction(interaction: ChatInputCommandInteraction){
51
+ interaction.reply("pong !)
52
+ }
47
53
 
48
54
  }
49
55
  ```
@@ -51,9 +57,13 @@ Turn your Discord bot into independent modules that can be enabled or disabled a
51
57
  ```ts
52
58
  client.once(Events.ClientReady, () => {
53
59
  const manager = ModuleManager.createInstance(client); // ModuleManager is a singleton
60
+ const interactionManager = InteractionManager.createInstance(client); // ModuleManager is a singleton
54
61
  manager.register(new PongModule(client)); // You can register a Module or a MultiModule (Menu for Module)
55
62
  manager.enableAll(); // By default, a Module is disable
56
63
  manager.sendUIToChannel("channelID") // Optionnal, only if you want to dynamically toggle modules
64
+
65
+ // Register commands
66
+ interactionManager.registerSlash("ping", PongModule.pong_interaction)
57
67
  });
58
68
  ```
59
69
 
@@ -61,4 +71,5 @@ client.once(Events.ClientReady, () => {
61
71
  |---------------------|------------------|---------------|
62
72
  | Hidden client.on | ❌ | ✅ |
63
73
  | Live module enabled | ❌ (Need restart) | ✅ (One click) |
64
- | Organised | ❌ | ✅ |
74
+ | Organised | ❌ | ✅ |
75
+ | Automatic interaction binding | ❌ | ✅ |
package/dist/index.d.mts CHANGED
@@ -65,4 +65,40 @@ declare class ModuleManager {
65
65
  updateMultiModuleUI(interaction: ButtonInteraction, module: Module): void;
66
66
  }
67
67
 
68
- export { Module, type ModuleEventsMap, ModuleManager, MultiModule };
68
+ declare enum InteractionType {
69
+ AUTOCOMPLETE = "AUTOCOMPLETE",
70
+ BUTTON = "BUTTON",
71
+ MESSAGE_CONTEXT_MENU = "MESSAGE_CONTEXT_MENU",
72
+ USER_CONTEXT_MENU = "USER_CONTEXT_MENU",
73
+ MODAL = "MODAL",
74
+ PRIMARY_ENTRY_POINT = "PRIMARY_ENTRY_POINT",
75
+ SELECT_MENU = "SELECT_MENU",
76
+ SLASH = "SLASH"
77
+ }
78
+ type InteractionHandler = (...args: any[]) => any;
79
+ declare class InteractionsManager {
80
+ private interactionMap;
81
+ private client;
82
+ private static instance;
83
+ private constructor();
84
+ static createInstance(client: Client): InteractionsManager;
85
+ private initClient;
86
+ private getInteractionInfo;
87
+ private handle;
88
+ register(type: InteractionType, interaction: {
89
+ name: string;
90
+ func: InteractionHandler;
91
+ }): boolean;
92
+ private createMap;
93
+ private _register;
94
+ registerAutocomplete(name: string, func: (...args: any[]) => any): boolean;
95
+ registerButton(name: string, func: (...args: any[]) => any): boolean;
96
+ registerMessageContextMenus(name: string, func: (...args: any[]) => any): boolean;
97
+ registerUserContextMenus(name: string, func: (...args: any[]) => any): boolean;
98
+ registerModal(name: string, func: (...args: any[]) => any): boolean;
99
+ registerPrimaryEntryPoint(name: string, func: (...args: any[]) => any): boolean;
100
+ registerSelectMenu(name: string, func: (...args: any[]) => any): boolean;
101
+ registerSlash(name: string, func: (...args: any[]) => any): boolean;
102
+ }
103
+
104
+ export { InteractionType, InteractionsManager, Module, type ModuleEventsMap, ModuleManager, MultiModule };
package/dist/index.d.ts CHANGED
@@ -65,4 +65,40 @@ declare class ModuleManager {
65
65
  updateMultiModuleUI(interaction: ButtonInteraction, module: Module): void;
66
66
  }
67
67
 
68
- export { Module, type ModuleEventsMap, ModuleManager, MultiModule };
68
+ declare enum InteractionType {
69
+ AUTOCOMPLETE = "AUTOCOMPLETE",
70
+ BUTTON = "BUTTON",
71
+ MESSAGE_CONTEXT_MENU = "MESSAGE_CONTEXT_MENU",
72
+ USER_CONTEXT_MENU = "USER_CONTEXT_MENU",
73
+ MODAL = "MODAL",
74
+ PRIMARY_ENTRY_POINT = "PRIMARY_ENTRY_POINT",
75
+ SELECT_MENU = "SELECT_MENU",
76
+ SLASH = "SLASH"
77
+ }
78
+ type InteractionHandler = (...args: any[]) => any;
79
+ declare class InteractionsManager {
80
+ private interactionMap;
81
+ private client;
82
+ private static instance;
83
+ private constructor();
84
+ static createInstance(client: Client): InteractionsManager;
85
+ private initClient;
86
+ private getInteractionInfo;
87
+ private handle;
88
+ register(type: InteractionType, interaction: {
89
+ name: string;
90
+ func: InteractionHandler;
91
+ }): boolean;
92
+ private createMap;
93
+ private _register;
94
+ registerAutocomplete(name: string, func: (...args: any[]) => any): boolean;
95
+ registerButton(name: string, func: (...args: any[]) => any): boolean;
96
+ registerMessageContextMenus(name: string, func: (...args: any[]) => any): boolean;
97
+ registerUserContextMenus(name: string, func: (...args: any[]) => any): boolean;
98
+ registerModal(name: string, func: (...args: any[]) => any): boolean;
99
+ registerPrimaryEntryPoint(name: string, func: (...args: any[]) => any): boolean;
100
+ registerSelectMenu(name: string, func: (...args: any[]) => any): boolean;
101
+ registerSlash(name: string, func: (...args: any[]) => any): boolean;
102
+ }
103
+
104
+ export { InteractionType, InteractionsManager, Module, type ModuleEventsMap, ModuleManager, MultiModule };
package/dist/index.js CHANGED
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ InteractionType: () => InteractionType,
24
+ InteractionsManager: () => InteractionsManager,
23
25
  Module: () => Module,
24
26
  ModuleManager: () => ModuleManager,
25
27
  MultiModule: () => MultiModule
@@ -295,8 +297,123 @@ var MultiModule = class extends Module {
295
297
  return Object.values(this.manager.modules).flat().some((m) => m.enabled);
296
298
  }
297
299
  };
300
+
301
+ // src/code/InteractionsManager.ts
302
+ var import_discord4 = require("discord.js");
303
+ var InteractionType = /* @__PURE__ */ ((InteractionType2) => {
304
+ InteractionType2["AUTOCOMPLETE"] = "AUTOCOMPLETE";
305
+ InteractionType2["BUTTON"] = "BUTTON";
306
+ InteractionType2["MESSAGE_CONTEXT_MENU"] = "MESSAGE_CONTEXT_MENU";
307
+ InteractionType2["USER_CONTEXT_MENU"] = "USER_CONTEXT_MENU";
308
+ InteractionType2["MODAL"] = "MODAL";
309
+ InteractionType2["PRIMARY_ENTRY_POINT"] = "PRIMARY_ENTRY_POINT";
310
+ InteractionType2["SELECT_MENU"] = "SELECT_MENU";
311
+ InteractionType2["SLASH"] = "SLASH";
312
+ return InteractionType2;
313
+ })(InteractionType || {});
314
+ var InteractionsManager = class _InteractionsManager {
315
+ interactionMap = {
316
+ ["AUTOCOMPLETE" /* AUTOCOMPLETE */]: {},
317
+ ["BUTTON" /* BUTTON */]: {},
318
+ ["MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */]: {},
319
+ ["USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */]: {},
320
+ ["MODAL" /* MODAL */]: {},
321
+ ["PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */]: {},
322
+ ["SELECT_MENU" /* SELECT_MENU */]: {},
323
+ ["SLASH" /* SLASH */]: {}
324
+ };
325
+ client;
326
+ static instance;
327
+ constructor(client) {
328
+ this.client = client;
329
+ this.initClient(this.client);
330
+ }
331
+ static createInstance(client) {
332
+ _InteractionsManager.instance = new _InteractionsManager(client);
333
+ return _InteractionsManager.instance;
334
+ }
335
+ initClient(client) {
336
+ client.on(import_discord4.Events.InteractionCreate, async (interaction) => {
337
+ const info = this.getInteractionInfo(interaction);
338
+ if (!info) throw new Error("Interaction info not found");
339
+ const { type, identifier } = info;
340
+ const map = this.interactionMap[type];
341
+ if (map) {
342
+ await this.handle(map, identifier, interaction);
343
+ }
344
+ });
345
+ }
346
+ getInteractionInfo(interaction) {
347
+ if (interaction.isCommand()) {
348
+ if (interaction.isChatInputCommand()) return { type: "SLASH" /* SLASH */, identifier: interaction.commandName };
349
+ if (interaction.isContextMenuCommand()) {
350
+ if (interaction.isMessageContextMenuCommand()) return { type: "MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */, identifier: interaction.commandName };
351
+ if (interaction.isUserContextMenuCommand()) return { type: "USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */, identifier: interaction.commandName };
352
+ }
353
+ if (interaction.isPrimaryEntryPointCommand()) return { type: "PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */, identifier: interaction.commandName };
354
+ return void 0;
355
+ }
356
+ if (interaction.isMessageComponent()) {
357
+ if (interaction.isButton()) return { type: "BUTTON" /* BUTTON */, identifier: interaction.customId };
358
+ if (interaction.isStringSelectMenu()) return { type: "SELECT_MENU" /* SELECT_MENU */, identifier: interaction.customId };
359
+ return void 0;
360
+ }
361
+ if (interaction.isModalSubmit()) return { type: "MODAL" /* MODAL */, identifier: interaction.customId };
362
+ if (interaction.isAutocomplete()) return { type: "AUTOCOMPLETE" /* AUTOCOMPLETE */, identifier: interaction.commandName };
363
+ return void 0;
364
+ }
365
+ async handle(interactionMap, name, interaction) {
366
+ const handler = interactionMap[name];
367
+ if (!handler) {
368
+ throw new Error(`No handler registered for "${name}"`);
369
+ }
370
+ await handler(interaction);
371
+ }
372
+ register(type, interaction) {
373
+ return this._register(type, { key: interaction.name, value: interaction.func });
374
+ }
375
+ createMap(name, func) {
376
+ return {
377
+ key: name,
378
+ value: func
379
+ };
380
+ }
381
+ _register(type, interaction) {
382
+ if (Object.hasOwn(this.interactionMap[type], interaction.key)) {
383
+ throw new Error(`Duplicate entry when registering ${type}`);
384
+ }
385
+ this.interactionMap[type][interaction.key] = interaction.value;
386
+ return true;
387
+ }
388
+ registerAutocomplete(name, func) {
389
+ return this._register("AUTOCOMPLETE" /* AUTOCOMPLETE */, this.createMap(name, func));
390
+ }
391
+ registerButton(name, func) {
392
+ return this._register("BUTTON" /* BUTTON */, this.createMap(name, func));
393
+ }
394
+ registerMessageContextMenus(name, func) {
395
+ return this._register("MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */, this.createMap(name, func));
396
+ }
397
+ registerUserContextMenus(name, func) {
398
+ return this._register("USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */, this.createMap(name, func));
399
+ }
400
+ registerModal(name, func) {
401
+ return this._register("MODAL" /* MODAL */, this.createMap(name, func));
402
+ }
403
+ registerPrimaryEntryPoint(name, func) {
404
+ return this._register("PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */, this.createMap(name, func));
405
+ }
406
+ registerSelectMenu(name, func) {
407
+ return this._register("SELECT_MENU" /* SELECT_MENU */, this.createMap(name, func));
408
+ }
409
+ registerSlash(name, func) {
410
+ return this._register("SLASH" /* SLASH */, this.createMap(name, func));
411
+ }
412
+ };
298
413
  // Annotate the CommonJS export names for ESM import in node:
299
414
  0 && (module.exports = {
415
+ InteractionType,
416
+ InteractionsManager,
300
417
  Module,
301
418
  ModuleManager,
302
419
  MultiModule
package/dist/index.mjs CHANGED
@@ -286,7 +286,122 @@ var MultiModule = class extends Module {
286
286
  return Object.values(this.manager.modules).flat().some((m) => m.enabled);
287
287
  }
288
288
  };
289
+
290
+ // src/code/InteractionsManager.ts
291
+ import { Events as Events2 } from "discord.js";
292
+ var InteractionType = /* @__PURE__ */ ((InteractionType2) => {
293
+ InteractionType2["AUTOCOMPLETE"] = "AUTOCOMPLETE";
294
+ InteractionType2["BUTTON"] = "BUTTON";
295
+ InteractionType2["MESSAGE_CONTEXT_MENU"] = "MESSAGE_CONTEXT_MENU";
296
+ InteractionType2["USER_CONTEXT_MENU"] = "USER_CONTEXT_MENU";
297
+ InteractionType2["MODAL"] = "MODAL";
298
+ InteractionType2["PRIMARY_ENTRY_POINT"] = "PRIMARY_ENTRY_POINT";
299
+ InteractionType2["SELECT_MENU"] = "SELECT_MENU";
300
+ InteractionType2["SLASH"] = "SLASH";
301
+ return InteractionType2;
302
+ })(InteractionType || {});
303
+ var InteractionsManager = class _InteractionsManager {
304
+ interactionMap = {
305
+ ["AUTOCOMPLETE" /* AUTOCOMPLETE */]: {},
306
+ ["BUTTON" /* BUTTON */]: {},
307
+ ["MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */]: {},
308
+ ["USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */]: {},
309
+ ["MODAL" /* MODAL */]: {},
310
+ ["PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */]: {},
311
+ ["SELECT_MENU" /* SELECT_MENU */]: {},
312
+ ["SLASH" /* SLASH */]: {}
313
+ };
314
+ client;
315
+ static instance;
316
+ constructor(client) {
317
+ this.client = client;
318
+ this.initClient(this.client);
319
+ }
320
+ static createInstance(client) {
321
+ _InteractionsManager.instance = new _InteractionsManager(client);
322
+ return _InteractionsManager.instance;
323
+ }
324
+ initClient(client) {
325
+ client.on(Events2.InteractionCreate, async (interaction) => {
326
+ const info = this.getInteractionInfo(interaction);
327
+ if (!info) throw new Error("Interaction info not found");
328
+ const { type, identifier } = info;
329
+ const map = this.interactionMap[type];
330
+ if (map) {
331
+ await this.handle(map, identifier, interaction);
332
+ }
333
+ });
334
+ }
335
+ getInteractionInfo(interaction) {
336
+ if (interaction.isCommand()) {
337
+ if (interaction.isChatInputCommand()) return { type: "SLASH" /* SLASH */, identifier: interaction.commandName };
338
+ if (interaction.isContextMenuCommand()) {
339
+ if (interaction.isMessageContextMenuCommand()) return { type: "MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */, identifier: interaction.commandName };
340
+ if (interaction.isUserContextMenuCommand()) return { type: "USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */, identifier: interaction.commandName };
341
+ }
342
+ if (interaction.isPrimaryEntryPointCommand()) return { type: "PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */, identifier: interaction.commandName };
343
+ return void 0;
344
+ }
345
+ if (interaction.isMessageComponent()) {
346
+ if (interaction.isButton()) return { type: "BUTTON" /* BUTTON */, identifier: interaction.customId };
347
+ if (interaction.isStringSelectMenu()) return { type: "SELECT_MENU" /* SELECT_MENU */, identifier: interaction.customId };
348
+ return void 0;
349
+ }
350
+ if (interaction.isModalSubmit()) return { type: "MODAL" /* MODAL */, identifier: interaction.customId };
351
+ if (interaction.isAutocomplete()) return { type: "AUTOCOMPLETE" /* AUTOCOMPLETE */, identifier: interaction.commandName };
352
+ return void 0;
353
+ }
354
+ async handle(interactionMap, name, interaction) {
355
+ const handler = interactionMap[name];
356
+ if (!handler) {
357
+ throw new Error(`No handler registered for "${name}"`);
358
+ }
359
+ await handler(interaction);
360
+ }
361
+ register(type, interaction) {
362
+ return this._register(type, { key: interaction.name, value: interaction.func });
363
+ }
364
+ createMap(name, func) {
365
+ return {
366
+ key: name,
367
+ value: func
368
+ };
369
+ }
370
+ _register(type, interaction) {
371
+ if (Object.hasOwn(this.interactionMap[type], interaction.key)) {
372
+ throw new Error(`Duplicate entry when registering ${type}`);
373
+ }
374
+ this.interactionMap[type][interaction.key] = interaction.value;
375
+ return true;
376
+ }
377
+ registerAutocomplete(name, func) {
378
+ return this._register("AUTOCOMPLETE" /* AUTOCOMPLETE */, this.createMap(name, func));
379
+ }
380
+ registerButton(name, func) {
381
+ return this._register("BUTTON" /* BUTTON */, this.createMap(name, func));
382
+ }
383
+ registerMessageContextMenus(name, func) {
384
+ return this._register("MESSAGE_CONTEXT_MENU" /* MESSAGE_CONTEXT_MENU */, this.createMap(name, func));
385
+ }
386
+ registerUserContextMenus(name, func) {
387
+ return this._register("USER_CONTEXT_MENU" /* USER_CONTEXT_MENU */, this.createMap(name, func));
388
+ }
389
+ registerModal(name, func) {
390
+ return this._register("MODAL" /* MODAL */, this.createMap(name, func));
391
+ }
392
+ registerPrimaryEntryPoint(name, func) {
393
+ return this._register("PRIMARY_ENTRY_POINT" /* PRIMARY_ENTRY_POINT */, this.createMap(name, func));
394
+ }
395
+ registerSelectMenu(name, func) {
396
+ return this._register("SELECT_MENU" /* SELECT_MENU */, this.createMap(name, func));
397
+ }
398
+ registerSlash(name, func) {
399
+ return this._register("SLASH" /* SLASH */, this.createMap(name, func));
400
+ }
401
+ };
289
402
  export {
403
+ InteractionType,
404
+ InteractionsManager,
290
405
  Module,
291
406
  ModuleManager,
292
407
  MultiModule
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spatulox/discord-module",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Automatic Module Manager for Discordjs",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {