@hyperneutrino/djs-lite 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.ts +78 -34
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -31,6 +31,10 @@ import path from "node:path";
31
31
 
32
32
  process.on("uncaughtException", (err) => console.error(err));
33
33
 
34
+ const identity = <T>(value: T): T => value;
35
+
36
+ type Wrapper<T extends Function> = (fn: T) => T;
37
+
34
38
  type Handler<T extends CommandInteraction | AutocompleteInteraction | MessageComponentInteraction | ModalSubmitInteraction> = (
35
39
  interaction: T,
36
40
  ...args: T extends MessageComponentInteraction | ModalSubmitInteraction ? (string | undefined)[] : []
@@ -95,11 +99,11 @@ abstract class ComponentHandler<T extends ModalSubmitInteraction | MessageCompon
95
99
 
96
100
  export class ModalHandler extends ComponentHandler<ModalSubmitInteraction> {}
97
101
  export class ButtonHandler extends ComponentHandler<ButtonInteraction> {}
98
- export class StringSelectHandler extends ComponentHandler<StringSelectMenuInteraction> {}
99
- export class UserSelectHandler extends ComponentHandler<UserSelectMenuInteraction> {}
100
- export class RoleSelectHandler extends ComponentHandler<RoleSelectMenuInteraction> {}
101
- export class MentionSelectHandler extends ComponentHandler<MentionableSelectMenuInteraction> {}
102
- export class ChannelSelectHandler extends ComponentHandler<ChannelSelectMenuInteraction> {}
102
+ export class StringSelectMenuHandler extends ComponentHandler<StringSelectMenuInteraction> {}
103
+ export class UserSelectMenuHandler extends ComponentHandler<UserSelectMenuInteraction> {}
104
+ export class RoleSelectMenuHandler extends ComponentHandler<RoleSelectMenuInteraction> {}
105
+ export class MentionableSelectMenuHandler extends ComponentHandler<MentionableSelectMenuInteraction> {}
106
+ export class ChannelSelectMenuHandler extends ComponentHandler<ChannelSelectMenuInteraction> {}
103
107
 
104
108
  export class EventHandler<T extends keyof ClientEvents> {
105
109
  event: T;
@@ -186,7 +190,19 @@ async function loadSubcommandsAndGroups(directory: string): Promise<{
186
190
  };
187
191
  }
188
192
 
189
- export async function loadCommands(client: Client<true>, directory: string, guildId?: string) {
193
+ export async function loadCommands(
194
+ client: Client<true>,
195
+ directory: string,
196
+ config?: {
197
+ guildId?: string;
198
+ wrappers?: {
199
+ slashCommands?: Wrapper<Handler<ChatInputCommandInteraction>>;
200
+ userCommands?: Wrapper<Handler<UserContextMenuCommandInteraction>>;
201
+ messageCommands?: Wrapper<Handler<MessageContextMenuCommandInteraction>>;
202
+ autocompletes?: Wrapper<Handler<AutocompleteInteraction>>;
203
+ };
204
+ },
205
+ ) {
190
206
  const commandData: (ChatInputApplicationCommandData | UserApplicationCommandData | MessageApplicationCommandData)[] = [];
191
207
 
192
208
  const slashCommandHandlers = new Map<string, Handler<ChatInputCommandInteraction>>();
@@ -198,18 +214,18 @@ export async function loadCommands(client: Client<true>, directory: string, guil
198
214
  await importAll({ directory, recursive: false }, async ({ file, absolutePath, relativePath, item }) => {
199
215
  if (item instanceof SlashCommand) {
200
216
  commandData.push({ ...item.data, type: ApplicationCommandType.ChatInput });
201
- slashCommandHandlers.set(item.data.name, item.handler);
202
- if (item.autocomplete) slashCommandAutocompletes.set(item.data.name, item.autocomplete);
217
+ slashCommandHandlers.set(item.data.name, (config?.wrappers?.slashCommands ?? identity)(item.handler));
218
+ if (item.autocomplete) slashCommandAutocompletes.set(item.data.name, (config?.wrappers?.autocompletes ?? identity)(item.autocomplete));
203
219
  } else if (item instanceof UserCommand) {
204
220
  commandData.push({ ...item.data, type: ApplicationCommandType.User });
205
- userCommandHandlers.set(item.data.name, item.handler);
221
+ userCommandHandlers.set(item.data.name, (config?.wrappers?.userCommands ?? identity)(item.handler));
206
222
  } else if (item instanceof MessageCommand) {
207
223
  commandData.push({ ...item.data, type: ApplicationCommandType.Message });
208
- messageCommandHandlers.set(item.data.name, item.handler);
224
+ messageCommandHandlers.set(item.data.name, (config?.wrappers?.messageCommands ?? identity)(item.handler));
209
225
  } else if (item instanceof SlashCommandWithSubcommands) {
210
226
  const { options, handler } = await loadSubcommandsAndGroups(relativePath.replace(/\.[^/.]+$/, ""));
211
227
  commandData.push({ ...item.data, options });
212
- slashCommandHandlers.set(item.data.name, handler);
228
+ slashCommandHandlers.set(item.data.name, (config?.wrappers?.slashCommands ?? identity)(handler));
213
229
  } else {
214
230
  throw new Error(`Loading commands failed: export from ${absolutePath} was not an instance of <Type>Command.`);
215
231
  }
@@ -235,10 +251,12 @@ export async function loadCommands(client: Client<true>, directory: string, guil
235
251
  await fs.mkdir(".cache", { recursive: true }).catch(() => null);
236
252
  await fs.writeFile(".cache/command-data.json", JSON.stringify(commandData)).catch(() => null);
237
253
 
238
- if (guildId) {
239
- const testGuild = client.guilds.resolve(guildId);
254
+ if (config?.guildId) {
255
+ const testGuild = client.guilds.resolve(config.guildId);
240
256
  if (!testGuild)
241
- throw new Error(`Provided test guild (${guildId}) can not be found, please make sure the bot you started this project on is in this guild.`);
257
+ throw new Error(
258
+ `Provided test guild (${config.guildId}) can not be found, please make sure the bot you started this project on is in this guild.`,
259
+ );
242
260
  await testGuild.commands.set(commandData);
243
261
  } else {
244
262
  await client.application.commands.set(commandData);
@@ -248,14 +266,29 @@ export async function loadCommands(client: Client<true>, directory: string, guil
248
266
  return { commands: commandData, slashCommandHandlers, userCommandHandlers, messageCommandHandlers, setCommands: commandDataHasBeenUpdated };
249
267
  }
250
268
 
251
- export async function loadInteractions(client: Client, directory: string, argumentSeparator: string = ":") {
269
+ export async function loadInteractions(
270
+ client: Client,
271
+ directory: string,
272
+ config?: {
273
+ argumentSeparator?: string;
274
+ wrappers?: {
275
+ modal?: Wrapper<Handler<ModalSubmitInteraction>>;
276
+ button?: Wrapper<Handler<ButtonInteraction>>;
277
+ stringSelectMenu?: Wrapper<Handler<StringSelectMenuInteraction>>;
278
+ userSelectMenu?: Wrapper<Handler<UserSelectMenuInteraction>>;
279
+ roleSelectMenu?: Wrapper<Handler<RoleSelectMenuInteraction>>;
280
+ mentionableSelectMenu?: Wrapper<Handler<MentionableSelectMenuInteraction>>;
281
+ channelSelectMenu?: Wrapper<Handler<ChannelSelectMenuInteraction>>;
282
+ };
283
+ },
284
+ ) {
252
285
  const modalHandlers = new Map<string, Handler<ModalSubmitInteraction>>();
253
286
  const buttonHandlers = new Map<string, Handler<ButtonInteraction>>();
254
- const stringSelectHandlers = new Map<string, Handler<StringSelectMenuInteraction>>();
255
- const userSelectHandlers = new Map<string, Handler<UserSelectMenuInteraction>>();
256
- const roleSelectHandlers = new Map<string, Handler<RoleSelectMenuInteraction>>();
257
- const mentionSelectHandlers = new Map<string, Handler<MentionableSelectMenuInteraction>>();
258
- const channelSelectHandlers = new Map<string, Handler<ChannelSelectMenuInteraction>>();
287
+ const stringSelectMenuHandlers = new Map<string, Handler<StringSelectMenuInteraction>>();
288
+ const userSelectMenuHandlers = new Map<string, Handler<UserSelectMenuInteraction>>();
289
+ const roleSelectMenuHandlers = new Map<string, Handler<RoleSelectMenuInteraction>>();
290
+ const mentionableSelectMenuHandlers = new Map<string, Handler<MentionableSelectMenuInteraction>>();
291
+ const channelSelectMenuHandlers = new Map<string, Handler<ChannelSelectMenuInteraction>>();
259
292
 
260
293
  await importAll({ directory, recursive: true }, async ({ absolutePath, item }) => {
261
294
  const handlerKey = path
@@ -263,32 +296,43 @@ export async function loadInteractions(client: Client, directory: string, argume
263
296
  .replace(/\.[^/.]+$/, "")
264
297
  .replace(/\\/g, "/");
265
298
 
266
- if (item instanceof ModalHandler) modalHandlers.set(handlerKey, item.handler);
267
- else if (item instanceof ButtonHandler) buttonHandlers.set(handlerKey, item.handler);
268
- else if (item instanceof StringSelectHandler) stringSelectHandlers.set(handlerKey, item.handler);
269
- else if (item instanceof UserSelectHandler) userSelectHandlers.set(handlerKey, item.handler);
270
- else if (item instanceof RoleSelectHandler) roleSelectHandlers.set(handlerKey, item.handler);
271
- else if (item instanceof MentionSelectHandler) mentionSelectHandlers.set(handlerKey, item.handler);
272
- else if (item instanceof ChannelSelectHandler) channelSelectHandlers.set(handlerKey, item.handler);
299
+ if (item instanceof ModalHandler) modalHandlers.set(handlerKey, (config?.wrappers?.modal ?? identity)(item.handler));
300
+ else if (item instanceof ButtonHandler) buttonHandlers.set(handlerKey, (config?.wrappers?.button ?? identity)(item.handler));
301
+ else if (item instanceof StringSelectMenuHandler)
302
+ stringSelectMenuHandlers.set(handlerKey, (config?.wrappers?.stringSelectMenu ?? identity)(item.handler));
303
+ else if (item instanceof UserSelectMenuHandler) userSelectMenuHandlers.set(handlerKey, (config?.wrappers?.userSelectMenu ?? identity)(item.handler));
304
+ else if (item instanceof RoleSelectMenuHandler) roleSelectMenuHandlers.set(handlerKey, (config?.wrappers?.roleSelectMenu ?? identity)(item.handler));
305
+ else if (item instanceof MentionableSelectMenuHandler)
306
+ mentionableSelectMenuHandlers.set(handlerKey, (config?.wrappers?.mentionableSelectMenu ?? identity)(item.handler));
307
+ else if (item instanceof ChannelSelectMenuHandler)
308
+ channelSelectMenuHandlers.set(handlerKey, (config?.wrappers?.channelSelectMenu ?? identity)(item.handler));
273
309
  else throw new Error(`Loading interactions failed: export from ${absolutePath} was not an instance of <InteractionType>Handler.`);
274
310
  });
275
311
 
276
312
  client.on(Events.InteractionCreate, (interaction) => {
277
313
  if (!interaction.isMessageComponent() && !interaction.isModalSubmit()) return;
278
314
 
279
- const [, userId, path, ...args] = interaction.customId.split(argumentSeparator);
315
+ const [, userId, path, ...args] = interaction.customId.split(config?.argumentSeparator ?? ":");
280
316
  if (!path || (userId && interaction.user.id !== userId)) return;
281
317
 
282
318
  if (interaction.isModalSubmit()) modalHandlers.get(path)?.(interaction, ...args);
283
319
  else if (interaction.isButton()) buttonHandlers.get(path)?.(interaction, ...args);
284
- else if (interaction.isStringSelectMenu()) stringSelectHandlers.get(path)?.(interaction, ...args);
285
- else if (interaction.isUserSelectMenu()) userSelectHandlers.get(path)?.(interaction, ...args);
286
- else if (interaction.isRoleSelectMenu()) roleSelectHandlers.get(path)?.(interaction, ...args);
287
- else if (interaction.isMentionableSelectMenu()) mentionSelectHandlers.get(path)?.(interaction, ...args);
288
- else if (interaction.isChannelSelectMenu()) channelSelectHandlers.get(path)?.(interaction, ...args);
320
+ else if (interaction.isStringSelectMenu()) stringSelectMenuHandlers.get(path)?.(interaction, ...args);
321
+ else if (interaction.isUserSelectMenu()) userSelectMenuHandlers.get(path)?.(interaction, ...args);
322
+ else if (interaction.isRoleSelectMenu()) roleSelectMenuHandlers.get(path)?.(interaction, ...args);
323
+ else if (interaction.isMentionableSelectMenu()) mentionableSelectMenuHandlers.get(path)?.(interaction, ...args);
324
+ else if (interaction.isChannelSelectMenu()) channelSelectMenuHandlers.get(path)?.(interaction, ...args);
289
325
  });
290
326
 
291
- return { modalHandlers, buttonHandlers, stringSelectHandlers, userSelectHandlers, roleSelectHandlers, mentionSelectHandlers, channelSelectHandlers };
327
+ return {
328
+ modalHandlers,
329
+ buttonHandlers,
330
+ stringSelectHandlers: stringSelectMenuHandlers,
331
+ userSelectHandlers: userSelectMenuHandlers,
332
+ roleSelectHandlers: roleSelectMenuHandlers,
333
+ mentionSelectHandlers: mentionableSelectMenuHandlers,
334
+ channelSelectHandlers: channelSelectMenuHandlers,
335
+ };
292
336
  }
293
337
 
294
338
  export async function loadEvents(client: Client, directory: string, recursive: boolean = false) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hyperneutrino/djs-lite",
3
3
  "private": false,
4
- "version": "1.5.1",
4
+ "version": "1.6.0",
5
5
  "module": "index.ts",
6
6
  "type": "module",
7
7
  "devDependencies": {