djs-builder 0.5.32 → 0.5.41

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 (31) hide show
  1. package/.tsbuildinfo +1 -1
  2. package/dist/discord/builder/system/Pagination.d.ts.map +1 -1
  3. package/dist/discord/builder/system/Pagination.js +10 -10
  4. package/dist/discord/builder/system/Pagination.js.map +1 -1
  5. package/dist/discord/builder/system/collectors.d.ts +27 -0
  6. package/dist/discord/builder/system/collectors.d.ts.map +1 -0
  7. package/dist/discord/builder/system/collectors.js +137 -0
  8. package/dist/discord/builder/system/collectors.js.map +1 -0
  9. package/dist/discord/events-handler/slash-register.d.ts.map +1 -1
  10. package/dist/discord/events-handler/slash-register.js +30 -41
  11. package/dist/discord/events-handler/slash-register.js.map +1 -1
  12. package/dist/discord/events-handler/slash-responder.d.ts.map +1 -1
  13. package/dist/discord/events-handler/slash-responder.js +23 -27
  14. package/dist/discord/events-handler/slash-responder.js.map +1 -1
  15. package/dist/discord/events-handler/starter.js.map +1 -1
  16. package/dist/discord/utils.d.ts +2 -1
  17. package/dist/discord/utils.d.ts.map +1 -1
  18. package/dist/discord/utils.js +3 -1
  19. package/dist/discord/utils.js.map +1 -1
  20. package/dist/index.d.ts +2 -28
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +3 -4
  23. package/dist/index.js.map +1 -1
  24. package/lib/discord/builder/system/Pagination.ts +22 -21
  25. package/lib/discord/builder/system/collectors.ts +197 -0
  26. package/lib/discord/events-handler/slash-register.ts +32 -46
  27. package/lib/discord/events-handler/slash-responder.ts +43 -38
  28. package/lib/discord/events-handler/starter.ts +4 -1
  29. package/lib/discord/utils.ts +2 -1
  30. package/lib/index.ts +2 -5
  31. package/package.json +1 -1
@@ -0,0 +1,197 @@
1
+ import {
2
+ Message,
3
+ Interaction,
4
+ MessageCollector,
5
+ InteractionCollector,
6
+ CollectorFilter,
7
+ Snowflake,
8
+ ReadonlyCollection,
9
+ CommandInteraction,
10
+ ButtonInteraction,
11
+ MessageReaction,
12
+ ModalSubmitInteraction,
13
+ StringSelectMenuInteraction,
14
+ UserSelectMenuInteraction,
15
+ RoleSelectMenuInteraction,
16
+ ContextMenuCommandInteraction,
17
+ Collector,
18
+ } from 'discord.js';
19
+
20
+ type EventSource = Message | CommandInteraction | ButtonInteraction | MessageReaction | Interaction;
21
+
22
+ const collectorCache: Map<string, any> = new Map();
23
+
24
+ /**
25
+ * @param sources - The event source(s) (message, interaction, reaction, etc.) to collect from.
26
+ * @param options - Custom options for collection (time, filter, max, idle).
27
+ * @param events - Custom event handlers for `onCollect`, `onEnd`, `onError`, etc.
28
+ */
29
+ function Djs_Collectors<T extends EventSource>(
30
+ sources: T | T[],
31
+ options: {
32
+ time?: number;
33
+ filter?: CollectorFilter<[T]>;
34
+ max?: number;
35
+ idle?: number;
36
+ log?: boolean;
37
+ throttle?: number;
38
+ uniqueId?: string;
39
+ },
40
+ events: {
41
+ onCollect: (collectedItem: T, meta?: Record<string, any>) => void;
42
+ onEnd?: (collected: ReadonlyCollection<Snowflake, T>, reason: string) => void;
43
+ onError?: (error: Error) => void;
44
+ onDispose?: (disposedItem: T) => void;
45
+ onTimeout?: () => void;
46
+ onStart?: () => void;
47
+ },
48
+ metadata?: Record<string, any>
49
+ ): { stop: (reason?: string) => void } {
50
+ const eventSources = Array.isArray(sources) ? sources : [sources];
51
+ const filter: CollectorFilter<[T]> = options.filter || (() => true);
52
+ const time: number = options.time || 60000;
53
+
54
+ if (events.onStart) events.onStart();
55
+
56
+ if (options.uniqueId && collectorCache.has(options.uniqueId)) {
57
+ console.warn(`Collector with unique ID "${options.uniqueId}" is already active. Skipping creation.`);
58
+ return { stop: () => {} };
59
+ }
60
+
61
+ if (options.uniqueId) {
62
+ collectorCache.set(options.uniqueId, { sources: eventSources, time, max: options.max, idle: options.idle });
63
+ }
64
+
65
+ const collectors: any[] = [];
66
+
67
+ for (const source of eventSources) {
68
+ if (source instanceof Message) {
69
+ const messageCollector = new MessageCollector(source.channel, {
70
+ filter: filter as CollectorFilter<[Message]>,
71
+ time,
72
+ max: options.max,
73
+ idle: options.idle,
74
+ });
75
+
76
+ collectors.push(messageCollector); // Store reference
77
+ handleCollector(messageCollector, events, options, metadata);
78
+
79
+ } else if (
80
+ source instanceof CommandInteraction ||
81
+ source instanceof ButtonInteraction ||
82
+ source instanceof StringSelectMenuInteraction ||
83
+ source instanceof UserSelectMenuInteraction ||
84
+ source instanceof RoleSelectMenuInteraction ||
85
+ source instanceof ContextMenuCommandInteraction ||
86
+ source instanceof ModalSubmitInteraction
87
+ ) {
88
+ if (!source.client.isReady()) {
89
+ throw new Error('Client is not ready. Please ensure the client is logged in and ready before creating a collector.');
90
+ }
91
+
92
+ const interactionCollector = new InteractionCollector(source.client, {
93
+ filter: filter as CollectorFilter<[Interaction]>,
94
+ time,
95
+ max: options.max,
96
+ idle: options.idle,
97
+ });
98
+
99
+ collectors.push(interactionCollector); // Store reference
100
+ handleCollector(interactionCollector, events, options, metadata);
101
+
102
+ } else if (source instanceof MessageReaction) {
103
+ const reactionCollector = source.message.createReactionCollector({
104
+ filter: filter as CollectorFilter<[MessageReaction]>,
105
+ time,
106
+ max: options.max,
107
+ idle: options.idle,
108
+ });
109
+
110
+ collectors.push(reactionCollector); // Store reference
111
+ handleCollector(reactionCollector, events, options, metadata);
112
+
113
+ } else {
114
+ throw new Error("Source must be either a Message, Interaction, or Reaction.");
115
+ }
116
+ }
117
+
118
+ return {
119
+ stop: (reason: string = 'manual') => {
120
+ if (options.uniqueId) {
121
+ const cached = collectorCache.get(options.uniqueId);
122
+ if (cached) {
123
+ collectors.forEach((collector) => collector.stop(reason));
124
+ collectorCache.delete(options.uniqueId);
125
+ console.log(`Collector with unique ID "${options.uniqueId}" has been ended. Reason: ${reason}`);
126
+ } else {
127
+ console.warn(`No collector found with unique ID "${options.uniqueId}".`);
128
+ }
129
+ } else {
130
+ collectors.forEach((collector) => collector.stop(reason));
131
+ console.log(`Collectors have been ended. Reason: ${reason}`);
132
+ }
133
+ },
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Generic function to handle a collector's events and lifecycle.
139
+ * @param collector - The specific collector (MessageCollector, InteractionCollector, etc.).
140
+ * @param events - The event handlers for collection lifecycle.
141
+ * @param options - Additional collection options.
142
+ * @param metadata - Optional metadata attached to each collected item.
143
+ */
144
+ function handleCollector<T>(
145
+ collector: any,
146
+ events: {
147
+ onCollect: (collectedItem: T, meta?: Record<string, any>) => void;
148
+ onEnd?: (collected: ReadonlyCollection<Snowflake, T>, reason: string) => void;
149
+ onError?: (error: Error) => void;
150
+ onDispose?: (disposedItem: T) => void;
151
+ onTimeout?: () => void;
152
+ },
153
+ options: { log?: boolean; throttle?: number; uniqueId?: string },
154
+ metadata?: Record<string, any>
155
+ ) {
156
+ let lastCollectedTime = 0;
157
+
158
+ collector.on('collect', (collectedItem: T) => {
159
+ const now = Date.now();
160
+ if (options.throttle && now - lastCollectedTime < options.throttle) {
161
+ if (options.log) console.warn(`Throttled collect for ${collectedItem}`);
162
+ return;
163
+ }
164
+ lastCollectedTime = now;
165
+
166
+ if (options.log) console.log('Collected item:', collectedItem);
167
+ events.onCollect(collectedItem, metadata);
168
+ });
169
+
170
+ collector.on('end', (collected: ReadonlyCollection<Snowflake, T>, reason: string) => {
171
+ if (options.log) console.log(`Collector ended. Reason: ${reason}`);
172
+ if (events.onEnd) events.onEnd(collected, reason);
173
+ if (reason === 'time' && events.onTimeout) {
174
+ events.onTimeout();
175
+ }
176
+
177
+ if (options.uniqueId) {
178
+ collectorCache.delete(options.uniqueId);
179
+ }
180
+ });
181
+
182
+ if (events.onError) {
183
+ collector.on('error', (error: Error) => {
184
+ if (options.log) console.error('Collector error:', error);
185
+ (events.onError as (error: Error) => void)(error);
186
+ });
187
+ }
188
+
189
+ if (events.onDispose) {
190
+ collector.on('dispose', (disposedItem: T) => {
191
+ if (options.log) console.log('Disposed item:', disposedItem);
192
+ (events.onDispose as (disposedItem: T) => void)(disposedItem);
193
+ });
194
+ }
195
+ }
196
+
197
+ export { Djs_Collectors };
@@ -4,7 +4,26 @@ 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 { logError } from '../functions/logger';
7
+ import { logError } from '../functions/logger';
8
+
9
+ async function loadCommand(filePath: string) {
10
+ try {
11
+ const command = require(filePath);
12
+ if (command.data) {
13
+ command.data.cooldown = command.cooldown && !isNaN(command.cooldown) ? command.cooldown : 0;
14
+ command.data.botPerms = command.botPerms || [];
15
+ command.data.userPerms = command.userPerms || [];
16
+ command.data.owner = command.owner || false;
17
+ command.data.developer = command.developer || false;
18
+ command.data.category = command.category || 'Uncategorized';
19
+ return command;
20
+ }
21
+ } catch (error: any) {
22
+ logError(`Error loading command from file: ${filePath}`);
23
+ logError(error.message);
24
+ }
25
+ return null;
26
+ }
8
27
 
9
28
  export async function registerSlashCommands(client: any, token: string, slash: SlashOptions): Promise<Collection<string, any>> {
10
29
  if (!token) {
@@ -19,74 +38,41 @@ export async function registerSlashCommands(client: any, token: string, slash: S
19
38
  const dirents = await readdir(resolvedPath, { withFileTypes: true });
20
39
 
21
40
  for (const dirent of dirents) {
41
+ const folderPath = path.join(resolvedPath, dirent.name);
22
42
  if (dirent.isDirectory()) {
23
- const folderPath = path.join(resolvedPath, dirent.name);
24
43
  const files = await readdir(folderPath);
25
-
26
44
  for (const file of files) {
27
- try {
28
- const command = require(path.join(folderPath, file));
29
- if (command.data) {
30
- if (command.cooldown && !isNaN(command.cooldown)) {
31
- command.data.cooldown = command.cooldown || 0;
32
- }
33
- command.data.botPerms = command.botPerms || [];
34
- command.data.userPerms = command.userPerms || [];
35
- command.data.owner = command.owner || false;
36
- command.data.developer = command.developer || false;
37
- command.data.category = command.category || 'Uncategorized';
38
-
39
-
40
- slashCommands.set(command.data.name, command);
41
- }
42
- } catch (error: any) {
43
- logError(`Error in file: ${path.join(folderPath, file)}`);
44
- logError(error.message);
45
+ const command = await loadCommand(path.join(folderPath, file));
46
+ if (command) {
47
+ slashCommands.set(command.data.name, command);
45
48
  }
46
49
  }
47
50
  } else {
48
- try {
49
- const command = require(path.join(resolvedPath, dirent.name));
50
- if (command.data) {
51
- if (command.cooldown && !isNaN(command.cooldown)) {
52
- command.data.cooldown = command.cooldown || 0;
53
- }
54
- command.data.botPerms = command.botPerms || [];
55
- command.data.userPerms = command.userPerms || [];
56
- command.data.owner = command.owner || false;
57
- command.data.developer = command.developer || false;
58
- command.data.category = command.category || 'Uncategorized';
59
-
60
-
61
- slashCommands.set(command.data.name, command);
62
- }
63
- } catch (error: any) {
64
- logError(`Error in file: ${path.join(resolvedPath, dirent.name)}`);
65
- logError(error.message);
51
+ const command = await loadCommand(path.join(resolvedPath, dirent.name));
52
+ if (command) {
53
+ slashCommands.set(command.data.name, command);
66
54
  }
67
55
  }
68
56
  }
69
57
 
58
+ const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
59
+
70
60
  if (slash.global && !slash.serverId) {
71
- const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
72
- await rest.put(Routes.applicationCommands((client.user?.id || '')), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
61
+ await rest.put(Routes.applicationCommands(client.user?.id || ''), { body: slashCommandArray });
73
62
  } else if (!slash.global && slash.serverId) {
74
63
  const guild = client.guilds.cache.get(slash.serverId) as Guild | undefined;
75
64
  if (guild) {
76
- const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
77
- await rest.put(Routes.applicationGuildCommands((client.user?.id || ''), guild.id), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
65
+ await rest.put(Routes.applicationGuildCommands(client.user?.id || '', guild.id), { body: slashCommandArray });
78
66
  } else {
79
67
  logError(`Guild with ID ${slash.serverId} not found.`);
80
68
  }
81
69
  } else {
82
- const slashCommandArray = Array.from(slashCommands.values()).map(command => command.data.toJSON());
83
- await rest.put(Routes.applicationCommands((client.user?.id || '')), { body: slashCommandArray, headers: { Authorization: `Bot ${token}` } });
70
+ await rest.put(Routes.applicationCommands(client.user?.id || ''), { body: slashCommandArray });
84
71
  }
85
72
  } catch (error: any) {
86
73
  logError('Error registering slash commands:');
87
74
  logError(error.message);
88
75
  console.error(error);
89
-
90
76
  }
91
77
 
92
78
  client.slashCommands = slashCommands;
@@ -1,4 +1,11 @@
1
- import { Collection, Interaction, EmbedBuilder, Snowflake, PermissionResolvable, TextChannel } from 'discord.js';
1
+ import {
2
+ Collection,
3
+ Interaction,
4
+ EmbedBuilder,
5
+ Snowflake,
6
+ PermissionResolvable,
7
+ TextChannel
8
+ } from 'discord.js';
2
9
  import { registerSlashCommands } from './slash-register';
3
10
  import { SlashOptions } from '../types/starter';
4
11
  import { logWarning, logError, logInfo } from '../functions/logger';
@@ -14,41 +21,47 @@ export async function loadSlash(client: any, token: string, options: SlashOption
14
21
  const interactionCooldowns: Collection<Snowflake, Collection<string, number>> = new Collection();
15
22
 
16
23
  client.on('interactionCreate', async (interaction: Interaction) => {
17
- if (!interaction.isCommand() || !interaction.isChatInputCommand()) {
24
+ // Ensure we are handling the correct type of interaction
25
+ if (!interaction.isCommand() && !interaction.isChatInputCommand() && !interaction.isContextMenuCommand()) {
18
26
  return;
19
27
  }
20
28
 
21
- if (interaction.guild?.members.me) {
22
- const user = interaction.user;
29
+ const guild = interaction.guild; // Get the guild once for better readability
30
+ const user = interaction.user;
31
+
32
+ if (guild) {
23
33
  const botData = new Collection<string, string | string[]>();
24
34
  const permissionsArray = botData.get('permissions') as string[] | undefined;
25
-
26
- if (!interaction.guild.members.me.permissions.has('SendMessages')) {
35
+
36
+ // Check if bot has permission to send messages
37
+ if (!guild.members.me?.permissions.has('SendMessages')) {
27
38
  try {
28
- user.send({ content: "I'm sorry, but I don't have permission to send messages in this server."});
39
+ await user.send({ content: "I'm sorry, but I don't have permission to send messages in this server." });
29
40
  } catch (error) {
30
- return;
41
+ return; // Ignore errors when sending the message
31
42
  }
32
43
  }
33
-
44
+
45
+ // Check for missing permissions
34
46
  if (permissionsArray && permissionsArray.length > 0) {
35
- const missingPermissions = permissionsArray.filter(permission => !interaction.guild?.members.me?.permissions.has(permission as PermissionResolvable));
36
-
47
+ const missingPermissions = permissionsArray.filter(permission => !guild.members.me?.permissions.has(permission as PermissionResolvable));
48
+
37
49
  if (missingPermissions.length > 0) {
38
50
  try {
39
- user.send({ content:`I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.`});
51
+ await user.send({ content: `I'm sorry, but I don't have permission(s): ${missingPermissions.join(', ')} in this server.` });
40
52
  } catch (error) {
41
- return;
53
+ return; // Ignore errors when sending the message
42
54
  }
43
55
  }
44
56
  }
45
- }
57
+ }
46
58
 
47
59
  const commandName = interaction.commandName;
48
60
  const command = slashCommands.get(commandName);
49
61
 
50
62
  if (!command) return;
51
63
 
64
+ // Handle command cooldowns
52
65
  if (command.cooldown && !isNaN(command.cooldown)) {
53
66
  const userCooldowns = interactionCooldowns.get(interaction.user.id) || new Collection<string, number>();
54
67
  const cooldownExpiration = userCooldowns.get(command.data.name);
@@ -65,37 +78,29 @@ export async function loadSlash(client: any, token: string, options: SlashOption
65
78
 
66
79
  try {
67
80
  if (command.run) {
68
- if (command.run.length === 2) {
69
- await command.run(interaction, client);
70
- } else {
71
- await command.run(interaction);
72
- }
73
- }
74
- else if (command.execute) {
75
- if (command.execute.length === 2) {
76
- await command.execute(interaction, client);
77
- } else {
78
- await command.execute(interaction);
79
- }
81
+ await command.run.length === 2 ? command.run(interaction, client) : command.run(interaction);
82
+ } else if (command.execute) {
83
+ await command.execute.length === 2 ? command.execute(interaction, client) : command.execute(interaction);
80
84
  } else {
81
85
  logWarning(`Command "${command.data.name}" has neither run nor execute method.`);
82
86
  }
83
87
 
84
- if (options.logsId) {
85
- const channel = interaction.guild?.channels.cache.get(options.logsId as string) as TextChannel;
86
- if(channel) {
87
- const userName = interaction.user.username;
88
- const userId = interaction.user.id;
89
- const serverName = interaction.guild?.name || 'Unknown Server';
90
- const serverId = interaction.guild?.id || 'Unknown ID';
88
+ // Logging command usage
89
+ if (options.logsId && guild) {
90
+ const channel = guild.channels.cache.get(options.logsId as string) as TextChannel;
91
+ if (channel) {
92
+ const userName = user.username;
93
+ const userId = user.id;
94
+ const serverName = guild.name || 'Unknown Server';
95
+ const serverId = guild.id || 'Unknown ID';
91
96
  let messageLink = '';
92
-
97
+
93
98
  if (interaction.channel) {
94
99
  messageLink = `https://discord.com/channels/${serverId}/${interaction.channel.id}/${interaction.id}`;
95
100
  } else {
96
101
  messageLink = 'Unknown';
97
102
  }
98
-
103
+
99
104
  const embedLog = new EmbedBuilder()
100
105
  .setColor("Blue")
101
106
  .setThumbnail(interaction.client.user?.displayAvatarURL())
@@ -110,9 +115,9 @@ export async function loadSlash(client: any, token: string, options: SlashOption
110
115
  { name: "\u200B", value: "\u200B", inline: true },
111
116
  { name: "⏳ Date:", value: `- <t:${Math.floor(Date.now() / 1000)}:R>`, inline: true }
112
117
  );
113
-
114
- await channel.send({ embeds: [embedLog] });
115
- }
118
+
119
+ await channel.send({ embeds: [embedLog] });
120
+ }
116
121
  }
117
122
 
118
123
  const executionTime = Date.now() - startExecutionTime;
@@ -4,7 +4,7 @@ const wait = require('node:timers/promises').setTimeout;
4
4
  import { botData, login } from './login';
5
5
  import { AntiCrash } from '../functions/anticrash';
6
6
  import { loadEvents } from './events';
7
- import { ShardingManager, ShardClientUtil } from 'discord.js';
7
+ import { MessageCollector, InteractionCollector, ShardingManager, ShardClientUtil } from 'discord.js';
8
8
  import path from 'path';
9
9
  import fs from 'fs';
10
10
  import { logError, logInfo, logSuccess } from '../utils';
@@ -80,3 +80,6 @@ export class Starter implements StarterInterface {
80
80
  }, 5000);
81
81
  }
82
82
  }
83
+
84
+
85
+
@@ -9,8 +9,9 @@ import { registerSlashCommands } from "./events-handler/slash-register";
9
9
  import { loadSlash } from "./events-handler/slash-responder";
10
10
  import { logError, logInfo, logSuccess, logWarning } from "./functions/logger";
11
11
  import { Pagination } from "./builder/system/Pagination";
12
+ import { Djs_Collectors } from "./builder/system/collectors";
12
13
  import { loadEvents, withRetry, processEventFile, processDirectory, limitConcurrency, countEventFiles } from "./events-handler/events";
13
14
 
14
15
  export { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
15
16
  loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
16
- processEventFile, logError, logInfo, logSuccess, logWarning, Pagination };
17
+ processEventFile, logError, logInfo, logSuccess, logWarning, Pagination, Djs_Collectors };
package/lib/index.ts CHANGED
@@ -29,12 +29,9 @@ fetch("https://registry.npmjs.com/-/v1/search?text=djs-builder")
29
29
 
30
30
  import { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
31
31
  loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
32
- processEventFile, logError, logInfo, logSuccess, logWarning, Pagination } from "./discord/utils";
32
+ processEventFile, logError, logInfo, logSuccess, logWarning, Pagination, Djs_Collectors } from "./discord/utils";
33
33
 
34
34
  export { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
35
35
  loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
36
- processEventFile , logError, logInfo, logSuccess, logWarning };
37
- export default { Starter, ButtonManager, MenuManager, PermissionChecker, slashLoader, prefixLoader, eventLoader, readCommands, loadEvents,
38
- loadSlash, loadPrefix, handleMessageCreate, processDirectory, countEventFiles, limitConcurrency, withRetry, registerSlashCommands,
39
- processEventFile, logError, logInfo, logSuccess, logWarning, Pagination };
36
+ processEventFile , logError, logInfo, logSuccess, logWarning, Pagination, Djs_Collectors };
40
37
  export * from './discord/types/starter';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "djs-builder",
3
- "version": "0.5.32",
3
+ "version": "0.5.41",
4
4
  "description": "Discord.js bot builder. Supports Ts and Js.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",