reciple 5.6.0 → 6.0.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/cjs/bin.js +6 -7
  2. package/dist/cjs/index.js +6 -5
  3. package/dist/cjs/reciple/classes/RecipleClient.js +11 -146
  4. package/dist/cjs/reciple/classes/builders/MessageCommandBuilder.js +1 -1
  5. package/dist/cjs/reciple/classes/managers/ApplicationCommandManager.js +137 -0
  6. package/dist/cjs/reciple/classes/managers/ClientCommandManager.js +62 -0
  7. package/dist/cjs/reciple/classes/managers/ClientModuleManager.js +189 -0
  8. package/dist/cjs/reciple/classes/{CommandCooldownManager.js → managers/CommandCooldownManager.js} +8 -5
  9. package/dist/cjs/reciple/classes/{MessageCommandOptionManager.js → managers/MessageCommandOptionManager.js} +0 -0
  10. package/dist/cjs/reciple/util.js +10 -1
  11. package/dist/types/index.d.ts +6 -5
  12. package/dist/types/reciple/classes/RecipleClient.d.ts +16 -61
  13. package/dist/types/reciple/classes/builders/MessageCommandBuilder.d.ts +1 -1
  14. package/dist/types/reciple/classes/managers/ApplicationCommandManager.d.ts +20 -0
  15. package/dist/types/reciple/classes/managers/ClientCommandManager.d.ts +37 -0
  16. package/dist/types/reciple/classes/managers/ClientModuleManager.d.ts +79 -0
  17. package/dist/types/reciple/classes/{CommandCooldownManager.d.ts → managers/CommandCooldownManager.d.ts} +3 -2
  18. package/dist/types/reciple/classes/{MessageCommandOptionManager.d.ts → managers/MessageCommandOptionManager.d.ts} +1 -1
  19. package/dist/types/reciple/types/commands.d.ts +2 -2
  20. package/dist/types/reciple/types/paramOptions.d.ts +6 -17
  21. package/dist/types/reciple/util.d.ts +2 -0
  22. package/package.json +17 -15
  23. package/dist/cjs/reciple/registerApplicationCommands.js +0 -49
  24. package/dist/types/reciple/registerApplicationCommands.d.ts +0 -9
package/dist/cjs/bin.js CHANGED
@@ -12,7 +12,6 @@ const flags_1 = require("./reciple/flags");
12
12
  const fallout_utility_1 = require("fallout-utility");
13
13
  const chalk_1 = __importDefault(require("chalk"));
14
14
  require("dotenv/config");
15
- const discord_js_1 = require("discord.js");
16
15
  const path_1 = __importDefault(require("path"));
17
16
  const allowedFiles = ['node_modules', 'reciple.yml', 'package.json'];
18
17
  const configPath = path_1.default.join(flags_1.cwd, './reciple.yml');
@@ -34,15 +33,15 @@ const client = new RecipleClient_1.RecipleClient({ config: config, ...config.cli
34
33
  if (config.fileLogging.clientLogs)
35
34
  client.logger.info('Starting Reciple client v' + version_1.rawVersion);
36
35
  (async () => {
37
- await client.startModules((0, discord_js_1.normalizeArray)([config.modulesFolder]));
36
+ client.addCommandListeners();
37
+ await client.modules.startModulesFromFiles({
38
+ files: await client.modules.getModuleFiles()
39
+ });
38
40
  client.on('ready', async () => {
41
+ await client.modules.loadAll(true);
39
42
  if (client.isClientLogsEnabled())
40
43
  client.logger.warn(`Logged in as ${client.user?.tag || 'Unknown'}!`);
41
- client.on('cacheSweep', () => {
42
- client.cooldowns.clean();
43
- });
44
- await client.loadModules();
45
- client.addCommandListeners();
44
+ client.on('cacheSweep', () => client.cooldowns.clean());
46
45
  });
47
46
  client.login(config.token).catch(err => {
48
47
  if (client.isClientLogsEnabled())
package/dist/cjs/index.js CHANGED
@@ -14,13 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./reciple/classes/CommandCooldownManager"), exports);
18
- __exportStar(require("./reciple/classes/MessageCommandOptionManager"), exports);
19
- __exportStar(require("./reciple/classes/RecipleClient"), exports);
20
- __exportStar(require("./reciple/classes/RecipleConfig"), exports);
21
17
  __exportStar(require("./reciple/classes/builders/MessageCommandBuilder"), exports);
22
18
  __exportStar(require("./reciple/classes/builders/MessageCommandOptionBuilder"), exports);
23
19
  __exportStar(require("./reciple/classes/builders/SlashCommandBuilder"), exports);
20
+ __exportStar(require("./reciple/classes/managers/ApplicationCommandManager"), exports);
21
+ __exportStar(require("./reciple/classes/managers/CommandCooldownManager"), exports);
22
+ __exportStar(require("./reciple/classes/managers/ClientCommandManager"), exports);
23
+ __exportStar(require("./reciple/classes/managers/MessageCommandOptionManager"), exports);
24
+ __exportStar(require("./reciple/classes/RecipleClient"), exports);
25
+ __exportStar(require("./reciple/classes/RecipleConfig"), exports);
24
26
  __exportStar(require("./reciple/types/builders"), exports);
25
27
  __exportStar(require("./reciple/types/commands"), exports);
26
28
  __exportStar(require("./reciple/types/paramOptions"), exports);
@@ -28,6 +30,5 @@ __exportStar(require("./reciple/flags"), exports);
28
30
  __exportStar(require("./reciple/logger"), exports);
29
31
  __exportStar(require("./reciple/modules"), exports);
30
32
  __exportStar(require("./reciple/permissions"), exports);
31
- __exportStar(require("./reciple/registerApplicationCommands"), exports);
32
33
  __exportStar(require("./reciple/util"), exports);
33
34
  __exportStar(require("./reciple/version"), exports);
@@ -6,21 +6,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RecipleClient = void 0;
7
7
  const MessageCommandBuilder_1 = require("./builders/MessageCommandBuilder");
8
8
  const SlashCommandBuilder_1 = require("./builders/SlashCommandBuilder");
9
- const builders_1 = require("../types/builders");
10
- const registerApplicationCommands_1 = require("../registerApplicationCommands");
11
9
  const commands_1 = require("../types/commands");
10
+ const CommandCooldownManager_1 = require("./managers/CommandCooldownManager");
12
11
  const permissions_1 = require("../permissions");
13
- const CommandCooldownManager_1 = require("./CommandCooldownManager");
14
- const MessageCommandOptionManager_1 = require("./MessageCommandOptionManager");
12
+ const MessageCommandOptionManager_1 = require("./managers/MessageCommandOptionManager");
13
+ const ApplicationCommandManager_1 = require("./managers/ApplicationCommandManager");
14
+ const builders_1 = require("../types/builders");
15
+ const ClientCommandManager_1 = require("./managers/ClientCommandManager");
15
16
  const RecipleConfig_1 = require("./RecipleConfig");
16
- const modules_1 = require("../modules");
17
17
  const fallout_utility_1 = require("fallout-utility");
18
18
  const logger_1 = require("../logger");
19
19
  const version_1 = require("../version");
20
20
  const flags_1 = require("../flags");
21
21
  const path_1 = __importDefault(require("path"));
22
22
  const discord_js_1 = require("discord.js");
23
- const util_1 = require("../util");
23
+ const ClientModuleManager_1 = require("./managers/ClientModuleManager");
24
24
  class RecipleClient extends discord_js_1.Client {
25
25
  /**
26
26
  * @param options Client options
@@ -28,126 +28,15 @@ class RecipleClient extends discord_js_1.Client {
28
28
  constructor(options) {
29
29
  super(options);
30
30
  this.config = RecipleConfig_1.RecipleConfig.getDefaultConfig();
31
- this.commands = { slashCommands: new discord_js_1.Collection(), messageCommands: new discord_js_1.Collection() };
32
- this.additionalApplicationCommands = [];
31
+ this.commands = new ClientCommandManager_1.ClientCommandManager({ client: this });
33
32
  this.cooldowns = new CommandCooldownManager_1.CommandCooldownManager();
34
- this.modules = [];
33
+ this.modules = new ClientModuleManager_1.ClientModuleManager({ client: this });
35
34
  this.version = version_1.version;
36
35
  this.logger = (0, logger_1.createLogger)(!!options.config?.fileLogging.stringifyLoggedJSON, options.config?.fileLogging.debugmode);
37
36
  this.config = { ...this.config, ...(options.config ?? {}) };
38
37
  if (this.config.fileLogging.enabled)
39
38
  this.logger.logFile(path_1.default.join(flags_1.cwd, this.config.fileLogging.logFilePath ?? 'logs/latest.log'), false);
40
- }
41
- /**
42
- * Load and start modules from given folders
43
- * @param folders folders that contains the modules you want to load
44
- */
45
- async startModules(...folders) {
46
- folders = (0, discord_js_1.normalizeArray)(folders).map(f => path_1.default.join(flags_1.cwd, f));
47
- for (const folder of folders) {
48
- if (this.isClientLogsEnabled())
49
- this.logger.info(`Loading Modules from ${folder}`);
50
- const modules = await (0, modules_1.getModules)(this, folder).catch(() => null);
51
- if (!modules) {
52
- if (this.isClientLogsEnabled())
53
- this.logger.error(`Failed to load modules from ${folder}`);
54
- continue;
55
- }
56
- this.modules.push(...modules.modules);
57
- }
58
- return this;
59
- }
60
- /**
61
- * Execute {@link RecipleModule['onLoad']} from client modules and register application commands if enabled
62
- */
63
- async loadModules() {
64
- if (!this.isReady())
65
- throw new Error('Client is not ready');
66
- for (const m in this.modules) {
67
- const index = (m);
68
- const module_ = this.modules[index];
69
- try {
70
- if (typeof module_.script?.onLoad === 'function') {
71
- await Promise.resolve(module_.script.onLoad(this)).catch(err => {
72
- if (this.isClientLogsEnabled()) {
73
- this.logger.error(`Error loading ${module_.info.filename ?? 'unknown module'}:`);
74
- this.logger.error(err);
75
- }
76
- this.modules.splice(index);
77
- });
78
- }
79
- }
80
- catch (err) {
81
- if (this.isClientLogsEnabled()) {
82
- this.logger.error(`Error loading ${module_.info.filename ?? 'unknown module'}:`);
83
- this.logger.error(err);
84
- }
85
- this.modules.splice(index);
86
- }
87
- if (module_.script?.commands && Array.isArray(module_.script?.commands)) {
88
- for (const command of module_.script.commands) {
89
- this.addCommand(command);
90
- }
91
- }
92
- }
93
- if (this.isClientLogsEnabled()) {
94
- this.logger.info(`${this.modules.length} modules loaded.`);
95
- this.logger.info(`${this.commands.messageCommands.size} message commands loaded.`);
96
- this.logger.info(`${this.commands.slashCommands.size} slash commands loaded.`);
97
- }
98
- if (this.config.commands.slashCommand.registerCommands)
99
- await this.registerClientApplicationCommands();
100
- return this;
101
- }
102
- /**
103
- * Add module
104
- * @param options Module options
105
- * @deprecated This is very stupid, Just add it manually
106
- */
107
- async addModule(options) {
108
- (0, util_1.deprecationWarning)('Add modules manually It\'s not that hard');
109
- // TODO: DEPRECATED!
110
- const { script } = options;
111
- const registerCommands = options.registerApplicationCommands;
112
- const info = options.moduleInfo;
113
- if (!this.isReady())
114
- throw new Error('Client is not ready');
115
- this.modules.push({
116
- script,
117
- info: {
118
- filename: undefined,
119
- versions: typeof script.versions == 'string' ? [script.versions] : script.versions,
120
- path: undefined,
121
- ...info
122
- }
123
- });
124
- if (typeof script?.onLoad === 'function')
125
- await Promise.resolve(script.onLoad(this));
126
- if (this.isClientLogsEnabled())
127
- this.logger.info(`${this.modules.length} modules loaded.`);
128
- for (const command of script.commands ?? []) {
129
- if (!command.name)
130
- continue;
131
- this.addCommand(command);
132
- }
133
- if (registerCommands)
134
- await this.registerClientApplicationCommands();
135
- }
136
- /**
137
- * Add slash or message command to client
138
- * @param command Slash/Message command builder
139
- */
140
- addCommand(command) {
141
- if (command.type === builders_1.CommandBuilderType.SlashCommand) {
142
- this.commands.slashCommands.set(command.name, SlashCommandBuilder_1.SlashCommandBuilder.resolveSlashCommand(command));
143
- }
144
- else if (command.type === builders_1.CommandBuilderType.MessageCommand) {
145
- this.commands.messageCommands.set(command.name, MessageCommandBuilder_1.MessageCommandBuilder.resolveMessageCommand(command));
146
- }
147
- else if (this.isClientLogsEnabled()) {
148
- this.logger.error(`Unknow command "${typeof command ?? 'unknown'}".`);
149
- }
150
- return this;
39
+ this.applicationCommands = new ApplicationCommandManager_1.ApplicationCommandManager(this);
151
40
  }
152
41
  /**
153
42
  * Listed to command executions
@@ -172,7 +61,7 @@ class RecipleClient extends discord_js_1.Client {
172
61
  return;
173
62
  if (!this.config.commands.slashCommand.acceptRepliedInteractions && (interaction.replied || interaction.deferred))
174
63
  return;
175
- const command = this.findCommand(interaction.commandName, builders_1.CommandBuilderType.SlashCommand);
64
+ const command = this.commands.get(interaction.commandName, builders_1.CommandBuilderType.SlashCommand);
176
65
  if (!command)
177
66
  return;
178
67
  const executeData = {
@@ -226,7 +115,7 @@ class RecipleClient extends discord_js_1.Client {
226
115
  const parseCommand = (0, fallout_utility_1.getCommand)(message.content, prefix || this.config.commands.messageCommand.prefix || '!', this.config.commands.messageCommand.commandArgumentSeparator || ' ');
227
116
  if (!parseCommand || !parseCommand?.command)
228
117
  return;
229
- const command = this.findCommand(parseCommand.command, builders_1.CommandBuilderType.MessageCommand);
118
+ const command = this.commands.get(parseCommand.command, builders_1.CommandBuilderType.MessageCommand);
230
119
  if (!command)
231
120
  return;
232
121
  const commandOptions = await (0, MessageCommandBuilder_1.validateMessageCommandOptions)(command, parseCommand);
@@ -286,17 +175,6 @@ class RecipleClient extends discord_js_1.Client {
286
175
  message.reply(this.getConfigMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this._replyError(er));
287
176
  }
288
177
  }
289
- /**
290
- * Registers client slash commands and other application commands
291
- */
292
- async registerClientApplicationCommands() {
293
- await (0, registerApplicationCommands_1.registerApplicationCommands)({
294
- client: this,
295
- commands: [...this.commands.slashCommands.toJSON(), ...this.additionalApplicationCommands],
296
- guilds: this.config.commands.slashCommand.guilds
297
- });
298
- this.emit('recipleRegisterApplicationCommands');
299
- }
300
178
  /**
301
179
  * Get a message from config
302
180
  * @param messageKey Config messages key
@@ -305,19 +183,6 @@ class RecipleClient extends discord_js_1.Client {
305
183
  getConfigMessage(messageKey, defaultMessage) {
306
184
  return this.config.messages[messageKey] ?? defaultMessage ?? messageKey;
307
185
  }
308
- findCommand(command, type) {
309
- switch (type) {
310
- case builders_1.CommandBuilderType.SlashCommand:
311
- return this.commands.slashCommands.get(command);
312
- case builders_1.CommandBuilderType.MessageCommand:
313
- return this.commands.messageCommands.get(command.toLowerCase())
314
- ?? (this.config.commands.messageCommand.allowCommandAlias
315
- ? this.commands.messageCommands.find(c => c.aliases.some(a => a == command?.toLowerCase()))
316
- : undefined);
317
- default:
318
- throw new TypeError('Unknown command type');
319
- }
320
- }
321
186
  /**
322
187
  * Returns true if client logs is enabled
323
188
  */
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateMessageCommandOptions = exports.MessageCommandBuilder = void 0;
4
4
  const builders_1 = require("../../types/builders");
5
5
  const discord_js_1 = require("discord.js");
6
- const MessageCommandOptionManager_1 = require("../MessageCommandOptionManager");
6
+ const MessageCommandOptionManager_1 = require("../managers/MessageCommandOptionManager");
7
7
  const MessageCommandOptionBuilder_1 = require("./MessageCommandOptionBuilder");
8
8
  /**
9
9
  * Reciple builder for message command
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApplicationCommandManager = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const SlashCommandBuilder_1 = require("../builders/SlashCommandBuilder");
6
+ class ApplicationCommandManager {
7
+ constructor(client) {
8
+ this.client = client;
9
+ }
10
+ get commands() { return this.client.application?.commands; }
11
+ async set(commands, guilds) {
12
+ if (!this.client.isReady())
13
+ throw new Error('Client is not ready');
14
+ if (guilds && guilds.length > 1) {
15
+ for (const guild of guilds) {
16
+ await this.set(commands, [guild]);
17
+ }
18
+ return;
19
+ }
20
+ let guild = guilds?.shift();
21
+ guild = guild ? this.client.guilds.resolveId(guild) || undefined : undefined;
22
+ if (!guild) {
23
+ this.client.application.commands.set(commands);
24
+ if (this.client.isClientLogsEnabled())
25
+ this.client.logger.log(`Registered ${this.client.commands.applicationCommandsSize} application command(s) globally...`);
26
+ }
27
+ else {
28
+ this.client.application.commands.set(commands, guild);
29
+ if (this.client.isClientLogsEnabled())
30
+ this.client.logger.log(`Registered ${this.client.commands.applicationCommandsSize} application command(s) to guild ${guild}...`);
31
+ }
32
+ }
33
+ async add(command, guilds) {
34
+ if (!this.client.isReady())
35
+ throw new Error('Client is not ready');
36
+ if (!command)
37
+ throw new Error('Command is undefined');
38
+ if (guilds && guilds.length > 1) {
39
+ for (const guild of guilds) {
40
+ await this.add(command, [guild]);
41
+ }
42
+ return;
43
+ }
44
+ let guild = guilds?.shift();
45
+ guild = guild ? this.client.guilds.resolveId(guild) || undefined : undefined;
46
+ if (!guild) {
47
+ this.client.application.commands.create(command);
48
+ if (this.client.isClientLogsEnabled())
49
+ this.client.logger.log(`Created application command '${command.name}' globally`);
50
+ }
51
+ else {
52
+ this.client.application.commands.create(command, guild);
53
+ if (this.client.isClientLogsEnabled())
54
+ this.client.logger.log(`Created application command '${command.name}' to guild ${guild}`);
55
+ }
56
+ }
57
+ async remove(command, guilds) {
58
+ if (!this.client.isReady())
59
+ throw new Error('Client is not ready');
60
+ if (!command)
61
+ throw new Error('Command is undefined');
62
+ if (guilds && guilds.length > 1) {
63
+ for (const guild of guilds) {
64
+ await this.remove(command, [guild]);
65
+ }
66
+ return;
67
+ }
68
+ let guild = guilds?.shift();
69
+ guild = guild ? this.client.guilds.resolveId(guild) || undefined : undefined;
70
+ if (!guild) {
71
+ this.client.application.commands.delete(command);
72
+ if (this.client.isClientLogsEnabled())
73
+ this.client.logger.log(`Removed application command '${typeof command === 'string' ? command : command.name}' globally`);
74
+ }
75
+ else {
76
+ this.client.application.commands.delete(command, guild);
77
+ if (this.client.isClientLogsEnabled())
78
+ this.client.logger.log(`Removed application command '${typeof command === 'string' ? command : command.name}' from guild ${guild}`);
79
+ }
80
+ }
81
+ async edit(command, newCommand, guilds) {
82
+ if (!this.client.isReady())
83
+ throw new Error('Client is not ready');
84
+ if (!command)
85
+ throw new Error('Command is undefined');
86
+ if (guilds && guilds.length > 1) {
87
+ for (const guild of guilds) {
88
+ await this.edit(command, newCommand, [guild]);
89
+ }
90
+ return;
91
+ }
92
+ let guild = guilds?.shift();
93
+ guild = guild ? this.client.guilds.resolveId(guild) || undefined : undefined;
94
+ if (!guild) {
95
+ this.client.application.commands.edit(command, newCommand);
96
+ if (this.client.isClientLogsEnabled())
97
+ this.client.logger.log(`Removed application command '${typeof command === 'string' ? command : command.name}' globally`);
98
+ }
99
+ else {
100
+ this.client.application.commands.edit(command, newCommand, guild);
101
+ if (this.client.isClientLogsEnabled())
102
+ this.client.logger.log(`Removed application command '${typeof command === 'string' ? command : command.name}' from guild ${guild}`);
103
+ }
104
+ }
105
+ get(command, guild) {
106
+ const commands = guild ? this.client.guilds.resolve(guild)?.commands.cache : this.client.application?.commands.cache;
107
+ if (!commands)
108
+ throw new Error('Guild not found in cache');
109
+ return commands.find(cmd => typeof command === 'string'
110
+ ? (cmd.id === command || cmd.name === command)
111
+ : (cmd.name === command.name || (command instanceof discord_js_1.ApplicationCommand && cmd.id === command.id)));
112
+ }
113
+ async fetch(commandId, guild) {
114
+ const manager = guild ? this.client.guilds.resolve(guild)?.commands : this.client.application?.commands;
115
+ if (!manager)
116
+ throw new Error('Guild not found in cache');
117
+ return manager.fetch(commandId);
118
+ }
119
+ parseCommands(commands, setPermissions = true) {
120
+ return commands.map(cmd => {
121
+ if (cmd?.toJSON === undefined)
122
+ return (cmd);
123
+ if (SlashCommandBuilder_1.SlashCommandBuilder.isSlashCommandBuilder(cmd) && this.client.config.commands.slashCommand.setRequiredPermissions) {
124
+ const permissions = (setPermissions || this.client.config.commands.slashCommand.permissions.enabled)
125
+ ? this.client.config.commands.slashCommand.permissions.commands.find(cmd_ => cmd_.command.toLowerCase() === cmd.name.toLowerCase())?.permissions
126
+ : undefined;
127
+ if (permissions) {
128
+ cmd.setRequiredMemberPermissions(...permissions);
129
+ if (this.client.isClientLogsEnabled())
130
+ this.client.logger.debug(`Set required permissions for ${cmd.name}`);
131
+ }
132
+ }
133
+ return cmd.toJSON();
134
+ });
135
+ }
136
+ }
137
+ exports.ApplicationCommandManager = ApplicationCommandManager;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientCommandManager = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const builders_1 = require("../../types/builders");
6
+ const MessageCommandBuilder_1 = require("../builders/MessageCommandBuilder");
7
+ const SlashCommandBuilder_1 = require("../builders/SlashCommandBuilder");
8
+ class ClientCommandManager {
9
+ constructor(options) {
10
+ this.slashCommands = new discord_js_1.Collection();
11
+ this.messageCommands = new discord_js_1.Collection();
12
+ this.additionalApplicationCommands = [];
13
+ this.client = options.client;
14
+ options.slashCommands?.forEach(e => this.slashCommands.set(e.name, SlashCommandBuilder_1.SlashCommandBuilder.resolveSlashCommand(e)));
15
+ options.messageCommands?.forEach(e => this.messageCommands.set(e.name, MessageCommandBuilder_1.MessageCommandBuilder.resolveMessageCommand(e)));
16
+ }
17
+ get applicationCommandsSize() { return this.client.commands.slashCommands.size + this.client.commands.additionalApplicationCommands.length; }
18
+ /**
19
+ * Add command to command manager
20
+ * @param commands Any command data or builder
21
+ */
22
+ add(...commands) {
23
+ for (const command of (0, discord_js_1.normalizeArray)(commands)) {
24
+ if (command.type === builders_1.CommandBuilderType.SlashCommand) {
25
+ this.slashCommands.set(command.name, SlashCommandBuilder_1.SlashCommandBuilder.resolveSlashCommand(command));
26
+ }
27
+ else if (command.type === builders_1.CommandBuilderType.MessageCommand) {
28
+ this.messageCommands.set(command.name, MessageCommandBuilder_1.MessageCommandBuilder.resolveMessageCommand(command));
29
+ }
30
+ }
31
+ return this;
32
+ }
33
+ get(command, type) {
34
+ switch (type) {
35
+ case builders_1.CommandBuilderType.SlashCommand:
36
+ return this.slashCommands.get(command);
37
+ case builders_1.CommandBuilderType.MessageCommand:
38
+ return this.messageCommands.get(command.toLowerCase())
39
+ ?? (this.client.config.commands.messageCommand.allowCommandAlias
40
+ ? this.messageCommands.find(c => c.aliases.some(a => a == command?.toLowerCase()))
41
+ : undefined);
42
+ default:
43
+ throw new TypeError('Unknown command type');
44
+ }
45
+ }
46
+ /**
47
+ * Register application commands
48
+ * @param guilds Register application commands to guilds
49
+ */
50
+ async registerApplicationCommands(...guilds) {
51
+ guilds = (0, discord_js_1.normalizeArray)(guilds);
52
+ guilds = guilds.length
53
+ ? guilds
54
+ : (0, discord_js_1.normalizeArray)([this.client.config.commands.slashCommand.guilds]);
55
+ if (this.client.isClientLogsEnabled())
56
+ this.client.logger.log(`Regestering ${this.applicationCommandsSize} application command(s) ${!guilds.length ? 'globaly' : 'to ' + guilds.length + ' guilds'}...`);
57
+ await this.client.applicationCommands.set([...this.slashCommands.toJSON(), ...this.additionalApplicationCommands], guilds);
58
+ this.client.emit('RegisterApplicationCommands');
59
+ return this;
60
+ }
61
+ }
62
+ exports.ClientCommandManager = ClientCommandManager;
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.ClientModuleManager = void 0;
30
+ const crypto_1 = require("crypto");
31
+ const discord_js_1 = require("discord.js");
32
+ const fs_1 = require("fs");
33
+ const path_1 = __importDefault(require("path"));
34
+ const wildcard_match_1 = __importDefault(require("wildcard-match"));
35
+ const flags_1 = require("../../flags");
36
+ const builders_1 = require("../../types/builders");
37
+ const util_1 = require("../../util");
38
+ const version_1 = require("../../version");
39
+ const MessageCommandBuilder_1 = require("../builders/MessageCommandBuilder");
40
+ const SlashCommandBuilder_1 = require("../builders/SlashCommandBuilder");
41
+ class ClientModuleManager {
42
+ constructor(options) {
43
+ this.modules = new discord_js_1.Collection();
44
+ this.client = options.client;
45
+ options.modules?.forEach(m => {
46
+ if (!m.id)
47
+ m.id = (0, crypto_1.randomUUID)();
48
+ this.modules.set(m.id, this.resolveModule(m));
49
+ });
50
+ }
51
+ async startModulesFromFiles(options) {
52
+ const modules = await this.resolveModulesFromFiles(options);
53
+ for (const module_ of modules) {
54
+ try {
55
+ await this.startModule(module_);
56
+ }
57
+ catch (err) {
58
+ if (options.dontSkipError)
59
+ throw err;
60
+ if (this.client.isClientLogsEnabled())
61
+ this.client.logger.err(`Cannot start module ${ClientModuleManager.getModuleDisplayId(module_)}:`, err);
62
+ }
63
+ }
64
+ return modules;
65
+ }
66
+ async resolveModulesFromFiles(options) {
67
+ const modules = [];
68
+ const isVersionCheckDisabled = (options.disabeVersionCheck || this.client.config.disableVersionCheck);
69
+ for (const file of options.files) {
70
+ const moduleFileName = path_1.default.basename(file);
71
+ const moduleDirPath = path_1.default.dirname(file);
72
+ const id = (0, crypto_1.randomUUID)();
73
+ let script;
74
+ try {
75
+ const resolveModuleFile = await Promise.resolve().then(() => __importStar(require(file)));
76
+ script = resolveModuleFile?.default ?? resolveModuleFile;
77
+ const module_ = this.resolveModule({
78
+ id,
79
+ script,
80
+ info: {
81
+ filename: moduleFileName,
82
+ path: moduleDirPath
83
+ }
84
+ }, isVersionCheckDisabled);
85
+ modules.push(module_);
86
+ if (this.client.isClientLogsEnabled())
87
+ this.client.logger.log(`Resolved ${file}`);
88
+ }
89
+ catch (err) {
90
+ if (options.dontSkipError)
91
+ throw err;
92
+ if (this.client.isClientLogsEnabled())
93
+ this.client.logger.err(`Cannot resolve module file ${file}:`, err);
94
+ }
95
+ }
96
+ return modules;
97
+ }
98
+ resolveScriptCommands(...modules) {
99
+ const resolvedCommands = [];
100
+ for (const script of (0, discord_js_1.normalizeArray)(modules)) {
101
+ const commands = [];
102
+ if (Array.isArray(script?.commands)) {
103
+ for (const command of script.commands) {
104
+ if (command.type === builders_1.CommandBuilderType.MessageCommand) {
105
+ commands.push(MessageCommandBuilder_1.MessageCommandBuilder.resolveMessageCommand(command));
106
+ }
107
+ else if (command.type === builders_1.CommandBuilderType.SlashCommand) {
108
+ commands.push(SlashCommandBuilder_1.SlashCommandBuilder.resolveSlashCommand(command));
109
+ }
110
+ }
111
+ }
112
+ const invalidBuilders = commands.some(c => !(0, util_1.validateCommandBuilder)(c));
113
+ if (invalidBuilders)
114
+ throw new Error(`Module script commands contains a command builder without name or option name`);
115
+ resolvedCommands.push({
116
+ script,
117
+ commands
118
+ });
119
+ }
120
+ return resolvedCommands;
121
+ }
122
+ async loadAll(registerApplicationCommands, ...registerApplicationCommandsGuilds) {
123
+ await Promise.all(this.modules.map(async (m) => {
124
+ if (typeof m.script?.onLoad === 'function') {
125
+ try {
126
+ await Promise.resolve(m.script.onLoad(this.client)).catch(err => { throw err; });
127
+ }
128
+ catch (err) {
129
+ this.modules.delete(m.id);
130
+ if (this.client.isClientLogsEnabled())
131
+ this.client.logger.error(`Error loading ${m.info.filename ?? 'unknown module'}:`, err);
132
+ return;
133
+ }
134
+ }
135
+ this.client.commands.add(m.commands);
136
+ if (this.client.isClientLogsEnabled())
137
+ this.client.logger.log(`Loaded module: ${ClientModuleManager.getModuleDisplayId(m)}`);
138
+ }));
139
+ if (this.client.isClientLogsEnabled()) {
140
+ this.client.logger.info(`${this.modules.size} modules loaded.`);
141
+ this.client.logger.info(`${this.client.commands.messageCommands.size} message commands loaded.`);
142
+ this.client.logger.info(`${this.client.commands.slashCommands.size} slash commands loaded.`);
143
+ }
144
+ if (registerApplicationCommands)
145
+ this.client.commands.registerApplicationCommands((0, discord_js_1.normalizeArray)(registerApplicationCommandsGuilds));
146
+ }
147
+ async startModule(mod) {
148
+ let err;
149
+ const identifier = ClientModuleManager.getModuleDisplayId(mod);
150
+ if (this.client.isClientLogsEnabled())
151
+ this.client.logger.log(`Starting Module: ${identifier}`);
152
+ const start = await Promise.resolve(mod.script.onStart(this.client)).catch(e => err = e);
153
+ if (err)
154
+ throw err;
155
+ if (!start)
156
+ throw new Error(`Module ${identifier} returned 'false' on start`);
157
+ this.modules.set(mod.id, mod);
158
+ }
159
+ resolveModule(mod, disabeVersionCheck) {
160
+ const identifier = ClientModuleManager.getModuleDisplayId(mod);
161
+ if (!disabeVersionCheck && !mod?.script?.versions?.length)
162
+ throw new Error(`Module ${identifier} does not contain supported versions`);
163
+ if (typeof mod.script?.onStart !== 'function')
164
+ throw new Error(`Module ${identifier} does not have a valid 'onStart' method`);
165
+ const versions = (0, discord_js_1.normalizeArray)([mod.script.versions]);
166
+ const commands = this.resolveScriptCommands(mod.script)[0].commands;
167
+ if (!disabeVersionCheck && !versions.some(v => (0, version_1.isSupportedVersion)(v, version_1.version)))
168
+ throw new Error(`Module ${identifier} does not support 'reciple@${version_1.rawVersion}'`);
169
+ return {
170
+ ...mod,
171
+ commands,
172
+ };
173
+ }
174
+ async getModuleFiles(...folders) {
175
+ const modules = [];
176
+ for (const dir of ((0, discord_js_1.normalizeArray)(folders).length ? (0, discord_js_1.normalizeArray)(folders) : (0, discord_js_1.normalizeArray)([this.client.config.modulesFolder]))) {
177
+ if (!(0, fs_1.existsSync)(dir))
178
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
179
+ if (!(0, fs_1.lstatSync)(dir).isDirectory())
180
+ continue;
181
+ modules.push(...(0, fs_1.readdirSync)(dir).map(file => path_1.default.join(flags_1.cwd, dir, file)).filter(file => file.endsWith('.js') || file.endsWith('.cjs')));
182
+ }
183
+ return modules.filter(file => !this.client.config.ignoredFiles.some(ignored => (0, wildcard_match_1.default)(ignored, path_1.default.basename(file))));
184
+ }
185
+ static getModuleDisplayId(mod) {
186
+ return mod.info.path && mod.info.filename ? path_1.default.join(mod.info.path, mod.info.filename) : mod.id;
187
+ }
188
+ }
189
+ exports.ClientModuleManager = ClientModuleManager;
@@ -20,21 +20,24 @@ class CommandCooldownManager extends Array {
20
20
  * Remove cooldown from specific user, channel or guild
21
21
  * @param options Remove cooldown data options
22
22
  * @param limit Remove cooldown data limit
23
+ * @returns Returns the removed values
23
24
  */
24
25
  remove(options, limit = 0) {
25
26
  if (!Object.keys(options).length)
26
27
  throw new TypeError('Provide atleast one option to remove cooldown data.');
28
+ const removed = [];
27
29
  let i = 0;
28
- for (const index in this) {
29
- if (!CommandCooldownManager.checkOptions(options, this[index]))
30
+ for (let i = 0; i < this.length; i++) {
31
+ if (!CommandCooldownManager.checkOptions(options, this[i]))
30
32
  continue;
31
- if (options.expireTime && this[index].expireTime > Date.now())
33
+ if (options.expireTime && this[i].expireTime > Date.now())
32
34
  continue;
33
35
  if (limit && i >= limit)
34
36
  continue;
35
- this.splice(Number(index));
36
- i++;
37
+ removed.push(this[i]);
38
+ this.splice(Number(i));
37
39
  }
40
+ return removed;
38
41
  }
39
42
  /**
40
43
  * Check if the given user is cooled-down
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deprecationWarning = exports.isClass = void 0;
3
+ exports.validateCommandBuilder = exports.deprecationWarning = exports.isClass = void 0;
4
+ const builders_1 = require("./types/builders");
4
5
  /**
5
6
  * Check if an object is a class
6
7
  * @param object Object to identify
@@ -21,3 +22,11 @@ function deprecationWarning(content) {
21
22
  process.emitWarning(content, 'DeprecationWarning');
22
23
  }
23
24
  exports.deprecationWarning = deprecationWarning;
25
+ function validateCommandBuilder(command) {
26
+ if (!command.name)
27
+ return false;
28
+ if (command.type === builders_1.CommandBuilderType.MessageCommand && command.options.length && command.options.some(o => !o.name))
29
+ return false;
30
+ return true;
31
+ }
32
+ exports.validateCommandBuilder = validateCommandBuilder;
@@ -1,10 +1,12 @@
1
- export * from './reciple/classes/CommandCooldownManager';
2
- export * from './reciple/classes/MessageCommandOptionManager';
3
- export * from './reciple/classes/RecipleClient';
4
- export * from './reciple/classes/RecipleConfig';
5
1
  export * from './reciple/classes/builders/MessageCommandBuilder';
6
2
  export * from './reciple/classes/builders/MessageCommandOptionBuilder';
7
3
  export * from './reciple/classes/builders/SlashCommandBuilder';
4
+ export * from './reciple/classes/managers/ApplicationCommandManager';
5
+ export * from './reciple/classes/managers/CommandCooldownManager';
6
+ export * from './reciple/classes/managers/ClientCommandManager';
7
+ export * from './reciple/classes/managers/MessageCommandOptionManager';
8
+ export * from './reciple/classes/RecipleClient';
9
+ export * from './reciple/classes/RecipleConfig';
8
10
  export * from './reciple/types/builders';
9
11
  export * from './reciple/types/commands';
10
12
  export * from './reciple/types/paramOptions';
@@ -12,6 +14,5 @@ export * from './reciple/flags';
12
14
  export * from './reciple/logger';
13
15
  export * from './reciple/modules';
14
16
  export * from './reciple/permissions';
15
- export * from './reciple/registerApplicationCommands';
16
17
  export * from './reciple/util';
17
18
  export * from './reciple/version';
@@ -1,33 +1,19 @@
1
1
  import { MessageCommandBuilder, MessageCommandExecuteData, MessageCommandHaltData } from './builders/MessageCommandBuilder';
2
2
  import { SlashCommandBuilder, SlashCommandExecuteData, SlashCommandHaltData } from './builders/SlashCommandBuilder';
3
- import { AnyCommandBuilder, AnyCommandData, AnySlashCommandBuilder, CommandBuilderType } from '../types/builders';
4
- import { ApplicationCommandBuilder } from '../registerApplicationCommands';
5
3
  import { AnyCommandExecuteData, AnyCommandHaltData } from '../types/commands';
6
- import { CommandCooldownManager } from './CommandCooldownManager';
7
- import { RecipleClientAddModuleOptions } from '../types/paramOptions';
4
+ import { CommandCooldownManager } from './managers/CommandCooldownManager';
5
+ import { ApplicationCommandManager } from './managers/ApplicationCommandManager';
6
+ import { ClientCommandManager } from './managers/ClientCommandManager';
8
7
  import { Config } from './RecipleConfig';
9
- import { RecipleModule } from '../modules';
10
8
  import { Logger } from 'fallout-utility';
11
- import { ApplicationCommandData, Awaitable, ChatInputCommandInteraction, Client, ClientEvents, ClientOptions, Collection, Interaction, Message, RestOrArray } from 'discord.js';
9
+ import { Awaitable, ChatInputCommandInteraction, Client, ClientEvents, ClientOptions, Interaction, Message } from 'discord.js';
10
+ import { ClientModuleManager } from './managers/ClientModuleManager';
12
11
  /**
13
12
  * Options for {@link RecipleClient}
14
13
  */
15
14
  export interface RecipleClientOptions extends ClientOptions {
16
15
  config?: Config;
17
16
  }
18
- /**
19
- * Reciple client commands
20
- */
21
- export interface RecipleClientCommands {
22
- /**
23
- * Collection of loaded slash commands
24
- */
25
- slashCommands: Collection<string, AnySlashCommandBuilder>;
26
- /**
27
- * Collection of loaded message commands
28
- */
29
- messageCommands: Collection<string, MessageCommandBuilder>;
30
- }
31
17
  /**
32
18
  * Reciple client events
33
19
  */
@@ -54,37 +40,17 @@ export interface RecipleClient<Ready extends boolean = boolean> extends Client<R
54
40
  isReady(): this is RecipleClient<true>;
55
41
  }
56
42
  export declare class RecipleClient<Ready extends boolean = boolean> extends Client<Ready> {
57
- config: Config;
58
- commands: RecipleClientCommands;
59
- additionalApplicationCommands: (ApplicationCommandBuilder | ApplicationCommandData)[];
60
- cooldowns: CommandCooldownManager;
61
- modules: RecipleModule[];
62
- logger: Logger;
63
- version: string;
43
+ readonly config: Config;
44
+ readonly commands: ClientCommandManager;
45
+ readonly applicationCommands: ApplicationCommandManager;
46
+ readonly cooldowns: CommandCooldownManager;
47
+ readonly modules: ClientModuleManager;
48
+ readonly logger: Logger;
49
+ readonly version: string;
64
50
  /**
65
51
  * @param options Client options
66
52
  */
67
53
  constructor(options: RecipleClientOptions);
68
- /**
69
- * Load and start modules from given folders
70
- * @param folders folders that contains the modules you want to load
71
- */
72
- startModules(...folders: RestOrArray<string>): Promise<this>;
73
- /**
74
- * Execute {@link RecipleModule['onLoad']} from client modules and register application commands if enabled
75
- */
76
- loadModules(): Promise<this>;
77
- /**
78
- * Add module
79
- * @param options Module options
80
- * @deprecated This is very stupid, Just add it manually
81
- */
82
- addModule(options: RecipleClientAddModuleOptions): Promise<void>;
83
- /**
84
- * Add slash or message command to client
85
- * @param command Slash/Message command builder
86
- */
87
- addCommand(command: AnyCommandData | AnyCommandBuilder): RecipleClient<Ready>;
88
54
  /**
89
55
  * Listed to command executions
90
56
  */
@@ -93,30 +59,19 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
93
59
  * Execute a slash command
94
60
  * @param interaction Slash command interaction
95
61
  */
96
- slashCommandExecute(interaction: Interaction | ChatInputCommandInteraction): Promise<void | SlashCommandExecuteData>;
62
+ slashCommandExecute(interaction: Interaction | ChatInputCommandInteraction): Promise<undefined | SlashCommandExecuteData>;
97
63
  /**
98
64
  * Execute a Message command
99
65
  * @param message Message command executor
100
66
  * @param prefix Message command prefix
101
67
  */
102
- messageCommandExecute(message: Message, prefix?: string): Promise<void | MessageCommandExecuteData>;
103
- /**
104
- * Registers client slash commands and other application commands
105
- */
106
- registerClientApplicationCommands(): Promise<void>;
68
+ messageCommandExecute(message: Message, prefix?: string): Promise<undefined | MessageCommandExecuteData>;
107
69
  /**
108
70
  * Get a message from config
109
71
  * @param messageKey Config messages key
110
72
  * @param defaultMessage Default message when the key does not exists
111
73
  */
112
74
  getConfigMessage<T = unknown>(messageKey: string, defaultMessage?: T): T;
113
- /**
114
- * Get command builder by name or alias if it's a message command
115
- * @param command Command name
116
- * @param type Command type
117
- */
118
- findCommand(command: string, type: CommandBuilderType.MessageCommand): MessageCommandBuilder | undefined;
119
- findCommand(command: string, type: CommandBuilderType.SlashCommand): SlashCommandBuilder | undefined;
120
75
  /**
121
76
  * Returns true if client logs is enabled
122
77
  */
@@ -138,8 +93,8 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
138
93
  * @param command Command builder
139
94
  * @param executeData Command execute data
140
95
  */
141
- protected _executeCommand(command: SlashCommandBuilder, executeData: SlashCommandExecuteData): Promise<SlashCommandExecuteData | void>;
142
- protected _executeCommand(command: MessageCommandBuilder, executeData: MessageCommandExecuteData): Promise<MessageCommandExecuteData | void>;
96
+ protected _executeCommand(command: SlashCommandBuilder, executeData: SlashCommandExecuteData): Promise<SlashCommandExecuteData | undefined>;
97
+ protected _executeCommand(command: MessageCommandBuilder, executeData: MessageCommandExecuteData): Promise<MessageCommandExecuteData | undefined>;
143
98
  /**
144
99
  * Error message when a command fails to execute
145
100
  * @param err Received error
@@ -1,7 +1,7 @@
1
1
  import { CommandBuilderType, CommandHaltFunction, CommandExecuteFunction, SharedCommandBuilderProperties, MessageCommandData } from '../../types/builders';
2
2
  import { Message, PermissionResolvable, RestOrArray } from 'discord.js';
3
3
  import { BaseCommandExecuteData, CommandHaltData } from '../../types/commands';
4
- import { MessageCommandOptionManager } from '../MessageCommandOptionManager';
4
+ import { MessageCommandOptionManager } from '../managers/MessageCommandOptionManager';
5
5
  import { MessageCommandOptionBuilder } from './MessageCommandOptionBuilder';
6
6
  import { Command } from 'fallout-utility';
7
7
  /**
@@ -0,0 +1,20 @@
1
+ import { ApplicationCommand, ApplicationCommandData, ContextMenuCommandBuilder, GuildResolvable, RESTPostAPIApplicationCommandsJSONBody, SlashCommandBuilder as DiscordJsSlashCommandBuilder } from 'discord.js';
2
+ import { AnySlashCommandBuilder } from '../../types/builders';
3
+ import { RecipleClient } from '../RecipleClient';
4
+ export declare type ApplicationCommandBuilder = AnySlashCommandBuilder | ContextMenuCommandBuilder | DiscordJsSlashCommandBuilder;
5
+ export declare class ApplicationCommandManager {
6
+ readonly client: RecipleClient;
7
+ get commands(): import("discord.js").ApplicationCommandManager<ApplicationCommand<{
8
+ guild: GuildResolvable;
9
+ }>, {
10
+ guild: GuildResolvable;
11
+ }, null> | undefined;
12
+ constructor(client: RecipleClient);
13
+ set(commands: (ApplicationCommandBuilder | ApplicationCommandData)[], guilds?: GuildResolvable[]): Promise<void>;
14
+ add(command: ApplicationCommandBuilder | ApplicationCommandData, guilds?: GuildResolvable[]): Promise<void>;
15
+ remove(command: string | ApplicationCommand, guilds?: GuildResolvable[]): Promise<void>;
16
+ edit(command: string | ApplicationCommand, newCommand: ApplicationCommandBuilder | ApplicationCommandData, guilds?: GuildResolvable[]): Promise<void>;
17
+ get(command: (ApplicationCommandData | ApplicationCommandBuilder | string), guild?: GuildResolvable): ApplicationCommand | undefined;
18
+ fetch(commandId: string, guild?: GuildResolvable): Promise<ApplicationCommand>;
19
+ protected parseCommands(commands: (ApplicationCommandData | ApplicationCommandBuilder | RESTPostAPIApplicationCommandsJSONBody)[], setPermissions?: boolean): (ApplicationCommandData | RESTPostAPIApplicationCommandsJSONBody)[];
20
+ }
@@ -0,0 +1,37 @@
1
+ import { ApplicationCommandData, Collection, GuildResolvable, RestOrArray } from 'discord.js';
2
+ import { AnyCommandBuilder, AnyCommandData, AnySlashCommandBuilder, CommandBuilderType, MessageCommandData, SlashCommandData } from '../../types/builders';
3
+ import { MessageCommandBuilder } from '../builders/MessageCommandBuilder';
4
+ import { SlashCommandBuilder } from '../builders/SlashCommandBuilder';
5
+ import { RecipleClient } from '../RecipleClient';
6
+ import { ApplicationCommandBuilder } from './ApplicationCommandManager';
7
+ export interface ClientCommandManagerOptions {
8
+ client: RecipleClient;
9
+ messageCommands?: (MessageCommandBuilder | MessageCommandData)[];
10
+ slashCommands?: (AnySlashCommandBuilder | SlashCommandData)[];
11
+ }
12
+ export declare class ClientCommandManager {
13
+ readonly client: RecipleClient;
14
+ readonly slashCommands: Collection<string, AnySlashCommandBuilder>;
15
+ readonly messageCommands: Collection<string, MessageCommandBuilder>;
16
+ readonly additionalApplicationCommands: (ApplicationCommandBuilder | ApplicationCommandData)[];
17
+ get applicationCommandsSize(): number;
18
+ constructor(options: ClientCommandManagerOptions);
19
+ /**
20
+ * Add command to command manager
21
+ * @param commands Any command data or builder
22
+ */
23
+ add(...commands: RestOrArray<AnyCommandBuilder | AnyCommandData>): this;
24
+ /**
25
+ * Get command builder by name or alias if it's a message command
26
+ * @param command Command name
27
+ * @param type Command type
28
+ */
29
+ get(command: string, type?: undefined): AnyCommandBuilder | undefined;
30
+ get(command: string, type?: CommandBuilderType.MessageCommand): MessageCommandBuilder | undefined;
31
+ get(command: string, type?: CommandBuilderType.SlashCommand): SlashCommandBuilder | undefined;
32
+ /**
33
+ * Register application commands
34
+ * @param guilds Register application commands to guilds
35
+ */
36
+ registerApplicationCommands(...guilds: RestOrArray<GuildResolvable>): Promise<this>;
37
+ }
@@ -0,0 +1,79 @@
1
+ import { Collection, GuildResolvable, RestOrArray } from 'discord.js';
2
+ import { AnyCommandBuilder, AnyCommandData } from '../../types/builders';
3
+ import { ModuleManagerResolveFilesOptions } from '../../types/paramOptions';
4
+ import { RecipleClient } from '../RecipleClient';
5
+ /**
6
+ * Reciple script object
7
+ */
8
+ export interface RecipleScript {
9
+ /**
10
+ * Supported reciple versions
11
+ */
12
+ versions: string | string[];
13
+ /**
14
+ * Module commands
15
+ */
16
+ commands?: (AnyCommandBuilder | AnyCommandData)[];
17
+ /**
18
+ * Action on module start
19
+ * @param client Bot client
20
+ */
21
+ onStart(client: RecipleClient<false>): boolean | Promise<boolean>;
22
+ /**
23
+ * Action on bot ready
24
+ * @param client Bot client
25
+ */
26
+ onLoad?(client: RecipleClient<true>): void | Promise<void>;
27
+ }
28
+ /**
29
+ * Reciple module object
30
+ */
31
+ export interface RecipleModule {
32
+ /**
33
+ * Module Id
34
+ */
35
+ id: string;
36
+ /**
37
+ * Module script
38
+ */
39
+ script: RecipleScript;
40
+ /**
41
+ * Module local information
42
+ */
43
+ info: {
44
+ /**
45
+ * Module file name
46
+ */
47
+ filename?: string;
48
+ /**
49
+ * Module local file path
50
+ */
51
+ path?: string;
52
+ };
53
+ }
54
+ export interface ResolvedModule extends RecipleModule {
55
+ commands: AnyCommandBuilder[];
56
+ }
57
+ export interface ResolvedScriptCommands {
58
+ script: RecipleScript;
59
+ commands: AnyCommandBuilder[];
60
+ }
61
+ export interface ClientModuleManagerOptions {
62
+ client: RecipleClient;
63
+ modules?: (RecipleModule & {
64
+ id?: string;
65
+ })[];
66
+ }
67
+ export declare class ClientModuleManager {
68
+ readonly client: RecipleClient;
69
+ readonly modules: Collection<string, ResolvedModule>;
70
+ constructor(options: ClientModuleManagerOptions);
71
+ startModulesFromFiles(options: ModuleManagerResolveFilesOptions): Promise<ResolvedModule[]>;
72
+ resolveModulesFromFiles(options: ModuleManagerResolveFilesOptions): Promise<ResolvedModule[]>;
73
+ resolveScriptCommands(...modules: RestOrArray<RecipleScript>): ResolvedScriptCommands[];
74
+ loadAll(registerApplicationCommands?: boolean, ...registerApplicationCommandsGuilds: RestOrArray<GuildResolvable>): Promise<void>;
75
+ startModule(mod: ResolvedModule): Promise<void>;
76
+ resolveModule(mod: RecipleModule, disabeVersionCheck?: boolean): ResolvedModule;
77
+ getModuleFiles(...folders: RestOrArray<string>): Promise<string[]>;
78
+ static getModuleDisplayId(mod: RecipleModule): string;
79
+ }
@@ -1,5 +1,5 @@
1
1
  import { Guild, RestOrArray, TextBasedChannel, User } from 'discord.js';
2
- import { CommandBuilderType } from '../types/builders';
2
+ import { CommandBuilderType } from '../../types/builders';
3
3
  /**
4
4
  * cooled-down user object interface
5
5
  */
@@ -43,8 +43,9 @@ export declare class CommandCooldownManager extends Array<CooledDownUser> {
43
43
  * Remove cooldown from specific user, channel or guild
44
44
  * @param options Remove cooldown data options
45
45
  * @param limit Remove cooldown data limit
46
+ * @returns Returns the removed values
46
47
  */
47
- remove(options: Partial<CooledDownUser>, limit?: number): void;
48
+ remove(options: Partial<CooledDownUser>, limit?: number): CooledDownUser[];
48
49
  /**
49
50
  * Check if the given user is cooled-down
50
51
  * @param options Options to identify if user is on cooldown
@@ -1,4 +1,4 @@
1
- import { MessageCommandValidatedOption } from './builders/MessageCommandBuilder';
1
+ import { MessageCommandValidatedOption } from '../builders/MessageCommandBuilder';
2
2
  import { RestOrArray } from 'discord.js';
3
3
  /**
4
4
  * Validated message options manager
@@ -1,7 +1,7 @@
1
1
  import { MessageCommandExecuteData, MessageCommandHaltData } from '../classes/builders/MessageCommandBuilder';
2
2
  import { SlashCommandExecuteData, SlashCommandHaltData } from '../classes/builders/SlashCommandBuilder';
3
- import { MessageCommandOptionManager } from '../classes/MessageCommandOptionManager';
4
- import { CooledDownUser } from '../classes/CommandCooldownManager';
3
+ import { MessageCommandOptionManager } from '../classes/managers/MessageCommandOptionManager';
4
+ import { CooledDownUser } from '../classes/managers/CommandCooldownManager';
5
5
  import { RecipleClient } from '../classes/RecipleClient';
6
6
  import { CommandBuilderType } from '../types/builders';
7
7
  /**
@@ -1,8 +1,6 @@
1
- import { ApplicationCommandBuilder } from '../registerApplicationCommands';
2
- import { ApplicationCommandData, PermissionsBitField } from 'discord.js';
3
1
  import { ConfigCommandPermissions } from '../classes/RecipleConfig';
4
2
  import { RecipleModule, RecipleScript } from '../modules';
5
- import { RecipleClient } from '../classes/RecipleClient';
3
+ import { PermissionsBitField } from 'discord.js';
6
4
  import { AnyCommandBuilder } from './builders';
7
5
  export interface RecipleClientAddModuleOptions {
8
6
  /**
@@ -18,20 +16,6 @@ export interface RecipleClientAddModuleOptions {
18
16
  */
19
17
  moduleInfo?: RecipleModule["info"];
20
18
  }
21
- export interface RegisterApplicationCommandsOptions {
22
- /**
23
- * Bot client
24
- */
25
- client: RecipleClient;
26
- /**
27
- * Commands to register
28
- */
29
- commands: (ApplicationCommandData | ApplicationCommandBuilder)[];
30
- /**
31
- * Set guild to not register commands globally
32
- */
33
- guilds?: string | string[];
34
- }
35
19
  export interface UserHasCommandPermissionsOptions {
36
20
  /**
37
21
  * Command builder
@@ -49,3 +33,8 @@ export interface UserHasCommandPermissionsOptions {
49
33
  commands: ConfigCommandPermissions[];
50
34
  };
51
35
  }
36
+ export interface ModuleManagerResolveFilesOptions {
37
+ files: string[];
38
+ disabeVersionCheck?: boolean;
39
+ dontSkipError?: boolean;
40
+ }
@@ -1,3 +1,4 @@
1
+ import { AnyCommandBuilder } from './types/builders';
1
2
  /**
2
3
  * Check if an object is a class
3
4
  * @param object Object to identify
@@ -8,3 +9,4 @@ export declare function isClass<T = any>(object: any): object is T;
8
9
  * @param content Warning content
9
10
  */
10
11
  export declare function deprecationWarning(content: string | Error): void;
12
+ export declare function validateCommandBuilder(command: AnyCommandBuilder): boolean;
package/package.json CHANGED
@@ -1,19 +1,22 @@
1
1
  {
2
2
  "name": "reciple",
3
- "version": "5.6.0",
4
- "bin": "dist/cjs/bin.js",
3
+ "version": "6.0.0-dev.1",
4
+ "bin": "./dist/cjs/bin.js",
5
5
  "license": "GPL-3.0",
6
- "main": "dist/cjs/index.js",
7
- "typings": "dist/types/index.d.ts",
6
+ "main": "./dist/cjs/index.js",
7
+ "typings": "./dist/types/index.d.ts",
8
+ "module": "./dist/mjs/index.js",
8
9
  "author": "FalloutStudios",
9
10
  "description": "Handler for Discord.js",
10
11
  "homepage": "https://reciple.js.org",
12
+ "exports": {
13
+ "require": "./dist/cjs/index.js",
14
+ "import": "./dist/mjs/index.js"
15
+ },
11
16
  "keywords": [
12
17
  "Discord",
13
18
  "Discord.js handler",
14
- "Reciple",
15
- "Slash command handler",
16
- "Message command handler"
19
+ "Reciple"
17
20
  ],
18
21
  "contributors": [
19
22
  "GhexterCortes"
@@ -25,7 +28,7 @@
25
28
  "clean": "yarn exec rimraf dist",
26
29
  "build": "yarn clean && yarn exec tsc",
27
30
  "build:publish": "yarn build && yarn docs && yarn npm publish",
28
- "build:publish-prerelease": "yarn build && yarn npm publish --tag pre",
31
+ "build:publish-dev": "yarn build && yarn npm publish --tag dev",
29
32
  "test": "yarn build && yarn workspace test start",
30
33
  "docs": "yarn exec docgen --typescript true -c ./docs/index.json -o ./docs/docs.json -i src/index.ts",
31
34
  "watch": "yarn exec tsc --watch --noEmit"
@@ -41,7 +44,6 @@
41
44
  "files": [
42
45
  "dist",
43
46
  "resource",
44
- "package.json",
45
47
  "LICENSE",
46
48
  "README.md"
47
49
  ],
@@ -49,21 +51,21 @@
49
51
  "chalk": "4.1.2",
50
52
  "commander": "^9.4.1",
51
53
  "dotenv": "^16.0.3",
52
- "fallout-utility": "^1.5.2",
53
- "semver": "^7.3.8",
54
+ "fallout-utility": "^1.5.4",
55
+ "semver": "^7.3.7",
54
56
  "wildcard-match": "^5.1.2",
55
- "yaml": "^2.1.3"
57
+ "yaml": "^2.1.1"
56
58
  },
57
59
  "devDependencies": {
58
60
  "@discordjs/docgen": "^0.12.1",
59
- "@types/node": "^18.8.3",
61
+ "@types/node": "^18.11.0",
60
62
  "@types/semver": "^7.3.12",
61
- "discord.js": "^14.5.0",
63
+ "discord.js": "^14.6.0",
62
64
  "rimraf": "^3.0.2",
63
65
  "typescript": "^4.8.4"
64
66
  },
65
67
  "peerDependencies": {
66
- "discord.js": "^14.1.0"
68
+ "discord.js": "^14.5.0"
67
69
  },
68
70
  "workspaces": [
69
71
  "test"
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerApplicationCommands = void 0;
4
- const discord_js_1 = require("discord.js");
5
- const SlashCommandBuilder_1 = require("./classes/builders/SlashCommandBuilder");
6
- /**
7
- * Register application commands
8
- * @param options Register application commands options
9
- */
10
- async function registerApplicationCommands(options) {
11
- const client = options.client;
12
- const guilds = (0, discord_js_1.normalizeArray)([options.guilds]);
13
- const commands = options.commands ?? client.commands.slashCommands.toJSON().map(cmd => {
14
- if (cmd?.toJSON === undefined)
15
- return (cmd);
16
- if (SlashCommandBuilder_1.SlashCommandBuilder.isSlashCommandBuilder(cmd) && client.config.commands.slashCommand.setRequiredPermissions) {
17
- const permissions = client.config.commands.slashCommand.permissions.enabled
18
- ? client.config.commands.slashCommand.permissions.commands.find(cmd_ => cmd_.command.toLowerCase() === cmd.name.toLowerCase())?.permissions
19
- : undefined;
20
- if (permissions) {
21
- cmd.setRequiredMemberPermissions(...permissions);
22
- if (client.isClientLogsEnabled())
23
- client.logger.debug(`Set required permissions for ${cmd.name}`);
24
- }
25
- }
26
- return cmd.toJSON();
27
- }) ?? [];
28
- if (!client.isReady())
29
- throw new Error('Client is not ready');
30
- if (!guilds || !guilds?.length) {
31
- client.application?.commands.set(commands).then(() => {
32
- if (client.isClientLogsEnabled())
33
- client.logger.warn('No guilds were specified for application commands. Registered application commands globally.');
34
- });
35
- }
36
- else {
37
- if (client.isClientLogsEnabled())
38
- client.logger.warn(`Registering ${commands.length} application commands to ${guilds.length} guild(s).`);
39
- for (const guild of guilds) {
40
- if (!guild)
41
- continue;
42
- client.application?.commands.set(commands, guild).then(() => {
43
- if (client.isClientLogsEnabled())
44
- client.logger.warn(`Registered ${commands.length} application command(s) for ${guild}.`);
45
- });
46
- }
47
- }
48
- }
49
- exports.registerApplicationCommands = registerApplicationCommands;
@@ -1,9 +0,0 @@
1
- import { ContextMenuCommandBuilder, SlashCommandBuilder as DiscordJsSlashCommandBuilder } from 'discord.js';
2
- import { RegisterApplicationCommandsOptions } from './types/paramOptions';
3
- import { AnySlashCommandBuilder } from './types/builders';
4
- export declare type ApplicationCommandBuilder = AnySlashCommandBuilder | ContextMenuCommandBuilder | DiscordJsSlashCommandBuilder;
5
- /**
6
- * Register application commands
7
- * @param options Register application commands options
8
- */
9
- export declare function registerApplicationCommands(options: RegisterApplicationCommandsOptions): Promise<void>;