djs-builder 0.4.85 → 0.5.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.
Files changed (67) 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 +5 -0
  14. package/dist/discord/events-handler/prefix-register.d.ts.map +1 -1
  15. package/dist/discord/events-handler/prefix-register.js +15 -4
  16. package/dist/discord/events-handler/prefix-register.js.map +1 -1
  17. package/dist/discord/events-handler/prefix-responder.d.ts +2 -1
  18. package/dist/discord/events-handler/prefix-responder.d.ts.map +1 -1
  19. package/dist/discord/events-handler/prefix-responder.js +130 -59
  20. package/dist/discord/events-handler/prefix-responder.js.map +1 -1
  21. package/dist/discord/events-handler/prefixLoader.d.ts +5 -1
  22. package/dist/discord/events-handler/prefixLoader.d.ts.map +1 -1
  23. package/dist/discord/events-handler/prefixLoader.js +38 -24
  24. package/dist/discord/events-handler/prefixLoader.js.map +1 -1
  25. package/dist/discord/events-handler/slash-register.d.ts.map +1 -1
  26. package/dist/discord/events-handler/slash-register.js +1 -5
  27. package/dist/discord/events-handler/slash-register.js.map +1 -1
  28. package/dist/discord/events-handler/slash-responder.d.ts.map +1 -1
  29. package/dist/discord/events-handler/slash-responder.js +1 -0
  30. package/dist/discord/events-handler/slash-responder.js.map +1 -1
  31. package/dist/discord/events-handler/slashLoader.d.ts +5 -1
  32. package/dist/discord/events-handler/slashLoader.d.ts.map +1 -1
  33. package/dist/discord/events-handler/slashLoader.js +57 -11
  34. package/dist/discord/events-handler/slashLoader.js.map +1 -1
  35. package/dist/discord/events-handler/starter.d.ts.map +1 -1
  36. package/dist/discord/events-handler/starter.js +2 -6
  37. package/dist/discord/events-handler/starter.js.map +1 -1
  38. package/dist/discord/functions/logger.d.ts +1 -1
  39. package/dist/discord/functions/logger.d.ts.map +1 -1
  40. package/dist/discord/functions/logger.js +9 -2
  41. package/dist/discord/functions/logger.js.map +1 -1
  42. package/dist/discord/types/starter.d.ts +8 -1
  43. package/dist/discord/types/starter.d.ts.map +1 -1
  44. package/dist/discord/utils.d.ts +9 -2
  45. package/dist/discord/utils.d.ts.map +1 -1
  46. package/dist/discord/utils.js +26 -3
  47. package/dist/discord/utils.js.map +1 -1
  48. package/dist/index.d.ts +20 -3
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +35 -2
  51. package/dist/index.js.map +1 -1
  52. package/lib/discord/events-handler/eventLoader.ts +130 -0
  53. package/lib/discord/events-handler/events.ts +11 -12
  54. package/lib/discord/events-handler/login.ts +7 -1
  55. package/lib/discord/events-handler/prefix-register.ts +43 -6
  56. package/lib/discord/events-handler/prefix-responder.ts +141 -61
  57. package/lib/discord/events-handler/prefixLoader.ts +43 -29
  58. package/lib/discord/events-handler/slash-register.ts +3 -6
  59. package/lib/discord/events-handler/slash-responder.ts +1 -0
  60. package/lib/discord/events-handler/slashLoader.ts +64 -12
  61. package/lib/discord/events-handler/starter.ts +4 -8
  62. package/lib/discord/functions/logger.ts +10 -2
  63. package/lib/discord/types/starter.ts +8 -1
  64. package/lib/discord/utils.ts +11 -2
  65. package/lib/index.ts +10 -3
  66. package/package.json +2 -1
  67. package/lib/discord/events-handler/events loader.ts +0 -21
@@ -0,0 +1,130 @@
1
+ import { Collection } from 'discord.js';
2
+ import { readdir } from 'fs/promises';
3
+ import { resolve, extname } from 'path';
4
+ import { EventsOptions, Event } from '../types/utils';
5
+ import { logError, logInfo } from '../functions/logger';
6
+ import { botData } from './login';
7
+ const validExtensions = ['.js', '.ts'];
8
+
9
+ export async function eventLoader(client: any, eventsOptions: EventsOptions): Promise<{ events: Collection<string, Event>; success: boolean }> {
10
+ try {
11
+ const eventsPath = botData.get('eventsPath') as string;
12
+ const eventPath = resolve(process.cwd(), eventsPath);
13
+
14
+ const getAllFiles = async (dirPath: string): Promise<string[]> => {
15
+ let files: string[] = [];
16
+ const dirents = await readdir(dirPath, { withFileTypes: true });
17
+
18
+ for (const dirent of dirents) {
19
+ const res = resolve(dirPath, dirent.name);
20
+ if (dirent.isDirectory()) {
21
+ files = files.concat(await getAllFiles(res));
22
+ } else if (validExtensions.includes(extname(dirent.name))) {
23
+ files.push(res);
24
+ }
25
+ }
26
+ return files;
27
+ };
28
+
29
+ const files = await getAllFiles(eventPath);
30
+ if (files.length === 0) {
31
+ logInfo(`No event files found in directory \`${eventPath}\`.`);
32
+ return { events: new Collection<string, Event>(), success: false };
33
+ }
34
+
35
+ client.removeAllListeners();
36
+
37
+ for (const file of files) {
38
+ delete require.cache[require.resolve(file)];
39
+ logInfo(`Unlinked cached module: ${file}`);
40
+ }
41
+
42
+ const newEvents = new Collection<string, Event>();
43
+ for (const file of files) {
44
+ try {
45
+ const event: Event = await import(file);
46
+ if (eventsOptions.eventBlacklist?.includes(file)) {
47
+ continue;
48
+ }
49
+
50
+ let eventHandler: (...args: any[]) => Promise<void> = async (...args: any[]) => {
51
+ if (event.initializer) {
52
+ await new Promise(resolve => setTimeout(resolve, event.initializer));
53
+ }
54
+ await event.execute(...args, client);
55
+
56
+ if (event.interval) {
57
+ if (event.intervalId) clearInterval(event.intervalId);
58
+ event.intervalId = setInterval(async () => {
59
+ await event.execute(...args, client);
60
+ }, event.interval);
61
+ }
62
+ };
63
+
64
+ if (event.once) {
65
+ client.once(event.name, eventHandler);
66
+ } else {
67
+ client.on(event.name, eventHandler);
68
+ }
69
+
70
+ if (event.maxExecution !== undefined) {
71
+ eventHandler = await limitConcurrency(eventHandler, event.maxExecution);
72
+ }
73
+
74
+ if (event.retryAttempts !== undefined) {
75
+ eventHandler = await withRetry(eventHandler, event.retryAttempts);
76
+ }
77
+
78
+ newEvents.set(event.name, event);
79
+ } catch (error: any) {
80
+ logError(`Error re-importing file: ${file}`);
81
+ logError(error.message, error);
82
+ }
83
+ }
84
+
85
+ client.eventSize = newEvents.size;
86
+
87
+ return { events: newEvents, success: true };
88
+ } catch (error: any) {
89
+ logError('Error reloading events:');
90
+ logError(error.message, error);
91
+ return { events: new Collection<string, Event>(), success: false };
92
+ }
93
+ }
94
+
95
+ async function limitConcurrency(handler: (...args: any[]) => void, maxConcurrentExecutions: number): Promise<(...args: any[]) => Promise<void>> {
96
+ let executing = 0;
97
+ const queue: any[] = [];
98
+
99
+ return async function(...args: any[]) {
100
+ if (executing < maxConcurrentExecutions) {
101
+ executing++;
102
+ await handler(...args);
103
+ executing--;
104
+
105
+ if (queue.length > 0) {
106
+ const next = queue.shift();
107
+ next();
108
+ }
109
+ } else {
110
+ queue.push(() => handler(...args));
111
+ }
112
+ };
113
+ }
114
+
115
+ async function withRetry(handler: (...args: any[]) => Promise<void>, retryAttempts: number): Promise<(...args: any[]) => Promise<void>> {
116
+ return async function(...args: any[]) {
117
+ let attempts = 0;
118
+ while (attempts < retryAttempts) {
119
+ try {
120
+ await handler(...args);
121
+ return;
122
+ } catch (error: any) {
123
+ logError('Error executing event:');
124
+ logError(error.message, error);
125
+ attempts++;
126
+ }
127
+ }
128
+ logError('Reached maximum retry attempts.');
129
+ };
130
+ }
@@ -1,11 +1,11 @@
1
- import { logSuccess, logError } from '../functions/logger';
2
1
  import { readdir, stat } from 'fs/promises';
3
2
  import { resolve, join, extname } from 'path';
4
3
  import { EventsOptions, Event } from '../types/utils';
4
+ import { logError } from '../functions/logger';
5
5
 
6
6
  const validExtensions = ['.js', '.ts'];
7
7
 
8
- async function processEventFile(client: any, eventsOptions: EventsOptions, filePath: string) {
8
+ export async function processEventFile(client: any, eventsOptions: EventsOptions, filePath: string) {
9
9
  try {
10
10
  const resolvedPath = resolve(process.cwd(), filePath);
11
11
  const stats = await stat(resolvedPath);
@@ -48,11 +48,11 @@ async function processEventFile(client: any, eventsOptions: EventsOptions, fileP
48
48
  }
49
49
  } catch (error: any) {
50
50
  logError(`Error in event file: ${filePath}`);
51
- logError(error.message);
51
+ logError(error.message, error);
52
52
  }
53
53
  }
54
54
 
55
- async function limitConcurrency(handler: (...args: any[]) => void, maxConcurrentExecutions: number): Promise<(...args: any[]) => Promise<void>> {
55
+ export async function limitConcurrency(handler: (...args: any[]) => void, maxConcurrentExecutions: number): Promise<(...args: any[]) => Promise<void>> {
56
56
  let executing = 0;
57
57
  const queue: any[] = [];
58
58
 
@@ -72,7 +72,7 @@ async function limitConcurrency(handler: (...args: any[]) => void, maxConcurrent
72
72
  };
73
73
  }
74
74
 
75
- async function withRetry(handler: (...args: any[]) => Promise<void>, retryAttempts: number): Promise<(...args: any[]) => Promise<void>> {
75
+ export async function withRetry(handler: (...args: any[]) => Promise<void>, retryAttempts: number): Promise<(...args: any[]) => Promise<void>> {
76
76
  return async function(...args: any[]) {
77
77
  let attempts = 0;
78
78
  while (attempts < retryAttempts) {
@@ -81,7 +81,7 @@ async function withRetry(handler: (...args: any[]) => Promise<void>, retryAttemp
81
81
  return;
82
82
  } catch (error: any) {
83
83
  logError('Error executing event:');
84
- logError(error.message);
84
+ logError(error.message, error);
85
85
  attempts++;
86
86
  }
87
87
  }
@@ -89,7 +89,7 @@ async function withRetry(handler: (...args: any[]) => Promise<void>, retryAttemp
89
89
  };
90
90
  }
91
91
 
92
- async function processDirectory(client: any, eventsOptions: EventsOptions, directoryPath: string) {
92
+ export async function processDirectory(client: any, eventsOptions: EventsOptions, directoryPath: string) {
93
93
  try {
94
94
  const filesInDirectory = await readdir(directoryPath);
95
95
  for (const file of filesInDirectory) {
@@ -103,7 +103,7 @@ async function processDirectory(client: any, eventsOptions: EventsOptions, direc
103
103
  }
104
104
  } catch (error: any) {
105
105
  logError(`Error while processing directory: ${directoryPath}`);
106
- logError(error.message);
106
+ logError(error.message, error);
107
107
  }
108
108
  }
109
109
 
@@ -123,14 +123,13 @@ export async function loadEvents(client: any, eventsOptions: EventsOptions) {
123
123
 
124
124
  const eventCount = await countEventFiles(eventsOptions.path, eventsOptions);
125
125
  client.eventSize = eventCount;
126
- logSuccess(`Loaded ${eventCount} events successfully.`);
127
126
  } catch (error: any) {
128
127
  logError(`Error while loading events from path: ${eventsOptions.path}`);
129
- logError(error.message);
128
+ logError(error.message, error);
130
129
  }
131
130
  }
132
131
 
133
- async function countEventFiles(filePath: string, eventsOptions: EventsOptions): Promise<number> {
132
+ export async function countEventFiles(filePath: string, eventsOptions: EventsOptions): Promise<number> {
134
133
  let count = 0;
135
134
  try {
136
135
  const resolvedPath = resolve(process.cwd(), filePath);
@@ -154,7 +153,7 @@ async function countEventFiles(filePath: string, eventsOptions: EventsOptions):
154
153
  }
155
154
  } catch (error: any) {
156
155
  logError(`Error counting event files in directory: ${filePath}`);
157
- logError(error.message);
156
+ logError(error.message, error);
158
157
  }
159
158
  return count;
160
159
  }
@@ -3,9 +3,11 @@ import { StarterOptions } from '../types/starter';
3
3
  import { loadPrefix } from './prefix-responder';
4
4
  import { loadSlash } from './slash-responder';
5
5
  import { readCommands } from './prefix-register';
6
+
6
7
  export const botData = new Collection<string, string | string[]>();
7
8
  import * as path from 'path';
8
9
  import fs from 'fs';
10
+ import { loadEvents } from './events';
9
11
  export async function login(djs: Client, options: StarterOptions) {
10
12
 
11
13
  if (!djs) {
@@ -57,6 +59,10 @@ export async function login(djs: Client, options: StarterOptions) {
57
59
  botData.set('developers', options.bot.BotInfo.developers);
58
60
  }
59
61
 
62
+ if (options.events) {
63
+ await loadEvents(djs, options.events);
64
+ botData.set('eventsPath', options.events.path);
65
+ }
60
66
 
61
67
  if (options.prefix) {
62
68
  await readCommands(djs, options.prefix)
@@ -66,7 +72,7 @@ export async function login(djs: Client, options: StarterOptions) {
66
72
  }
67
73
  if (options.slash && options.bot.token) {
68
74
  await loadSlash(djs, options.bot?.token, options.slash);
69
- botData.set('slashCommands', options.slash.path);
75
+ botData.set('slashCommandPath', options.slash.path);
70
76
  if (options.slash.serverId) botData.set('serverIdSlash', options.slash.serverId);
71
77
  if (options.slash.global === true) botData.set('globalSlash', 'true');
72
78
  if (options.slash.global === false) botData.set('globalSlash', 'false');
@@ -2,13 +2,40 @@ import { Collection } from 'discord.js';
2
2
  import { promises as fsPromises } from 'fs';
3
3
  import { join, resolve } from 'path';
4
4
  import { Command } from '../types/utils';
5
+ import { logError } from '../functions/logger';
5
6
 
6
7
  export const commands = new Collection<string, Command>();
7
8
  export const aliases = new Collection<string, string>();
8
9
  export const commandNames = new Set<string>();
9
10
 
10
- export async function readCommands(client: any, prefix: { path: string }): Promise<Array<{ name: string; usage: string | undefined; description: string | undefined; aliases: string[] | undefined; cooldown: number | undefined; developer: boolean | undefined; owner: boolean | undefined }>> {
11
- const commandDetails: Array<{ name: string; usage: string | undefined; description: string | undefined; aliases: string[] | undefined; cooldown: number | undefined; developer: boolean | undefined; owner: boolean | undefined }> = [];
11
+ export async function readCommands(client: any, prefix: { path: string }): Promise<Array<{
12
+ name: string;
13
+ usage: string | undefined;
14
+ description: string | undefined;
15
+ aliases: string[] | undefined;
16
+ cooldown: number | undefined;
17
+ developer: boolean | undefined;
18
+ owner: boolean | undefined;
19
+ fastUse: boolean | undefined;
20
+ botPerms: string[] | undefined;
21
+ userPerms: string[] | undefined;
22
+ category: string | undefined;
23
+ accessLevel: string | undefined;
24
+ }>> {
25
+ const commandDetails: Array<{
26
+ name: string;
27
+ usage: string | undefined;
28
+ description: string | undefined;
29
+ aliases: string[] | undefined;
30
+ cooldown: number | undefined;
31
+ developer: boolean | undefined;
32
+ owner: boolean | undefined;
33
+ fastUse: boolean | undefined;
34
+ botPerms: string[] | undefined;
35
+ userPerms: string[] | undefined;
36
+ category: string | undefined;
37
+ accessLevel: string | undefined;
38
+ }> = [];
12
39
 
13
40
  try {
14
41
  const resolvedPath = resolve(process.cwd(), prefix.path);
@@ -34,6 +61,11 @@ export async function readCommands(client: any, prefix: { path: string }): Promi
34
61
  aliases: [],
35
62
  developer: false,
36
63
  owner: false,
64
+ fastUse: false,
65
+ botPerms: [],
66
+ userPerms: [],
67
+ category: "Uncategorized",
68
+ accessLevel: undefined,
37
69
  ...command
38
70
  };
39
71
 
@@ -55,11 +87,16 @@ export async function readCommands(client: any, prefix: { path: string }): Promi
55
87
  cooldown: defaultCommand.cooldown,
56
88
  developer: defaultCommand.developer,
57
89
  owner: defaultCommand.owner,
90
+ fastUse: defaultCommand.fastUse,
91
+ botPerms: defaultCommand.botPerms,
92
+ userPerms: defaultCommand.userPerms,
93
+ category: defaultCommand.category || 'Uncategorized',
94
+ accessLevel: defaultCommand.accessLevel,
58
95
  });
59
96
  }
60
97
  } catch (error: any) {
61
- console.error(`Error in file: ${filePath}`);
62
- console.error(error.message);
98
+ logError(`Error in file: ${filePath}`);
99
+ logError(error.message, error);
63
100
  }
64
101
  }
65
102
  }
@@ -68,8 +105,8 @@ export async function readCommands(client: any, prefix: { path: string }): Promi
68
105
  client.prefixSize = commandDetails.length;
69
106
  return commandDetails;
70
107
  } catch (error: any) {
71
- console.error(`⚠️ Error reading directory: ${prefix.path}`);
72
- console.error(error.message);
108
+ logError(`⚠️ Error reading directory: ${prefix.path}`);
109
+ logError(error.message, error);
73
110
  return [];
74
111
  }
75
112
  }
@@ -1,53 +1,62 @@
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';
7
+
6
8
  const cooldowns: Collection<string, Collection<string, number>> = new Collection();
7
9
 
8
- async function handleMessageCreate(message: Message, prefix: PrefixOptions): Promise<void> {
9
- const botPrefix = prefix.prefix || '!';
10
+ export async function handleMessageCreate(message: Message, prefixOptions: PrefixOptions): Promise<void> {
11
+ let botPrefix = prefixOptions.prefix || '!';
10
12
  const developers = botData.get('developers') as string[] | undefined;
11
13
  const ownerId = botData.get('ownerId') as string;
12
14
 
13
- if (message.guild?.members.me) {
15
+ if (message.guild) {
16
+ const customPrefixEntry = prefixOptions.customPrefix?.find(entry => entry.serverId === message.guild?.id);
17
+ if (customPrefixEntry) {
18
+ botPrefix = customPrefixEntry.prefix;
19
+ }
20
+ }
21
+
22
+ if (message.guild && message.guild.members.me) {
14
23
  const user = message.author;
15
- const botData = new Collection<string, string | string[]>();
16
- const permissionsArray = botData.get('permissions') as string[] | undefined;
24
+ const botPermissions = message.guild.members.me.permissions;
17
25
 
18
- if (!message.guild.members.me.permissions.has('SendMessages')) {
26
+ if (!botPermissions.has('SendMessages')) {
19
27
  try {
20
- user.send({ content:"I'm sorry, but I don't have permission to send messages in this server."});
21
- } catch (error) {
28
+ await user.send("I'm sorry, but I don't have permission to send messages in this server.");
29
+ } catch (error: any) {
30
+ logError("Failed to send permission error message to user.", error);
22
31
  return;
23
32
  }
24
33
  }
25
-
34
+
35
+ const permissionsArray = botData.get('permissions') as string[] | undefined;
26
36
  if (permissionsArray && permissionsArray.length > 0) {
27
- const missingPermissions = permissionsArray.filter(permission => !message.guild?.members.me?.permissions.has(permission as PermissionResolvable));
28
-
37
+ const missingPermissions = permissionsArray.filter(permission => !botPermissions.has(permission as PermissionResolvable));
38
+
29
39
  if (missingPermissions.length > 0) {
30
40
  try {
31
- user.send({ content:`I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.`});
32
- } catch (error) {
41
+ await user.send(`I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.`);
42
+ } catch (error: any) {
43
+ logError("Failed to send missing permissions message to user.", error);
33
44
  return;
34
45
  }
35
46
  }
36
47
  }
37
48
  }
38
-
39
-
40
- if (!message.content.startsWith(botPrefix) || message.author.bot) return;
41
-
42
- if (prefix.global === false && prefix.serverIds && prefix.serverIds.length > 0) {
43
49
 
44
- const guildId = message.guild?.id;
45
- if (guildId && !prefix.serverIds.includes(guildId)) return;
50
+ let args = [];
51
+ let commandName: string | undefined;
46
52
 
53
+ if (message.content.startsWith(botPrefix)) {
54
+ args = message.content.slice(botPrefix.length).trim().split(/ +/);
55
+ commandName = args.shift()?.toLowerCase();
47
56
  } else {
48
-
49
- const args = message.content.slice(botPrefix.length).trim().split(/ +/);
50
- const commandName = args.shift()?.toLowerCase();
57
+ commandName = message.content.split(/ +/)[0].toLowerCase();
58
+ args = message.content.split(/ +/).slice(1);
59
+ }
51
60
 
52
61
  if (!commandName || (!commands.has(commandName) && !aliases.has(commandName))) return;
53
62
 
@@ -68,7 +77,6 @@ async function handleMessageCreate(message: Message, prefix: PrefixOptions): Pro
68
77
  return;
69
78
  }
70
79
 
71
-
72
80
  if (command.developer) {
73
81
  if (developers && !developers.includes(message.author.id)) {
74
82
  if (message.author.id === ownerId) return;
@@ -77,6 +85,78 @@ async function handleMessageCreate(message: Message, prefix: PrefixOptions): Pro
77
85
  }
78
86
  }
79
87
 
88
+ if (message.guild) {
89
+ if (command.botPerms && command.botPerms.length > 0) {
90
+ const missingBotPerms = command.botPerms.filter(perm => !message.guild?.members.me?.permissions.has(perm as PermissionResolvable));
91
+ if (missingBotPerms.length > 0) {
92
+ await message.reply(`I'm missing the following permissions to execute this command: ${missingBotPerms.join(', ')}`);
93
+ return;
94
+ }
95
+ }
96
+
97
+ if (command.userPerms && command.userPerms.length > 0) {
98
+ const member = message.guild.members.cache.get(message.author.id);
99
+ if (member) {
100
+ const missingUserPerms = command.userPerms.filter(perm => !member.permissions.has(perm as PermissionResolvable));
101
+ if (missingUserPerms.length > 0) {
102
+ await message.reply(`You are missing the following permissions to use this command: ${missingUserPerms.join(', ')}`);
103
+ return;
104
+ }
105
+ }
106
+ }
107
+
108
+ if (command.accessLevel) {
109
+ const member = message.guild.members.cache.get(message.author.id);
110
+ if (member) {
111
+ const highestRole = member.roles.highest;
112
+ if (highestRole.id !== command.accessLevel) {
113
+ await message.reply("You do not have the required role to use this command.");
114
+ return;
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ if (command.fastUse && !message.content.startsWith(botPrefix)) {
121
+ try {
122
+ if (command.run) {
123
+ await command.run(message.client, message, args);
124
+ } else if (command.execute) {
125
+ await command.execute(message.client, message, args);
126
+ }
127
+
128
+ if (message.guild) {
129
+ const channel = message.guild.channels.cache.get(prefixOptions.logsId || '') as TextChannel | undefined;
130
+ const userName = message.author.username;
131
+ const userId = message.author.id;
132
+ const serverName = message.guild.name || null;
133
+ const serverId = message.guild.id || null;
134
+ const messageLink = `https://discord.com/channels/${serverId}/${message.channel.id}/${message.id}`;
135
+
136
+ const embedLog = new EmbedBuilder()
137
+ .setColor("Blue")
138
+ .setThumbnail(message.client.user?.displayAvatarURL())
139
+ .setTitle("Use Prefix Command")
140
+ .setTimestamp()
141
+ .addFields(
142
+ { name: "📧 Cmd:", value: `- ${command.name}`, inline: true },
143
+ { name: "🤪 User:", value: `- ${userName} (<@${userId}>)`, inline: true },
144
+ { name: "\u200B", value: "\u200B", inline: true },
145
+ { name: "🏠 Server:", value: `- ${serverName}.\n- [\`${serverId}\`].`, inline: true },
146
+ { name: "📩 Message:", value: `- [Link](${messageLink})`, inline: true },
147
+ { name: "\u200B", value: "\u200B", inline: true },
148
+ { name: "⏳ Date:", value: `- <t:${Math.floor(Date.now() / 1000)}:R>`, inline: true }
149
+ );
150
+
151
+ if (prefixOptions.logsId && channel) {
152
+ await channel.send({ embeds: [embedLog] });
153
+ }
154
+ }
155
+ } catch (error: any) {
156
+ logError(`Error executing command ${command.name}`, error);
157
+ }
158
+ return;
159
+ }
80
160
 
81
161
  const now = Date.now();
82
162
  const timestamps = cooldowns.get(command.name) || new Collection<string, number>();
@@ -96,53 +176,53 @@ async function handleMessageCreate(message: Message, prefix: PrefixOptions): Pro
96
176
  setTimeout(() => timestamps.delete(message.author.id), cooldownAmount);
97
177
  cooldowns.set(command.name, timestamps);
98
178
 
99
-
100
179
  try {
101
180
  if (command.run) {
102
- command.run(message.client, message, args);
181
+ await command.run(message.client, message, args);
103
182
  } else if (command.execute) {
104
- command.execute(message.client, message, args);
183
+ await command.execute(message.client, message, args);
105
184
  }
106
185
 
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] });
186
+ if (message.guild) {
187
+ const channel = message.guild.channels.cache.get(prefixOptions.logsId || '') as TextChannel | undefined;
188
+ const userName = message.author.username;
189
+ const userId = message.author.id;
190
+ const serverName = message.guild.name || null;
191
+ const serverId = message.guild.id || null;
192
+ const messageLink = `https://discord.com/channels/${serverId}/${message.channel.id}/${message.id}`;
193
+
194
+ const embedLog = new EmbedBuilder()
195
+ .setColor("Blue")
196
+ .setThumbnail(message.client.user?.displayAvatarURL())
197
+ .setTitle("Use Prefix Command")
198
+ .setTimestamp()
199
+ .addFields(
200
+ { name: "📧 Cmd:", value: `- ${command.name}`, inline: true },
201
+ { name: "🤪 User:", value: `- ${userName} (<@${userId}>)`, inline: true },
202
+ { name: "\u200B", value: "\u200B", inline: true },
203
+ { name: "🏠 Server:", value: `- ${serverName}.\n- [\`${serverId}\`].`, inline: true },
204
+ { name: "📩 Message:", value: `- [Link](${messageLink})`, inline: true },
205
+ { name: "\u200B", value: "\u200B", inline: true },
206
+ { name: "⏳ Date:", value: `- <t:${Math.floor(Date.now() / 1000)}:R>`, inline: true }
207
+ );
208
+
209
+ if (prefixOptions.logsId && channel) {
210
+ await channel.send({ embeds: [embedLog] });
211
+ }
131
212
  }
132
- } catch (error) {
133
- console.error(`⚠️ \x1b[33m%s Error executing command ${command.name}\x1b[0m:`, error);
213
+ } catch (error: any) {
214
+ logError(`Error executing command ${command.name}`, error);
134
215
  }
135
- }
136
216
  }
137
217
 
138
218
  export async function loadPrefix(client: Client, prefix: PrefixOptions): Promise<void> {
139
219
  if (!prefix.prefix) {
140
- throw new Error("⚠️ \x1b[33m%s No command prefix provided. Please provide a command prefix.\x1b[0m");
220
+ throw new Error("⚠️ No command prefix provided. Please provide a command prefix.");
141
221
  }
142
222
 
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);
223
+ try {
224
+ client.on("messageCreate", async (message) => await handleMessageCreate(message, prefix));
225
+ } catch (error: any) {
226
+ logError("An error occurred while loading prefix.", error);
147
227
  }
148
- }
228
+ }