@spatulox/discord-interaction-manager 1.0.0 ā 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.
- package/dist/cli/BaseCLI.js +1 -1
- package/dist/cli/GenerationCLI/ContextMenuGeneratorCLI.js +32 -89
- package/dist/cli/GenerationCLI/GenerationCLI.js +0 -2
- package/dist/cli/GenerationCLI/InteractionGeneratorCLI.js +58 -0
- package/dist/cli/GenerationCLI/SlashCommandsGeneratorCLI.js +98 -173
- package/dist/cli/GuildListManager.js +1 -2
- package/dist/cli/interactions/BaseInteractionManager.js +5 -4
- package/dist/cli/type/InteractionType.js +33 -1
- package/package.json +1 -1
package/dist/cli/BaseCLI.js
CHANGED
|
@@ -136,7 +136,7 @@ class BaseCLI {
|
|
|
136
136
|
}
|
|
137
137
|
async saveFile(folderName, filename, data) {
|
|
138
138
|
let finalFilename = filename;
|
|
139
|
-
if (await FileManager_1.FileManager.readJsonFile(`./handlers/${folderName}/${filename}`)) {
|
|
139
|
+
if (await FileManager_1.FileManager.readJsonFile(`./handlers/${folderName}/${filename.split(".json")[0] + ".json"}`)) {
|
|
140
140
|
if (!await this.yesNoInput(`"${finalFilename}" already exists. Overwrite? (y/n): `)) {
|
|
141
141
|
const timestamp = Date.now();
|
|
142
142
|
finalFilename = `${filename.replace('.json', '')}-${timestamp}`;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
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
4
|
const FolderName_1 = require("../../type/FolderName");
|
|
8
|
-
|
|
5
|
+
const InteractionGeneratorCLI_1 = require("./InteractionGeneratorCLI");
|
|
6
|
+
class ContextMenuGeneratorCLI extends InteractionGeneratorCLI_1.InteractionGeneratorCLI {
|
|
9
7
|
constructor() {
|
|
10
8
|
super(...arguments);
|
|
11
9
|
this.menuSelection = [
|
|
@@ -14,96 +12,41 @@ class ContextMenuGeneratorCLI extends BaseCLI_1.BaseCLI {
|
|
|
14
12
|
];
|
|
15
13
|
}
|
|
16
14
|
getTitle() {
|
|
17
|
-
return "
|
|
15
|
+
return "š½ļø Context Menu JSON Generator";
|
|
18
16
|
}
|
|
19
17
|
async execute() {
|
|
20
|
-
const config = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
console.
|
|
28
|
-
console.log("
|
|
29
|
-
console.log("
|
|
30
|
-
config.type = parseInt(await this.requireInput("
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
console.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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());
|
|
18
|
+
const config = {
|
|
19
|
+
name: "",
|
|
20
|
+
type: 2,
|
|
21
|
+
dm_permission: false,
|
|
22
|
+
integration_types: [0, 1]
|
|
23
|
+
};
|
|
24
|
+
// 1. Type & Nom
|
|
25
|
+
console.clear();
|
|
26
|
+
console.log("š½ļø 1/5 - Menu Type");
|
|
27
|
+
console.log("2 = User Menu | 3 = Message Menu");
|
|
28
|
+
config.type = parseInt(await this.requireInput("Type (2 or 3): ", val => ["2", "3"].includes(val)));
|
|
29
|
+
console.clear();
|
|
30
|
+
config.name = await this.requireInput("Name (1-32 chars): ", val => val.length >= 1 && val.length <= 32);
|
|
31
|
+
// 2. Permissions
|
|
32
|
+
console.clear();
|
|
33
|
+
console.log("š 2/5 - Command Permissions");
|
|
34
|
+
await this.addPermissions(config);
|
|
35
|
+
// 3. DM
|
|
36
|
+
console.clear();
|
|
37
|
+
console.log("š¬ 3/5 - DM Permissions");
|
|
38
|
+
config.dm_permission = await this.yesNoInput("Authorize in DM ? (y/n): ");
|
|
39
|
+
// 4. Guild Specific
|
|
40
|
+
console.clear();
|
|
41
|
+
console.log("āļø 4/5 - Guild Specific");
|
|
42
|
+
if (await this.yesNoInput("Guild Specific ? (y/n): ")) {
|
|
43
|
+
config.guild_ids = await this.optionalGuildIds();
|
|
100
44
|
}
|
|
101
|
-
//
|
|
45
|
+
// 5. Save
|
|
102
46
|
console.clear();
|
|
103
|
-
console.log("š¾
|
|
104
|
-
const filename = (
|
|
47
|
+
console.log("š¾ 5/5 - Save");
|
|
48
|
+
const filename = `${config.name.toLowerCase().replace(/\s+/g, '-')}.json`;
|
|
105
49
|
await this.saveFile(FolderName_1.FolderName.CONTEXT_MENU, filename, config);
|
|
106
|
-
return this.showMainMenu();
|
|
107
50
|
}
|
|
108
51
|
}
|
|
109
52
|
exports.ContextMenuGeneratorCLI = ContextMenuGeneratorCLI;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GenerationCLI = void 0;
|
|
4
4
|
const BaseCLI_1 = require("../BaseCLI");
|
|
5
5
|
const ContextMenuGeneratorCLI_1 = require("./ContextMenuGeneratorCLI");
|
|
6
|
-
const ModalGeneratorCLI_1 = require("./ModalGeneratorCLI");
|
|
7
6
|
const SlashCommandsGeneratorCLI_1 = require("./SlashCommandsGeneratorCLI");
|
|
8
7
|
class GenerationCLI extends BaseCLI_1.BaseCLI {
|
|
9
8
|
constructor() {
|
|
@@ -11,7 +10,6 @@ class GenerationCLI extends BaseCLI_1.BaseCLI {
|
|
|
11
10
|
this.menuSelection = [
|
|
12
11
|
{ label: 'Generate Slash Command Template', action: () => new SlashCommandsGeneratorCLI_1.SlashCommandGeneratorCLI(this) },
|
|
13
12
|
{ label: 'Generate Context Menu Template', action: () => new ContextMenuGeneratorCLI_1.ContextMenuGeneratorCLI(this) },
|
|
14
|
-
{ label: 'Generate Modal Template', action: () => new ModalGeneratorCLI_1.ModalGeneratorCLI(this) },
|
|
15
13
|
{ label: 'Back', action: () => this.goBack() },
|
|
16
14
|
];
|
|
17
15
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InteractionGeneratorCLI = void 0;
|
|
4
|
+
const BaseCLI_1 = require("../BaseCLI");
|
|
5
|
+
const discord_js_1 = require("discord.js");
|
|
6
|
+
const DiscordRegex_1 = require("../../utils/DiscordRegex");
|
|
7
|
+
class InteractionGeneratorCLI extends BaseCLI_1.BaseCLI {
|
|
8
|
+
async addPermissions(config) {
|
|
9
|
+
console.clear();
|
|
10
|
+
const permEntries = Object.entries(discord_js_1.PermissionFlagsBits);
|
|
11
|
+
const numberedPerms = permEntries.map(([name, _value], index) => `${index + 1}. ${name}`).join('\n');
|
|
12
|
+
console.log("Valid Permissions:\n" + numberedPerms);
|
|
13
|
+
const input = await this.requireInput("Permission numbers (comma-separated, 'everyone', or leave empty): ", (val) => {
|
|
14
|
+
if (!val.trim() || val.toLowerCase() === 'everyone')
|
|
15
|
+
return true;
|
|
16
|
+
return val.split(',').every(numStr => {
|
|
17
|
+
const num = parseInt(numStr.trim());
|
|
18
|
+
return num >= 1 && num <= permEntries.length && !isNaN(num);
|
|
19
|
+
});
|
|
20
|
+
}, true);
|
|
21
|
+
if (!input.trim() || input.toLowerCase() === 'everyone') {
|
|
22
|
+
config.default_member_permissions_string = ['everyone'];
|
|
23
|
+
config.default_member_permissions = 0n.toString();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const selectedNums = input.split(',').map(n => parseInt(n.trim()));
|
|
27
|
+
const selectedPermNames = [];
|
|
28
|
+
for (const i of selectedNums) {
|
|
29
|
+
const entry = permEntries[i];
|
|
30
|
+
if (entry) {
|
|
31
|
+
selectedPermNames.push(entry[0]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
config.default_member_permissions_string = selectedPermNames;
|
|
35
|
+
config.default_member_permissions = this.permissionsToBitfield(input.split(","));
|
|
36
|
+
}
|
|
37
|
+
async optionalGuildIds() {
|
|
38
|
+
const input = await this.prompt("Guild IDs (separated by comma, or 'none' to cancel): ");
|
|
39
|
+
return input.trim() && input.toLowerCase() !== 'none'
|
|
40
|
+
? input.split(',').map(id => id.trim()).filter(DiscordRegex_1.DiscordRegex.GUILD_ID.test.bind(DiscordRegex_1.DiscordRegex.GUILD_ID))
|
|
41
|
+
: undefined;
|
|
42
|
+
}
|
|
43
|
+
permissionsToBitfield(perms) {
|
|
44
|
+
if (!perms || perms.length === 0)
|
|
45
|
+
return 0n.toString();
|
|
46
|
+
let bits = 0n;
|
|
47
|
+
for (const name of perms) {
|
|
48
|
+
const value = discord_js_1.PermissionFlagsBits[name];
|
|
49
|
+
if (!value) {
|
|
50
|
+
console.warn(`Unknow permission in default_member_permissions: ${name}`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
bits |= value;
|
|
54
|
+
}
|
|
55
|
+
return bits.toString();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.InteractionGeneratorCLI = InteractionGeneratorCLI;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SlashCommandGeneratorCLI = void 0;
|
|
4
|
-
const BaseCLI_1 = require("../BaseCLI");
|
|
5
4
|
const FolderName_1 = require("../../type/FolderName");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
class SlashCommandGeneratorCLI extends
|
|
5
|
+
const InteractionType_1 = require("../type/InteractionType");
|
|
6
|
+
const InteractionGeneratorCLI_1 = require("./InteractionGeneratorCLI");
|
|
7
|
+
class SlashCommandGeneratorCLI extends InteractionGeneratorCLI_1.InteractionGeneratorCLI {
|
|
9
8
|
constructor() {
|
|
10
9
|
super(...arguments);
|
|
11
10
|
this.menuSelection = [
|
|
@@ -23,199 +22,125 @@ class SlashCommandGeneratorCLI extends BaseCLI_1.BaseCLI {
|
|
|
23
22
|
description: "",
|
|
24
23
|
options: [],
|
|
25
24
|
dm_permission: false,
|
|
26
|
-
default_member_permissions: undefined,
|
|
27
|
-
default_member_permissions_string: undefined,
|
|
28
25
|
integration_types: [0, 1],
|
|
29
26
|
contexts: [0]
|
|
30
27
|
};
|
|
31
|
-
// 1. Command Name
|
|
32
28
|
console.clear();
|
|
33
|
-
console.log("š 1/
|
|
34
|
-
config.name = await this.requireInput("
|
|
35
|
-
|
|
29
|
+
console.log("š 1/6 - Base");
|
|
30
|
+
config.name = await this.requireInput("Name (a-z0-9_-, 1-32 chars): ", val => /^[a-z0-9_-]{1,32}$/.test(val));
|
|
31
|
+
config.description = await this.requireInput("Description (1-100 chars): ", val => val.length >= 1 && val.length <= 100);
|
|
36
32
|
console.clear();
|
|
37
|
-
console.log("
|
|
38
|
-
|
|
39
|
-
// 3. Member Permissions
|
|
33
|
+
console.log("š 2/6 - Command Permissions");
|
|
34
|
+
await this.addPermissions(config);
|
|
40
35
|
console.clear();
|
|
41
|
-
console.log("
|
|
42
|
-
|
|
43
|
-
const permsInput = await this.requireInput("Default member permissions (comma separated, or 'none'): ", (val) => {
|
|
44
|
-
if (!val || val.toLowerCase() === "none" || val === '')
|
|
45
|
-
return true;
|
|
46
|
-
const permissions = val.split(",").map(p => p.trim());
|
|
47
|
-
const invalidPerms = permissions.filter(perm => !(perm in discord_js_1.PermissionFlagsBits));
|
|
48
|
-
if (invalidPerms.length > 0) {
|
|
49
|
-
console.log(`ā Invalid: ${invalidPerms.join(', ')}`);
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
}, true);
|
|
54
|
-
if (permsInput && permsInput.toLowerCase() !== "none") {
|
|
55
|
-
config.default_member_permissions_string = permsInput.split(",").map(p => p.trim());
|
|
56
|
-
}
|
|
57
|
-
// 4. DM Permission
|
|
58
|
-
console.clear();
|
|
59
|
-
console.log("š¬ 4/12 - DM Permission");
|
|
60
|
-
config.dm_permission = (await this.yesNoInput("Allow in DMs? (y/n): "));
|
|
61
|
-
// 5. Integration Types
|
|
62
|
-
console.clear();
|
|
63
|
-
console.log("š 5/12 - Integration Types");
|
|
64
|
-
console.log("0 => GUILD_INSTALL, 1 => USER_INSTALL (comma separated, or 'all')");
|
|
65
|
-
const intInput = await this.requireInput("Integration types: ");
|
|
66
|
-
if (intInput.toLowerCase() === "all") {
|
|
67
|
-
config.integration_types = [0, 1];
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
config.integration_types = intInput.split(",").map(i => parseInt(i.trim())).filter(i => !isNaN(i));
|
|
71
|
-
}
|
|
72
|
-
// 6. Contexts
|
|
73
|
-
console.clear();
|
|
74
|
-
console.log("š 6/12 - Contexts");
|
|
75
|
-
console.log("0 => Server, 1 => Bot DMs, 2 => Group/Other DMs (comma separated, or 'server')");
|
|
76
|
-
const ctxInput = await this.requireInput("Contexts: ", undefined, true);
|
|
77
|
-
if (!ctxInput || ctxInput.trim() === "") {
|
|
78
|
-
config.contexts = [0, 1, 2];
|
|
79
|
-
}
|
|
80
|
-
else if (ctxInput.toLowerCase() === "all") {
|
|
81
|
-
config.contexts = [0, 1, 2];
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
config.contexts = ctxInput.split(",").map(i => parseInt(i.trim())).filter(i => !isNaN(i));
|
|
85
|
-
}
|
|
86
|
-
// 7. Add Subcommands/Groups?
|
|
36
|
+
console.log("š¬ 3/6 - DM Permissions");
|
|
37
|
+
config.dm_permission = await this.yesNoInput("Authorize DM ? (y/n): ");
|
|
87
38
|
console.clear();
|
|
88
|
-
console.log("
|
|
89
|
-
|
|
90
|
-
if (addStructure) {
|
|
91
|
-
await this.addCommandStructure(config);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// Add basic options if no structure
|
|
95
|
-
await this.addSimpleOptions(config);
|
|
96
|
-
}
|
|
97
|
-
// 8. Guild IDs (optional)
|
|
39
|
+
console.log("āļø 4/6 - Options/Subcommands");
|
|
40
|
+
await this.addOptions(config.options);
|
|
98
41
|
console.clear();
|
|
99
|
-
console.log("
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return true;
|
|
103
|
-
const ids = val.split(",").map(id => id.trim());
|
|
104
|
-
const invalidIds = ids.filter(id => !DiscordRegex_1.DiscordRegex.GUILD_ID.test(id));
|
|
105
|
-
if (invalidIds.length > 0) {
|
|
106
|
-
console.log(`ā Invalid Guild IDs: ${invalidIds.join(', ')}`);
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
return true;
|
|
110
|
-
}, true);
|
|
111
|
-
if (guildInput && guildInput.toLowerCase() !== "none") {
|
|
112
|
-
config.guildID = guildInput.split(",").map(id => id.trim());
|
|
42
|
+
console.log("āļø 5/6 - Guild Specific");
|
|
43
|
+
if (await this.yesNoInput("Guild Specific ? (y/n): ")) {
|
|
44
|
+
config.guild_ids = await this.optionalGuildIds();
|
|
113
45
|
}
|
|
114
|
-
// 9. Filename
|
|
115
46
|
console.clear();
|
|
116
|
-
console.log("š¾
|
|
117
|
-
const filename =
|
|
118
|
-
await this.saveFile(FolderName_1.FolderName.SLASH_COMMANDS, filename, config);
|
|
47
|
+
console.log("š¾ 6/6 - Save");
|
|
48
|
+
const filename = await this.requireInput("Filename : ");
|
|
49
|
+
await this.saveFile(FolderName_1.FolderName.SLASH_COMMANDS, filename.split(".json")[0] ?? filename, config);
|
|
119
50
|
}
|
|
120
|
-
async
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
// Direct Sub Command
|
|
141
|
-
await this.addSubCommands(config.options);
|
|
51
|
+
async addOptions(options) {
|
|
52
|
+
const addOptions = await this.yesNoInput("Add options/subcommands ? (y/n): ");
|
|
53
|
+
if (!addOptions)
|
|
54
|
+
return;
|
|
55
|
+
while (true) {
|
|
56
|
+
console.clear();
|
|
57
|
+
console.log("š Options type :");
|
|
58
|
+
console.log("Valid options : " +
|
|
59
|
+
Object.entries(InteractionType_1.DiscordOptionType)
|
|
60
|
+
.filter(([, value]) => typeof value === 'number')
|
|
61
|
+
.map(([key, value]) => `${value}.${key}`)
|
|
62
|
+
.join(', '));
|
|
63
|
+
const type = parseInt(await this.requireInput("Type (1-11): ", val => {
|
|
64
|
+
const n = parseInt(val);
|
|
65
|
+
return n >= 1 && n <= 11;
|
|
66
|
+
}));
|
|
67
|
+
const option = await this.buildOption(type);
|
|
68
|
+
options.push(option);
|
|
69
|
+
if (!await this.yesNoInput("Other option ? (y/n): "))
|
|
70
|
+
break;
|
|
142
71
|
}
|
|
143
72
|
}
|
|
144
|
-
async
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await this.
|
|
153
|
-
options.push(subCmd);
|
|
154
|
-
continueAdding = await this.yesNoInput("Add another subcommand? (y/n): ");
|
|
73
|
+
async buildOption(type) {
|
|
74
|
+
const name = await this.requireInput("Option name (a-z0-9_-, 1-32): ", val => /^[a-z0-9_-]{1,32}$/.test(val));
|
|
75
|
+
const description = await this.requireInput("Description (1-100): ", val => val.length >= 1 && val.length <= 100);
|
|
76
|
+
const required = type !== 2 && await this.yesNoInput("Required ? (y/n): ");
|
|
77
|
+
const option = { type, name, description, required };
|
|
78
|
+
await this.handleOptionType(option, type);
|
|
79
|
+
if (type === 1 || type === 2) {
|
|
80
|
+
option.options = [];
|
|
81
|
+
await this.addOptions(option.options);
|
|
155
82
|
}
|
|
83
|
+
return option;
|
|
156
84
|
}
|
|
157
|
-
async
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
option.min_length = parseInt(await this.prompt("Min length (optional, Enter=skip): ")) || undefined;
|
|
176
|
-
option.max_length = parseInt(await this.prompt("Max length (optional, Enter=skip): ")) || undefined;
|
|
177
|
-
}
|
|
178
|
-
else if ([4, 10].includes(type)) { // Int/Number
|
|
179
|
-
option.min_value = parseFloat(await this.prompt("Min value (optional, Enter=skip): ")) || undefined;
|
|
180
|
-
option.max_value = parseFloat(await this.prompt("Max value (optional, Enter=skip): ")) || undefined;
|
|
181
|
-
}
|
|
182
|
-
else if (type === 7) { // Channel
|
|
85
|
+
async handleOptionType(option, type) {
|
|
86
|
+
switch (type) {
|
|
87
|
+
case 3: // STRING
|
|
88
|
+
if (await this.yesNoInput("Autocomplete ? "))
|
|
89
|
+
option.autocomplete = true;
|
|
90
|
+
option.min_length = await this.optionalNumber("Min length: ");
|
|
91
|
+
option.max_length = await this.optionalNumber("Max Length: ");
|
|
92
|
+
if (!option.autocomplete)
|
|
93
|
+
option.choices = await this.addChoices();
|
|
94
|
+
break;
|
|
95
|
+
case 4:
|
|
96
|
+
case 10: // INTEGER/NUMBER
|
|
97
|
+
option.min_value = await this.optionalNumber("Min value: ");
|
|
98
|
+
option.max_value = await this.optionalNumber("Max value: ");
|
|
99
|
+
if (type === 4)
|
|
100
|
+
option.choices = await this.addChoices();
|
|
101
|
+
break;
|
|
102
|
+
case 7: // CHANNEL
|
|
183
103
|
option.channel_types = await this.addChannelTypes();
|
|
184
|
-
|
|
185
|
-
options.push(option);
|
|
186
|
-
continueAdding = await this.yesNoInput("Add another option? (y/n): ");
|
|
104
|
+
break;
|
|
187
105
|
}
|
|
188
106
|
}
|
|
107
|
+
async optionalNumber(prompt) {
|
|
108
|
+
const input = await this.prompt(prompt);
|
|
109
|
+
return input.trim() ? parseFloat(input) : undefined;
|
|
110
|
+
}
|
|
189
111
|
async addChoices() {
|
|
112
|
+
if (!await this.yesNoInput("Add Choices ? "))
|
|
113
|
+
return undefined;
|
|
190
114
|
const choices = [];
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
const value = await this.requireInput("Choice value: ");
|
|
115
|
+
while (choices.length < 25) {
|
|
116
|
+
const name = await this.requireInput("Choice name (ā¤100): ", val => val.length <= 100);
|
|
117
|
+
const value = await this.requireInput("Choice value (ā¤100): ", val => val.length <= 100);
|
|
195
118
|
choices.push({ name, value });
|
|
196
|
-
|
|
119
|
+
if (!await this.yesNoInput("Another choice ? "))
|
|
120
|
+
break;
|
|
197
121
|
}
|
|
198
|
-
return choices
|
|
122
|
+
return choices;
|
|
199
123
|
}
|
|
200
124
|
async addChannelTypes() {
|
|
201
|
-
console.log("
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
125
|
+
console.log("Types: " +
|
|
126
|
+
Object.entries(InteractionType_1.ChannelType)
|
|
127
|
+
.filter(([, value]) => typeof value === 'number')
|
|
128
|
+
.map(([name, value]) => `${value}. ${name}`)
|
|
129
|
+
.join(', '));
|
|
130
|
+
const input = await this.requireInput("Types (separated by comma, or leave empty for all): ", (val) => {
|
|
131
|
+
if (!val.trim())
|
|
132
|
+
return true;
|
|
133
|
+
const trimmed = val.trim().toLowerCase();
|
|
134
|
+
if (trimmed === 'all')
|
|
135
|
+
return true;
|
|
136
|
+
return val.split(',').every(i => {
|
|
137
|
+
const num = parseInt(i.trim());
|
|
138
|
+
return !isNaN(num) && Object.values(InteractionType_1.ChannelType).includes(num);
|
|
139
|
+
});
|
|
140
|
+
}, true);
|
|
141
|
+
if (!input.trim() || input.trim() == 'all')
|
|
142
|
+
return undefined;
|
|
143
|
+
return input.split(',').map(i => parseInt(i.trim()));
|
|
219
144
|
}
|
|
220
145
|
}
|
|
221
146
|
exports.SlashCommandGeneratorCLI = SlashCommandGeneratorCLI;
|
|
@@ -30,8 +30,7 @@ class GuildListManager extends BaseCLI_1.BaseCLI {
|
|
|
30
30
|
try {
|
|
31
31
|
this.guilds = await this.rest.get(v10_1.Routes.userGuilds());
|
|
32
32
|
if (printResult) {
|
|
33
|
-
console.table(this.guilds.map((g,
|
|
34
|
-
Index: i,
|
|
33
|
+
console.table(this.guilds.map((g, _i) => ({
|
|
35
34
|
"Guild ID": g.id,
|
|
36
35
|
Nom: g.name
|
|
37
36
|
})));
|
|
@@ -75,7 +75,6 @@ class BaseInteractionManager {
|
|
|
75
75
|
}
|
|
76
76
|
console.log(`ā
${commandList.length} local ${this.folderPath}(s) not deployed\n`);
|
|
77
77
|
console.table(commandList.map((cmd) => ({
|
|
78
|
-
'#': cmd.index,
|
|
79
78
|
Nom: cmd.name,
|
|
80
79
|
Type: cmd.type === CommandType.SLASH ? 'Slash' :
|
|
81
80
|
cmd.type === CommandType.USER_CONTEXT_MENU ? 'User' : 'Message',
|
|
@@ -162,11 +161,13 @@ class BaseInteractionManager {
|
|
|
162
161
|
}
|
|
163
162
|
});
|
|
164
163
|
const results = await Promise.all(guildCommandPromises);
|
|
165
|
-
|
|
164
|
+
const interactionTypeTitle = this.folderPath ? (this.folderPath?.toUpperCase()) : "INTERACTION";
|
|
165
|
+
const interactionTypeDesc = this.folderPath ? (this.folderPath?.charAt(0).toUpperCase() + this.folderPath?.slice(1)) : " Interactions";
|
|
166
|
+
console.log(`š ${interactionTypeTitle} PER GUILD :`);
|
|
166
167
|
console.table(results.map(r => ({
|
|
167
168
|
"Guild": r.guild,
|
|
168
|
-
[
|
|
169
|
-
[
|
|
169
|
+
["Global " + interactionTypeDesc]: r.globalCommands.length,
|
|
170
|
+
["Specific " + interactionTypeDesc]: r.guildCommands.length,
|
|
170
171
|
"Total": r.count
|
|
171
172
|
})));
|
|
172
173
|
return results.filter(r => r.count > 0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InteractionContextType = exports.InteractionIntegrationType = void 0;
|
|
3
|
+
exports.ChannelType = exports.DiscordOptionType = exports.DiscordCommandType = exports.InteractionContextType = exports.InteractionIntegrationType = void 0;
|
|
4
4
|
var InteractionIntegrationType;
|
|
5
5
|
(function (InteractionIntegrationType) {
|
|
6
6
|
InteractionIntegrationType[InteractionIntegrationType["GUILD_INSTALL"] = 0] = "GUILD_INSTALL";
|
|
@@ -12,3 +12,35 @@ var InteractionContextType;
|
|
|
12
12
|
InteractionContextType[InteractionContextType["BOT_DM"] = 1] = "BOT_DM";
|
|
13
13
|
InteractionContextType[InteractionContextType["GROUP_DM"] = 2] = "GROUP_DM";
|
|
14
14
|
})(InteractionContextType || (exports.InteractionContextType = InteractionContextType = {}));
|
|
15
|
+
var DiscordCommandType;
|
|
16
|
+
(function (DiscordCommandType) {
|
|
17
|
+
DiscordCommandType[DiscordCommandType["CHANT_INPUT"] = 1] = "CHANT_INPUT";
|
|
18
|
+
DiscordCommandType[DiscordCommandType["USER"] = 2] = "USER";
|
|
19
|
+
DiscordCommandType[DiscordCommandType["MESSAGE"] = 3] = "MESSAGE";
|
|
20
|
+
})(DiscordCommandType || (exports.DiscordCommandType = DiscordCommandType = {}));
|
|
21
|
+
var DiscordOptionType;
|
|
22
|
+
(function (DiscordOptionType) {
|
|
23
|
+
DiscordOptionType[DiscordOptionType["SUB_COMMAND"] = 1] = "SUB_COMMAND";
|
|
24
|
+
DiscordOptionType[DiscordOptionType["SUB_COMMAND_GROUP"] = 2] = "SUB_COMMAND_GROUP";
|
|
25
|
+
DiscordOptionType[DiscordOptionType["STRING"] = 3] = "STRING";
|
|
26
|
+
DiscordOptionType[DiscordOptionType["INTEGER"] = 4] = "INTEGER";
|
|
27
|
+
DiscordOptionType[DiscordOptionType["BOOLEAN"] = 5] = "BOOLEAN";
|
|
28
|
+
DiscordOptionType[DiscordOptionType["USER"] = 6] = "USER";
|
|
29
|
+
DiscordOptionType[DiscordOptionType["CHANNEL"] = 7] = "CHANNEL";
|
|
30
|
+
DiscordOptionType[DiscordOptionType["ROLE"] = 8] = "ROLE";
|
|
31
|
+
DiscordOptionType[DiscordOptionType["MENTIONABLE"] = 9] = "MENTIONABLE";
|
|
32
|
+
DiscordOptionType[DiscordOptionType["NUMBER"] = 10] = "NUMBER";
|
|
33
|
+
DiscordOptionType[DiscordOptionType["ATTACHMENT"] = 11] = "ATTACHMENT";
|
|
34
|
+
})(DiscordOptionType || (exports.DiscordOptionType = DiscordOptionType = {}));
|
|
35
|
+
var ChannelType;
|
|
36
|
+
(function (ChannelType) {
|
|
37
|
+
ChannelType[ChannelType["Text"] = 0] = "Text";
|
|
38
|
+
ChannelType[ChannelType["Voice"] = 2] = "Voice";
|
|
39
|
+
ChannelType[ChannelType["Category"] = 4] = "Category";
|
|
40
|
+
ChannelType[ChannelType["Announcement"] = 5] = "Announcement";
|
|
41
|
+
ChannelType[ChannelType["ThreadPublic"] = 10] = "ThreadPublic";
|
|
42
|
+
ChannelType[ChannelType["ThreadPublicAnnouncement"] = 11] = "ThreadPublicAnnouncement";
|
|
43
|
+
ChannelType[ChannelType["ThreadPrivate"] = 12] = "ThreadPrivate";
|
|
44
|
+
ChannelType[ChannelType["Forum"] = 15] = "Forum";
|
|
45
|
+
ChannelType[ChannelType["Media"] = 16] = "Media";
|
|
46
|
+
})(ChannelType || (exports.ChannelType = ChannelType = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatulox/discord-interaction-manager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"author": "Spatulox",
|
|
5
5
|
"description": "discord-interaction-manager is a lightweight CLI tool to manage Discord bot interactions (slash commands, context menus) in under 30 seconds. Deploy, update, delete, and generate interaction files with an interactive terminal interface.",
|
|
6
6
|
"bin": {
|