@hyperneutrino/djs-lite 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/index.ts +45 -5
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  ApplicationCommandType,
3
+ AutocompleteInteraction,
3
4
  Client,
4
5
  CommandInteraction,
5
6
  Events,
@@ -7,6 +8,7 @@ import {
7
8
  type BaseApplicationCommandData,
8
9
  type ChatInputApplicationCommandData,
9
10
  type ChatInputCommandInteraction,
11
+ type ClientEvents,
10
12
  type MessageApplicationCommandData,
11
13
  type MessageContextMenuCommandInteraction,
12
14
  type UserApplicationCommandData,
@@ -17,22 +19,41 @@ import path from "node:path";
17
19
 
18
20
  process.on("uncaughtException", (err) => console.error(err));
19
21
 
20
- type Handler<T extends CommandInteraction> = (interaction: T) => Awaitable<unknown>;
22
+ type Handler<T extends CommandInteraction | AutocompleteInteraction> = (interaction: T) => Awaitable<unknown>;
21
23
 
22
- class Command<T extends BaseApplicationCommandData, U extends CommandInteraction> {
24
+ class Command<T extends BaseApplicationCommandData, U extends CommandInteraction, Z extends boolean = false> {
23
25
  data: T;
24
26
  handler: Handler<U>;
27
+ autocomplete: Handler<AutocompleteInteraction> | null;
28
+
29
+ constructor({ handler, ...data }: T & { handler: Handler<U> } & (Z extends true ? { autocomplete?: Handler<AutocompleteInteraction> } : {})) {
30
+ if ("autocomplete" in data) {
31
+ const { autocomplete, ...rest } = data;
32
+ this.autocomplete = autocomplete as Handler<AutocompleteInteraction>;
33
+ this.data = rest as unknown as T;
34
+ } else {
35
+ this.autocomplete = null;
36
+ this.data = data as unknown as T;
37
+ }
25
38
 
26
- constructor({ handler, ...data }: T & { handler: Handler<U> }) {
27
- this.data = data as unknown as T;
28
39
  this.handler = handler;
29
40
  }
30
41
  }
31
42
 
32
- export class SlashCommand extends Command<ChatInputApplicationCommandData & { type: ApplicationCommandType.ChatInput }, ChatInputCommandInteraction> {}
43
+ export class SlashCommand extends Command<ChatInputApplicationCommandData & { type: ApplicationCommandType.ChatInput }, ChatInputCommandInteraction, true> {}
33
44
  export class UserCommand extends Command<UserApplicationCommandData, UserContextMenuCommandInteraction> {}
34
45
  export class MessageCommand extends Command<MessageApplicationCommandData, MessageContextMenuCommandInteraction> {}
35
46
 
47
+ export class EventHandler<T extends keyof ClientEvents> {
48
+ event: T;
49
+ handler: (...args: ClientEvents[T]) => unknown;
50
+
51
+ constructor({ event, handler }: { event: T; handler: (...args: ClientEvents[T]) => unknown }) {
52
+ this.event = event;
53
+ this.handler = handler;
54
+ }
55
+ }
56
+
36
57
  export async function loadCommands(client: Client<true>, directory: string) {
37
58
  const files = await fs.readdir(path.resolve(directory), { recursive: false, withFileTypes: true });
38
59
 
@@ -42,6 +63,8 @@ export async function loadCommands(client: Client<true>, directory: string) {
42
63
  const userCommandHandlers = new Map<string, Handler<UserContextMenuCommandInteraction>>();
43
64
  const messageCommandHandlers = new Map<string, Handler<MessageContextMenuCommandInteraction>>();
44
65
 
66
+ const slashCommandAutocompletes = new Map<string, Handler<AutocompleteInteraction>>();
67
+
45
68
  await Promise.all(
46
69
  files.map(async (file) => {
47
70
  const { default: item } = await import(path.resolve(file.parentPath, file.name));
@@ -49,6 +72,7 @@ export async function loadCommands(client: Client<true>, directory: string) {
49
72
  if (item instanceof SlashCommand) {
50
73
  commandData.push(item.data);
51
74
  slashCommandHandlers.set(item.data.name, item.handler);
75
+ if (item.autocomplete) slashCommandAutocompletes.set(item.data.name, item.autocomplete);
52
76
  } else if (item instanceof UserCommand) {
53
77
  commandData.push(item.data);
54
78
  userCommandHandlers.set(item.data.name, item.handler);
@@ -67,6 +91,7 @@ export async function loadCommands(client: Client<true>, directory: string) {
67
91
  if (interaction.isChatInputCommand()) slashCommandHandlers.get(interaction.commandName)?.(interaction);
68
92
  else if (interaction.isUserContextMenuCommand()) userCommandHandlers.get(interaction.commandName)?.(interaction);
69
93
  else if (interaction.isMessageContextMenuCommand()) messageCommandHandlers.get(interaction.commandName)?.(interaction);
94
+ else if (interaction.isAutocomplete()) slashCommandAutocompletes.get(interaction.commandName)?.(interaction);
70
95
  });
71
96
  }
72
97
 
@@ -97,3 +122,18 @@ export async function loadInteractions(client: Client<true>, directory: string,
97
122
  handlers.get(path)?.(interaction, ...args);
98
123
  });
99
124
  }
125
+
126
+ export async function loadEvents(client: Client<true>, directory: string, recursive: boolean = false) {
127
+ const files = await fs.readdir(path.resolve(directory), { recursive, withFileTypes: true });
128
+ const handlers: Partial<{ [K in keyof ClientEvents]: ((...args: ClientEvents[K]) => unknown)[] }> = {};
129
+
130
+ await Promise.all(
131
+ files.map(async (file) => {
132
+ if (file.isDirectory()) return;
133
+ const { default: item } = await import(path.resolve(file.parentPath, file.name));
134
+ if (item instanceof EventHandler) (handlers[item.event as keyof ClientEvents] ??= []).push(item.handler);
135
+ }),
136
+ );
137
+
138
+ Object.entries(handlers).forEach(([key, handlers]) => client.on(key, (...args) => handlers.forEach((handler) => (handler as any)(...args))));
139
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hyperneutrino/djs-lite",
3
3
  "private": false,
4
- "version": "1.0.0",
4
+ "version": "1.0.2",
5
5
  "module": "index.ts",
6
6
  "type": "module",
7
7
  "devDependencies": {