@spatulox/simplediscordbot 1.0.24 → 1.0.26

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 (37) hide show
  1. package/.env.example +2 -0
  2. package/dist/SimpleDiscordBotInfo.js +14 -0
  3. package/dist/bot/Bot.js +92 -0
  4. package/dist/bot/BotEnv.js +24 -0
  5. package/dist/bot/BotInteraction.js +74 -0
  6. package/dist/bot/BotLog.js +134 -0
  7. package/dist/bot/BotMessage.js +110 -0
  8. package/dist/manager/FileManager.js +136 -0
  9. package/dist/manager/builder/SendableComponentBuilder.js +62 -0
  10. package/dist/manager/direct/BasicUserManager.js +81 -0
  11. package/dist/manager/direct/UserManager.js +18 -0
  12. package/dist/manager/guild/ChannelManager/ForumChannelManager.js +33 -0
  13. package/dist/manager/guild/ChannelManager/GuildChannelList.js +20 -0
  14. package/dist/manager/guild/ChannelManager/GuildChannelManager.js +91 -0
  15. package/dist/manager/guild/ChannelManager/GuildMessageManager.js +93 -0
  16. package/dist/manager/guild/ChannelManager/GuildTextChannelManager.js +33 -0
  17. package/dist/manager/guild/ChannelManager/GuildVoiceChannelManager.js +33 -0
  18. package/dist/manager/guild/ChannelManager/NewsChannelManager.js +33 -0
  19. package/dist/manager/guild/ChannelManager/StageChannelManager.js +33 -0
  20. package/dist/manager/guild/ChannelManager/ThreadChannelManager.js +49 -0
  21. package/dist/manager/guild/GuildManager.js +144 -0
  22. package/dist/manager/guild/GuildUserManager.js +251 -0
  23. package/dist/manager/guild/InviteManager.js +68 -0
  24. package/dist/manager/guild/InviteManager_old.js +89 -0
  25. package/dist/manager/guild/RoleManager.js +83 -0
  26. package/dist/manager/interactions/ModalManager.js +113 -0
  27. package/dist/manager/interactions/SelectMenuManager.js +123 -0
  28. package/dist/manager/messages/EmbedManager.js +161 -0
  29. package/dist/manager/messages/ReactionManager.js +99 -0
  30. package/dist/manager/messages/WebhookManager.js +108 -0
  31. package/dist/type/FolderName.js +9 -0
  32. package/dist/utils/DiscordRegex.js +117 -0
  33. package/dist/utils/Log.js +28 -0
  34. package/dist/utils/SimpleMutex.js +39 -0
  35. package/dist/utils/network/InternetChecker.js +54 -0
  36. package/dist/utils/times/UnitTime.js +85 -0
  37. package/package.json +2 -4
@@ -0,0 +1,251 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GuildUserManager = void 0;
4
+ const Bot_1 = require("../../bot/Bot");
5
+ const Log_1 = require("../../utils/Log");
6
+ const BasicUserManager_1 = require("../direct/BasicUserManager");
7
+ const discord_js_1 = require("discord.js");
8
+ const promises_1 = require("timers/promises");
9
+ const EmbedManager_1 = require("../messages/EmbedManager");
10
+ const GuildManager_1 = require("./GuildManager");
11
+ const MAX_NICKNAME_LENGTH = 32;
12
+ class GuildUserManager extends BasicUserManager_1.BasicUserManager {
13
+ static async find(userId, guild) {
14
+ try {
15
+ if (guild instanceof discord_js_1.Guild) {
16
+ return await guild.members.fetch(userId);
17
+ }
18
+ else {
19
+ return await (await GuildManager_1.GuildManager.find(guild)).members.fetch(userId);
20
+ }
21
+ }
22
+ catch (error) {
23
+ Log_1.Log.error(`UserManager: Member ${userId} not found`);
24
+ return null;
25
+ }
26
+ }
27
+ static async rename(member, nickname, maxAttempts = 3) {
28
+ if (nickname.length > MAX_NICKNAME_LENGTH) {
29
+ nickname = nickname.slice(0, MAX_NICKNAME_LENGTH);
30
+ }
31
+ for (let attempts = 0; attempts < maxAttempts; attempts++) {
32
+ try {
33
+ const oldName = member.displayName;
34
+ await member.setNickname(nickname.trim());
35
+ Log_1.Log.info(`Renaming user: ${oldName} → ${nickname.trim()}`);
36
+ await (0, promises_1.setTimeout)(1500);
37
+ return true;
38
+ }
39
+ catch (error) {
40
+ console.error(`Attempt ${attempts + 1} failed when renaming ${member.displayName} into ${nickname.trim()}:`, error);
41
+ await (0, promises_1.setTimeout)(1000);
42
+ }
43
+ }
44
+ Bot_1.Bot.log.info(EmbedManager_1.EmbedManager.error(`Failed to rename ${member.displayName} to ${nickname.trim()} after ${maxAttempts} attempts.`));
45
+ return false;
46
+ }
47
+ /**
48
+ * Check if user is banned from guild
49
+ */
50
+ static async isBanned(guildId, userId) {
51
+ try {
52
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
53
+ if (!guild) {
54
+ Log_1.Log.warn(`Guild ${guildId} not found`);
55
+ return false;
56
+ }
57
+ const ban = await guild.bans.fetch(userId);
58
+ return !!ban;
59
+ }
60
+ catch (error) {
61
+ Log_1.Log.debug(`User ${userId} is not banned from guild ${guildId}`);
62
+ return false;
63
+ }
64
+ }
65
+ /**
66
+ * Deconnect a member from a voice
67
+ */
68
+ static async deconnectFromVoice(guildId, memberId) {
69
+ try {
70
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
71
+ if (!guild) {
72
+ throw new Error(`Guild ${guildId} not found`);
73
+ }
74
+ const member = await guild.members.fetch(memberId);
75
+ if (!member.voice.channel) {
76
+ throw new Error(`Member ${memberId} is not in a voice channel`);
77
+ }
78
+ await member.voice.disconnect();
79
+ Log_1.Log.info(`Disconnected member ${memberId} from voice in guild ${guildId}`);
80
+ }
81
+ catch (error) {
82
+ Log_1.Log.error(`Failed to disconnect member ${memberId} from voice in ${guildId}: ${error}`);
83
+ throw error;
84
+ }
85
+ }
86
+ /**
87
+ * Check if a member is in voice
88
+ */
89
+ static async isInVoice(memberId, guildId) {
90
+ try {
91
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
92
+ if (!guild)
93
+ return false;
94
+ const member = await guild.members.fetch(memberId);
95
+ return member.voice.channelId !== null;
96
+ }
97
+ catch (error) {
98
+ Log_1.Log.debug(`Member ${memberId} not found or not in voice in guild ${guildId}`);
99
+ return false;
100
+ }
101
+ }
102
+ /**
103
+ * Mute a member
104
+ */
105
+ static async mute(guildId, memberId, reason) {
106
+ try {
107
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
108
+ if (!guild)
109
+ throw new Error(`Guild ${guildId} not found`);
110
+ const member = await guild.members.fetch(memberId);
111
+ await member.voice.setMute(true, reason);
112
+ Log_1.Log.info(`Server muted ${memberId} in guild ${guildId}: ${reason || 'No reason'}`);
113
+ }
114
+ catch (error) {
115
+ Log_1.Log.error(`Failed to server mute ${memberId} in ${guildId}:, error`);
116
+ throw error;
117
+ }
118
+ }
119
+ /**
120
+ * Unmute a member
121
+ */
122
+ static async unmute(guildId, memberId, reason) {
123
+ try {
124
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
125
+ if (!guild)
126
+ throw new Error(`Guild ${guildId} not found`);
127
+ const member = await guild.members.fetch(memberId);
128
+ await member.voice.setMute(false, reason);
129
+ Log_1.Log.info(`Server unmuted ${memberId} in guild ${guildId}: ${reason || 'No reason'}`);
130
+ }
131
+ catch (error) {
132
+ Log_1.Log.error(`Failed to server unmute ${memberId} in ${guildId}: ${error}`);
133
+ throw error;
134
+ }
135
+ }
136
+ /**
137
+ * Deafen a member
138
+ */
139
+ static async deafen(guildId, memberId, reason) {
140
+ try {
141
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
142
+ if (!guild)
143
+ throw new Error(`Guild ${guildId} not found`);
144
+ const member = await guild.members.fetch(memberId);
145
+ await member.voice.setDeaf(true, reason);
146
+ Log_1.Log.info(`Server deafened ${memberId} in guild ${guildId}: ${reason || 'No reason'}`);
147
+ }
148
+ catch (error) {
149
+ Log_1.Log.error(`Failed to server deafen ${memberId} in ${guildId}: ${error}`);
150
+ throw error;
151
+ }
152
+ }
153
+ /**
154
+ * Undeafen member voice
155
+ */
156
+ static async undeafen(guildId, memberId, reason) {
157
+ try {
158
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
159
+ if (!guild)
160
+ throw new Error(`Guild ${guildId} not found`);
161
+ const member = await guild.members.fetch(memberId);
162
+ await member.voice.setDeaf(false, reason);
163
+ Log_1.Log.info(`Server undeafened ${memberId} in guild ${guildId}: ${reason || 'No reason'}`);
164
+ }
165
+ catch (error) {
166
+ Log_1.Log.error(`Failed to server undeafen ${memberId} in ${guildId}: ${error}`);
167
+ throw error;
168
+ }
169
+ }
170
+ /**
171
+ * Timeout a member
172
+ */
173
+ static async timeout(guildId, memberId, duration, reason) {
174
+ try {
175
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
176
+ if (!guild)
177
+ throw new Error(`Guild ${guildId} not found`);
178
+ const member = await guild.members.fetch(memberId);
179
+ const expires = Date.now() + duration;
180
+ await member.timeout(expires, reason);
181
+ Log_1.Log.info(`Timed out ${memberId} for ${duration}ms in guild ${guildId}: ${reason || 'No reason'}`);
182
+ }
183
+ catch (error) {
184
+ Log_1.Log.error(`Failed to timeout ${memberId} in ${guildId}: ${error}`);
185
+ throw error;
186
+ }
187
+ }
188
+ /**
189
+ * Remove the timeout of a member
190
+ */
191
+ static async untimeout(guildId, memberId, reason) {
192
+ try {
193
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
194
+ if (!guild)
195
+ throw new Error(`Guild ${guildId} not found`);
196
+ const member = await guild.members.fetch(memberId);
197
+ await member.timeout(null, reason);
198
+ Log_1.Log.info(`Untimed out ${memberId} in guild ${guildId}: ${reason || 'No reason'}`);
199
+ }
200
+ catch (error) {
201
+ Log_1.Log.error(`Failed to untimeout ${memberId} in ${guildId}: ${error}`);
202
+ throw error;
203
+ }
204
+ }
205
+ /**
206
+ * Kick a member
207
+ */
208
+ static async kick(guildId, memberId, reason) {
209
+ try {
210
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
211
+ if (!guild)
212
+ throw new Error(`Guild ${guildId} not found`);
213
+ const member = await guild.members.fetch(memberId);
214
+ await member.kick(reason);
215
+ Log_1.Log.info(`Kicked ${memberId} from guild ${guildId}: ${reason || 'No reason'}`);
216
+ }
217
+ catch (error) {
218
+ Log_1.Log.error(`Failed to kick ${memberId} from ${guildId}: ${error}`);
219
+ throw error;
220
+ }
221
+ }
222
+ static async ban(guildId, userId, banOption) {
223
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
224
+ if (!guild) {
225
+ throw new Error(`Guild ${guildId} not found`);
226
+ }
227
+ try {
228
+ await guild.members.ban(userId, banOption);
229
+ Log_1.Log.info(`Banned user ${userId} from guild ${guildId}`);
230
+ }
231
+ catch (error) {
232
+ Log_1.Log.error(`Failed to ban user ${userId} from guild ${guildId}: ${error}`);
233
+ throw error;
234
+ }
235
+ }
236
+ static async unban(guildId, userId, reason) {
237
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
238
+ if (!guild) {
239
+ throw new Error(`Guild ${guildId} not found`);
240
+ }
241
+ try {
242
+ await guild.members.unban(userId, reason);
243
+ Log_1.Log.info(`Unbanned user ${userId} from guild ${guildId}`);
244
+ }
245
+ catch (error) {
246
+ Log_1.Log.error(`Failed to unban user ${userId} from guild ${guildId}: ${error}`);
247
+ throw error;
248
+ }
249
+ }
250
+ }
251
+ exports.GuildUserManager = GuildUserManager;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InviteManager = void 0;
4
+ const Log_1 = require("../../utils/Log");
5
+ const Bot_1 = require("../../bot/Bot");
6
+ const GuildChannelManager_1 = require("./ChannelManager/GuildChannelManager");
7
+ class InviteManager {
8
+ /**
9
+ * Create an invite for a channel
10
+ */
11
+ static async create(channelId, options = {}) {
12
+ try {
13
+ const channel = await GuildChannelManager_1.GuildChannelManager.find(channelId);
14
+ if (!channel) {
15
+ throw new Error(`Channel ${channelId} not found`);
16
+ }
17
+ const guild = channel.guild;
18
+ const inviteOptions = {
19
+ maxAge: options.maxAge ?? 86400,
20
+ maxUses: options.maxUses ?? 0,
21
+ temporary: options.temporary ?? false,
22
+ reason: options.reason
23
+ };
24
+ // ✅ guild.invites.create(channelId, options)
25
+ const invite = await guild.invites.create(channelId, inviteOptions);
26
+ Log_1.Log.info(`Created invite ${invite.code} for channel ${channelId}`);
27
+ return invite;
28
+ }
29
+ catch (error) {
30
+ Log_1.Log.error(`Failed to create invite for channel ${channelId}: ${error}`);
31
+ throw error;
32
+ }
33
+ }
34
+ /**
35
+ * Delete an invitation
36
+ */
37
+ static async delete(invite) {
38
+ try {
39
+ await invite.delete();
40
+ Log_1.Log.info(`Deleted invite ${invite.code} from guild ${invite.guild?.id}`);
41
+ return true;
42
+ }
43
+ catch (error) {
44
+ Log_1.Log.error(`Failed to delete invite ${invite.code}: ${error}`);
45
+ return false;
46
+ }
47
+ }
48
+ /**
49
+ * List every invitation from a guild
50
+ */
51
+ static async list(guildId) {
52
+ try {
53
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
54
+ if (!guild) {
55
+ throw new Error(`Guild ${guildId} not found`);
56
+ }
57
+ const invites = await guild.invites.fetch();
58
+ const inviteList = Array.from(invites.values());
59
+ Log_1.Log.info(`Fetched ${inviteList.length} invites for guild ${guildId}`);
60
+ return inviteList;
61
+ }
62
+ catch (error) {
63
+ Log_1.Log.error(`Failed to fetch invites for guild ${guildId}: ${error}`);
64
+ throw error;
65
+ }
66
+ }
67
+ }
68
+ exports.InviteManager = InviteManager;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InviteManager = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const Bot_1 = require("../../bot/Bot");
6
+ const Log_1 = require("../../utils/Log");
7
+ class InviteManager {
8
+ /**
9
+ * Check if invite is old (more than 1 hour)
10
+ */
11
+ static isOld(invite, excludedInvite = []) {
12
+ const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000); // 1h
13
+ if (!invite.createdAt) {
14
+ return false;
15
+ }
16
+ return (invite.maxAge !== 0 &&
17
+ !excludedInvite.includes(invite.code) &&
18
+ invite.createdAt < oneHourAgo);
19
+ }
20
+ /**
21
+ * Delete single invite
22
+ */
23
+ static async delete(invite) {
24
+ try {
25
+ await invite.delete();
26
+ if (invite.createdAt) {
27
+ Log_1.Log.info(`🗑️ Deleted invite \`${invite.code}\` created ${invite.createdAt.toDateString()}`);
28
+ return true;
29
+ }
30
+ Log_1.Log.warn(`Invite ${invite.code} deleted but no createdAt`);
31
+ return true;
32
+ }
33
+ catch (error) {
34
+ Log_1.Log.error(`Failed to delete invite ${invite.code}: ${error.message}`);
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Delete all old invites from guild
40
+ */
41
+ static async cleanupGuild(guildId) {
42
+ try {
43
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
44
+ if (!guild) {
45
+ Log_1.Log.error(`Guild ${guildId} not found for invite cleanup`);
46
+ return 0;
47
+ }
48
+ const invites = await guild.invites.fetch();
49
+ let deletedCount = 0;
50
+ for (const [_code, invite] of invites) {
51
+ if (this.isOld(invite)) {
52
+ const success = await this.delete(invite);
53
+ if (success)
54
+ deletedCount++;
55
+ // Rate limit protection
56
+ await new Promise(r => setTimeout(r, 100));
57
+ }
58
+ }
59
+ Log_1.Log.info(`Invite cleanup ${guild.name}: ${deletedCount} old invites deleted`);
60
+ return deletedCount;
61
+ }
62
+ catch (error) {
63
+ Log_1.Log.error(`Invite cleanup failed for ${guildId}: ${error}`);
64
+ return 0;
65
+ }
66
+ }
67
+ /**
68
+ * Get all invites from guild
69
+ */
70
+ static async fetchGuildInvites(guildId) {
71
+ try {
72
+ const guild = Bot_1.Bot.client.guilds.cache.get(guildId);
73
+ if (!guild)
74
+ throw new Error(`Guild ${guildId} not found`);
75
+ return await guild.invites.fetch();
76
+ }
77
+ catch (error) {
78
+ Log_1.Log.error(`Failed to fetch invites for ${guildId}: ${error}`);
79
+ return new discord_js_1.Collection();
80
+ }
81
+ }
82
+ /**
83
+ * Get old invites only
84
+ */
85
+ static getOldInvites(invites) {
86
+ return invites.filter(invite => this.isOld(invite)).map(invite => invite);
87
+ }
88
+ }
89
+ exports.InviteManager = InviteManager;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleManager = void 0;
4
+ const Log_1 = require("../../utils/Log");
5
+ class RoleManager {
6
+ /**
7
+ * Add role - CACHE ONLY
8
+ * @param member - GuildMember ALREADY FETCHED
9
+ * @param roleId - Role ID (string)
10
+ */
11
+ static async add(member, roleId) {
12
+ try {
13
+ const role = member.roles.cache.get(roleId);
14
+ if (!role) {
15
+ Log_1.Log.warn(`Role ${roleId} not found in cache`);
16
+ return false;
17
+ }
18
+ await member.roles.add(role);
19
+ Log_1.Log.info(`✅ Added ${role.name} to ${member.displayName}`);
20
+ return true;
21
+ }
22
+ catch (error) {
23
+ Log_1.Log.error(`Failed to add role ${roleId}: ${error}`);
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Remove role - CACHE ONLY
29
+ * @param member - GuildMember ALREADY FETCHED
30
+ * @param roleIdOrName - Role ID or name
31
+ */
32
+ static async remove(member, roleIdOrName) {
33
+ try {
34
+ let role;
35
+ if (typeof roleIdOrName === 'string' && roleIdOrName.length === 18) {
36
+ role = member.roles.cache.get(roleIdOrName);
37
+ }
38
+ else {
39
+ role = member.roles.cache.find(r => r.id === roleIdOrName || r.name.toLowerCase() === roleIdOrName.toString().toLowerCase());
40
+ }
41
+ if (!role) {
42
+ Log_1.Log.warn(`Role ${roleIdOrName} not found for ${member.displayName}`);
43
+ return false;
44
+ }
45
+ await member.roles.remove(role);
46
+ Log_1.Log.info(`✅ Removed ${role.name} from ${member.displayName}`);
47
+ return true;
48
+ }
49
+ catch (error) {
50
+ Log_1.Log.error(`Failed to remove role ${roleIdOrName}: ${error}`);
51
+ return false;
52
+ }
53
+ }
54
+ /**
55
+ * Toggle role (add/remove)
56
+ */
57
+ static async toggle(member, roleIdOrName) {
58
+ const role = member.roles.cache.get(roleIdOrName) ||
59
+ member.roles.cache.find(r => r.name.toLowerCase() === roleIdOrName.toString().toLowerCase());
60
+ if (!role) {
61
+ Log_1.Log.warn(`Role ${roleIdOrName} not found`);
62
+ throw new Error(`Role not found`);
63
+ }
64
+ if (member.roles.cache.has(role.id)) {
65
+ await this.remove(member, role.id);
66
+ return 'removed';
67
+ }
68
+ else {
69
+ await this.add(member, role.id);
70
+ return 'added';
71
+ }
72
+ }
73
+ /**
74
+ * Check if member has role
75
+ */
76
+ static hasRole(member, roleIdOrName) {
77
+ if (typeof roleIdOrName === 'string' && roleIdOrName.length === 18) {
78
+ return member.roles.cache.has(roleIdOrName);
79
+ }
80
+ return member.roles.cache.some(r => r.id === roleIdOrName || r.name.toLowerCase() === roleIdOrName.toString().toLowerCase());
81
+ }
82
+ }
83
+ exports.RoleManager = RoleManager;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModalManager = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const FolderName_1 = require("../../type/FolderName");
6
+ const FileManager_1 = require("../FileManager");
7
+ class ModalManager {
8
+ /**
9
+ * Load modal from JSON file and return ModalBuilder
10
+ */
11
+ static async load(filename) {
12
+ try {
13
+ const file = await FileManager_1.FileManager.readJsonFile(`./handlers/${FolderName_1.FolderName.MODAL}/${filename}`);
14
+ if (!file)
15
+ return false;
16
+ return ModalManager.jsonToBuilder(file);
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ /**
23
+ * List all modal files
24
+ */
25
+ static async list() {
26
+ try {
27
+ const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${FolderName_1.FolderName.MODAL}`);
28
+ return files || [];
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ static jsonToBuilder(json) {
35
+ const modal = new discord_js_1.ModalBuilder()
36
+ .setCustomId(json.customId)
37
+ .setTitle(json.title.slice(0, 45));
38
+ const actionRows = [];
39
+ for (const fieldJson of json.fields) {
40
+ const input = this.fieldJsonToInput(fieldJson);
41
+ const row = new discord_js_1.ActionRowBuilder()
42
+ .addComponents(input);
43
+ actionRows.push(row);
44
+ }
45
+ return modal.addComponents(...actionRows);
46
+ }
47
+ static fieldJsonToInput(fieldJson) {
48
+ const input = new discord_js_1.TextInputBuilder()
49
+ .setCustomId(fieldJson.customId)
50
+ .setLabel(fieldJson.title.slice(0, 45))
51
+ .setPlaceholder(fieldJson.placeholder || 'Enter value...')
52
+ .setRequired(fieldJson.required !== false)
53
+ .setMinLength(fieldJson.minLength || 0)
54
+ .setMaxLength(fieldJson.maxLength || 400);
55
+ // Convertir style JSON (1, 2, "Number") → TextInputStyle
56
+ const style = fieldJson.style;
57
+ if (typeof style === 'number') {
58
+ // 1=Short, 2=Paragraph
59
+ input.setStyle(style);
60
+ }
61
+ else {
62
+ // "Number", "Phone", "Date"
63
+ switch (style) {
64
+ case 'Number':
65
+ case 'Phone':
66
+ case 'Date':
67
+ input.setStyle(discord_js_1.TextInputStyle.Short);
68
+ input.setPlaceholder(style === 'Number' ? '123' :
69
+ style === 'Phone' ? '+33 6 12 34 56 78' :
70
+ '2024-02-05');
71
+ break;
72
+ default:
73
+ input.setStyle(discord_js_1.TextInputStyle.Short);
74
+ }
75
+ }
76
+ return input;
77
+ }
78
+ static parseNumber(value) {
79
+ if (!/^\d+$/.test(value))
80
+ return null;
81
+ const num = parseInt(value);
82
+ return isNaN(num) ? null : num;
83
+ }
84
+ static parsePhone(value) {
85
+ // 0604050359, +33604050359, 06 40 50 35 59, (06) 40-50-35-59
86
+ const clean = value.replace(/[\s\-\(\)]/g, '');
87
+ // Français : 06/07/09 + 8 chiffres OU +33 + 9 chiffres
88
+ if (/^(06|07|09)\d{8}$/.test(clean) || /^(\+33|0033)?[6-9]\d{8}$/.test(clean)) {
89
+ // Normalise au format international
90
+ if (clean.startsWith('06') || clean.startsWith('07') || clean.startsWith('09')) {
91
+ return '+33' + clean.slice(2);
92
+ }
93
+ return clean.startsWith('0033') ? '+33' + clean.slice(4) : clean;
94
+ }
95
+ return null;
96
+ }
97
+ static parseDate(value) {
98
+ // yyyy-mm-dd → Date
99
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
100
+ const [year, month, day] = value.split('-').map(Number);
101
+ const date = new Date(year, month - 1, day);
102
+ return isNaN(date.getTime()) ? null : date;
103
+ }
104
+ // dd/mm/yyyy → Date
105
+ if (/^\d{2}\/\d{2}\/\d{4}$/.test(value)) {
106
+ const [day, month, year] = value.split('/').map(Number);
107
+ const date = new Date(year, month - 1, day);
108
+ return isNaN(date.getTime()) ? null : date;
109
+ }
110
+ return null;
111
+ }
112
+ }
113
+ exports.ModalManager = ModalManager;