@hyperneutrino/djs-lite 1.3.0 → 1.4.1
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/index.ts +51 -81
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ApplicationCommandOptionType,
|
|
2
3
|
ApplicationCommandType,
|
|
3
4
|
AutocompleteInteraction,
|
|
4
5
|
ButtonInteraction,
|
|
@@ -56,12 +57,12 @@ abstract class Command<T extends BaseApplicationCommandData, U extends CommandIn
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
export class SlashCommand extends Command<ChatInputApplicationCommandData
|
|
60
|
-
export class UserCommand extends Command<UserApplicationCommandData, UserContextMenuCommandInteraction> {}
|
|
61
|
-
export class MessageCommand extends Command<MessageApplicationCommandData, MessageContextMenuCommandInteraction> {}
|
|
60
|
+
export class SlashCommand extends Command<Omit<ChatInputApplicationCommandData, "type">, ChatInputCommandInteraction, true> {}
|
|
61
|
+
export class UserCommand extends Command<Omit<UserApplicationCommandData, "type">, UserContextMenuCommandInteraction> {}
|
|
62
|
+
export class MessageCommand extends Command<Omit<MessageApplicationCommandData, "type">, MessageContextMenuCommandInteraction> {}
|
|
62
63
|
|
|
63
64
|
export class SlashCommandWithSubcommands {
|
|
64
|
-
data: Omit<ChatInputApplicationCommandData, "options"
|
|
65
|
+
data: Omit<ChatInputApplicationCommandData, "options" | "type">;
|
|
65
66
|
|
|
66
67
|
constructor(data: typeof this.data) {
|
|
67
68
|
this.data = data;
|
|
@@ -69,7 +70,7 @@ export class SlashCommandWithSubcommands {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
export class SubcommandGroup {
|
|
72
|
-
data: Omit<ApplicationCommandSubGroupData, "options">;
|
|
73
|
+
data: Omit<ApplicationCommandSubGroupData, "options" | "type">;
|
|
73
74
|
|
|
74
75
|
constructor(data: typeof this.data) {
|
|
75
76
|
this.data = data;
|
|
@@ -77,7 +78,7 @@ export class SubcommandGroup {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
export class Subcommand {
|
|
80
|
-
data: ApplicationCommandSubCommandData
|
|
81
|
+
data: Omit<ApplicationCommandSubCommandData, "type">;
|
|
81
82
|
handler: Handler<ChatInputCommandInteraction>;
|
|
82
83
|
|
|
83
84
|
constructor({ handler, ...data }: typeof this.data & { handler: Subcommand["handler"] }) {
|
|
@@ -123,7 +124,7 @@ async function importAll(
|
|
|
123
124
|
if (file.isDirectory()) return;
|
|
124
125
|
|
|
125
126
|
const absolutePath = path.resolve(file.parentPath, file.name);
|
|
126
|
-
const relativePath = path.relative(path.resolve(directory), absolutePath);
|
|
127
|
+
const relativePath = path.join(directory, path.relative(path.resolve(directory), absolutePath));
|
|
127
128
|
|
|
128
129
|
const { default: item } = await import(absolutePath);
|
|
129
130
|
|
|
@@ -143,7 +144,7 @@ export async function loadSubcommands(directory: string): Promise<{
|
|
|
143
144
|
|
|
144
145
|
await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
|
|
145
146
|
if (item instanceof Subcommand) {
|
|
146
|
-
options.push(item.data);
|
|
147
|
+
options.push({ ...item.data, type: ApplicationCommandOptionType.Subcommand });
|
|
147
148
|
handlers.set(item.data.name, item.handler);
|
|
148
149
|
} else throw new Error(`Loading commands failed: export from ${relativePath} (third-level in commands folder) was not an instance of Subcommand.`);
|
|
149
150
|
|
|
@@ -158,18 +159,18 @@ export async function loadSubcommandsAndGroups(directory: string): Promise<{
|
|
|
158
159
|
options: (ApplicationCommandSubGroupData | ApplicationCommandSubCommandData)[];
|
|
159
160
|
handler: Handler<ChatInputCommandInteraction>;
|
|
160
161
|
}> {
|
|
161
|
-
if (!(await fs.exists(directory))) throw new Error(`Loading
|
|
162
|
+
if (!(await fs.exists(directory))) throw new Error(`Loading subcommands/groups failed: ${directory} is required but could not be found.`);
|
|
162
163
|
|
|
163
164
|
const options: (ApplicationCommandSubGroupData | ApplicationCommandSubCommandData)[] = [];
|
|
164
165
|
const handlers = new Map<string, Handler<ChatInputCommandInteraction>>();
|
|
165
166
|
|
|
166
167
|
await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
|
|
167
168
|
if (item instanceof Subcommand) {
|
|
168
|
-
options.push(item.data);
|
|
169
|
+
options.push({ ...item.data, type: ApplicationCommandOptionType.Subcommand });
|
|
169
170
|
handlers.set(`/${item.data.name}`, item.handler);
|
|
170
171
|
} else if (item instanceof SubcommandGroup) {
|
|
171
172
|
const subcommands = await loadSubcommands(relativePath.replace(/\.[^/.]+$/, ""));
|
|
172
|
-
options.push({ ...item.data, options: subcommands.options });
|
|
173
|
+
options.push({ ...item.data, type: ApplicationCommandOptionType.SubcommandGroup, options: subcommands.options });
|
|
173
174
|
subcommands.handlers.entries().forEach(([key, handler]) => handlers.set(`${item.data.name}/${key}`, handler));
|
|
174
175
|
} else
|
|
175
176
|
throw new Error(
|
|
@@ -187,8 +188,6 @@ export async function loadSubcommandsAndGroups(directory: string): Promise<{
|
|
|
187
188
|
}
|
|
188
189
|
|
|
189
190
|
export async function loadCommands(client: Client<true>, directory: string, guildId?: string) {
|
|
190
|
-
const files = await fs.readdir(path.resolve(directory), { recursive: false, withFileTypes: true });
|
|
191
|
-
|
|
192
191
|
const commandData: (ChatInputApplicationCommandData | UserApplicationCommandData | MessageApplicationCommandData)[] = [];
|
|
193
192
|
|
|
194
193
|
const slashCommandHandlers = new Map<string, Handler<ChatInputCommandInteraction>>();
|
|
@@ -197,36 +196,28 @@ export async function loadCommands(client: Client<true>, directory: string, guil
|
|
|
197
196
|
|
|
198
197
|
const slashCommandAutocompletes = new Map<string, Handler<AutocompleteInteraction>>();
|
|
199
198
|
|
|
200
|
-
await
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
199
|
+
await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
|
|
200
|
+
if (item instanceof SlashCommand) {
|
|
201
|
+
commandData.push({ ...item.data, type: ApplicationCommandType.ChatInput });
|
|
202
|
+
slashCommandHandlers.set(item.data.name, item.handler);
|
|
203
|
+
if (item.autocomplete) slashCommandAutocompletes.set(item.data.name, item.autocomplete);
|
|
204
|
+
} else if (item instanceof UserCommand) {
|
|
205
|
+
commandData.push({ ...item.data, type: ApplicationCommandType.User });
|
|
206
|
+
userCommandHandlers.set(item.data.name, item.handler);
|
|
207
|
+
} else if (item instanceof MessageCommand) {
|
|
208
|
+
commandData.push({ ...item.data, type: ApplicationCommandType.Message });
|
|
209
|
+
messageCommandHandlers.set(item.data.name, item.handler);
|
|
210
|
+
} else if (item instanceof SlashCommandWithSubcommands) {
|
|
211
|
+
const { options, handler } = await loadSubcommandsAndGroups(relativePath.replace(/\.[^/.]+$/, ""));
|
|
212
|
+
commandData.push({ ...item.data, options });
|
|
213
|
+
slashCommandHandlers.set(item.data.name, handler);
|
|
214
|
+
} else {
|
|
215
|
+
throw new Error(`Loading commands failed: export from ${relativePath} was not an instance of <Type>Command.`);
|
|
216
|
+
}
|
|
208
217
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
} else if (item instanceof UserCommand) {
|
|
213
|
-
userCommandHandlers.set(item.data.name, item.handler);
|
|
214
|
-
} else if (item instanceof MessageCommand) {
|
|
215
|
-
messageCommandHandlers.set(item.data.name, item.handler);
|
|
216
|
-
} else if (item instanceof SlashCommandWithSubcommands) {
|
|
217
|
-
const { options, handler } = await loadSubcommandsAndGroups(relativePath.replace(/\.[^/.]+$/, ""));
|
|
218
|
-
commandData.push({ ...item.data, options });
|
|
219
|
-
slashCommandHandlers.set(item.data.name, handler);
|
|
220
|
-
} else {
|
|
221
|
-
throw new Error(`Loading commands failed: export from ${relativePath} was not an instance of <Type>Command.`);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (item.data.name !== file.name.replace(/.[^/.]+$/, ""))
|
|
225
|
-
throw new Error(`Code style enforcement: name exported from ${relativePath} does not match the filename`);
|
|
226
|
-
|
|
227
|
-
commandData.push(item.data);
|
|
228
|
-
}),
|
|
229
|
-
);
|
|
218
|
+
if (item.data.name !== file.name.replace(/.[^/.]+$/, ""))
|
|
219
|
+
throw new Error(`Code style enforcement: name exported from ${relativePath} does not match the filename`);
|
|
220
|
+
});
|
|
230
221
|
|
|
231
222
|
client.on(Events.InteractionCreate, (interaction) => {
|
|
232
223
|
if (interaction.isChatInputCommand()) slashCommandHandlers.get(interaction.commandName)?.(interaction);
|
|
@@ -246,8 +237,6 @@ export async function loadCommands(client: Client<true>, directory: string, guil
|
|
|
246
237
|
}
|
|
247
238
|
|
|
248
239
|
export async function loadInteractions(client: Client, directory: string, argumentSeparator: string = ":") {
|
|
249
|
-
const files = await fs.readdir(path.resolve(directory), { recursive: true, withFileTypes: true });
|
|
250
|
-
|
|
251
240
|
const modalHandlers = new Map<string, Handler<ModalSubmitInteraction>>();
|
|
252
241
|
const buttonHandlers = new Map<string, Handler<ButtonInteraction>>();
|
|
253
242
|
const stringHandlers = new Map<string, Handler<StringSelectMenuInteraction>>();
|
|
@@ -256,26 +245,18 @@ export async function loadInteractions(client: Client, directory: string, argume
|
|
|
256
245
|
const mentionHandlers = new Map<string, Handler<MentionableSelectMenuInteraction>>();
|
|
257
246
|
const channelHandlers = new Map<string, Handler<ChannelSelectMenuInteraction>>();
|
|
258
247
|
|
|
259
|
-
await
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
else if (item instanceof StringSelectHandler) stringHandlers.set(handlerKey, item.handler);
|
|
272
|
-
else if (item instanceof UserSelectHandler) userHandlers.set(handlerKey, item.handler);
|
|
273
|
-
else if (item instanceof RoleSelectHandler) roleHandlers.set(handlerKey, item.handler);
|
|
274
|
-
else if (item instanceof MentionSelectHandler) mentionHandlers.set(handlerKey, item.handler);
|
|
275
|
-
else if (item instanceof ChannelSelectHandler) channelHandlers.set(handlerKey, item.handler);
|
|
276
|
-
else throw new Error(`Loading interactions failed: export from ${relativePath} was not an instance of <InteractionType>Handler.`);
|
|
277
|
-
}),
|
|
278
|
-
);
|
|
248
|
+
await importAll({ directory, recursive: true }, async ({ file, relativePath, item }) => {
|
|
249
|
+
const handlerKey = relativePath.replace(/\.[^/.]+$/, "").replace(/\\/g, "/");
|
|
250
|
+
|
|
251
|
+
if (item instanceof ModalHandler) modalHandlers.set(handlerKey, item.handler);
|
|
252
|
+
else if (item instanceof ButtonHandler) buttonHandlers.set(handlerKey, item.handler);
|
|
253
|
+
else if (item instanceof StringSelectHandler) stringHandlers.set(handlerKey, item.handler);
|
|
254
|
+
else if (item instanceof UserSelectHandler) userHandlers.set(handlerKey, item.handler);
|
|
255
|
+
else if (item instanceof RoleSelectHandler) roleHandlers.set(handlerKey, item.handler);
|
|
256
|
+
else if (item instanceof MentionSelectHandler) mentionHandlers.set(handlerKey, item.handler);
|
|
257
|
+
else if (item instanceof ChannelSelectHandler) channelHandlers.set(handlerKey, item.handler);
|
|
258
|
+
else throw new Error(`Loading interactions failed: export from ${relativePath} was not an instance of <InteractionType>Handler.`);
|
|
259
|
+
});
|
|
279
260
|
|
|
280
261
|
client.on(Events.InteractionCreate, (interaction) => {
|
|
281
262
|
if (!interaction.isMessageComponent() && !interaction.isModalSubmit()) return;
|
|
@@ -294,25 +275,14 @@ export async function loadInteractions(client: Client, directory: string, argume
|
|
|
294
275
|
}
|
|
295
276
|
|
|
296
277
|
export async function loadEvents(client: Client, directory: string, recursive: boolean = false) {
|
|
297
|
-
const files = await fs.readdir(path.resolve(directory), { recursive, withFileTypes: true });
|
|
298
278
|
const handlers: Partial<{ [K in keyof ClientEvents]: ((...args: ClientEvents[K]) => unknown)[] }> = {};
|
|
299
279
|
|
|
300
|
-
await
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const { default: item } = await import(absolutePath);
|
|
307
|
-
|
|
308
|
-
if (item instanceof EventHandler) (handlers[item.event as keyof ClientEvents] ??= []).push(item.handler);
|
|
309
|
-
else {
|
|
310
|
-
throw new Error(
|
|
311
|
-
`Loading events failed: export from ${path.relative(path.resolve(directory), absolutePath)} was not an instance of EventHandler<T>.`,
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
}),
|
|
315
|
-
);
|
|
280
|
+
await importAll({ directory, recursive }, async ({ relativePath, item }) => {
|
|
281
|
+
if (item instanceof EventHandler) (handlers[item.event as keyof ClientEvents] ??= []).push(item.handler);
|
|
282
|
+
else {
|
|
283
|
+
throw new Error(`Loading events failed: export from ${relativePath} was not an instance of EventHandler<T>.`);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
316
286
|
|
|
317
287
|
Object.entries(handlers).forEach(([key, handlers]) => client.on(key, (...args) => handlers.forEach((handler) => (handler as any)(...args))));
|
|
318
288
|
}
|