djs-builder 0.4.85 → 0.5.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 (66) hide show
  1. package/.tsbuildinfo +1 -1
  2. package/dist/discord/events-handler/eventLoader.d.ts +7 -0
  3. package/dist/discord/events-handler/eventLoader.d.ts.map +1 -0
  4. package/dist/discord/events-handler/eventLoader.js +144 -0
  5. package/dist/discord/events-handler/eventLoader.js.map +1 -0
  6. package/dist/discord/events-handler/events.d.ts +5 -0
  7. package/dist/discord/events-handler/events.d.ts.map +1 -1
  8. package/dist/discord/events-handler/events.js +11 -7
  9. package/dist/discord/events-handler/events.js.map +1 -1
  10. package/dist/discord/events-handler/login.d.ts.map +1 -1
  11. package/dist/discord/events-handler/login.js +6 -1
  12. package/dist/discord/events-handler/login.js.map +1 -1
  13. package/dist/discord/events-handler/prefix-register.d.ts.map +1 -1
  14. package/dist/discord/events-handler/prefix-register.js +5 -4
  15. package/dist/discord/events-handler/prefix-register.js.map +1 -1
  16. package/dist/discord/events-handler/prefix-responder.d.ts +2 -1
  17. package/dist/discord/events-handler/prefix-responder.d.ts.map +1 -1
  18. package/dist/discord/events-handler/prefix-responder.js +21 -11
  19. package/dist/discord/events-handler/prefix-responder.js.map +1 -1
  20. package/dist/discord/events-handler/prefixLoader.d.ts +5 -1
  21. package/dist/discord/events-handler/prefixLoader.d.ts.map +1 -1
  22. package/dist/discord/events-handler/prefixLoader.js +38 -24
  23. package/dist/discord/events-handler/prefixLoader.js.map +1 -1
  24. package/dist/discord/events-handler/slash-register.d.ts.map +1 -1
  25. package/dist/discord/events-handler/slash-register.js +1 -5
  26. package/dist/discord/events-handler/slash-register.js.map +1 -1
  27. package/dist/discord/events-handler/slash-responder.d.ts.map +1 -1
  28. package/dist/discord/events-handler/slash-responder.js +1 -0
  29. package/dist/discord/events-handler/slash-responder.js.map +1 -1
  30. package/dist/discord/events-handler/slashLoader.d.ts +5 -1
  31. package/dist/discord/events-handler/slashLoader.d.ts.map +1 -1
  32. package/dist/discord/events-handler/slashLoader.js +57 -11
  33. package/dist/discord/events-handler/slashLoader.js.map +1 -1
  34. package/dist/discord/events-handler/starter.d.ts.map +1 -1
  35. package/dist/discord/events-handler/starter.js +2 -6
  36. package/dist/discord/events-handler/starter.js.map +1 -1
  37. package/dist/discord/functions/logger.d.ts +1 -1
  38. package/dist/discord/functions/logger.d.ts.map +1 -1
  39. package/dist/discord/functions/logger.js +9 -2
  40. package/dist/discord/functions/logger.js.map +1 -1
  41. package/dist/discord/types/starter.d.ts +4 -0
  42. package/dist/discord/types/starter.d.ts.map +1 -1
  43. package/dist/discord/utils.d.ts +8 -2
  44. package/dist/discord/utils.d.ts.map +1 -1
  45. package/dist/discord/utils.js +21 -3
  46. package/dist/discord/utils.js.map +1 -1
  47. package/dist/index.d.ts +16 -3
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +31 -2
  50. package/dist/index.js.map +1 -1
  51. package/lib/discord/events-handler/eventLoader.ts +130 -0
  52. package/lib/discord/events-handler/events.ts +11 -12
  53. package/lib/discord/events-handler/login.ts +7 -1
  54. package/lib/discord/events-handler/prefix-register.ts +5 -4
  55. package/lib/discord/events-handler/prefix-responder.ts +93 -91
  56. package/lib/discord/events-handler/prefixLoader.ts +43 -29
  57. package/lib/discord/events-handler/slash-register.ts +3 -6
  58. package/lib/discord/events-handler/slash-responder.ts +1 -0
  59. package/lib/discord/events-handler/slashLoader.ts +64 -12
  60. package/lib/discord/events-handler/starter.ts +4 -8
  61. package/lib/discord/functions/logger.ts +12 -2
  62. package/lib/discord/types/starter.ts +4 -0
  63. package/lib/discord/utils.ts +10 -2
  64. package/lib/index.ts +10 -3
  65. package/package.json +2 -1
  66. package/lib/discord/events-handler/events loader.ts +0 -21
@@ -1,15 +1,22 @@
1
1
  import { Client, Message, Collection, EmbedBuilder, TextChannel, PermissionResolvable } from 'discord.js';
2
2
  import { commands, aliases } from './prefix-register';
3
3
  import { PrefixOptions } from '../types/utils';
4
- import { getSimilarCommands } from '../functions/utils'
4
+ import { getSimilarCommands } from '../functions/utils';
5
5
  import { botData } from './login';
6
+ import { logError } from '../functions/logger';
6
7
  const cooldowns: Collection<string, Collection<string, number>> = new Collection();
7
8
 
8
- async function handleMessageCreate(message: Message, prefix: PrefixOptions): Promise<void> {
9
- const botPrefix = prefix.prefix || '!';
9
+ export async function handleMessageCreate(message: Message, prefixOptions: PrefixOptions): Promise<void> {
10
+ let botPrefix = prefixOptions.prefix || '!';
10
11
  const developers = botData.get('developers') as string[] | undefined;
11
12
  const ownerId = botData.get('ownerId') as string;
12
13
 
14
+ if (message.guild) {
15
+ const customPrefixEntry = prefixOptions.customPrefix?.find(entry => entry.serverId === message.guild?.id);
16
+ if (customPrefixEntry) {
17
+ botPrefix = customPrefixEntry.prefix;
18
+ }
19
+ }
13
20
  if (message.guild?.members.me) {
14
21
  const user = message.author;
15
22
  const botData = new Collection<string, string | string[]>();
@@ -17,132 +24,127 @@ async function handleMessageCreate(message: Message, prefix: PrefixOptions): Pro
17
24
 
18
25
  if (!message.guild.members.me.permissions.has('SendMessages')) {
19
26
  try {
20
- user.send({ content:"I'm sorry, but I don't have permission to send messages in this server."});
21
- } catch (error) {
27
+ user.send({ content: "I'm sorry, but I don't have permission to send messages in this server." });
28
+ } catch (error: any) {
29
+ logError("Failed to send permission error message to user.", error);
22
30
  return;
23
31
  }
24
32
  }
25
-
33
+
26
34
  if (permissionsArray && permissionsArray.length > 0) {
27
35
  const missingPermissions = permissionsArray.filter(permission => !message.guild?.members.me?.permissions.has(permission as PermissionResolvable));
28
-
36
+
29
37
  if (missingPermissions.length > 0) {
30
38
  try {
31
- user.send({ content:`I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.`});
32
- } catch (error) {
39
+ user.send({ content: `I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.` });
40
+ } catch (error: any) {
41
+ logError("Failed to send missing permissions message to user.", error); // Log the error with details
33
42
  return;
34
43
  }
35
44
  }
36
45
  }
37
46
  }
38
-
39
47
 
40
48
  if (!message.content.startsWith(botPrefix) || message.author.bot) return;
41
49
 
42
- if (prefix.global === false && prefix.serverIds && prefix.serverIds.length > 0) {
43
-
50
+ if (prefixOptions.global === false && prefixOptions.serverIds && prefixOptions.serverIds.length > 0) {
44
51
  const guildId = message.guild?.id;
45
- if (guildId && !prefix.serverIds.includes(guildId)) return;
46
-
52
+ if (guildId && !prefixOptions.serverIds.includes(guildId)) return;
47
53
  } else {
54
+ const args = message.content.slice(botPrefix.length).trim().split(/ +/);
55
+ const commandName = args.shift()?.toLowerCase();
48
56
 
49
- const args = message.content.slice(botPrefix.length).trim().split(/ +/);
50
- const commandName = args.shift()?.toLowerCase();
51
-
52
- if (!commandName || (!commands.has(commandName) && !aliases.has(commandName))) return;
57
+ if (!commandName || (!commands.has(commandName) && !aliases.has(commandName))) return;
53
58
 
54
- const command = commands.get(commandName) || commands.get(aliases.get(commandName) || '');
59
+ const command = commands.get(commandName) || commands.get(aliases.get(commandName) || '');
55
60
 
56
- if (!command) {
57
- const similarCommands = getSimilarCommands(commandName, commands);
58
- if (similarCommands.length > 0) {
59
- await message.reply(`Command not found. Did you mean: ${similarCommands.join(', ')}?`);
60
- } else {
61
- await message.reply(`Command '${commandName}' doesn't exist.`);
61
+ if (!command) {
62
+ const similarCommands = getSimilarCommands(commandName, commands);
63
+ if (similarCommands.length > 0) {
64
+ await message.reply(`Command not found. Did you mean: ${similarCommands.join(', ')}?`);
65
+ } else {
66
+ await message.reply(`Command '${commandName}' doesn't exist.`);
67
+ }
68
+ return;
62
69
  }
63
- return;
64
- }
65
70
 
66
- if (command.owner && message.author.id !== ownerId) {
67
- await message.reply(`Only the bot owner can use this command.`);
68
- return;
69
- }
70
-
71
-
72
- if (command.developer) {
73
- if (developers && !developers.includes(message.author.id)) {
74
- if (message.author.id === ownerId) return;
75
- await message.reply("You are not authorized to use this command.");
71
+ if (command.owner && message.author.id !== ownerId) {
72
+ await message.reply(`Only the bot owner can use this command.`);
76
73
  return;
77
74
  }
78
- }
79
75
 
76
+ if (command.developer) {
77
+ if (developers && !developers.includes(message.author.id)) {
78
+ if (message.author.id === ownerId) return;
79
+ await message.reply("You are not authorized to use this command.");
80
+ return;
81
+ }
82
+ }
80
83
 
81
- const now = Date.now();
82
- const timestamps = cooldowns.get(command.name) || new Collection<string, number>();
83
- const cooldownAmount = (command.cooldown || 3) * 1000;
84
+ const now = Date.now();
85
+ const timestamps = cooldowns.get(command.name) || new Collection<string, number>();
86
+ const cooldownAmount = (command.cooldown || 3) * 1000;
84
87
 
85
- if (timestamps.has(message.author.id)) {
86
- const expirationTime = timestamps.get(message.author.id) || 0;
87
- const timeLeft = (expirationTime - now) / 1000;
88
+ if (timestamps.has(message.author.id)) {
89
+ const expirationTime = timestamps.get(message.author.id) || 0;
90
+ const timeLeft = (expirationTime - now) / 1000;
88
91
 
89
- if (now < expirationTime) {
90
- await message.reply(`Please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
91
- return;
92
+ if (now < expirationTime) {
93
+ await message.reply(`Please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
94
+ return;
95
+ }
92
96
  }
93
- }
94
97
 
95
- timestamps.set(message.author.id, now);
96
- setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
97
- cooldowns.set(command.name, timestamps);
98
+ timestamps.set(message.author.id, now);
99
+ setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
100
+ cooldowns.set(command.name, timestamps);
98
101
 
102
+ try {
103
+ if (command.run) {
104
+ await command.run(message.client, message, args);
105
+ } else if (command.execute) {
106
+ await command.execute(message.client, message, args);
107
+ }
99
108
 
100
- try {
101
- if (command.run) {
102
- command.run(message.client, message, args);
103
- } else if (command.execute) {
104
- command.execute(message.client, message, args);
105
- }
106
-
107
- const channel = message.guild?.channels.cache.get(prefix.logsId || '') as TextChannel | undefined;
108
- const userName = message.author.username;
109
- const userId = message.author.id;
110
- const serverName = message.guild?.name || null;
111
- const serverId = message.guild?.id || null;
112
- const messageLink = `https://discord.com/channels/${serverId}/${message.channel.id}/${message.id}`;
113
-
114
- const embedLog = new EmbedBuilder()
115
- .setColor("Blue")
116
- .setThumbnail(message.client.user?.displayAvatarURL())
117
- .setTitle("Use Prefix Command")
118
- .setTimestamp()
119
- .addFields(
120
- { name: "📧 Cmd:", value: `- ${command.name}`, inline: true },
121
- { name: "🤪 User:", value: `- ${userName} (<@${userId}>)`, inline: true },
122
- { name: "\u200B", value: "\u200B", inline: true },
123
- { name: "🏠 Server:", value: `- ${serverName}.\n- [\`${serverId}\`].`, inline: true },
124
- { name: "📩 Message:", value: `- [Link](${messageLink})`, inline: true },
125
- { name: "\u200B", value: "\u200B", inline: true },
126
- { name: "⏳ Date:", value: `- <t:${Math.floor(Date.now() / 1000)}:R>`, inline: true }
127
- );
128
-
129
- if (prefix.logsId && channel) {
130
- await channel.send({ embeds: [embedLog] });
109
+ const channel = message.guild?.channels.cache.get(prefixOptions.logsId || '') as TextChannel | undefined;
110
+ const userName = message.author.username;
111
+ const userId = message.author.id;
112
+ const serverName = message.guild?.name || null;
113
+ const serverId = message.guild?.id || null;
114
+ const messageLink = `https://discord.com/channels/${serverId}/${message.channel.id}/${message.id}`;
115
+
116
+ const embedLog = new EmbedBuilder()
117
+ .setColor("Blue")
118
+ .setThumbnail(message.client.user?.displayAvatarURL())
119
+ .setTitle("Use Prefix Command")
120
+ .setTimestamp()
121
+ .addFields(
122
+ { name: "📧 Cmd:", value: `- ${command.name}`, inline: true },
123
+ { name: "🤪 User:", value: `- ${userName} (<@${userId}>)`, inline: true },
124
+ { name: "\u200B", value: "\u200B", inline: true },
125
+ { name: "🏠 Server:", value: `- ${serverName}.\n- [\`${serverId}\`].`, inline: true },
126
+ { name: "📩 Message:", value: `- [Link](${messageLink})`, inline: true },
127
+ { name: "\u200B", value: "\u200B", inline: true },
128
+ { name: "⏳ Date:", value: `- <t:${Math.floor(Date.now() / 1000)}:R>`, inline: true }
129
+ );
130
+
131
+ if (prefixOptions.logsId && channel) {
132
+ await channel.send({ embeds: [embedLog] });
133
+ }
134
+ } catch (error: any) {
135
+ logError(`Error executing command ${command.name}`, error);
131
136
  }
132
- } catch (error) {
133
- console.error(`⚠️ \x1b[33m%s Error executing command ${command.name}\x1b[0m:`, error);
134
137
  }
135
- }
136
138
  }
137
139
 
138
140
  export async function loadPrefix(client: Client, prefix: PrefixOptions): Promise<void> {
139
141
  if (!prefix.prefix) {
140
- throw new Error("⚠️ \x1b[33m%s No command prefix provided. Please provide a command prefix.\x1b[0m");
142
+ throw new Error("⚠️ No command prefix provided. Please provide a command prefix.");
141
143
  }
142
144
 
143
- try {
144
- client.on("messageCreate", async message => await handleMessageCreate(message, prefix));
145
- } catch (error) {
146
- console.error('⚠️ \x1b[33m%s An error occurred while loading prefix\x1b[0m:', error);
145
+ try {
146
+ client.on("messageCreate", async (message) => await handleMessageCreate(message, prefix));
147
+ } catch (error: any) {
148
+ logError("An error occurred while loading prefix.", error);
147
149
  }
148
- }
150
+ }
@@ -1,40 +1,54 @@
1
- import { logSuccess, logError, logInfo, logWarning } from '../functions/logger';
2
- import { commands, aliases, commandNames, readCommands } from './prefix-register';
1
+ import { Collection } from 'discord.js';
2
+ import { readdir } from 'fs/promises';
3
+ import { join, resolve, extname } from 'path';
4
+ import { commands, aliases, commandNames } from './prefix-register';
5
+ import { readCommands } from './prefix-register';
6
+ import { logError } from '../functions/logger';
3
7
  import { botData } from './login';
8
+ const validExtensions = ['.js', '.ts'];
4
9
 
5
- export async function prefixLoader(client: any): Promise<boolean> {
6
- const currentCommandNames = new Set(commands.keys());
7
- console.log('Before clearing:');
8
- console.log('Commands size:', commands.size);
9
- console.log('Aliases size:', aliases.size);
10
- console.log('Command names size:', commandNames.size);
11
-
12
-
13
- commands.clear();
14
- aliases.clear();
15
- commandNames.clear();
10
+ export async function prefixLoader(client: any): Promise<{ commands: Collection<string, any>; success: boolean }> {
11
+ try {
16
12
 
17
- console.log('After clearing:');
18
- console.log('Commands size:', commands.size);
19
- console.log('Aliases size:', aliases.size);
20
- console.log('Command names size:', commandNames.size);
21
- const prefixPath = botData.get('prefixPath') as string;
13
+ const prefixPath = botData.get('prefixPath') as string;
22
14
 
23
- logInfo(`Reloading prefix commands from ${prefixPath}`);
15
+ commands.clear();
16
+ aliases.clear();
17
+ commandNames.clear();
18
+ client.prefixCommands = [];
19
+ client.prefixSize = 0;
24
20
 
25
- try {
26
- await readCommands(client, { path: prefixPath });
21
+ const resolvedPath = resolve(process.cwd(), prefixPath);
22
+ const dirents = await readdir(resolvedPath, { withFileTypes: true });
27
23
 
28
- commands.forEach((_, name) => {
29
- if (!currentCommandNames.has(name)) {
30
- logWarning(`Removed old command: ${name}`);
24
+ const filePaths: string[] = [];
25
+ for (const dirent of dirents) {
26
+ if (dirent.isDirectory()) {
27
+ const folderPath = join(resolvedPath, dirent.name);
28
+ const files = await readdir(folderPath);
29
+ for (const file of files) {
30
+ if (validExtensions.includes(extname(file))) {
31
+ filePaths.push(join(folderPath, file));
32
+ }
33
+ }
34
+ } else if (validExtensions.includes(extname(dirent.name))) {
35
+ filePaths.push(join(resolvedPath, dirent.name));
31
36
  }
32
- });
37
+ }
33
38
 
34
- logSuccess(`Successfully reloaded prefix commands.`);
35
- return true;
39
+ for (const filePath of filePaths) {
40
+ delete require.cache[require.resolve(filePath)];
41
+ }
42
+
43
+ const commandDetails = await readCommands(client, { path: prefixPath });
44
+ client.prefixCommands = commandDetails;
45
+ client.prefixSize = commandDetails.length;
46
+
47
+ return { commands: commands, success: true };
36
48
  } catch (error: any) {
37
- logError(`Error reloading prefix commands: ${error.message}`);
38
- return false;
49
+ logError('Error reloading commands:');
50
+ logError(error.message);
51
+
52
+ return { commands: new Collection(), success: false };
39
53
  }
40
54
  }
@@ -4,7 +4,7 @@ import { Routes } from 'discord-api-types/v10';
4
4
  import { readdir } from 'fs/promises';
5
5
  import path from 'path';
6
6
  import { SlashOptions } from '../types/starter';
7
- import { logSuccess, logError, logInfo } from '../functions/logger';
7
+ import { logError } from '../functions/logger';
8
8
 
9
9
  export async function registerSlashCommands(client: any, token: string, slash: SlashOptions): Promise<Collection<string, any>> {
10
10
  if (!token) {
@@ -31,7 +31,6 @@ export async function registerSlashCommands(client: any, token: string, slash: S
31
31
  command.data.cooldown = command.cooldown || 0;
32
32
  }
33
33
  slashCommands.set(command.data.name, command);
34
- logInfo(`Loaded command: ${command.data.name}`);
35
34
  }
36
35
  } catch (error: any) {
37
36
  logError(`Error in file: ${path.join(folderPath, file)}`);
@@ -46,7 +45,6 @@ export async function registerSlashCommands(client: any, token: string, slash: S
46
45
  command.data.cooldown = command.cooldown || 0;
47
46
  }
48
47
  slashCommands.set(command.data.name, command);
49
- logInfo(`Loaded command: ${command.data.name}`);
50
48
  }
51
49
  } catch (error: any) {
52
50
  logError(`Error in file: ${path.join(resolvedPath, dirent.name)}`);
@@ -58,24 +56,23 @@ export async function registerSlashCommands(client: any, token: string, slash: S
58
56
  if (slash.global && !slash.serverId) {
59
57
  const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
60
58
  await rest.put(Routes.applicationCommands((client.user?.id || '')), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
61
- logSuccess('Successfully registered global slash commands.');
62
59
  } else if (!slash.global && slash.serverId) {
63
60
  const guild = client.guilds.cache.get(slash.serverId) as Guild | undefined;
64
61
  if (guild) {
65
62
  const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
66
63
  await rest.put(Routes.applicationGuildCommands((client.user?.id || ''), guild.id), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
67
- logSuccess(`Successfully registered guild slash commands for server ID: ${slash.serverId}`);
68
64
  } else {
69
65
  logError(`Guild with ID ${slash.serverId} not found.`);
70
66
  }
71
67
  } else {
72
68
  const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
73
69
  await rest.put(Routes.applicationCommands((client.user?.id || '')), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
74
- logSuccess('Successfully registered global slash commands.');
75
70
  }
76
71
  } catch (error: any) {
77
72
  logError('Error registering slash commands:');
78
73
  logError(error.message);
74
+ console.error(error);
75
+
79
76
  }
80
77
 
81
78
  client.slashCommands = slashCommands;
@@ -118,6 +118,7 @@ export async function loadSlash(client: Client, token: string, options: SlashOpt
118
118
  } catch (error: any) {
119
119
  logError(`Error executing command "${command.data.name}":`);
120
120
  logError(error.message);
121
+ console.error(error);
121
122
  if (interaction.channel) {
122
123
  await interaction.channel.send({ content: 'An error occurred while executing the command.' });
123
124
  }
@@ -1,19 +1,71 @@
1
- import { logSuccess, logError, logInfo } from '../functions/logger';
2
- import { registerSlashCommands } from './slash-register';
1
+ import { Collection } from 'discord.js';
2
+ import { REST } from '@discordjs/rest';
3
+ import { Routes } from 'discord-api-types/v10';
4
+ import { readdir } from 'fs/promises';
5
+ import { resolve, extname } from 'path';
3
6
  import { botData } from './login';
7
+ import { logError, logInfo } from '../functions/logger';
4
8
 
5
- export async function slashLoader(client: any, token: string, global: boolean, serverId?: string) {
6
- client.slashCommands.clear();
7
- const slashPath = botData.get('slashCommands') as string;
8
-
9
- logInfo(`Reloading slash commands from ${slashPath}`);
9
+ const validExtensions = ['.js', '.ts'];
10
10
 
11
+ export async function slashLoader(client: any): Promise<{ commands: Collection<string, any>; success: boolean }> {
11
12
  try {
12
- const newSlashCommands = await registerSlashCommands(client, token, { path: slashPath, global, serverId });
13
- logSuccess(`Successfully reloaded ${newSlashCommands.size} slash commands.`);
14
- return true
13
+ const slashPath = botData.get('slashCommandPath') as string;
14
+ const token = botData.get('botToken') as string;
15
+
16
+ const commandPath = resolve(process.cwd(), slashPath);
17
+
18
+ const getAllFiles = async (dirPath: string): Promise<string[]> => {
19
+ let files: string[] = [];
20
+ const dirents = await readdir(dirPath, { withFileTypes: true });
21
+
22
+ for (const dirent of dirents) {
23
+ const res = resolve(dirPath, dirent.name);
24
+ if (dirent.isDirectory()) {
25
+ files = files.concat(await getAllFiles(res));
26
+ } else if (validExtensions.includes(extname(dirent.name))) {
27
+ files.push(res);
28
+ }
29
+ }
30
+ return files;
31
+ };
32
+
33
+ const files = await getAllFiles(commandPath);
34
+ if (files.length === 0) {
35
+ logInfo(`No command files found in directory \`${commandPath}\`.`);
36
+ return { commands: new Collection<string, any>(), success: false };
37
+ }
38
+
39
+ for (const file of files) {
40
+ delete require.cache[require.resolve(file)];
41
+ logInfo(`Unlinked cached module: ${file}`);
42
+ }
43
+
44
+ const newCommands = new Collection<string, any>();
45
+ for (const file of files) {
46
+ try {
47
+ const command = require(file);
48
+ if (command.data) {
49
+ client.slashCommands.set(command.data.name, command);
50
+ newCommands.set(command.data.name, command);
51
+ }
52
+ } catch (error: any) {
53
+ logError(`Error re-importing file: ${file}`);
54
+ logError(error.message);
55
+ }
56
+ }
57
+
58
+ const rest = new REST({ version: '10' }).setToken(token);
59
+ const slashCommandArray = Array.from(newCommands.values()).map((command: any) => command.data.toJSON());
60
+
61
+ await rest.put(Routes.applicationCommands(client.user?.id || ''), { body: [] });
62
+ await rest.put(Routes.applicationCommands(client.user?.id || ''), { body: slashCommandArray });
63
+
64
+ return { commands: newCommands, success: true };
15
65
  } catch (error: any) {
16
- logError(`Error reloading slash commands: ${error.message}`);
17
- return false
66
+ logError('Error reloading slash commands:');
67
+ logError(error.message);
68
+ console.error(error);
69
+ return { commands: new Collection<string, any>(), success: false };
18
70
  }
19
71
  }
@@ -1,6 +1,5 @@
1
1
  import { StarterOptions, StarterInterface } from '../types/utils';
2
2
  import { mongoConnect, getDb, verseConnect } from '../functions/utils';
3
- import { loadEvents } from './events';
4
3
  const wait = require('node:timers/promises').setTimeout;
5
4
  import { login } from './login';
6
5
  import { AntiCrash } from '../functions/anticrash';
@@ -17,16 +16,13 @@ export class Starter implements StarterInterface {
17
16
  }
18
17
  if (options.bot?.Database?.verse) {
19
18
  verseDb = await verseConnect(options.bot.Database.verse);
20
- }
21
- if (options.events) {
22
- await loadEvents(djs, options.events);
23
- }
24
- if (options.anticrash?.enable) {
25
- await AntiCrash(djs, options)
26
- }
19
+ }
27
20
  if (options.bot) {
28
21
  await login(djs, options);
29
22
  }
23
+ if (options.anticrash?.enable) {
24
+ await AntiCrash(djs, options)
25
+ }
30
26
  } catch (error: any) {
31
27
  console.error('An error occurred during bot startup:', error.message);
32
28
  await this.handleStartupError(error, djs, options);
@@ -9,6 +9,8 @@ const cyan = '\x1b[36m';
9
9
  const reset = '\x1b[0m';
10
10
  const yellow = '\x1b[33m';
11
11
 
12
+ import { inspect } from 'util';
13
+
12
14
 
13
15
  function getTimestamp(): string {
14
16
  const now = new Date();
@@ -25,10 +27,18 @@ export function logSuccess(message: string) {
25
27
  console.log(`${getTimestamp()} ${green}${successEmoji}${reset} ${green}${message}${reset}`);
26
28
  }
27
29
 
28
- export function logError(message: string) {
29
- console.error(`${getTimestamp()} ${red}${errorEmoji}${reset} ${red}${message}${reset}`);
30
+ export function logError(message: string, error?: Error) {
31
+ const timestamp = getTimestamp();
32
+ const baseMessage = `${timestamp} ${red}${errorEmoji}${reset} ${red}${message}${reset}`;
33
+
34
+ if (error && error.stack) {
35
+ console.error(`${baseMessage}\n${error.stack}`);
36
+ } else {
37
+ console.error(baseMessage);
38
+ }
30
39
  }
31
40
 
41
+
32
42
  export function logInfo(message: string) {
33
43
  console.log(`${getTimestamp()} ${cyan}${infoEmoji}${reset} ${cyan}${message}${reset}`);
34
44
  }
@@ -47,6 +47,10 @@ export interface PrefixOptions {
47
47
  prefix: string;
48
48
  global?: boolean;
49
49
  serverIds?: string[];
50
+ customPrefix?: {
51
+ serverId: string;
52
+ prefix: string;
53
+ }[];
50
54
  logsId?: string;
51
55
  }
52
56
 
@@ -1,5 +1,13 @@
1
1
  import { Starter } from "./events-handler/starter";
2
2
  import { ButtonManager, MenuManager, PermissionChecker } from './builder/utils';
3
- import { prefixLoader } from "./events-handler/prefixLoader";
4
3
  import { slashLoader } from "./events-handler/slashLoader";
5
- export { Starter, ButtonManager, MenuManager, PermissionChecker, prefixLoader, slashLoader }
4
+ import { prefixLoader } from "./events-handler/prefixLoader";
5
+ import { eventLoader } from "./events-handler/eventLoader";
6
+ import { readCommands } from "./events-handler/prefix-register";
7
+ import { loadPrefix, handleMessageCreate } from "./events-handler/prefix-responder";
8
+ import { registerSlashCommands } from "./events-handler/slash-register";
9
+ import { loadSlash } from "./events-handler/slash-responder";
10
+ import { loadEvents, withRetry, processEventFile, processDirectory, limitConcurrency, countEventFiles } from "./events-handler/events";
11
+ export { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
12
+ loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
13
+ processEventFile }
package/lib/index.ts CHANGED
@@ -27,7 +27,14 @@ fetch("https://registry.npmjs.com/-/v1/search?text=djs-builder")
27
27
  .catch((e: any) => {});
28
28
 
29
29
 
30
- import { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader} from "./discord/utils";
30
+ import { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
31
+ loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
32
+ processEventFile } from "./discord/utils";
31
33
 
32
- export { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader };
33
- export default { Starter, ButtonManager, MenuManager, PermissionChecker, prefixLoader, slashLoader };
34
+ export { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
35
+ loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
36
+ processEventFile };
37
+ export default { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
38
+ loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
39
+ processEventFile };
40
+ export * from './discord/types/starter';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "djs-builder",
3
- "version": "0.4.85",
3
+ "version": "0.5.0",
4
4
  "description": "Discord.js bot builder. Supports Ts and Js.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -33,6 +33,7 @@
33
33
  "cli-table": "^0.3.11",
34
34
  "colorette": "^2.0.20",
35
35
  "discord.js": "^14.15.3",
36
+ "djs-builder": "^0.4.10",
36
37
  "mongodb": "^6.5.0",
37
38
  "verse.db": "^2.0.4"
38
39
  },
@@ -1,21 +0,0 @@
1
- import { logSuccess, logError, logInfo } from '../functions/logger';
2
- import { EventsOptions } from '../types/starter';
3
- import { loadEvents } from './events';
4
- export async function eventsLoader(client: any, eventsOptions: EventsOptions) {
5
-
6
- client.eventSize = 0;
7
- client.removeAllListeners();
8
-
9
- logInfo(`Reloading events from ${eventsOptions.path}`);
10
-
11
- try {
12
-
13
- await loadEvents(client, eventsOptions);
14
-
15
- logSuccess(`Successfully reloaded ${client.eventSize} events.`);
16
- return true
17
- } catch (error: any) {
18
- logError(`Error reloading events: ${error.message}`);
19
- return false
20
- }
21
- }