@spatulox/simplediscordbot 1.0.5 → 1.0.7

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 (28) hide show
  1. package/.env.example +1 -1
  2. package/LICENSE.md +21 -21
  3. package/README.md +44 -44
  4. package/dist/bot/BotMessage.js +54 -28
  5. package/dist/index.js +6 -2
  6. package/dist/manager/builder/SendableComponentBuilder.js +62 -0
  7. package/dist/manager/direct/UserManager.js +16 -5
  8. package/dist/manager/guild/ChannelManager/GuildMessageManager.js +12 -4
  9. package/dist/manager/guild/ChannelManager/ThreadChannelManager.js +15 -0
  10. package/dist/manager/interactions/InteractionManager.js +68 -0
  11. package/dist/manager/{handlers/builder → interactions}/ModalManager.js +2 -2
  12. package/dist/manager/interactions/SelectMenuManager.js +123 -0
  13. package/dist/manager/messages/WebhookManager.js +8 -5
  14. package/package.json +36 -41
  15. package/dist/cli/BaseCLI.js +0 -166
  16. package/dist/cli/GenerationCLI/ContextMenuGeneratorCLI.js +0 -109
  17. package/dist/cli/GenerationCLI/GenerationCLI.js +0 -25
  18. package/dist/cli/GenerationCLI/ModalGeneratorCLI.js +0 -166
  19. package/dist/cli/GenerationCLI/SlashCommandsGeneratorCLI.js +0 -221
  20. package/dist/cli/GuildListManager.js +0 -61
  21. package/dist/cli/InteractionCLI/InteractionCLI.js +0 -30
  22. package/dist/cli/InteractionCLI/InteractionCLIManager.js +0 -80
  23. package/dist/cli/MainCLI.js +0 -32
  24. package/dist/cli/type/ContextMenuConfig.js +0 -2
  25. package/dist/cli/type/InteractionType.js +0 -14
  26. package/dist/cli/type/SlashCommandConfig.js +0 -2
  27. package/dist/manager/handlers/interactions/BaseInteractionManager.js +0 -338
  28. package/dist/manager/handlers/interactions/InteractionManager.js +0 -29
@@ -5,6 +5,7 @@ const discord_js_1 = require("discord.js");
5
5
  const EmbedManager_1 = require("./EmbedManager");
6
6
  const Log_1 = require("../../utils/Log");
7
7
  const Bot_1 = require("../../bot/Bot");
8
+ const SendableComponentBuilder_1 = require("../builder/SendableComponentBuilder");
8
9
  class WebhookManager {
9
10
  constructor(channel, name = Bot_1.Bot.config.botName || "", avatarURL) {
10
11
  this.channel = channel;
@@ -39,14 +40,16 @@ class WebhookManager {
39
40
  throw error;
40
41
  }
41
42
  }
42
- /**
43
- * Send message/text/embed - EmbedBuilder NATIVE !
44
- */
45
43
  async send(content) {
46
44
  const webhook = await this.getWebhook();
47
45
  const options = {};
48
- if (content instanceof discord_js_1.EmbedBuilder) {
49
- options.embeds = [content];
46
+ if (SendableComponentBuilder_1.SendableComponentBuilder.isSendableComponent(content)) {
47
+ const t = SendableComponentBuilder_1.SendableComponentBuilder.buildMessage(content);
48
+ options.embeds = t.embeds;
49
+ options.components = t.components;
50
+ }
51
+ else if (typeof content == 'string') {
52
+ options.content = content;
50
53
  }
51
54
  else if (typeof content === 'object') {
52
55
  Object.assign(options, content);
package/package.json CHANGED
@@ -1,41 +1,36 @@
1
- {
2
- "name": "@spatulox/simplediscordbot",
3
- "version": "1.0.5",
4
- "author": "Spatulox",
5
- "description": "Simple discord bot framework to set up a bot under 30 secondes",
6
- "exports": "./dist/index.js",
7
- "main": "./dist/index.js",
8
- "bin": {
9
- "sdb": "dist/cli/MainCLI.js"
10
- },
11
- "scripts": {
12
- "build": "tsc",
13
- "dev": "nodemon --exec tsx src/test/index.ts",
14
- "cli": "node dist/cli/MainCLI.js"
15
- },
16
- "license": "MIT",
17
- "dependencies": {
18
- "discord.js": "^14.25.1",
19
- "dotenv": "^17.2.0",
20
- "fs": "^0.0.1-security"
21
- },
22
- "devDependencies": {
23
- "@types/node": "^22.14.0",
24
- "@types/node-schedule": "^2.1.7",
25
- "nodemon": "^3.1.9",
26
- "tsx": "^4.20.3",
27
- "typescript": "^5.9.3"
28
- },
29
- "keywords": [
30
- "discord",
31
- "framework",
32
- "bot",
33
- "client",
34
- "discordjs",
35
- "discord.js",
36
- "node"
37
- ],
38
- "bugs": {
39
- "url": "https://github.com/Spatulox/SimpleDiscordBot/issues"
40
- }
41
- }
1
+ {
2
+ "name": "@spatulox/simplediscordbot",
3
+ "version": "1.0.7",
4
+ "author": "Spatulox",
5
+ "description": "Simple discord bot framework to set up a bot under 30 secondes",
6
+ "main": "./dist/index.js",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "nodemon --exec tsx src/test/index.ts"
10
+ },
11
+ "license": "MIT",
12
+ "dependencies": {
13
+ "@spatulox/discord-interaction-manager": "^1.0.8",
14
+ "discord.js": "^14.25.1"
15
+ },
16
+ "devDependencies": {
17
+ "@types/node": "^22.14.0",
18
+ "@types/node-schedule": "^2.1.7",
19
+ "dotenv": "^17.2.4",
20
+ "nodemon": "^3.1.9",
21
+ "tsx": "^4.20.3",
22
+ "typescript": "^5.9.3"
23
+ },
24
+ "keywords": [
25
+ "discord",
26
+ "framework",
27
+ "bot",
28
+ "client",
29
+ "discordjs",
30
+ "discord.js",
31
+ "node"
32
+ ],
33
+ "bugs": {
34
+ "url": "https://github.com/Spatulox/SimpleDiscordBot/issues"
35
+ }
36
+ }
@@ -1,166 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.BaseCLI = void 0;
8
- const readline_1 = __importDefault(require("readline"));
9
- const FileManager_1 = require("../manager/FileManager");
10
- /**
11
- * --- BaseCLI ---
12
- */
13
- class BaseCLI {
14
- get rl() {
15
- if (!BaseCLI._rl) {
16
- BaseCLI._rl = readline_1.default.createInterface({
17
- input: process.stdin,
18
- output: process.stdout
19
- });
20
- }
21
- return BaseCLI._rl;
22
- }
23
- constructor(parent) {
24
- this.parent = parent;
25
- }
26
- getTitle() {
27
- return "BaseCLI";
28
- }
29
- async showMainMenu() {
30
- console.clear();
31
- console.log(this.getTitle());
32
- console.log('═'.repeat(40));
33
- this.menuSelection.forEach((option, index) => {
34
- console.log(`${index + 1}. ${option.label}`);
35
- });
36
- console.log('═'.repeat(40));
37
- const choice = await this.prompt('Choose an option: ');
38
- if (choice == "exit") {
39
- return this.goBack();
40
- }
41
- const choiceIndex = parseInt(choice) - 1;
42
- if (choiceIndex >= 0 && choiceIndex < this.menuSelection.length) {
43
- const option = this.menuSelection[choiceIndex];
44
- if (!option) {
45
- console.log("Invalid Choice");
46
- return this.showMainMenu();
47
- }
48
- const result = await option.action();
49
- if (result instanceof BaseCLI) {
50
- if (result == this) {
51
- await this.execute();
52
- }
53
- else {
54
- return await result.showMainMenu();
55
- }
56
- }
57
- }
58
- await this.prompt('Press Enter to continue...');
59
- return this.showMainMenu();
60
- }
61
- async prompt(question) {
62
- return new Promise(resolve => this.rl.question(question, resolve));
63
- }
64
- async requireInput(message, validator, canBeEmpty = false) {
65
- while (true) {
66
- const value = (await this.prompt(message));
67
- if (!value && !canBeEmpty) {
68
- console.log("⚠️ This field is required. Please enter a value.");
69
- continue;
70
- }
71
- if (validator && !validator(value)) {
72
- console.log("⚠️ Invalid input. Try again.");
73
- continue;
74
- }
75
- return value;
76
- }
77
- }
78
- async yesNoInput(message) {
79
- while (true) {
80
- const value = (await this.prompt(message));
81
- if (!value) {
82
- console.log("⚠️ This field is required. Please enter a value.");
83
- continue;
84
- }
85
- if (!["y", "n", "yes", "no"].includes(value.toLowerCase())) {
86
- console.log("⚠️ Invalid input. Try again.");
87
- continue;
88
- }
89
- return value == "y" || value == "yes";
90
- }
91
- }
92
- async showHelp() {
93
- console.clear();
94
- console.log('');
95
- console.log('||| HELP - Discord Bot Command Manager CLI |||');
96
- console.log('');
97
- console.log('🔗 Wiki: https://github.com/Spatulox/SimpleDiscordBot/wiki');
98
- console.log('═'.repeat(80));
99
- console.log('🤖 What it does:');
100
- console.log(' • Manage your Discord interactions (slash commands & context menus) via an interactive CLI');
101
- console.log(' • Let you deploy/update/delete any interaction');
102
- console.log(' • Let you generate an interaction files');
103
- console.log('');
104
- console.log('How you need to save your interaction files');
105
- console.log('📁 Folder Structure:');
106
- console.log(' ├── handlers/ ← In the root folder of your project');
107
- console.log(' │ ├── commands/ ← Slash Commands (type 1)');
108
- console.log(' │ └── context_menu/ ← Context Menus (type 2/3)');
109
- console.log('');
110
- console.log('🎯 Features:');
111
- console.log(' 📊 1. List Remote → Show deployed commands on Discord');
112
- console.log(' 🚀 2. Deploy Local → Deploy local JSON files → Discord');
113
- console.log(' 🔄 3. Update Remote → Update Discord commands based on local JSON file');
114
- console.log(' 🗑️ 4. Delete Remote → Remove Discord commands based on local JSON file');
115
- console.log('');
116
- console.log('🎮 Selection:');
117
- console.log(' • Numbered lists appear after the interaction list');
118
- console.log(' • Enter: "1,3,5" or "all" to select which interaction you want to apply the action');
119
- console.log('');
120
- console.log('🔗 Wiki: https://github.com/Spatulox/SimpleDiscordBot/wiki');
121
- console.log('🔗 Bugs: https://github.com/Spatulox/SimpleDiscordBot/issues');
122
- console.log('═'.repeat(80));
123
- await this.prompt('Press Enter to continue...');
124
- if (this.parent) {
125
- await this.parent.showMainMenu();
126
- }
127
- else {
128
- await this.showMainMenu();
129
- }
130
- }
131
- async goBack() {
132
- if (this.parent) {
133
- return this.parent?.showMainMenu();
134
- }
135
- return this.execute(); // Fallback for MainCLI
136
- }
137
- async saveFile(folderName, filename, data) {
138
- let finalFilename = filename;
139
- if (await FileManager_1.FileManager.readJsonFile(`./handlers/${folderName}/${filename}`)) {
140
- if (!await this.yesNoInput(`"${finalFilename}" already exists. Overwrite? (y/n): `)) {
141
- const timestamp = Date.now();
142
- finalFilename = `${filename.replace('.json', '')}-${timestamp}`;
143
- console.log(`📝 New filename: ${finalFilename}`);
144
- }
145
- }
146
- // 2. Preview + Confirmation
147
- console.clear();
148
- console.log("✨ Final JSON preview:");
149
- console.log(JSON.stringify(data, null, 2));
150
- if (!await this.yesNoInput("\nSave this file? (y/n): ")) {
151
- console.log("Cancelled");
152
- await this.prompt('Press Enter to continue...');
153
- return this.showMainMenu();
154
- }
155
- try {
156
- await FileManager_1.FileManager.writeJsonFile(`./handlers/${folderName}`, finalFilename, data, false);
157
- console.log(`File saved: ./handlers/${folderName}/${finalFilename}`);
158
- }
159
- catch (error) {
160
- console.error("Error saving file:", error);
161
- }
162
- return;
163
- }
164
- }
165
- exports.BaseCLI = BaseCLI;
166
- BaseCLI._rl = null;
@@ -1,109 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContextMenuGeneratorCLI = void 0;
4
- const BaseCLI_1 = require("../BaseCLI");
5
- const discord_js_1 = require("discord.js");
6
- const DiscordRegex_1 = require("../../utils/DiscordRegex");
7
- const FolderName_1 = require("../../type/FolderName");
8
- class ContextMenuGeneratorCLI extends BaseCLI_1.BaseCLI {
9
- constructor() {
10
- super(...arguments);
11
- this.menuSelection = [
12
- { label: "Generate Context Menu", action: () => this },
13
- { label: "Back", action: () => this.goBack() },
14
- ];
15
- }
16
- getTitle() {
17
- return "📝 Context Menu JSON Generator";
18
- }
19
- async execute() {
20
- const config = { dm_permission: false, integration_types: [], name: "", type: 2 };
21
- // 1. Context Menu Name
22
- console.clear();
23
- console.log("👤 1/10 - Name");
24
- config.name = await this.requireInput("Enter Context Menu name (ex: 'Example context Menu'): ");
25
- // 2. Type (2=User, 3=Message)
26
- console.clear();
27
- console.log("🔧 2/10 - Type");
28
- console.log("2 => Context Menu for users");
29
- console.log("3 => Context Menu for messages");
30
- config.type = parseInt(await this.requireInput("Enter type (2 or 3): ", val => ["2", "3"].includes(val)));
31
- // 3. Member Permissions
32
- console.clear();
33
- console.log("🔐 3/10 - Permissions");
34
- console.log("📋 Valid permissions:\n", Object.keys(discord_js_1.PermissionFlagsBits).join(', '));
35
- const permsInput = await this.requireInput("Default member permissions (comma separated, or 'none'): ", (val) => {
36
- if (!val || val.toLowerCase() === "none" || val == '')
37
- return true;
38
- const permissions = val.split(",").map(p => p.trim());
39
- const invalidPerms = permissions.filter(perm => !(perm in discord_js_1.PermissionFlagsBits));
40
- if (invalidPerms.length > 0) {
41
- console.log(`❌ Invalid permissions: ${invalidPerms.join(', ')}`);
42
- console.log("📋 Valid permissions:\n", Object.keys(discord_js_1.PermissionFlagsBits).join(', '));
43
- return false;
44
- }
45
- return true;
46
- }, true);
47
- if (permsInput !== '' && permsInput.toLowerCase() !== "none") {
48
- config.default_member_permissions = permsInput.split(",")
49
- .map(p => p.trim());
50
- }
51
- // 4. DM Permission
52
- console.clear();
53
- console.log("💬 4/10 - DM Permission");
54
- config.dm_permission = (await this.yesNoInput("Allow in DMs? (y/n): "));
55
- // 5. Integration Types
56
- console.clear();
57
- console.log("🔗 5/10 - Integration Types");
58
- console.log("0 => GUILD_INSTALL");
59
- console.log("1 => USER_INSTALL");
60
- console.log("(comma separated, or 'all')");
61
- const intInput = await this.requireInput("Integration types: ");
62
- if (intInput.toLowerCase() === "all") {
63
- config.integration_types = [0, 1];
64
- }
65
- else {
66
- config.integration_types = intInput.split(",").map(i => parseInt(i.trim())).filter(i => !isNaN(i));
67
- }
68
- console.clear();
69
- console.log("🌐 6/10 - Contexts");
70
- console.log("0 => Can be used inside server");
71
- console.log("1 => Can be used inside DMs with bot");
72
- console.log("2 => Group DMs & other DMs");
73
- console.log("(comma separated, or 'all')");
74
- const ctxInput = await this.requireInput("Contexts: ");
75
- if (ctxInput.toLowerCase() === "all") {
76
- config.contexts = [0, 1, 2];
77
- }
78
- else {
79
- config.contexts = ctxInput.split(",").map(i => parseInt(i.trim())).filter(i => !isNaN(i));
80
- }
81
- // 7. Guild IDs
82
- console.clear();
83
- console.log("🏠 7/10 - Guild IDs (optional)");
84
- console.log(" => Used to deploy specific context menu for specific guild");
85
- const guildInput = await this.requireInput("Guild IDs (comma separated, or 'none'): ", (val) => {
86
- if (!val || val.toLowerCase() === "none")
87
- return true;
88
- const ids = val.split(",").map(id => id.trim());
89
- const invalidIds = ids.filter(id => !DiscordRegex_1.DiscordRegex.GUILD_ID.test(id));
90
- if (invalidIds.length > 0) {
91
- console.log(`❌ Invalid Guild IDs: ${invalidIds.join(', ')}`);
92
- console.log("ℹ️ Discord Guild ID = 18 chiffres (ex: 1111160769132896377)");
93
- return false;
94
- }
95
- console.log("✅ Valid Guild IDs:", ids.join(', '));
96
- return true;
97
- }, true);
98
- if (guildInput.toLowerCase() !== "none" && guildInput !== "") {
99
- config.guildID = guildInput.split(",").map(id => id.trim());
100
- }
101
- // 8. Filename
102
- console.clear();
103
- console.log("💾 8/10 - File");
104
- const filename = (await this.requireInput("Filename (ex: my-context-menu): ")) + ".json";
105
- await this.saveFile(FolderName_1.FolderName.CONTEXT_MENU, filename, config);
106
- return this.showMainMenu();
107
- }
108
- }
109
- exports.ContextMenuGeneratorCLI = ContextMenuGeneratorCLI;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GenerationCLI = void 0;
4
- const BaseCLI_1 = require("../BaseCLI");
5
- const ContextMenuGeneratorCLI_1 = require("./ContextMenuGeneratorCLI");
6
- const ModalGeneratorCLI_1 = require("./ModalGeneratorCLI");
7
- const SlashCommandsGeneratorCLI_1 = require("./SlashCommandsGeneratorCLI");
8
- class GenerationCLI extends BaseCLI_1.BaseCLI {
9
- constructor() {
10
- super(...arguments);
11
- this.menuSelection = [
12
- { label: 'Generate Slash Command Template', action: () => new SlashCommandsGeneratorCLI_1.SlashCommandGeneratorCLI(this) },
13
- { label: 'Generate Context Menu Template', action: () => new ContextMenuGeneratorCLI_1.ContextMenuGeneratorCLI(this) },
14
- { label: 'Generate Modal Template', action: () => new ModalGeneratorCLI_1.ModalGeneratorCLI(this) },
15
- { label: 'Back', action: () => this.goBack() },
16
- ];
17
- }
18
- getTitle() {
19
- return '⚙️ Generation Manager CLI';
20
- }
21
- async execute() {
22
- throw new Error("Method not implemented.");
23
- }
24
- }
25
- exports.GenerationCLI = GenerationCLI;
@@ -1,166 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ModalGeneratorCLI = exports.ModalFieldStyle = void 0;
4
- const discord_js_1 = require("discord.js");
5
- const BaseCLI_1 = require("../BaseCLI");
6
- const FolderName_1 = require("../../type/FolderName");
7
- var ModalFieldStyle;
8
- (function (ModalFieldStyle) {
9
- // Official TextInputStyle
10
- ModalFieldStyle[ModalFieldStyle["Short"] = 1] = "Short";
11
- ModalFieldStyle[ModalFieldStyle["Paragraph"] = 2] = "Paragraph";
12
- // Custom Styles
13
- ModalFieldStyle["Number"] = "Number";
14
- ModalFieldStyle["Phone"] = "Phone";
15
- ModalFieldStyle["Date"] = "Date";
16
- })(ModalFieldStyle || (exports.ModalFieldStyle = ModalFieldStyle = {}));
17
- class ModalGeneratorCLI extends BaseCLI_1.BaseCLI {
18
- constructor() {
19
- super(...arguments);
20
- this.menuSelection = [
21
- { label: "Generate Modal", action: () => this },
22
- { label: "Back", action: () => this.goBack() },
23
- ];
24
- }
25
- getTitle() {
26
- return "📝 Modal JSON Generator";
27
- }
28
- async execute() {
29
- const modal = {
30
- title: '',
31
- customId: '',
32
- label: '',
33
- fields: []
34
- };
35
- // 1. Nom du Modal (Title)
36
- console.clear();
37
- console.log("🎛️ 1/6 - Modal Title");
38
- modal.title = await this.requireInput("Enter modal title (max 45 chars): ", val => val.length <= 45);
39
- // 2. Custom ID
40
- console.clear();
41
- console.log("🔑 2/6 - Custom ID");
42
- modal.customId = await this.requireInput("Enter custom ID (lowercase, no spaces): ", val => /^[a-z0-9_-]+$/.test(val) && val.length <= 100);
43
- // 3. Label principal (optionnel)
44
- console.clear();
45
- console.log("📝 3/6 - Main Label");
46
- modal.label = (await this.prompt("Enter main label (optional, press Enter to skip): "))?.trim() || '';
47
- // 4. Nombre de champs
48
- console.clear();
49
- console.log("📊 4/6 - Fields");
50
- console.log("Max 5 fields per modal");
51
- const fieldCount = parseInt(await this.requireInput("How many fields? (1-5): ", val => {
52
- const num = parseInt(val);
53
- return num >= 1 && num <= 5;
54
- }));
55
- // 5. Générer chaque champ
56
- for (let i = 0; i < fieldCount; i++) {
57
- console.clear();
58
- console.log(`📝 5/6 - Field ${i + 1}/${fieldCount}`);
59
- const fieldLabel = await this.requireInput("Field label (max 45 chars): ", val => val.length <= 45);
60
- const fieldId = await this.requireInput("Field custom ID (lowercase): ", val => /^[a-z0-9_-]+$/.test(val));
61
- const fieldPlaceholder = (await this.prompt("Placeholder (optional): "))?.trim() || undefined;
62
- const fieldRequired = await this.yesNoInput("Required field? (y/n): ");
63
- console.clear();
64
- console.log("🎨 Field Styles:");
65
- console.log("1. Short (TextInputStyle.Short)");
66
- console.log("2. Paragraph (TextInputStyle.Paragraph)");
67
- console.log("3. Number");
68
- console.log("4. Phone");
69
- console.log("5. Date");
70
- const styleChoice = await this.requireInput("Choose style (1-5): ", val => ["1", "2", "3", "4", "5"].includes(val));
71
- let style;
72
- switch (styleChoice) {
73
- case '1':
74
- style = ModalFieldStyle.Short;
75
- break;
76
- case '2':
77
- style = ModalFieldStyle.Paragraph;
78
- break;
79
- case '3':
80
- style = ModalFieldStyle.Number;
81
- break;
82
- case '4':
83
- style = ModalFieldStyle.Phone;
84
- break;
85
- case '5':
86
- style = ModalFieldStyle.Date;
87
- break;
88
- default: style = ModalFieldStyle.Short;
89
- }
90
- // Min/Max length (optional)
91
- const minLengthInput = await this.prompt("Min length (optional, press Enter): ");
92
- const maxLengthInput = await this.prompt("Max length (optional, press Enter): ");
93
- modal.fields.push({
94
- title: fieldLabel,
95
- customId: fieldId,
96
- placeholder: fieldPlaceholder,
97
- required: fieldRequired,
98
- style,
99
- ...(minLengthInput && { minLength: parseInt(minLengthInput) }),
100
- ...(maxLengthInput && { maxLength: parseInt(maxLengthInput) })
101
- });
102
- }
103
- console.clear();
104
- console.log("💾 6/6 - Save");
105
- const filename = await this.requireInput("Filename (ex: server-config): ") + ".json";
106
- await this.saveFile(FolderName_1.FolderName.MODAL, filename, modal);
107
- return this.showMainMenu();
108
- }
109
- /**
110
- * Create modal from declarative config - SIMPLE API !
111
- */
112
- static create(options) {
113
- const modal = new discord_js_1.ModalBuilder()
114
- .setCustomId(options.customId)
115
- .setTitle(options.title.slice(0, 45));
116
- const actionRows = [];
117
- for (const field of options.fields) {
118
- const input = this.buildInput(field);
119
- const row = new discord_js_1.ActionRowBuilder()
120
- .addComponents(input);
121
- actionRows.push(row);
122
- }
123
- return modal.addComponents(...actionRows);
124
- }
125
- static buildInput(field) {
126
- const input = new discord_js_1.TextInputBuilder()
127
- .setCustomId(field.customId)
128
- .setLabel(field.title.slice(0, 45))
129
- .setPlaceholder(field.placeholder ?? '')
130
- .setRequired(field.required ?? false)
131
- .setMinLength(field.minLength ?? 0)
132
- .setMaxLength(field.maxLength ?? 400);
133
- // Mapper les styles custom
134
- switch (field.style) {
135
- case 'Number':
136
- input.setStyle(discord_js_1.TextInputStyle.Short).setPlaceholder('Enter a number');
137
- break;
138
- case 'Phone':
139
- input.setStyle(discord_js_1.TextInputStyle.Short).setPlaceholder('Enter a phone number : +33 6 12 34 56 78');
140
- break;
141
- case 'Date':
142
- input.setStyle(discord_js_1.TextInputStyle.Short).setPlaceholder('Enter a date : yyyy-mm-dd');
143
- break;
144
- default:
145
- input.setStyle(field.style);
146
- }
147
- return input;
148
- }
149
- /**
150
- * Quick helpers
151
- */
152
- static simple(option) {
153
- return this.create({
154
- title: option.title,
155
- customId: option.customId,
156
- label: option.label,
157
- fields: [{
158
- title: option.label,
159
- customId: 'input',
160
- placeholder: option.placeholder,
161
- style: ModalFieldStyle.Short
162
- }]
163
- });
164
- }
165
- }
166
- exports.ModalGeneratorCLI = ModalGeneratorCLI;