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.
- package/.tsbuildinfo +1 -1
- package/dist/discord/events-handler/eventLoader.d.ts +7 -0
- package/dist/discord/events-handler/eventLoader.d.ts.map +1 -0
- package/dist/discord/events-handler/eventLoader.js +144 -0
- package/dist/discord/events-handler/eventLoader.js.map +1 -0
- package/dist/discord/events-handler/events.d.ts +5 -0
- package/dist/discord/events-handler/events.d.ts.map +1 -1
- package/dist/discord/events-handler/events.js +11 -7
- package/dist/discord/events-handler/events.js.map +1 -1
- package/dist/discord/events-handler/login.d.ts.map +1 -1
- package/dist/discord/events-handler/login.js +6 -1
- package/dist/discord/events-handler/login.js.map +1 -1
- package/dist/discord/events-handler/prefix-register.d.ts.map +1 -1
- package/dist/discord/events-handler/prefix-register.js +5 -4
- package/dist/discord/events-handler/prefix-register.js.map +1 -1
- package/dist/discord/events-handler/prefix-responder.d.ts +2 -1
- package/dist/discord/events-handler/prefix-responder.d.ts.map +1 -1
- package/dist/discord/events-handler/prefix-responder.js +21 -11
- package/dist/discord/events-handler/prefix-responder.js.map +1 -1
- package/dist/discord/events-handler/prefixLoader.d.ts +5 -1
- package/dist/discord/events-handler/prefixLoader.d.ts.map +1 -1
- package/dist/discord/events-handler/prefixLoader.js +38 -24
- package/dist/discord/events-handler/prefixLoader.js.map +1 -1
- package/dist/discord/events-handler/slash-register.d.ts.map +1 -1
- package/dist/discord/events-handler/slash-register.js +1 -5
- package/dist/discord/events-handler/slash-register.js.map +1 -1
- package/dist/discord/events-handler/slash-responder.d.ts.map +1 -1
- package/dist/discord/events-handler/slash-responder.js +1 -0
- package/dist/discord/events-handler/slash-responder.js.map +1 -1
- package/dist/discord/events-handler/slashLoader.d.ts +5 -1
- package/dist/discord/events-handler/slashLoader.d.ts.map +1 -1
- package/dist/discord/events-handler/slashLoader.js +57 -11
- package/dist/discord/events-handler/slashLoader.js.map +1 -1
- package/dist/discord/events-handler/starter.d.ts.map +1 -1
- package/dist/discord/events-handler/starter.js +2 -6
- package/dist/discord/events-handler/starter.js.map +1 -1
- package/dist/discord/functions/logger.d.ts +1 -1
- package/dist/discord/functions/logger.d.ts.map +1 -1
- package/dist/discord/functions/logger.js +9 -2
- package/dist/discord/functions/logger.js.map +1 -1
- package/dist/discord/types/starter.d.ts +4 -0
- package/dist/discord/types/starter.d.ts.map +1 -1
- package/dist/discord/utils.d.ts +8 -2
- package/dist/discord/utils.d.ts.map +1 -1
- package/dist/discord/utils.js +21 -3
- package/dist/discord/utils.js.map +1 -1
- package/dist/index.d.ts +16 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -2
- package/dist/index.js.map +1 -1
- package/lib/discord/events-handler/eventLoader.ts +130 -0
- package/lib/discord/events-handler/events.ts +11 -12
- package/lib/discord/events-handler/login.ts +7 -1
- package/lib/discord/events-handler/prefix-register.ts +5 -4
- package/lib/discord/events-handler/prefix-responder.ts +93 -91
- package/lib/discord/events-handler/prefixLoader.ts +43 -29
- package/lib/discord/events-handler/slash-register.ts +3 -6
- package/lib/discord/events-handler/slash-responder.ts +1 -0
- package/lib/discord/events-handler/slashLoader.ts +64 -12
- package/lib/discord/events-handler/starter.ts +4 -8
- package/lib/discord/functions/logger.ts +12 -2
- package/lib/discord/types/starter.ts +4 -0
- package/lib/discord/utils.ts +10 -2
- package/lib/index.ts +10 -3
- package/package.json +2 -1
- 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,
|
|
9
|
-
|
|
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
|
|
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 (
|
|
43
|
-
|
|
50
|
+
if (prefixOptions.global === false && prefixOptions.serverIds && prefixOptions.serverIds.length > 0) {
|
|
44
51
|
const guildId = message.guild?.id;
|
|
45
|
-
if (guildId && !
|
|
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
|
-
|
|
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
|
-
|
|
59
|
+
const command = commands.get(commandName) || commands.get(aliases.get(commandName) || '');
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
67
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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("⚠️
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15
|
+
commands.clear();
|
|
16
|
+
aliases.clear();
|
|
17
|
+
commandNames.clear();
|
|
18
|
+
client.prefixCommands = [];
|
|
19
|
+
client.prefixSize = 0;
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
await
|
|
21
|
+
const resolvedPath = resolve(process.cwd(), prefixPath);
|
|
22
|
+
const dirents = await readdir(resolvedPath, { withFileTypes: true });
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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(
|
|
38
|
-
|
|
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 {
|
|
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 {
|
|
2
|
-
import {
|
|
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
|
-
|
|
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
|
|
13
|
-
|
|
14
|
-
|
|
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(
|
|
17
|
-
|
|
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
|
-
|
|
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
|
}
|
package/lib/discord/utils.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
}
|