@spatulox/simplediscordbot 1.0.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 (64) hide show
  1. package/.env.example +2 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +1 -0
  4. package/dist/bot/Bot.js +107 -0
  5. package/dist/bot/BotEnv.js +29 -0
  6. package/dist/bot/BotLog.js +90 -0
  7. package/dist/bot/BotMessage.js +79 -0
  8. package/dist/cli/BaseCLI.js +165 -0
  9. package/dist/cli/GenerationCLI/ContextMenuGeneratorCLI.js +109 -0
  10. package/dist/cli/GenerationCLI/GenerationCLI.js +25 -0
  11. package/dist/cli/GenerationCLI/InteractionGeneratorCLI.js +20 -0
  12. package/dist/cli/GenerationCLI/ModalGeneratorCLI.js +166 -0
  13. package/dist/cli/GenerationCLI/SlashCommandsGeneratorCLI.js +221 -0
  14. package/dist/cli/GenerationCLI.js +36 -0
  15. package/dist/cli/GuildListManager.js +61 -0
  16. package/dist/cli/InputCLI.js +25 -0
  17. package/dist/cli/InteractionCLI/InteractionCLI.js +30 -0
  18. package/dist/cli/InteractionCLI/InteractionCLIManager.js +80 -0
  19. package/dist/cli/InteractionCLI.js +109 -0
  20. package/dist/cli/MainCLI.js +32 -0
  21. package/dist/cli/type/ContextMenuConfig.js +2 -0
  22. package/dist/cli/type/InteractionType.js +14 -0
  23. package/dist/cli/type/SlashCommandConfig.js +2 -0
  24. package/dist/index.js +31 -0
  25. package/dist/manager/FileManager.js +136 -0
  26. package/dist/manager/direct/UserManager.js +76 -0
  27. package/dist/manager/discord/ChannelManager.js +48 -0
  28. package/dist/manager/discord/DiscordRegex.js +114 -0
  29. package/dist/manager/discord/GuildManager.js +67 -0
  30. package/dist/manager/discord/InviteManager.js +89 -0
  31. package/dist/manager/discord/RoleManager.js +83 -0
  32. package/dist/manager/discord/UserManager.js +69 -0
  33. package/dist/manager/guild/ChannelManager/ForumChannelManager.js +33 -0
  34. package/dist/manager/guild/ChannelManager/GuildChannelList.js +20 -0
  35. package/dist/manager/guild/ChannelManager/GuildChannelManager.js +91 -0
  36. package/dist/manager/guild/ChannelManager/GuildMessageManager.js +85 -0
  37. package/dist/manager/guild/ChannelManager/GuildTextChannelManager.js +33 -0
  38. package/dist/manager/guild/ChannelManager/GuildVoiceChannelManager.js +33 -0
  39. package/dist/manager/guild/ChannelManager/NewsChannelManager.js +33 -0
  40. package/dist/manager/guild/ChannelManager/StageChannelManager.js +33 -0
  41. package/dist/manager/guild/ChannelManager/ThreadChannelManager.js +34 -0
  42. package/dist/manager/guild/GuildManager.js +134 -0
  43. package/dist/manager/guild/GuildUserManager.js +212 -0
  44. package/dist/manager/guild/InviteManager.js +68 -0
  45. package/dist/manager/guild/InviteManager_old.js +89 -0
  46. package/dist/manager/guild/RoleManager.js +83 -0
  47. package/dist/manager/hadlers_old/builder/ModalManager.js +111 -0
  48. package/dist/manager/hadlers_old/builder/delete.js +49 -0
  49. package/dist/manager/hadlers_old/builder/deploy.js +225 -0
  50. package/dist/manager/hadlers_old/builder/interactions/CommandManager.js +14 -0
  51. package/dist/manager/hadlers_old/builder/interactions/ContextMenuManager.js +14 -0
  52. package/dist/manager/hadlers_old/builder/interactions/InteractionBase.js +341 -0
  53. package/dist/manager/hadlers_old/builder/interactions/InteractionManager.js +65 -0
  54. package/dist/manager/hadlers_old/builder/list.js +166 -0
  55. package/dist/manager/messages/EmbedManager.js +131 -0
  56. package/dist/manager/messages/ReactionManager.js +99 -0
  57. package/dist/manager/messages/WebhookManager.js +105 -0
  58. package/dist/type/FolderName.js +9 -0
  59. package/dist/utils/DiscordRegex.js +116 -0
  60. package/dist/utils/Log.js +28 -0
  61. package/dist/utils/SimpleMutex.js +39 -0
  62. package/dist/utils/network/InternetChecker.js +54 -0
  63. package/dist/utils/times/UnitTime.js +85 -0
  64. package/package.json +40 -0
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rest_1 = require("@discordjs/rest");
4
+ const v10_1 = require("discord-api-types/v10");
5
+ const Log_1 = require("../../../utils/Log");
6
+ const BotEnv_1 = require("../../../bot/BotEnv");
7
+ const Bot_1 = require("../../../bot/Bot");
8
+ async function deleteAllCommandsAndMenus() {
9
+ const rest = new rest_1.REST({ version: '10' }).setToken(BotEnv_1.BotEnv.token);
10
+ const guildIDs = ["1111160769132896377", "1214320754578165901"]; // Liste des guildes à vérifier
11
+ try {
12
+ // 1. Suppression des commandes/menus globaux
13
+ Log_1.Log.info('INFO : Suppression des commandes et menus contextuels globaux...');
14
+ const globalCommands = await rest.get(v10_1.Routes.applicationCommands(Bot_1.Bot.config.clientId));
15
+ for (const command of globalCommands) {
16
+ try {
17
+ await rest.delete(v10_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, command.id));
18
+ Log_1.Log.info(`Commande/menu contextuel global "${command.name}" supprimé.`);
19
+ }
20
+ catch (err) {
21
+ Log_1.Log.error(`Impossible de supprimer la commande/menu contextuel global "${command.name}" : ${err.message}`);
22
+ }
23
+ }
24
+ // 2. Suppression des commandes/menus spécifiques aux guildes
25
+ Log_1.Log.info('Suppression des commandes et menus contextuels spécifiques aux guildes...');
26
+ for (const guildId of guildIDs) {
27
+ try {
28
+ const guildCommands = await rest.get(v10_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId));
29
+ for (const command of guildCommands) {
30
+ try {
31
+ await rest.delete(v10_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, command.id));
32
+ Log_1.Log.info(`Commande/menu contextuel "${command.name}" supprimé sur la guilde ${guildId}.`);
33
+ }
34
+ catch (err) {
35
+ Log_1.Log.error(`Impossible de supprimer la commande/menu contextuel "${command.name}" sur la guilde ${guildId} : ${err.message}`);
36
+ }
37
+ }
38
+ }
39
+ catch (err) {
40
+ Log_1.Log.error(`Impossible de récupérer ou supprimer les commandes/menus contextuels pour le serveur ${guildId} : ${err.message}`);
41
+ }
42
+ }
43
+ Log_1.Log.info('Toutes les commandes et menus contextuels ont été supprimés.');
44
+ }
45
+ catch (err) {
46
+ Log_1.Log.error(`Impossible de récupérer ou supprimer les commandes/menus contextuels : ${err.message}`);
47
+ }
48
+ }
49
+ deleteAllCommandsAndMenus();
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /*import { PermissionFlagsBits } from 'discord-api-types/v10';
4
+ import { REST } from '@discordjs/rest';
5
+ import { Routes } from 'discord-api-types/v10';
6
+ import { setTimeout } from "timers/promises";
7
+ import { client } from '../utils/client.js';
8
+ import { Time } from '../utils/times/UnitTime.js';
9
+ import { log } from '../utils/log.js';
10
+ import { listJsonFile, readJsonFile, writeJsonFileRework } from '../utils/server/files.js';
11
+ import { loginBot } from '../utils/login.js';
12
+ import config from '../config.js';
13
+ import {Events} from "discord.js";
14
+
15
+
16
+ export interface Command {
17
+ name: string;
18
+ description: string;
19
+ options?: any[];
20
+ default_member_permissions?: string | bigint | number;
21
+ guildID?: string[];
22
+ type: 1 | 2 | 3; // 1 = slash, 2 = user context, 3 = message context
23
+ id?: string; // Discord API Command ID
24
+ }
25
+
26
+ // Initialisation du REST
27
+ client.rest = new REST({ version: '10' }).setToken(config.token);
28
+
29
+ export async function deployCommand(commandPath: string[]): Promise<void> {
30
+ if (!(await loginBot(client))) {
31
+ log("Erreur : Impossible de connecter le bot");
32
+ process.exit()
33
+ }
34
+
35
+ client.once(Events.ClientReady, async () => {
36
+ log('INFO : Déploiement des commandes slash');
37
+
38
+ for (const path of commandPath){
39
+ const slashFiles = await listJsonFile(`./handlers/${path}/`);
40
+ if (!slashFiles) {
41
+ log('ERREUR : Impossible de lire les fichiers de commandes');
42
+ return;
43
+ }
44
+ console.log(`${slashFiles.length} ${path}`)
45
+ }
46
+
47
+ // Récupère toutes les commandes actuelles sur Discord
48
+ const globalDiscordCmds: any[] = await client.rest.get(
49
+ Routes.applicationCommands(client.user!.id)
50
+ ) as any[];
51
+
52
+ const allLocalCommands: Command[] = [];
53
+ const guildDiscordCmds = {} as Record<string, any[]>;
54
+
55
+ for(const path of commandPath){
56
+ const slashFiles = await listJsonFile(`./${path}/`);
57
+ if (!slashFiles) {
58
+ log('ERREUR : Impossible de lire les fichiers de commandes');
59
+ return;
60
+ }
61
+
62
+
63
+ // Pour chaque guilde utilisée dans tes JSONs
64
+ const allGuildIds = new Set<string>();
65
+ for (const filename of slashFiles) {
66
+ const cmdData = await readJsonFile(`./${path}/${filename}`);
67
+ if (cmdData?.guildID) {
68
+ for (const gid of cmdData.guildID) allGuildIds.add(gid);
69
+ }
70
+ }
71
+
72
+ for (const guildId of allGuildIds) {
73
+ try {
74
+ guildDiscordCmds[guildId] = await client.rest.get(
75
+ Routes.applicationGuildCommands(config.clientId, guildId)
76
+ ) as any[];
77
+ } catch (error) {
78
+ console.error()
79
+ }
80
+ }
81
+
82
+ // ---------------------- Déploiement attendue ---------------------------
83
+
84
+ for (const file of slashFiles.filter((n: string | string[])=>!n.includes('example'))) {
85
+ let updated = false;
86
+ const cmd: Command | false = await readJsonFile(`./${path}/${file}`);
87
+ if(!cmd) continue;
88
+
89
+ // Traitement permissions
90
+ if (cmd.default_member_permissions && Array.isArray(cmd.default_member_permissions)) {
91
+ const bitfield = cmd.default_member_permissions
92
+ .map(perm => {
93
+ const flag = PermissionFlagsBits[perm as keyof typeof PermissionFlagsBits];
94
+ if (flag === undefined) throw new Error(`Permission inconnue : "${perm}"`);
95
+ return flag;
96
+ })
97
+ .reduce((acc, val) => acc | val, BigInt(0));
98
+ cmd.default_member_permissions = Number(bitfield)
99
+ }
100
+
101
+ // Déploiement Guild vs Global
102
+ const deployToGuilds = (cmd.guildID && cmd.guildID.length > 0) ? cmd.guildID : [];
103
+ if (deployToGuilds.length > 0) {
104
+ for (const guildId of deployToGuilds) {
105
+ // Cherche la commande existante sur Discord
106
+ const found = guildDiscordCmds[guildId]?.find(e => e.id === cmd.id || e.name === cmd.name);
107
+ const dataToSend = { ...cmd };
108
+ delete dataToSend.guildID;
109
+
110
+ if (cmd.type === 2 || cmd.type === 3) {
111
+ // Les context menus ne doivent **pas** utiliser `options`
112
+ console.log("on delete options")
113
+ delete dataToSend.options;
114
+ }
115
+
116
+ try {
117
+ if (!cmd.id || !found) {
118
+ // Pas d'ID ou pas trouvée, on crée la commande
119
+ console.log("Pas d'ID ou pas trouvée, on crée la commande : " + dataToSend.name)
120
+ const resp = await client.rest.post(
121
+ Routes.applicationGuildCommands(config.clientId, guildId),
122
+ { body: dataToSend }
123
+ ) as any;
124
+ cmd.id = resp.id;
125
+ updated = true;
126
+ log(`SUCCÈS : Commande "${cmd.name}" déployée/guild ${guildId}, id = ${cmd.id}`);
127
+ } else {
128
+ // Si déjà existante, on la met à jour
129
+ console.log("Si déjà existante, on la met à jour : " + dataToSend.name)
130
+ await client.rest.patch(
131
+ Routes.applicationGuildCommand(config.clientId, guildId, found.id),
132
+ { body: dataToSend }
133
+ );
134
+ cmd.id = found.id;
135
+ log(`MAJ : Commande "${cmd.name}" mise à jour/guild ${guildId}, id = ${cmd.id}`);
136
+ }
137
+ await setTimeout(Time.second.SEC_01.toMilliseconds());
138
+ } catch (error) {
139
+ console.log(error)
140
+ }
141
+ }
142
+ } else {
143
+ // Commande globale
144
+ const found = globalDiscordCmds.find(e => e.id === cmd.id || e.name === cmd.name);
145
+ const dataToSend = { ...cmd };
146
+ delete dataToSend.guildID;
147
+ if (cmd.type === 2 || cmd.type === 3) {
148
+ // Les context menus ne doivent **pas** utiliser `options`
149
+ delete dataToSend.options;
150
+ }
151
+
152
+ try {
153
+ if (!cmd.id || !found) {
154
+ const resp = await client.rest.post(
155
+ Routes.applicationCommands(client.user!.id),
156
+ { body: dataToSend }
157
+ ) as any;
158
+ cmd.id = resp.id;
159
+ updated = true;
160
+ log(`SUCCÈS : Commande globale "${cmd.name}" déployée, id = ${cmd.id}`);
161
+ } else {
162
+ await client.rest.patch(
163
+ Routes.applicationCommand(client.user!.id, found.id),
164
+ { body: dataToSend }
165
+ );
166
+ cmd.id = found.id;
167
+ log(`MAJ : Commande globale "${cmd.name}" mise à jour, id = ${cmd.id}`);
168
+ }
169
+ } catch (error) {
170
+ console.log(error)
171
+ }
172
+ }
173
+ //if (updated) await writeJsonFileRework(`./${path}/`, `${file}`, cmd); // Sauvegarde l'id Discord
174
+ if (updated) {
175
+ allLocalCommands.push(cmd); // Ajoute ici la version à jour de la commande
176
+ await writeJsonFileRework(`./${path}/`, `${file}`, cmd);
177
+ } else {
178
+ allLocalCommands.push(cmd); // Même si elle n’a pas été modifiée, on veut la conserver
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ // ---------------------- SUPPRESSION COMMANDES ---------------------------
186
+
187
+ const localNames = allLocalCommands.map(c => c.name); // Regroupe toutes les commandes locales
188
+
189
+ // Supprime les commandes globales non déclarées
190
+ for (const apiCmd of globalDiscordCmds) {
191
+ try {
192
+ if (!localNames.includes(apiCmd.name)) {
193
+ await client.rest.delete(
194
+ Routes.applicationCommand(client.user!.id, apiCmd.id)
195
+ );
196
+ log(`SUPPR : Commande globale "${apiCmd.name}" supprimée, id = ${apiCmd.id}`);
197
+ }
198
+ } catch (error) {
199
+ console.log(error);
200
+ }
201
+ }
202
+
203
+ // Supprime les commandes guild non déclarées
204
+ for (const gid of Object.keys(guildDiscordCmds)) {
205
+ const current = guildDiscordCmds[gid];
206
+ if (!current) continue;
207
+ for (const apiCmd of current) {
208
+ try {
209
+ if (!localNames.includes(apiCmd.name)) {
210
+ await client.rest.delete(
211
+ Routes.applicationGuildCommand(config.clientId, gid, apiCmd.id)
212
+ );
213
+ log(`SUPPR : Commande "${apiCmd.name}" supprimée de guild ${gid}`);
214
+ }
215
+ } catch (error) {
216
+ console.log(error);
217
+ }
218
+ }
219
+ }
220
+
221
+ process.exit();
222
+ });
223
+ }
224
+
225
+ deployCommand(["context_menu", "commands"]);*/
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommandManager = void 0;
4
+ // src/discord/CommandManager.ts
5
+ const InteractionBase_1 = require("./InteractionBase");
6
+ class CommandManager extends InteractionBase_1.InteractionBase {
7
+ get name() {
8
+ return "📋 SLASH COMMAND MANAGER";
9
+ }
10
+ get interactionHandlerFolder() {
11
+ return "commands";
12
+ }
13
+ }
14
+ exports.CommandManager = CommandManager;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextMenuManager = void 0;
4
+ // src/discord/ContextMenuManager.ts
5
+ const InteractionBase_1 = require("./InteractionBase");
6
+ class ContextMenuManager extends InteractionBase_1.InteractionBase {
7
+ get name() {
8
+ return `📋 CONTEXT MENU MANAGER`;
9
+ }
10
+ get interactionHandlerFolder() {
11
+ return "context_menu";
12
+ }
13
+ }
14
+ exports.ContextMenuManager = ContextMenuManager;
@@ -0,0 +1,341 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.InteractionBase = void 0;
7
+ const discord_js_1 = require("discord.js");
8
+ const readline_1 = __importDefault(require("readline"));
9
+ const FileManager_1 = require("../../../FileManager");
10
+ const Bot_1 = require("../../../../bot/Bot");
11
+ const BotEnv_1 = require("../../../../bot/BotEnv");
12
+ const Log_1 = require("../../../../utils/Log");
13
+ class InteractionBase {
14
+ constructor() {
15
+ this.currentState = 'menu';
16
+ this.deployFiles = [];
17
+ this.rest = new discord_js_1.REST({ version: '10' }).setToken(BotEnv_1.BotEnv.token);
18
+ this.rl = readline_1.default.createInterface({
19
+ input: process.stdin,
20
+ output: process.stdout
21
+ });
22
+ }
23
+ /** 🚀 START INTERACTIF (100% automatique) */
24
+ async startInteractive() {
25
+ Log_1.Log.info('================================');
26
+ console.clear();
27
+ Log_1.Log.info(`${this.name}`);
28
+ await this.showMenu();
29
+ this.rl.prompt();
30
+ this.rl.on('line', async (input) => {
31
+ await this.handleInput(input.trim().toLowerCase());
32
+ });
33
+ this.rl.on('close', () => {
34
+ Log_1.Log.info('👋 Au revoir !');
35
+ process.exit(0);
36
+ });
37
+ }
38
+ /** 🎛️ SINGLE INPUT HANDLER */
39
+ async handleInput(input) {
40
+ switch (this.currentState) {
41
+ case 'menu':
42
+ await this.handleMenuInput(input);
43
+ break;
44
+ case 'deploy_select':
45
+ await this.handleDeploySelect(input);
46
+ break;
47
+ case 'delete_name':
48
+ await this.handleDeleteName(input);
49
+ break;
50
+ case 'delete_all_confirm':
51
+ await this.handleDeleteAllConfirm(input);
52
+ break;
53
+ }
54
+ this.rl?.prompt();
55
+ }
56
+ /** 🎛️ MENU PRINCIPAL */
57
+ async handleMenuInput(input) {
58
+ const [action, arg] = input.split(' ');
59
+ switch (action) {
60
+ case 'deploy':
61
+ await this.startDeployInteractive();
62
+ break;
63
+ case 'deploy-all':
64
+ await this.deployAll();
65
+ break;
66
+ case 'list':
67
+ await this.listAll();
68
+ break;
69
+ case 'list-guild':
70
+ await this.listGuild(arg || '');
71
+ break;
72
+ case 'delete':
73
+ this.startDeleteInteractive();
74
+ break;
75
+ case 'delete-all':
76
+ this.startDeleteAllConfirm();
77
+ break;
78
+ case 'help':
79
+ await this.showMenu();
80
+ break;
81
+ case 'exit':
82
+ this.rl?.close();
83
+ break;
84
+ default:
85
+ Log_1.Log.error('❌ Commande inconnue. Tapez "help"');
86
+ }
87
+ }
88
+ /** 📁 START DEPLOY INTERACTIF */
89
+ async startDeployInteractive() {
90
+ const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${this.interactionHandlerFolder}`);
91
+ if (!files) {
92
+ Log_1.Log.error("Files not found!");
93
+ return;
94
+ }
95
+ this.deployFiles = files;
96
+ if (!this.deployFiles || this.deployFiles.length <= 0) {
97
+ Log_1.Log.error("Files not found");
98
+ return;
99
+ }
100
+ console.log(`\n📁 ${this.name} (${this.deployFiles.length} fichiers):`);
101
+ console.log(' 0. ALL → Tout déployer');
102
+ this.deployFiles.forEach((file, index) => {
103
+ console.log(` ${index + 1}. ${file.replace('.json', '')}`);
104
+ });
105
+ console.log('');
106
+ this.currentState = 'deploy_select';
107
+ console.log('Choisir (numéro ou 0 pour tout): ');
108
+ }
109
+ /** 🔢 HANDLE DEPLOY CHOICE */
110
+ async handleDeploySelect(input) {
111
+ const num = parseInt(input);
112
+ if (isNaN(num)) {
113
+ Log_1.Log.error("❌ Numéro invalide");
114
+ this.currentState = 'menu';
115
+ await this.showMenu();
116
+ return;
117
+ }
118
+ if (num === 0) {
119
+ await this.deployAll();
120
+ }
121
+ else if (num > 0 && num <= this.deployFiles.length) {
122
+ const selectedFile = this.deployFiles[num - 1];
123
+ Log_1.Log.info(`🚀 Déploiement ${selectedFile}...`);
124
+ const cmd = await FileManager_1.FileManager.readJsonFile(`./handlers/${this.interactionHandlerFolder}/${selectedFile}`);
125
+ if (cmd) {
126
+ const processed = await this.processPermissions(cmd);
127
+ const globalCmds = await this.getGlobalCommands();
128
+ await this.deploySingle(processed);
129
+ await this.cleanup(globalCmds, [processed]);
130
+ }
131
+ }
132
+ else {
133
+ Log_1.Log.error(`❌ Choix ${num} invalide (1-${this.deployFiles.length} ou 0)`);
134
+ this.currentState = 'menu';
135
+ await this.showMenu();
136
+ return;
137
+ }
138
+ this.currentState = 'menu';
139
+ await this.showMenu();
140
+ }
141
+ /** 🗑️ START DELETE INTERACTIF */
142
+ startDeleteInteractive() {
143
+ console.log('\nNom de la commande: ');
144
+ this.currentState = 'delete_name';
145
+ }
146
+ /** 🗑️ HANDLE DELETE NAME */
147
+ async handleDeleteName(input) {
148
+ await this.deleteCommand(input);
149
+ this.currentState = 'menu';
150
+ await this.showMenu();
151
+ }
152
+ /** 💥 START DELETE ALL CONFIRM */
153
+ startDeleteAllConfirm() {
154
+ console.log('\n⚠️ SUPPRIMER TOUT ? (yes/no): ');
155
+ this.currentState = 'delete_all_confirm';
156
+ }
157
+ /** 💥 HANDLE DELETE ALL CONFIRM */
158
+ async handleDeleteAllConfirm(input) {
159
+ if (input.toLowerCase() === 'yes') {
160
+ await this.deleteAllCommands();
161
+ }
162
+ this.currentState = 'menu';
163
+ await this.showMenu();
164
+ }
165
+ /** 🚀 DÉPLOIER TOUT */
166
+ async deployAll() {
167
+ Log_1.Log.info(`🚀 Déploiement ${this.name}...`);
168
+ await this.deployCommands([this.interactionHandlerFolder]);
169
+ this.currentState = 'menu';
170
+ await this.showMenu();
171
+ }
172
+ /** 📦 DÉPLOIEMENT BATCH */
173
+ async deployCommands(paths) {
174
+ const globalCmds = await this.getGlobalCommands();
175
+ const localCommands = [];
176
+ for (const path of paths) {
177
+ const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${path}`);
178
+ if (files == false || files.length <= 0) {
179
+ Log_1.Log.error(`Aucun fichier dans ${path}`);
180
+ return;
181
+ }
182
+ for (const file of files.filter(f => !f.includes('example'))) {
183
+ const cmd = await FileManager_1.FileManager.readJsonFile(`./handlers/${path}/${file}`);
184
+ if (!cmd)
185
+ continue;
186
+ const processed = await this.processPermissions(cmd);
187
+ localCommands.push(processed);
188
+ await this.deploySingle(processed);
189
+ await this.delay(100);
190
+ }
191
+ }
192
+ await this.cleanup(globalCmds, localCommands);
193
+ }
194
+ /** ⚡ DÉPLOYER UNE SEULE */
195
+ async deploySingle(cmd) {
196
+ const data = { ...cmd, guildID: undefined };
197
+ if (cmd.type === 2 || cmd.type === 3)
198
+ delete data.options;
199
+ try {
200
+ if (cmd.guildID?.length) {
201
+ for (const guildId of cmd.guildID) {
202
+ const guildCmds = await this.getGuildCommands(guildId);
203
+ const existing = guildCmds.find(c => c.name === cmd.name && c.type === cmd.type);
204
+ if (existing) {
205
+ await this.rest.patch(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, existing.id), { body: data });
206
+ Log_1.Log.info(`🔄 MAJ ${cmd.name} → ${guildId.slice(-4)}`);
207
+ }
208
+ else {
209
+ await this.rest.post(discord_js_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId), { body: data });
210
+ Log_1.Log.info(`✅ NEW ${cmd.name} → ${guildId.slice(-4)}`);
211
+ }
212
+ }
213
+ }
214
+ else {
215
+ const globalCmds = await this.getGlobalCommands();
216
+ const existing = globalCmds.find(c => c.name === cmd.name && c.type === cmd.type);
217
+ if (existing) {
218
+ await this.rest.patch(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, existing.id), { body: data });
219
+ Log_1.Log.info(`🔄 MAJ ${cmd.name} → GLOBAL`);
220
+ }
221
+ else {
222
+ await this.rest.post(discord_js_1.Routes.applicationCommands(Bot_1.Bot.config.clientId), { body: data });
223
+ Log_1.Log.info(`✅ NEW ${cmd.name} → GLOBAL`);
224
+ }
225
+ }
226
+ }
227
+ catch (error) {
228
+ Log_1.Log.error(`❌ ${cmd.name}: ${error}`);
229
+ }
230
+ }
231
+ /** 📊 LISTE TOUT */
232
+ async listAll() {
233
+ const globalCmds = await this.getGlobalCommands();
234
+ Log_1.Log.table([{ Type: `${this.name} GLOBAL`, Nombre: globalCmds.length }]);
235
+ this.currentState = 'menu';
236
+ await this.showMenu();
237
+ }
238
+ /** 📊 LISTE GUILDE */
239
+ async listGuild(guildId) {
240
+ if (!guildId) {
241
+ Log_1.Log.error('ID guilde requis');
242
+ this.currentState = 'menu';
243
+ await this.showMenu();
244
+ return;
245
+ }
246
+ const guildCmds = await this.getGuildCommands(guildId);
247
+ Log_1.Log.table([{ Guilde: guildId.slice(-8), [`${this.name}`]: guildCmds.length }]);
248
+ this.currentState = 'menu';
249
+ await this.showMenu();
250
+ }
251
+ /** 📋 MENU PRINCIPAL */
252
+ async showMenu() {
253
+ console.log(`\n${this.name}:`);
254
+ console.log(' deploy → Déployer spécifique');
255
+ console.log(' deploy-all → Tout déployer/MAJ');
256
+ console.log(' list → Lister toutes');
257
+ console.log(' list-guild <id> → Lister guilde');
258
+ console.log(' delete → Supprimer une');
259
+ console.log(' delete-all → Tout supprimer');
260
+ console.log(' help → Cette aide');
261
+ console.log(' exit → Quitter\n');
262
+ }
263
+ // ... [Toutes les autres méthodes restent EXACTEMENT identiques] ...
264
+ /** ⏱️ DELAY */
265
+ async delay(ms) {
266
+ return new Promise(r => setTimeout(r, ms));
267
+ }
268
+ /** 🌍 GLOBAL CMDS */
269
+ async getGlobalCommands() {
270
+ return this.rest.get(discord_js_1.Routes.applicationCommands(Bot_1.Bot.config.clientId));
271
+ }
272
+ /** 🏛️ GUILD CMDS */
273
+ async getGuildCommands(guildId) {
274
+ return this.rest.get(discord_js_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId));
275
+ }
276
+ /** 🔐 PERMISSIONS */
277
+ async processPermissions(cmd) {
278
+ const processed = { ...cmd };
279
+ if (cmd.default_member_permissions && Array.isArray(cmd.default_member_permissions)) {
280
+ const bitfield = cmd.default_member_permissions
281
+ .map(perm => BigInt(discord_js_1.PermissionFlagsBits[perm] || 0))
282
+ .reduce((acc, val) => acc | val, BigInt(0));
283
+ processed.default_member_permissions = Number(bitfield);
284
+ }
285
+ return processed;
286
+ }
287
+ /** 🗑️ DELETE UNE COMMANDE */
288
+ async deleteCommand(name) {
289
+ const globalCmds = await this.getGlobalCommands();
290
+ const globalMatch = globalCmds.find(c => c.name === name);
291
+ if (globalMatch) {
292
+ await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, globalMatch.id));
293
+ Log_1.Log.info(`✅ SUPPR GLOBAL ${name}`);
294
+ }
295
+ const botGuilds = Bot_1.Bot.client.guilds.cache.map(g => g.id);
296
+ for (const guildId of botGuilds) {
297
+ try {
298
+ const guildCmds = await this.getGuildCommands(guildId);
299
+ const guildMatch = guildCmds.find(c => c.name === name);
300
+ if (guildMatch) {
301
+ await this.rest.delete(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, guildMatch.id));
302
+ Log_1.Log.info(`✅ SUPPR ${name} → ${guildId.slice(-4)}`);
303
+ }
304
+ }
305
+ catch {
306
+ }
307
+ }
308
+ }
309
+ /** 💥 DELETE TOUS */
310
+ async deleteAllCommands() {
311
+ const globalCmds = await this.getGlobalCommands();
312
+ for (const cmd of globalCmds) {
313
+ await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, cmd.id));
314
+ Log_1.Log.info(`🗑️ SUPPR GLOBAL ${cmd.name}`);
315
+ await this.delay(100);
316
+ }
317
+ const botGuilds = Bot_1.Bot.client.guilds.cache.map(g => g.id);
318
+ for (const guildId of botGuilds) {
319
+ try {
320
+ const guildCmds = await this.getGuildCommands(guildId);
321
+ for (const cmd of guildCmds) {
322
+ await this.rest.delete(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, cmd.id));
323
+ Log_1.Log.info(`🗑️ SUPPR ${cmd.name} → ${guildId.slice(-4)}`);
324
+ await this.delay(100);
325
+ }
326
+ }
327
+ catch {
328
+ }
329
+ }
330
+ Log_1.Log.info('✅ TOUT SUPPRIMÉ !');
331
+ }
332
+ /** 🧹 NETTOYAGE */
333
+ async cleanup(globalCmds, localCmds) {
334
+ const localNames = localCmds.map(c => `${c.name}_${c.type}`);
335
+ for (const cmd of globalCmds.filter(c => !localNames.includes(`${c.name}_${c.type}`))) {
336
+ await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, cmd.id));
337
+ Log_1.Log.info(`🗑️ SUPPR ${cmd.name}`);
338
+ }
339
+ }
340
+ }
341
+ exports.InteractionBase = InteractionBase;