kythia-core 0.11.1-beta → 0.12.0-beta
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/Kythia.d.ts +45 -0
- package/dist/Kythia.d.ts.map +1 -0
- package/dist/Kythia.js +443 -0
- package/dist/Kythia.js.map +1 -0
- package/dist/KythiaClient.d.ts +3 -0
- package/dist/KythiaClient.d.ts.map +1 -0
- package/dist/KythiaClient.js +69 -0
- package/dist/KythiaClient.js.map +1 -0
- package/dist/cli/Command.d.ts +9 -0
- package/dist/cli/Command.d.ts.map +1 -0
- package/dist/cli/Command.js +19 -0
- package/dist/cli/Command.js.map +1 -0
- package/dist/cli/commands/CacheClearCommand.d.ts +8 -0
- package/dist/cli/commands/CacheClearCommand.d.ts.map +1 -0
- package/dist/cli/commands/CacheClearCommand.js +94 -0
- package/dist/cli/commands/CacheClearCommand.js.map +1 -0
- package/dist/cli/commands/LangCheckCommand.d.ts +7 -0
- package/dist/cli/commands/LangCheckCommand.d.ts.map +1 -0
- package/dist/cli/commands/LangCheckCommand.js +345 -0
- package/dist/cli/commands/LangCheckCommand.js.map +1 -0
- package/dist/cli/commands/LangTranslateCommand.d.ts +8 -0
- package/dist/cli/commands/LangTranslateCommand.d.ts.map +1 -0
- package/dist/cli/commands/LangTranslateCommand.js +221 -0
- package/dist/cli/commands/LangTranslateCommand.js.map +1 -0
- package/dist/cli/commands/MakeMigrationCommand.d.ts +7 -0
- package/dist/cli/commands/MakeMigrationCommand.d.ts.map +1 -0
- package/dist/cli/commands/MakeMigrationCommand.js +55 -0
- package/dist/cli/commands/MakeMigrationCommand.js.map +1 -0
- package/dist/cli/commands/MakeModelCommand.d.ts +7 -0
- package/dist/cli/commands/MakeModelCommand.d.ts.map +1 -0
- package/dist/cli/commands/MakeModelCommand.js +56 -0
- package/dist/cli/commands/MakeModelCommand.js.map +1 -0
- package/dist/cli/commands/MigrateCommand.d.ts +14 -0
- package/dist/cli/commands/MigrateCommand.d.ts.map +1 -0
- package/dist/cli/commands/MigrateCommand.js +190 -0
- package/dist/cli/commands/MigrateCommand.js.map +1 -0
- package/dist/cli/commands/NamespaceCommand.d.ts +7 -0
- package/dist/cli/commands/NamespaceCommand.d.ts.map +1 -0
- package/dist/cli/commands/NamespaceCommand.js +92 -0
- package/dist/cli/commands/NamespaceCommand.js.map +1 -0
- package/dist/cli/commands/StructureCommand.d.ts +7 -0
- package/dist/cli/commands/StructureCommand.d.ts.map +1 -0
- package/dist/cli/commands/StructureCommand.js +51 -0
- package/dist/cli/commands/StructureCommand.js.map +1 -0
- package/dist/cli/commands/UpversionCommand.d.ts +7 -0
- package/dist/cli/commands/UpversionCommand.d.ts.map +1 -0
- package/dist/cli/commands/UpversionCommand.js +68 -0
- package/dist/cli/commands/UpversionCommand.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +44 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/db.d.ts +9 -0
- package/dist/cli/utils/db.d.ts.map +1 -0
- package/dist/cli/utils/db.js +90 -0
- package/dist/cli/utils/db.js.map +1 -0
- package/dist/database/KythiaMigrator.d.ts +4 -0
- package/dist/database/KythiaMigrator.d.ts.map +1 -0
- package/dist/database/KythiaMigrator.js +94 -0
- package/dist/database/KythiaMigrator.js.map +1 -0
- package/dist/database/KythiaModel.d.ts +83 -0
- package/dist/database/KythiaModel.d.ts.map +1 -0
- package/dist/database/KythiaModel.js +1121 -0
- package/dist/database/KythiaModel.js.map +1 -0
- package/dist/database/KythiaSequelize.d.ts +4 -0
- package/dist/database/KythiaSequelize.d.ts.map +1 -0
- package/dist/database/KythiaSequelize.js +99 -0
- package/dist/database/KythiaSequelize.js.map +1 -0
- package/dist/database/KythiaStorage.d.ts +21 -0
- package/dist/database/KythiaStorage.d.ts.map +1 -0
- package/dist/database/KythiaStorage.js +80 -0
- package/dist/database/KythiaStorage.js.map +1 -0
- package/dist/database/ModelLoader.d.ts +4 -0
- package/dist/database/ModelLoader.d.ts.map +1 -0
- package/dist/database/ModelLoader.js +54 -0
- package/dist/database/ModelLoader.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/lang/en.json +85 -0
- package/dist/managers/AddonManager.d.ts +45 -0
- package/dist/managers/AddonManager.d.ts.map +1 -0
- package/dist/managers/AddonManager.js +932 -0
- package/dist/managers/AddonManager.js.map +1 -0
- package/dist/managers/EventManager.d.ts +19 -0
- package/dist/managers/EventManager.d.ts.map +1 -0
- package/dist/managers/EventManager.js +55 -0
- package/dist/managers/EventManager.js.map +1 -0
- package/dist/managers/InteractionManager.d.ts +41 -0
- package/dist/managers/InteractionManager.d.ts.map +1 -0
- package/dist/managers/InteractionManager.js +441 -0
- package/dist/managers/InteractionManager.js.map +1 -0
- package/dist/managers/MiddlewareManager.d.ts +14 -0
- package/dist/managers/MiddlewareManager.d.ts.map +1 -0
- package/dist/managers/MiddlewareManager.js +75 -0
- package/dist/managers/MiddlewareManager.js.map +1 -0
- package/dist/managers/ShutdownManager.d.ts +22 -0
- package/dist/managers/ShutdownManager.d.ts.map +1 -0
- package/dist/managers/ShutdownManager.js +151 -0
- package/dist/managers/ShutdownManager.js.map +1 -0
- package/dist/managers/TranslatorManager.d.ts +19 -0
- package/dist/managers/TranslatorManager.d.ts.map +1 -0
- package/dist/managers/TranslatorManager.js +118 -0
- package/dist/managers/TranslatorManager.js.map +1 -0
- package/dist/middlewares/botPermissions.d.ts +4 -0
- package/dist/middlewares/botPermissions.d.ts.map +1 -0
- package/dist/middlewares/botPermissions.js +28 -0
- package/dist/middlewares/botPermissions.js.map +1 -0
- package/dist/middlewares/cooldown.d.ts +4 -0
- package/dist/middlewares/cooldown.d.ts.map +1 -0
- package/dist/middlewares/cooldown.js +42 -0
- package/dist/middlewares/cooldown.js.map +1 -0
- package/dist/middlewares/isInMainGuild.d.ts +4 -0
- package/dist/middlewares/isInMainGuild.d.ts.map +1 -0
- package/dist/middlewares/isInMainGuild.js +52 -0
- package/dist/middlewares/isInMainGuild.js.map +1 -0
- package/dist/middlewares/ownerOnly.d.ts +4 -0
- package/dist/middlewares/ownerOnly.d.ts.map +1 -0
- package/dist/middlewares/ownerOnly.js +24 -0
- package/dist/middlewares/ownerOnly.js.map +1 -0
- package/dist/middlewares/teamOnly.d.ts +4 -0
- package/dist/middlewares/teamOnly.d.ts.map +1 -0
- package/dist/middlewares/teamOnly.js +26 -0
- package/dist/middlewares/teamOnly.js.map +1 -0
- package/dist/middlewares/userPermissions.d.ts +4 -0
- package/dist/middlewares/userPermissions.d.ts.map +1 -0
- package/dist/middlewares/userPermissions.js +28 -0
- package/dist/middlewares/userPermissions.js.map +1 -0
- package/dist/middlewares/voteLocked.d.ts +4 -0
- package/dist/middlewares/voteLocked.d.ts.map +1 -0
- package/dist/middlewares/voteLocked.js +50 -0
- package/dist/middlewares/voteLocked.js.map +1 -0
- package/dist/structures/BaseCommand.d.ts +23 -0
- package/dist/structures/BaseCommand.d.ts.map +1 -0
- package/dist/structures/BaseCommand.js +42 -0
- package/dist/structures/BaseCommand.js.map +1 -0
- package/dist/types/AddonManager.d.ts +58 -0
- package/dist/types/AddonManager.d.ts.map +1 -0
- package/dist/types/AddonManager.js +3 -0
- package/dist/types/AddonManager.js.map +1 -0
- package/dist/types/DiscordHelpers.d.ts +7 -0
- package/dist/types/DiscordHelpers.d.ts.map +1 -0
- package/dist/types/DiscordHelpers.js +3 -0
- package/dist/types/DiscordHelpers.js.map +1 -0
- package/dist/types/EventManager.d.ts +10 -0
- package/dist/types/EventManager.d.ts.map +1 -0
- package/dist/types/EventManager.js +3 -0
- package/dist/types/EventManager.js.map +1 -0
- package/dist/types/InteractionManager.d.ts +35 -0
- package/dist/types/InteractionManager.d.ts.map +1 -0
- package/dist/types/InteractionManager.js +3 -0
- package/dist/types/InteractionManager.js.map +1 -0
- package/dist/types/KythiaClient.d.ts +9 -0
- package/dist/types/KythiaClient.d.ts.map +1 -0
- package/dist/types/KythiaClient.js +3 -0
- package/dist/types/KythiaClient.js.map +1 -0
- package/dist/types/KythiaConfig.d.ts +291 -0
- package/dist/types/KythiaConfig.d.ts.map +1 -0
- package/dist/types/KythiaConfig.js +3 -0
- package/dist/types/KythiaConfig.js.map +1 -0
- package/dist/types/KythiaContainer.d.ts +38 -0
- package/dist/types/KythiaContainer.d.ts.map +1 -0
- package/dist/types/KythiaContainer.js +3 -0
- package/dist/types/KythiaContainer.js.map +1 -0
- package/dist/types/KythiaLogger.d.ts +5 -0
- package/dist/types/KythiaLogger.d.ts.map +1 -0
- package/dist/types/KythiaLogger.js +3 -0
- package/dist/types/KythiaLogger.js.map +1 -0
- package/dist/types/KythiaMigrator.d.ts +9 -0
- package/dist/types/KythiaMigrator.d.ts.map +1 -0
- package/dist/types/KythiaMigrator.js +3 -0
- package/dist/types/KythiaMigrator.js.map +1 -0
- package/dist/types/KythiaModel.d.ts +31 -0
- package/dist/types/KythiaModel.d.ts.map +1 -0
- package/dist/types/KythiaModel.js +3 -0
- package/dist/types/KythiaModel.js.map +1 -0
- package/dist/types/KythiaOptions.d.ts +13 -0
- package/dist/types/KythiaOptions.d.ts.map +1 -0
- package/dist/types/KythiaOptions.js +3 -0
- package/dist/types/KythiaOptions.js.map +1 -0
- package/dist/types/KythiaSequelize.d.ts +13 -0
- package/dist/types/KythiaSequelize.d.ts.map +1 -0
- package/dist/types/KythiaSequelize.js +3 -0
- package/dist/types/KythiaSequelize.js.map +1 -0
- package/dist/types/KythiaStorage.d.ts +22 -0
- package/dist/types/KythiaStorage.d.ts.map +1 -0
- package/dist/types/KythiaStorage.js +3 -0
- package/dist/types/KythiaStorage.js.map +1 -0
- package/dist/types/MiddlewareManager.d.ts +14 -0
- package/dist/types/MiddlewareManager.d.ts.map +1 -0
- package/dist/types/MiddlewareManager.js +3 -0
- package/dist/types/MiddlewareManager.js.map +1 -0
- package/dist/types/ModelLoader.d.ts +8 -0
- package/dist/types/ModelLoader.d.ts.map +1 -0
- package/dist/types/ModelLoader.js +3 -0
- package/dist/types/ModelLoader.js.map +1 -0
- package/dist/types/ShutdownManager.d.ts +15 -0
- package/dist/types/ShutdownManager.d.ts.map +1 -0
- package/dist/types/ShutdownManager.js +3 -0
- package/dist/types/ShutdownManager.js.map +1 -0
- package/dist/types/TranslatorManager.d.ts +16 -0
- package/dist/types/TranslatorManager.d.ts.map +1 -0
- package/dist/types/TranslatorManager.js +3 -0
- package/dist/types/TranslatorManager.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +29 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/color.d.ts +15 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +156 -0
- package/dist/utils/color.js.map +1 -0
- package/dist/utils/discord.d.ts +8 -0
- package/dist/utils/discord.d.ts.map +1 -0
- package/dist/utils/discord.js +53 -0
- package/dist/utils/discord.js.map +1 -0
- package/dist/utils/formatter.d.ts +3 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +89 -0
- package/dist/utils/formatter.js.map +1 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +54 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +5 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +150 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +28 -6
- package/src/lang/en.json +85 -0
- package/changelog.md +0 -53
- package/index.js +0 -15
- package/src/Kythia.js +0 -556
- package/src/KythiaClient.js +0 -93
- package/src/cli/Command.js +0 -68
- package/src/cli/commands/CacheClearCommand.js +0 -136
- package/src/cli/commands/LangCheckCommand.js +0 -396
- package/src/cli/commands/LangTranslateCommand.js +0 -336
- package/src/cli/commands/MakeMigrationCommand.js +0 -82
- package/src/cli/commands/MakeModelCommand.js +0 -81
- package/src/cli/commands/MigrateCommand.js +0 -259
- package/src/cli/commands/NamespaceCommand.js +0 -112
- package/src/cli/commands/StructureCommand.js +0 -70
- package/src/cli/commands/UpversionCommand.js +0 -94
- package/src/cli/index.js +0 -69
- package/src/cli/utils/db.js +0 -117
- package/src/database/KythiaMigrator.js +0 -116
- package/src/database/KythiaModel.js +0 -1586
- package/src/database/KythiaSequelize.js +0 -128
- package/src/database/KythiaStorage.js +0 -117
- package/src/database/ModelLoader.js +0 -79
- package/src/managers/AddonManager.js +0 -1219
- package/src/managers/EventManager.js +0 -104
- package/src/managers/InteractionManager.js +0 -869
- package/src/managers/ShutdownManager.js +0 -218
- package/src/structures/BaseCommand.js +0 -53
- package/src/utils/color.js +0 -180
- package/src/utils/formatter.js +0 -99
- package/src/utils/index.js +0 -4
|
@@ -0,0 +1,932 @@
|
|
|
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
|
+
const discord_js_1 = require("discord.js");
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
class AddonManager {
|
|
10
|
+
client;
|
|
11
|
+
container;
|
|
12
|
+
logger;
|
|
13
|
+
buttonHandlers;
|
|
14
|
+
modalHandlers;
|
|
15
|
+
selectMenuHandlers;
|
|
16
|
+
autocompleteHandlers;
|
|
17
|
+
commandCategoryMap;
|
|
18
|
+
categoryToFeatureMap;
|
|
19
|
+
embedDrafts;
|
|
20
|
+
eventHandlers;
|
|
21
|
+
constructor({ client, container, }) {
|
|
22
|
+
this.client = client;
|
|
23
|
+
this.container = container;
|
|
24
|
+
this.logger = this.container.logger;
|
|
25
|
+
this.buttonHandlers = new Map();
|
|
26
|
+
this.modalHandlers = new Map();
|
|
27
|
+
this.selectMenuHandlers = new Map();
|
|
28
|
+
this.autocompleteHandlers = new Map();
|
|
29
|
+
this.commandCategoryMap = new Map();
|
|
30
|
+
this.categoryToFeatureMap = new Map();
|
|
31
|
+
this.embedDrafts = new discord_js_1.Collection();
|
|
32
|
+
this.eventHandlers = new Map();
|
|
33
|
+
}
|
|
34
|
+
registerButtonHandler(customId, handler) {
|
|
35
|
+
if (this.buttonHandlers.has(customId)) {
|
|
36
|
+
this.logger.warn(`[REGISTRATION] Warning: Button handler for [${customId}] already exists and will be overwritten.`);
|
|
37
|
+
}
|
|
38
|
+
this.buttonHandlers.set(customId, handler);
|
|
39
|
+
}
|
|
40
|
+
registerSelectMenuHandler(customIdPrefix, handler) {
|
|
41
|
+
if (this.selectMenuHandlers.has(customIdPrefix)) {
|
|
42
|
+
this.logger.warn(`[REGISTRATION] Warning: Select menu handler for [${customIdPrefix}] already exists and will be overwritten.`);
|
|
43
|
+
}
|
|
44
|
+
this.selectMenuHandlers.set(customIdPrefix, handler);
|
|
45
|
+
}
|
|
46
|
+
registerModalHandler(customIdPrefix, handler) {
|
|
47
|
+
if (this.modalHandlers.has(customIdPrefix)) {
|
|
48
|
+
this.logger.warn(`[REGISTRATION] Warning: Modal handler for [${customIdPrefix}] already exists and will be overwritten.`);
|
|
49
|
+
}
|
|
50
|
+
this.modalHandlers.set(customIdPrefix, handler);
|
|
51
|
+
}
|
|
52
|
+
registerAutocompleteHandler(commandName, handler) {
|
|
53
|
+
if (this.autocompleteHandlers.has(commandName)) {
|
|
54
|
+
this.logger.warn(`[REGISTRATION] Warning: Autocomplete handler for [${commandName}] already exists and will be overwritten.`);
|
|
55
|
+
}
|
|
56
|
+
this.autocompleteHandlers.set(commandName, handler);
|
|
57
|
+
}
|
|
58
|
+
_isBaseCommandClass(module) {
|
|
59
|
+
if (typeof module !== 'function')
|
|
60
|
+
return false;
|
|
61
|
+
if (!module.prototype)
|
|
62
|
+
return false;
|
|
63
|
+
const hasExecute = typeof module.prototype.execute === 'function';
|
|
64
|
+
return hasExecute;
|
|
65
|
+
}
|
|
66
|
+
_instantiateBaseCommand(CommandClass) {
|
|
67
|
+
try {
|
|
68
|
+
return new CommandClass(this.container);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
this.logger.error(`Failed to instantiate BaseCommand class:`, error);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
_createBuilderFromData(data, BuilderClass) {
|
|
76
|
+
let builder = new BuilderClass();
|
|
77
|
+
if (typeof data === 'function') {
|
|
78
|
+
data(builder);
|
|
79
|
+
}
|
|
80
|
+
else if (data instanceof BuilderClass) {
|
|
81
|
+
builder = data;
|
|
82
|
+
}
|
|
83
|
+
else if (typeof data === 'object') {
|
|
84
|
+
builder.setName(data.name || 'unnamed');
|
|
85
|
+
builder.setDescription(data.description || 'No description');
|
|
86
|
+
if (BuilderClass === discord_js_1.SlashCommandBuilder) {
|
|
87
|
+
builder.setDescription(data.description || 'No description');
|
|
88
|
+
if (data.permissions) {
|
|
89
|
+
builder.setDefaultMemberPermissions(data.permissions);
|
|
90
|
+
}
|
|
91
|
+
if (data.guildOnly !== undefined) {
|
|
92
|
+
builder.setDMPermission(!data.guildOnly);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (BuilderClass === discord_js_1.ContextMenuCommandBuilder) {
|
|
96
|
+
builder.setType(data.type || discord_js_1.ApplicationCommandType.User);
|
|
97
|
+
if (data.permissions) {
|
|
98
|
+
builder.setDefaultMemberPermissions(data.permissions);
|
|
99
|
+
}
|
|
100
|
+
if (data.guildOnly !== undefined) {
|
|
101
|
+
builder.setDMPermission(!data.guildOnly);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return builder;
|
|
106
|
+
}
|
|
107
|
+
registerCommand(module, filePath, commandNamesSet, commandDataForDeployment, permissionDefaults = {}, options = {}) {
|
|
108
|
+
if (this._isBaseCommandClass(module)) {
|
|
109
|
+
module = this._instantiateBaseCommand(module);
|
|
110
|
+
}
|
|
111
|
+
const data = module.data || module.slashCommand || module.contextMenuCommand;
|
|
112
|
+
if (!module || !data)
|
|
113
|
+
return null;
|
|
114
|
+
let builderClass;
|
|
115
|
+
if (module.data instanceof discord_js_1.ContextMenuCommandBuilder) {
|
|
116
|
+
builderClass = discord_js_1.ContextMenuCommandBuilder;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
builderClass = discord_js_1.SlashCommandBuilder;
|
|
120
|
+
}
|
|
121
|
+
const commandBuilder = this._createBuilderFromData(module.data, builderClass);
|
|
122
|
+
const commandName = commandBuilder.name;
|
|
123
|
+
const category = options.folderName || node_path_1.default.basename(node_path_1.default.dirname(filePath));
|
|
124
|
+
const categoryDefaults = permissionDefaults[category] || {};
|
|
125
|
+
const finalCommand = {
|
|
126
|
+
...categoryDefaults,
|
|
127
|
+
...module,
|
|
128
|
+
};
|
|
129
|
+
this.commandCategoryMap.set(commandName, category);
|
|
130
|
+
if (commandNamesSet.has(commandName)) {
|
|
131
|
+
throw new Error(`Duplicate command name detected: "${commandName}" in ${filePath}`);
|
|
132
|
+
}
|
|
133
|
+
commandNamesSet.add(commandName);
|
|
134
|
+
this.client.commands.set(commandName, finalCommand);
|
|
135
|
+
commandDataForDeployment.push(commandBuilder.toJSON());
|
|
136
|
+
if (typeof finalCommand.autocomplete === 'function') {
|
|
137
|
+
this.registerAutocompleteHandler(commandName, finalCommand.autocomplete);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
type: 'single',
|
|
141
|
+
name: commandName,
|
|
142
|
+
folder: category,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async loadAddons(kythiaInstance) {
|
|
146
|
+
this.logger.info('🔌 Loading & Registering Kythia Addons...');
|
|
147
|
+
const commandDataForDeployment = [];
|
|
148
|
+
const addonsDir = node_path_1.default.join(this.container.appRoot, 'addons');
|
|
149
|
+
if (!node_fs_1.default.existsSync(addonsDir))
|
|
150
|
+
return commandDataForDeployment;
|
|
151
|
+
let addonFolders = node_fs_1.default
|
|
152
|
+
.readdirSync(addonsDir, { withFileTypes: true })
|
|
153
|
+
.filter((d) => d.isDirectory() && !d.name.startsWith('_'));
|
|
154
|
+
const coreAddon = addonFolders.find((d) => d.name === 'core');
|
|
155
|
+
const otherAddons = addonFolders.filter((d) => d.name !== 'core');
|
|
156
|
+
if (coreAddon) {
|
|
157
|
+
addonFolders = [coreAddon, ...otherAddons];
|
|
158
|
+
}
|
|
159
|
+
const commandNamesSet = new Set();
|
|
160
|
+
const addonSummaries = [];
|
|
161
|
+
for (const addon of addonFolders) {
|
|
162
|
+
const addonDir = node_path_1.default.join(addonsDir, addon.name);
|
|
163
|
+
let addonVersion = 'v0.0.0-alpha';
|
|
164
|
+
try {
|
|
165
|
+
const addonJsonPath = node_path_1.default.join(addonDir, 'addon.json');
|
|
166
|
+
if (node_fs_1.default.existsSync(addonJsonPath)) {
|
|
167
|
+
let addonJson;
|
|
168
|
+
try {
|
|
169
|
+
const addonJsonRaw = node_fs_1.default.readFileSync(addonJsonPath, 'utf8');
|
|
170
|
+
addonJson = JSON.parse(addonJsonRaw);
|
|
171
|
+
}
|
|
172
|
+
catch (jsonErr) {
|
|
173
|
+
this.logger.warn(`🔴 Failed to parse addon.json for ${addon.name}: ${jsonErr.message}`);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
addonVersion = addonJson.version || 'v0.0.0-alpha';
|
|
177
|
+
if (addonJson.active === false) {
|
|
178
|
+
this.logger.info(`🟠 Addon ${addon.name.toUpperCase()} disabled`);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (addonJson.featureFlag) {
|
|
182
|
+
this.commandCategoryMap.set(addon.name, addon.name);
|
|
183
|
+
this.categoryToFeatureMap.set(addon.name, addonJson.featureFlag);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
this.logger.warn(`🔴 Addon ${addon.name.toUpperCase()} is missing addon.json. Skipping.`);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
this.logger.warn(`🔴 Error reading addon.json for ${addonDir}: ${e.message}`);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
const configAddons = this.container.kythiaConfig?.addons || {};
|
|
197
|
+
if (configAddons.all?.active === false) {
|
|
198
|
+
this.logger.info(`🟠 Addon ${addon.name.toUpperCase()} disabled via kythia config`);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
else if (configAddons[addon.name]?.active === false) {
|
|
202
|
+
this.logger.info(`🟠 Addon ${addon.name.toUpperCase()} disabled via kythia config`);
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
this.logger.warn(`🔴 Error checking config for addon ${addon.name.toUpperCase()}: ${e.message}`);
|
|
208
|
+
}
|
|
209
|
+
let addonPermissionDefaults = {};
|
|
210
|
+
const permissionsFilePath = node_path_1.default.join(addonDir, 'permissions.js');
|
|
211
|
+
if (node_fs_1.default.existsSync(permissionsFilePath)) {
|
|
212
|
+
try {
|
|
213
|
+
addonPermissionDefaults = require(permissionsFilePath);
|
|
214
|
+
this.logger.info(` └─> Found and loaded permission defaults for addon '${addon.name.toUpperCase()}'`);
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
this.logger.warn(` └─> Failed to load permissions.js for addon '${addon.name.toUpperCase()}': ${e.message}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
let hasLocales = false;
|
|
221
|
+
const addonLangPath = node_path_1.default.join(addonDir, 'lang');
|
|
222
|
+
if (node_fs_1.default.existsSync(addonLangPath)) {
|
|
223
|
+
if (this.container.translator) {
|
|
224
|
+
this.container.translator.loadLocalesFromDir(addonLangPath);
|
|
225
|
+
hasLocales = true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const loadedCommandsSummary = [];
|
|
229
|
+
const loadedEventsSummary = [];
|
|
230
|
+
const loadedRegisterSummary = [];
|
|
231
|
+
const commandsPath = node_path_1.default.join(addonDir, 'commands');
|
|
232
|
+
if (node_fs_1.default.existsSync(commandsPath)) {
|
|
233
|
+
try {
|
|
234
|
+
const commandsResult = await this._loadCommandsFromPath(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment);
|
|
235
|
+
loadedCommandsSummary.push(...commandsResult);
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
this.logger.error(`❌ Failed to load commands from addon "${addon.name}":`, error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const registerPath = node_path_1.default.join(addonDir, 'register.js');
|
|
242
|
+
if (node_fs_1.default.existsSync(registerPath)) {
|
|
243
|
+
try {
|
|
244
|
+
const registration = require(registerPath);
|
|
245
|
+
if (typeof registration.initialize === 'function') {
|
|
246
|
+
const registrationSummary = await registration.initialize(kythiaInstance);
|
|
247
|
+
if (Array.isArray(registrationSummary) &&
|
|
248
|
+
registrationSummary.length > 0) {
|
|
249
|
+
loadedRegisterSummary.push(...registrationSummary);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
this.logger.error(`❌ Failed to register components for [${addon.name}]:`, error);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const eventsPath = node_path_1.default.join(addonDir, 'events');
|
|
258
|
+
if (node_fs_1.default.existsSync(eventsPath)) {
|
|
259
|
+
const eventFiles = node_fs_1.default
|
|
260
|
+
.readdirSync(eventsPath)
|
|
261
|
+
.filter((file) => file.endsWith('.js'));
|
|
262
|
+
for (const file of eventFiles) {
|
|
263
|
+
const eventName = node_path_1.default.basename(file, '.js');
|
|
264
|
+
try {
|
|
265
|
+
const eventHandler = require(node_path_1.default.join(eventsPath, file));
|
|
266
|
+
if (typeof eventHandler === 'function') {
|
|
267
|
+
if (!this.eventHandlers.has(eventName)) {
|
|
268
|
+
this.eventHandlers.set(eventName, []);
|
|
269
|
+
}
|
|
270
|
+
this.eventHandlers.get(eventName).push(eventHandler);
|
|
271
|
+
loadedEventsSummary.push(eventName);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
this.logger.error(`❌ Failed to register event [${eventName}] for [${addon.name}]:`, error);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
addonSummaries.push({
|
|
280
|
+
name: addon.name,
|
|
281
|
+
version: addonVersion,
|
|
282
|
+
commands: loadedCommandsSummary,
|
|
283
|
+
events: loadedEventsSummary,
|
|
284
|
+
register: loadedRegisterSummary,
|
|
285
|
+
hasLocales: hasLocales,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
this._logAddonSummary(addonSummaries);
|
|
289
|
+
return commandDataForDeployment;
|
|
290
|
+
}
|
|
291
|
+
async _loadCommandsFromPath(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment) {
|
|
292
|
+
const isTopLevelCommandGroup = node_fs_1.default.existsSync(node_path_1.default.join(commandsPath, '_command.js'));
|
|
293
|
+
if (isTopLevelCommandGroup) {
|
|
294
|
+
return await this._loadTopLevelCommandGroup(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
return await this._loadIndividualCommands(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async _loadTopLevelCommandGroup(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment) {
|
|
301
|
+
const loadedCommandsSummary = [];
|
|
302
|
+
let commandDef = require(node_path_1.default.join(commandsPath, '_command.js'));
|
|
303
|
+
if (this._isBaseCommandClass(commandDef)) {
|
|
304
|
+
commandDef = this._instantiateBaseCommand(commandDef);
|
|
305
|
+
}
|
|
306
|
+
const category = addon.name;
|
|
307
|
+
const categoryDefaults = addonPermissionDefaults[category] || {};
|
|
308
|
+
commandDef = {
|
|
309
|
+
...categoryDefaults,
|
|
310
|
+
...commandDef,
|
|
311
|
+
};
|
|
312
|
+
const mainData = commandDef.data || commandDef.slashCommand;
|
|
313
|
+
const mainBuilder = this._createBuilderFromData(mainData, discord_js_1.SlashCommandBuilder);
|
|
314
|
+
const mainCommandName = mainBuilder.name;
|
|
315
|
+
if (commandDef.featureFlag) {
|
|
316
|
+
this.commandCategoryMap.set(mainCommandName, addon.name);
|
|
317
|
+
this.categoryToFeatureMap.set(addon.name, commandDef.featureFlag);
|
|
318
|
+
}
|
|
319
|
+
this.commandCategoryMap.set(mainCommandName, addon.name);
|
|
320
|
+
if (commandNamesSet.has(mainCommandName))
|
|
321
|
+
throw new Error(`Duplicate command name: ${mainCommandName}`);
|
|
322
|
+
commandNamesSet.add(mainCommandName);
|
|
323
|
+
this.client.commands.set(mainCommandName, commandDef);
|
|
324
|
+
if (typeof commandDef.autocomplete === 'function') {
|
|
325
|
+
this.registerAutocompleteHandler(mainCommandName, commandDef.autocomplete);
|
|
326
|
+
}
|
|
327
|
+
const loadedSubcommandsSummary = [];
|
|
328
|
+
const contents = node_fs_1.default.readdirSync(commandsPath, { withFileTypes: true });
|
|
329
|
+
for (const item of contents) {
|
|
330
|
+
const itemPath = node_path_1.default.join(commandsPath, item.name);
|
|
331
|
+
if (item.isFile() &&
|
|
332
|
+
item.name.endsWith('.js') &&
|
|
333
|
+
!item.name.startsWith('_')) {
|
|
334
|
+
let subModule = require(itemPath);
|
|
335
|
+
const isSubcommand = subModule.subcommand === true || this._isBaseCommandClass(subModule);
|
|
336
|
+
if (this._isBaseCommandClass(subModule)) {
|
|
337
|
+
subModule = this._instantiateBaseCommand(subModule);
|
|
338
|
+
}
|
|
339
|
+
if (!isSubcommand)
|
|
340
|
+
continue;
|
|
341
|
+
const subData = subModule.data || subModule.slashCommand;
|
|
342
|
+
if (!subData)
|
|
343
|
+
continue;
|
|
344
|
+
const subBuilder = this._createBuilderFromData(subData, discord_js_1.SlashCommandSubcommandBuilder);
|
|
345
|
+
mainBuilder.addSubcommand(subBuilder);
|
|
346
|
+
this.client.commands.set(`${mainCommandName} ${subBuilder.name}`, subModule);
|
|
347
|
+
if (typeof subModule.autocomplete === 'function') {
|
|
348
|
+
this.registerAutocompleteHandler(`${mainCommandName} ${subBuilder.name}`, subModule.autocomplete);
|
|
349
|
+
}
|
|
350
|
+
loadedSubcommandsSummary.push(subBuilder.name);
|
|
351
|
+
}
|
|
352
|
+
else if (item.isDirectory()) {
|
|
353
|
+
const groupDefPath = node_path_1.default.join(itemPath, '_group.js');
|
|
354
|
+
if (!node_fs_1.default.existsSync(groupDefPath)) {
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
let groupModule = require(groupDefPath);
|
|
359
|
+
if (this._isBaseCommandClass(groupModule)) {
|
|
360
|
+
groupModule = this._instantiateBaseCommand(groupModule);
|
|
361
|
+
}
|
|
362
|
+
const groupData = groupModule.data || groupModule.slashCommand;
|
|
363
|
+
if (!groupData)
|
|
364
|
+
continue;
|
|
365
|
+
const groupBuilder = this._createBuilderFromData(groupData, discord_js_1.SlashCommandSubcommandGroupBuilder);
|
|
366
|
+
const subcommandsInGroupSummary = [];
|
|
367
|
+
const subCommandFiles = node_fs_1.default
|
|
368
|
+
.readdirSync(itemPath)
|
|
369
|
+
.filter((f) => f.endsWith('.js') && !f.startsWith('_'));
|
|
370
|
+
for (const file of subCommandFiles) {
|
|
371
|
+
const subCommandPath = node_path_1.default.join(itemPath, file);
|
|
372
|
+
let subModule = require(subCommandPath);
|
|
373
|
+
if (this._isBaseCommandClass(subModule)) {
|
|
374
|
+
subModule = this._instantiateBaseCommand(subModule);
|
|
375
|
+
}
|
|
376
|
+
const subData = subModule.data || subModule.slashCommand;
|
|
377
|
+
if (!subData)
|
|
378
|
+
continue;
|
|
379
|
+
const subBuilder = this._createBuilderFromData(subData, discord_js_1.SlashCommandSubcommandBuilder);
|
|
380
|
+
groupBuilder.addSubcommand(subBuilder);
|
|
381
|
+
const commandKey = `${mainCommandName} ${groupBuilder.name} ${subBuilder.name}`;
|
|
382
|
+
this.client.commands.set(commandKey, subModule);
|
|
383
|
+
if (typeof subModule.autocomplete === 'function') {
|
|
384
|
+
this.registerAutocompleteHandler(commandKey, subModule.autocomplete);
|
|
385
|
+
}
|
|
386
|
+
subcommandsInGroupSummary.push(subBuilder.name);
|
|
387
|
+
}
|
|
388
|
+
mainBuilder.addSubcommandGroup(groupBuilder);
|
|
389
|
+
loadedSubcommandsSummary.push({
|
|
390
|
+
group: groupBuilder.name,
|
|
391
|
+
subcommands: subcommandsInGroupSummary,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
catch (e) {
|
|
395
|
+
this.logger.error(`❌ Failed to load subcommand group from ${itemPath}:`, e);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
commandDataForDeployment.push(mainBuilder.toJSON());
|
|
400
|
+
loadedCommandsSummary.push({
|
|
401
|
+
type: 'group',
|
|
402
|
+
name: mainCommandName,
|
|
403
|
+
subcommands: loadedSubcommandsSummary,
|
|
404
|
+
});
|
|
405
|
+
return loadedCommandsSummary;
|
|
406
|
+
}
|
|
407
|
+
async _loadIndividualCommands(commandsPath, addon, addonPermissionDefaults, commandNamesSet, commandDataForDeployment) {
|
|
408
|
+
const loadedCommandsSummary = [];
|
|
409
|
+
const commandItems = node_fs_1.default.readdirSync(commandsPath, { withFileTypes: true });
|
|
410
|
+
for (const item of commandItems) {
|
|
411
|
+
const itemPath = node_path_1.default.join(commandsPath, item.name);
|
|
412
|
+
if (item.isDirectory() &&
|
|
413
|
+
node_fs_1.default.existsSync(node_path_1.default.join(itemPath, '_command.js'))) {
|
|
414
|
+
let commandDef = require(node_path_1.default.join(itemPath, '_command.js'));
|
|
415
|
+
if (this._isBaseCommandClass(commandDef)) {
|
|
416
|
+
commandDef = this._instantiateBaseCommand(commandDef);
|
|
417
|
+
}
|
|
418
|
+
const mainData = commandDef.data || commandDef.slashCommand;
|
|
419
|
+
const mainBuilder = this._createBuilderFromData(mainData, discord_js_1.SlashCommandBuilder);
|
|
420
|
+
const mainCommandName = mainBuilder.name;
|
|
421
|
+
if (commandDef.featureFlag) {
|
|
422
|
+
this.commandCategoryMap.set(mainCommandName, addon.name);
|
|
423
|
+
this.categoryToFeatureMap.set(addon.name, commandDef.featureFlag);
|
|
424
|
+
}
|
|
425
|
+
if (commandNamesSet.has(mainCommandName))
|
|
426
|
+
throw new Error(`Duplicate name: ${mainCommandName}`);
|
|
427
|
+
commandNamesSet.add(mainCommandName);
|
|
428
|
+
this.client.commands.set(mainCommandName, commandDef);
|
|
429
|
+
if (typeof commandDef.autocomplete === 'function') {
|
|
430
|
+
this.registerAutocompleteHandler(mainCommandName, commandDef.autocomplete);
|
|
431
|
+
}
|
|
432
|
+
const subcommandsList = [];
|
|
433
|
+
const groupContents = node_fs_1.default.readdirSync(itemPath, { withFileTypes: true });
|
|
434
|
+
for (const content of groupContents) {
|
|
435
|
+
const contentPath = node_path_1.default.join(itemPath, content.name);
|
|
436
|
+
if (content.isFile() &&
|
|
437
|
+
content.name.endsWith('.js') &&
|
|
438
|
+
!content.name.startsWith('_')) {
|
|
439
|
+
let subModule = require(contentPath);
|
|
440
|
+
if (this._isBaseCommandClass(subModule)) {
|
|
441
|
+
subModule = this._instantiateBaseCommand(subModule);
|
|
442
|
+
}
|
|
443
|
+
const subData = subModule.data || subModule.slashCommand;
|
|
444
|
+
if (!subData)
|
|
445
|
+
continue;
|
|
446
|
+
const subBuilder = this._createBuilderFromData(subData, discord_js_1.SlashCommandSubcommandBuilder);
|
|
447
|
+
mainBuilder.addSubcommand(subBuilder);
|
|
448
|
+
this.client.commands.set(`${mainCommandName} ${subBuilder.name}`, subModule);
|
|
449
|
+
if (typeof subModule.autocomplete === 'function') {
|
|
450
|
+
this.registerAutocompleteHandler(`${mainCommandName} ${subBuilder.name}`, subModule.autocomplete);
|
|
451
|
+
}
|
|
452
|
+
subcommandsList.push(subBuilder.name);
|
|
453
|
+
}
|
|
454
|
+
else if (content.isDirectory() &&
|
|
455
|
+
node_fs_1.default.existsSync(node_path_1.default.join(contentPath, '_group.js'))) {
|
|
456
|
+
let groupDef = require(node_path_1.default.join(contentPath, '_group.js'));
|
|
457
|
+
if (this._isBaseCommandClass(groupDef)) {
|
|
458
|
+
groupDef = this._instantiateBaseCommand(groupDef);
|
|
459
|
+
}
|
|
460
|
+
const groupData = groupDef.data || groupDef.slashCommand;
|
|
461
|
+
const groupBuilder = this._createBuilderFromData(groupData, discord_js_1.SlashCommandSubcommandGroupBuilder);
|
|
462
|
+
const subGroupList = [];
|
|
463
|
+
const subGroupContents = node_fs_1.default.readdirSync(contentPath, {
|
|
464
|
+
withFileTypes: true,
|
|
465
|
+
});
|
|
466
|
+
for (const subSubItem of subGroupContents) {
|
|
467
|
+
if (subSubItem.isFile() &&
|
|
468
|
+
subSubItem.name.endsWith('.js') &&
|
|
469
|
+
!subSubItem.name.startsWith('_')) {
|
|
470
|
+
const subSubPath = node_path_1.default.join(contentPath, subSubItem.name);
|
|
471
|
+
let subSubModule = require(subSubPath);
|
|
472
|
+
if (this._isBaseCommandClass(subSubModule)) {
|
|
473
|
+
subSubModule = this._instantiateBaseCommand(subSubModule);
|
|
474
|
+
}
|
|
475
|
+
const subSubData = subSubModule.data || subSubModule.slashCommand;
|
|
476
|
+
if (!subSubData)
|
|
477
|
+
continue;
|
|
478
|
+
const subSubBuilder = this._createBuilderFromData(subSubData, discord_js_1.SlashCommandSubcommandBuilder);
|
|
479
|
+
groupBuilder.addSubcommand(subSubBuilder);
|
|
480
|
+
this.client.commands.set(`${mainCommandName} ${groupBuilder.name} ${subSubBuilder.name}`, subSubModule);
|
|
481
|
+
if (typeof subSubModule.autocomplete === 'function') {
|
|
482
|
+
this.registerAutocompleteHandler(`${mainCommandName} ${groupBuilder.name} ${subSubBuilder.name}`, subSubModule.autocomplete);
|
|
483
|
+
}
|
|
484
|
+
subGroupList.push(subSubBuilder.name);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
mainBuilder.addSubcommandGroup(groupBuilder);
|
|
488
|
+
subcommandsList.push({
|
|
489
|
+
group: groupBuilder.name,
|
|
490
|
+
subcommands: subGroupList,
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
commandDataForDeployment.push(mainBuilder.toJSON());
|
|
495
|
+
loadedCommandsSummary.push({
|
|
496
|
+
type: 'group',
|
|
497
|
+
name: mainCommandName,
|
|
498
|
+
subcommands: subcommandsList,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
else if (item.isFile() &&
|
|
502
|
+
item.name.endsWith('.js') &&
|
|
503
|
+
!item.name.startsWith('_')) {
|
|
504
|
+
let commandModule = require(itemPath);
|
|
505
|
+
let isClass = false;
|
|
506
|
+
if (this._isBaseCommandClass(commandModule)) {
|
|
507
|
+
commandModule = this._instantiateBaseCommand(commandModule);
|
|
508
|
+
isClass = true;
|
|
509
|
+
}
|
|
510
|
+
if (!isClass && commandModule.subcommand)
|
|
511
|
+
continue;
|
|
512
|
+
let summarySlash = null;
|
|
513
|
+
let summaryContext = null;
|
|
514
|
+
if (commandModule.slashCommand) {
|
|
515
|
+
const builder = commandModule.slashCommand;
|
|
516
|
+
const name = builder.name;
|
|
517
|
+
try {
|
|
518
|
+
const allLocales = this.container.translator?.getLocales();
|
|
519
|
+
const nameLocalizations = {};
|
|
520
|
+
const descriptionLocalizations = {};
|
|
521
|
+
if (typeof allLocales.entries === 'function') {
|
|
522
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
523
|
+
const nameKey = `command_${name}_name`;
|
|
524
|
+
const descKey = `command_${name}_desc`;
|
|
525
|
+
if (translations[nameKey])
|
|
526
|
+
nameLocalizations[lang] = translations[nameKey];
|
|
527
|
+
if (translations[descKey])
|
|
528
|
+
descriptionLocalizations[lang] = translations[descKey];
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
for (const lang in allLocales) {
|
|
533
|
+
const translations = allLocales[lang];
|
|
534
|
+
const nameKey = `command_${name}_name`;
|
|
535
|
+
const descKey = `command_${name}_desc`;
|
|
536
|
+
if (translations[nameKey])
|
|
537
|
+
nameLocalizations[lang] = translations[nameKey];
|
|
538
|
+
if (translations[descKey])
|
|
539
|
+
descriptionLocalizations[lang] = translations[descKey];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (Object.keys(nameLocalizations).length > 0) {
|
|
543
|
+
builder.setNameLocalizations(nameLocalizations);
|
|
544
|
+
}
|
|
545
|
+
if (Object.keys(descriptionLocalizations).length > 0) {
|
|
546
|
+
builder.setDescriptionLocalizations(descriptionLocalizations);
|
|
547
|
+
}
|
|
548
|
+
this._applySubcommandLocalizations(builder, name, allLocales);
|
|
549
|
+
}
|
|
550
|
+
catch (e) {
|
|
551
|
+
this.logger.warn(`Failed to load localizations for command "${name}": ${e.message}`);
|
|
552
|
+
}
|
|
553
|
+
if (commandNamesSet.has(name)) {
|
|
554
|
+
this.logger.warn(`Duplicate command name detected: "${name}" in ${itemPath}`);
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
commandNamesSet.add(name);
|
|
558
|
+
this.client.commands.set(name, commandModule);
|
|
559
|
+
}
|
|
560
|
+
commandDataForDeployment.push(builder.toJSON());
|
|
561
|
+
summarySlash = {
|
|
562
|
+
type: 'single',
|
|
563
|
+
name: name,
|
|
564
|
+
folder: addon.name,
|
|
565
|
+
kind: 'slash',
|
|
566
|
+
};
|
|
567
|
+
if (summarySlash)
|
|
568
|
+
loadedCommandsSummary.push(summarySlash);
|
|
569
|
+
this.commandCategoryMap.set(name, addon.name);
|
|
570
|
+
}
|
|
571
|
+
if (commandModule.contextMenuCommand) {
|
|
572
|
+
const builder = commandModule.contextMenuCommand;
|
|
573
|
+
const name = builder.name;
|
|
574
|
+
if (commandNamesSet.has(name) && !commandModule.slashCommand) {
|
|
575
|
+
this.logger.warn(`Duplicate command name detected: "${name}" in ${itemPath}`);
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
if (!commandNamesSet.has(name))
|
|
579
|
+
commandNamesSet.add(name);
|
|
580
|
+
this.client.commands.set(name, commandModule);
|
|
581
|
+
}
|
|
582
|
+
commandDataForDeployment.push(builder.toJSON());
|
|
583
|
+
summaryContext = {
|
|
584
|
+
type: 'single',
|
|
585
|
+
name: name,
|
|
586
|
+
folder: addon.name,
|
|
587
|
+
kind: 'contextMenu',
|
|
588
|
+
};
|
|
589
|
+
if (summaryContext)
|
|
590
|
+
loadedCommandsSummary.push(summaryContext);
|
|
591
|
+
}
|
|
592
|
+
if (!isClass &&
|
|
593
|
+
!commandModule.slashCommand &&
|
|
594
|
+
!commandModule.contextMenuCommand) {
|
|
595
|
+
const summary = this.registerCommand(commandModule, itemPath, commandNamesSet, commandDataForDeployment, addonPermissionDefaults, { folderName: addon.name });
|
|
596
|
+
if (summary)
|
|
597
|
+
loadedCommandsSummary.push(summary);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
else if (item.isDirectory() && !item.name.startsWith('_')) {
|
|
601
|
+
const files = node_fs_1.default
|
|
602
|
+
.readdirSync(itemPath)
|
|
603
|
+
.filter((f) => f.endsWith('.js') && !f.startsWith('_'));
|
|
604
|
+
for (const file of files) {
|
|
605
|
+
const filePath = node_path_1.default.join(itemPath, file);
|
|
606
|
+
let commandModule = require(filePath);
|
|
607
|
+
let isClass = false;
|
|
608
|
+
if (this._isBaseCommandClass(commandModule)) {
|
|
609
|
+
commandModule = this._instantiateBaseCommand(commandModule);
|
|
610
|
+
isClass = true;
|
|
611
|
+
}
|
|
612
|
+
if (!isClass && commandModule.subcommand)
|
|
613
|
+
continue;
|
|
614
|
+
let summarySlash = null;
|
|
615
|
+
let summaryContext = null;
|
|
616
|
+
if (commandModule.slashCommand) {
|
|
617
|
+
const builder = commandModule.slashCommand;
|
|
618
|
+
const name = builder.name;
|
|
619
|
+
try {
|
|
620
|
+
const allLocales = this.container.translator?.getLocales();
|
|
621
|
+
const nameLocalizations = {};
|
|
622
|
+
const descriptionLocalizations = {};
|
|
623
|
+
if (typeof allLocales.entries === 'function') {
|
|
624
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
625
|
+
const nameKey = `command_${name}_name`;
|
|
626
|
+
const descKey = `command_${name}_desc`;
|
|
627
|
+
if (translations[nameKey])
|
|
628
|
+
nameLocalizations[lang] = translations[nameKey];
|
|
629
|
+
if (translations[descKey])
|
|
630
|
+
descriptionLocalizations[lang] = translations[descKey];
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
for (const lang in allLocales) {
|
|
635
|
+
const translations = allLocales[lang];
|
|
636
|
+
const nameKey = `command_${name}_name`;
|
|
637
|
+
const descKey = `command_${name}_desc`;
|
|
638
|
+
if (translations[nameKey])
|
|
639
|
+
nameLocalizations[lang] = translations[nameKey];
|
|
640
|
+
if (translations[descKey])
|
|
641
|
+
descriptionLocalizations[lang] = translations[descKey];
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (Object.keys(nameLocalizations).length > 0) {
|
|
645
|
+
builder.setNameLocalizations(nameLocalizations);
|
|
646
|
+
}
|
|
647
|
+
if (Object.keys(descriptionLocalizations).length > 0) {
|
|
648
|
+
builder.setDescriptionLocalizations(descriptionLocalizations);
|
|
649
|
+
}
|
|
650
|
+
this._applySubcommandLocalizations(builder, name, allLocales);
|
|
651
|
+
}
|
|
652
|
+
catch (e) {
|
|
653
|
+
this.logger.warn(`Failed to load localizations for command "${name}": ${e.message}`);
|
|
654
|
+
}
|
|
655
|
+
this.commandCategoryMap.set(name, item.name);
|
|
656
|
+
if (commandNamesSet.has(name)) {
|
|
657
|
+
this.logger.warn(`Duplicate slash command name detected: "${name}" in ${filePath}`);
|
|
658
|
+
}
|
|
659
|
+
else {
|
|
660
|
+
commandNamesSet.add(name);
|
|
661
|
+
this.client.commands.set(name, commandModule);
|
|
662
|
+
commandDataForDeployment.push(builder.toJSON());
|
|
663
|
+
summarySlash = {
|
|
664
|
+
type: 'single',
|
|
665
|
+
name: name,
|
|
666
|
+
folder: item.name,
|
|
667
|
+
kind: 'slash',
|
|
668
|
+
};
|
|
669
|
+
if (summarySlash)
|
|
670
|
+
loadedCommandsSummary.push(summarySlash);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (commandModule.contextMenuCommand) {
|
|
674
|
+
const builder = commandModule.contextMenuCommand;
|
|
675
|
+
const name = builder.name;
|
|
676
|
+
if (!this.client.commands.has(name)) {
|
|
677
|
+
this.client.commands.set(name, commandModule);
|
|
678
|
+
}
|
|
679
|
+
commandDataForDeployment.push(builder.toJSON());
|
|
680
|
+
summaryContext = {
|
|
681
|
+
type: 'single',
|
|
682
|
+
name: name,
|
|
683
|
+
folder: item.name,
|
|
684
|
+
kind: 'contextMenu',
|
|
685
|
+
};
|
|
686
|
+
if (summaryContext)
|
|
687
|
+
loadedCommandsSummary.push(summaryContext);
|
|
688
|
+
}
|
|
689
|
+
if (commandModule.prefixCommand) {
|
|
690
|
+
const pConfig = commandModule.prefixCommand;
|
|
691
|
+
const name = pConfig.name || pConfig.trigger;
|
|
692
|
+
if (name) {
|
|
693
|
+
Object.assign(commandModule, pConfig);
|
|
694
|
+
if (!this.client.commands.has(name)) {
|
|
695
|
+
if (commandNamesSet.has(name)) {
|
|
696
|
+
this.logger.warn(`Duplicate prefix command name detected: "${name}" in ${itemPath}`);
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
commandNamesSet.add(name);
|
|
700
|
+
this.client.commands.set(name, commandModule);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
else {
|
|
704
|
+
const existing = this.client.commands.get(name);
|
|
705
|
+
if (existing)
|
|
706
|
+
Object.assign(existing, pConfig);
|
|
707
|
+
}
|
|
708
|
+
const summaryPrefix = {
|
|
709
|
+
type: 'single',
|
|
710
|
+
name: name,
|
|
711
|
+
folder: addon.name,
|
|
712
|
+
kind: 'prefix',
|
|
713
|
+
};
|
|
714
|
+
loadedCommandsSummary.push(summaryPrefix);
|
|
715
|
+
this.commandCategoryMap.set(name, addon.name);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
if (!isClass &&
|
|
719
|
+
!commandModule.slashCommand &&
|
|
720
|
+
!commandModule.contextMenuCommand &&
|
|
721
|
+
!commandModule.prefixCommand) {
|
|
722
|
+
const summary = this.registerCommand(commandModule, filePath, commandNamesSet, commandDataForDeployment, addonPermissionDefaults, { folderName: item.name });
|
|
723
|
+
if (summary)
|
|
724
|
+
loadedCommandsSummary.push(summary);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return loadedCommandsSummary;
|
|
730
|
+
}
|
|
731
|
+
_applySubcommandLocalizations(commandBuilder, commandName, allLocales) {
|
|
732
|
+
if (Array.isArray(commandBuilder.options)) {
|
|
733
|
+
for (const group of commandBuilder.options) {
|
|
734
|
+
if (typeof discord_js_1.SlashCommandSubcommandGroupBuilder !== 'undefined' &&
|
|
735
|
+
group instanceof discord_js_1.SlashCommandSubcommandGroupBuilder) {
|
|
736
|
+
const groupName = group.name;
|
|
737
|
+
const groupDescLocalizations = {};
|
|
738
|
+
if (typeof allLocales.entries === 'function') {
|
|
739
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
740
|
+
const groupDescKey = `command_${commandName}_${groupName}_group_desc`;
|
|
741
|
+
if (translations[groupDescKey])
|
|
742
|
+
groupDescLocalizations[lang] = translations[groupDescKey];
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
for (const lang in allLocales) {
|
|
747
|
+
const translations = allLocales[lang];
|
|
748
|
+
const groupDescKey = `command_${commandName}_${groupName}_group_desc`;
|
|
749
|
+
if (translations[groupDescKey])
|
|
750
|
+
groupDescLocalizations[lang] = translations[groupDescKey];
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
if (Object.keys(groupDescLocalizations).length > 0 &&
|
|
754
|
+
typeof group.setDescriptionLocalizations === 'function') {
|
|
755
|
+
group.setDescriptionLocalizations(groupDescLocalizations);
|
|
756
|
+
}
|
|
757
|
+
if (Array.isArray(group.options)) {
|
|
758
|
+
for (const sub of group.options) {
|
|
759
|
+
const subName = sub.name;
|
|
760
|
+
const subDescLocalizations = {};
|
|
761
|
+
if (typeof allLocales.entries === 'function') {
|
|
762
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
763
|
+
const subDescKey = `command_${commandName}_${groupName}_${subName}_desc`;
|
|
764
|
+
if (translations[subDescKey])
|
|
765
|
+
subDescLocalizations[lang] = translations[subDescKey];
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
for (const lang in allLocales) {
|
|
770
|
+
const translations = allLocales[lang];
|
|
771
|
+
const subDescKey = `command_${commandName}_${groupName}_${subName}_desc`;
|
|
772
|
+
if (translations[subDescKey])
|
|
773
|
+
subDescLocalizations[lang] = translations[subDescKey];
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (Object.keys(subDescLocalizations).length > 0 &&
|
|
777
|
+
typeof sub.setDescriptionLocalizations === 'function') {
|
|
778
|
+
sub.setDescriptionLocalizations(subDescLocalizations);
|
|
779
|
+
}
|
|
780
|
+
if (Array.isArray(sub.options)) {
|
|
781
|
+
for (const opt of sub.options) {
|
|
782
|
+
const optName = opt.name;
|
|
783
|
+
const optDescLocalizations = {};
|
|
784
|
+
if (typeof allLocales.entries === 'function') {
|
|
785
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
786
|
+
const optDescKey = `command_${commandName}_${groupName}_${subName}_option_${optName}`;
|
|
787
|
+
if (translations[optDescKey])
|
|
788
|
+
optDescLocalizations[lang] = translations[optDescKey];
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
for (const lang in allLocales) {
|
|
793
|
+
const translations = allLocales[lang];
|
|
794
|
+
const optDescKey = `command_${commandName}_${groupName}_${subName}_option_${optName}`;
|
|
795
|
+
if (translations[optDescKey])
|
|
796
|
+
optDescLocalizations[lang] = translations[optDescKey];
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
if (Object.keys(optDescLocalizations).length > 0 &&
|
|
800
|
+
typeof opt.setDescriptionLocalizations === 'function') {
|
|
801
|
+
opt.setDescriptionLocalizations(optDescLocalizations);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
else if (typeof discord_js_1.SlashCommandSubcommandBuilder !== 'undefined' &&
|
|
809
|
+
group instanceof discord_js_1.SlashCommandSubcommandBuilder) {
|
|
810
|
+
const subName = group.name;
|
|
811
|
+
const subDescLocalizations = {};
|
|
812
|
+
if (typeof allLocales.entries === 'function') {
|
|
813
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
814
|
+
const subDescKey = `command_${commandName}_${subName}_desc`;
|
|
815
|
+
if (translations[subDescKey])
|
|
816
|
+
subDescLocalizations[lang] = translations[subDescKey];
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
for (const lang in allLocales) {
|
|
821
|
+
const translations = allLocales[lang];
|
|
822
|
+
const subDescKey = `command_${commandName}_${subName}_desc`;
|
|
823
|
+
if (translations[subDescKey])
|
|
824
|
+
subDescLocalizations[lang] = translations[subDescKey];
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (Object.keys(subDescLocalizations).length > 0 &&
|
|
828
|
+
typeof group.setDescriptionLocalizations === 'function') {
|
|
829
|
+
group.setDescriptionLocalizations(subDescLocalizations);
|
|
830
|
+
}
|
|
831
|
+
if (Array.isArray(group.options)) {
|
|
832
|
+
for (const opt of group.options) {
|
|
833
|
+
const optName = opt.name;
|
|
834
|
+
const optDescLocalizations = {};
|
|
835
|
+
if (typeof allLocales.entries === 'function') {
|
|
836
|
+
for (const [lang, translations] of allLocales.entries()) {
|
|
837
|
+
const optDescKey = `command_${commandName}_${subName}_option_${optName}`;
|
|
838
|
+
if (translations[optDescKey])
|
|
839
|
+
optDescLocalizations[lang] = translations[optDescKey];
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
for (const lang in allLocales) {
|
|
844
|
+
const translations = allLocales[lang];
|
|
845
|
+
const optDescKey = `command_${commandName}_${subName}_option_${optName}`;
|
|
846
|
+
if (translations[optDescKey])
|
|
847
|
+
optDescLocalizations[lang] = translations[optDescKey];
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
if (Object.keys(optDescLocalizations).length > 0 &&
|
|
851
|
+
typeof opt.setDescriptionLocalizations === 'function') {
|
|
852
|
+
opt.setDescriptionLocalizations(optDescLocalizations);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
_logAddonSummary(addonSummaries) {
|
|
861
|
+
this.logger.info('▬▬▬▬▬▬▬▬▬▬▬▬▬[ Addon(s) Loaded ]▬▬▬▬▬▬▬▬▬▬▬▬▬');
|
|
862
|
+
for (const addon of addonSummaries) {
|
|
863
|
+
this.logger.info(`📦 ${addon.name} (v${addon.version})`);
|
|
864
|
+
this.logger.info(' ⚙️ Command(s)');
|
|
865
|
+
if (!addon.commands.length) {
|
|
866
|
+
this.logger.info(' (no commands registered)');
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
for (const cmd of addon.commands) {
|
|
870
|
+
if (cmd.type === 'group') {
|
|
871
|
+
this.logger.info(` └─ /${cmd.name}`);
|
|
872
|
+
for (const sub of cmd.subcommands) {
|
|
873
|
+
if (typeof sub === 'string') {
|
|
874
|
+
this.logger.info(` └─ ${sub}`);
|
|
875
|
+
}
|
|
876
|
+
else if (typeof sub === 'object' && sub.group) {
|
|
877
|
+
this.logger.info(` └─ [${sub.group}]`);
|
|
878
|
+
for (const subsub of sub.subcommands) {
|
|
879
|
+
this.logger.info(` └─ ${subsub}`);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else if (cmd.type === 'single') {
|
|
885
|
+
let kindLabel = '';
|
|
886
|
+
if (cmd.kind === 'slash')
|
|
887
|
+
kindLabel = ' [slash]';
|
|
888
|
+
else if (cmd.kind === 'contextMenu')
|
|
889
|
+
kindLabel = ' [contextMenu]';
|
|
890
|
+
else if (cmd.kind === 'prefix')
|
|
891
|
+
kindLabel = ' [prefix]';
|
|
892
|
+
const prefixSymbol = cmd.kind === 'prefix' ? '!' : '/';
|
|
893
|
+
if (cmd.folder) {
|
|
894
|
+
this.logger.info(` └─ ${prefixSymbol}${cmd.name} (${cmd.folder})${kindLabel}`);
|
|
895
|
+
}
|
|
896
|
+
else {
|
|
897
|
+
this.logger.info(` └─ ${prefixSymbol}${cmd.name}${kindLabel}`);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
if (addon.hasLocales) {
|
|
903
|
+
this.logger.info(' 🌐 Locales: Loaded');
|
|
904
|
+
}
|
|
905
|
+
if (addon.register?.length) {
|
|
906
|
+
this.logger.info(' 🧩 Component(s)');
|
|
907
|
+
for (const reg of addon.register) {
|
|
908
|
+
this.logger.info(` ${reg}`);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
if (addon.events?.length) {
|
|
912
|
+
this.logger.info(' 📢 Event(s)');
|
|
913
|
+
for (const ev of addon.events) {
|
|
914
|
+
this.logger.info(` └─ ${ev}`);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
getHandlers() {
|
|
920
|
+
return {
|
|
921
|
+
buttonHandlers: this.buttonHandlers,
|
|
922
|
+
modalHandlers: this.modalHandlers,
|
|
923
|
+
selectMenuHandlers: this.selectMenuHandlers,
|
|
924
|
+
autocompleteHandlers: this.autocompleteHandlers,
|
|
925
|
+
commandCategoryMap: this.commandCategoryMap,
|
|
926
|
+
categoryToFeatureMap: this.categoryToFeatureMap,
|
|
927
|
+
eventHandlers: this.eventHandlers,
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
exports.default = AddonManager;
|
|
932
|
+
//# sourceMappingURL=AddonManager.js.map
|