reciple 1.7.1 → 2.0.2

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 (29) hide show
  1. package/README.md +16 -11
  2. package/bin/index.d.ts +4 -2
  3. package/bin/index.js +4 -2
  4. package/bin/reciple/classes/CommandCooldownManager.d.ts +36 -0
  5. package/bin/reciple/classes/CommandCooldownManager.js +77 -0
  6. package/bin/reciple/classes/{builders/MessageCommandOptions.d.ts → MessageCommandOptionManager.d.ts} +2 -2
  7. package/bin/reciple/classes/{builders/MessageCommandOptions.js → MessageCommandOptionManager.js} +3 -3
  8. package/bin/reciple/classes/RecipleClient.d.ts +14 -11
  9. package/bin/reciple/classes/RecipleClient.js +99 -41
  10. package/bin/reciple/classes/RecipleConfig.d.ts +4 -2
  11. package/bin/reciple/classes/RecipleConfig.js +1 -1
  12. package/bin/reciple/classes/builders/InteractionCommandBuilder.d.ts +20 -8
  13. package/bin/reciple/classes/builders/InteractionCommandBuilder.js +21 -6
  14. package/bin/reciple/classes/builders/MessageCommandBuilder.d.ts +26 -9
  15. package/bin/reciple/classes/builders/MessageCommandBuilder.js +28 -6
  16. package/bin/reciple/modules.d.ts +5 -8
  17. package/bin/reciple/permissions.d.ts +8 -0
  18. package/bin/reciple/permissions.js +23 -0
  19. package/bin/reciple/registerInteractionCommands.d.ts +2 -2
  20. package/bin/reciple/registerInteractionCommands.js +2 -2
  21. package/bin/reciple/types/builders.d.ts +4 -0
  22. package/bin/reciple/types/builders.js +2 -0
  23. package/bin/reciple/types/commands.d.ts +31 -0
  24. package/bin/reciple/types/commands.js +2 -0
  25. package/bin/reciple/version.js +1 -1
  26. package/package.json +14 -9
  27. package/resource/reciple.yml +11 -1
  28. package/bin/reciple/hasPermissions.d.ts +0 -7
  29. package/bin/reciple/hasPermissions.js +0 -16
package/README.md CHANGED
@@ -12,48 +12,54 @@ A simple Dicord.js command handler that just works.
12
12
  [![Discord Invite](https://i.imgur.com/GffJByO.png)](https://discord.gg/2CattJYNpw)
13
13
 
14
14
  ## Installation
15
- To install the bot, run the following command:
15
+ To install the bot, run the following command in your terminal:
16
16
 
17
17
  ```bash
18
18
  npm i reciple
19
19
  ```
20
+ ```bash
21
+ yarn add reciple
22
+ ```
23
+ ```bash
24
+ pnpm add reciple
25
+ ```
20
26
 
21
- You can initialize the bot to the current directory with the following command:
27
+ You can initialize the bot to the current directory with the following command in your terminal:
22
28
 
23
29
  ```bash
24
30
  npx reciple
25
31
  ```
26
32
 
27
- It will ask you to continue if the directory is not empty type `y` to continue after the bot has been initialized it will ask you for your bot token.
33
+ It will ask you to continue if the directory is not empty. Type `y` to continue. After the bot has been initialized, it will ask you for your bot token.
28
34
 
29
- > You can always change the token later
35
+ > You can change the token anytime you want
30
36
 
31
37
  ## Config
32
38
 
33
- You can configure the bot on `reciple.yml` in the bot root directory.
39
+ You can configure the bot in `reciple.yml` located in the bot's root directory.
34
40
 
35
41
  ### Token
36
42
 
37
- You can directly change the token on `reciple.yml` like so:
43
+ You can directly change the token in `reciple.yml`.
38
44
 
39
45
  ```yml
40
46
  token: "YOUR_TOKEN_HERE"
41
47
  ```
42
48
 
43
- Using environment variables is also supported:
49
+ Using environment variables is also supported.
44
50
 
45
51
  ```yml
46
52
  token: "env:TOKEN_VARIABLE"
47
53
  ```
48
54
 
49
- You can override the token on the command line like so:
55
+ You can override the given token using your terminal
50
56
 
51
57
  ```bash
52
58
  npx reciple --token "YOUR_TOKEN_HERE"
53
59
  ```
54
60
 
55
- ## Running the bot
56
- To run the bot, run the following command:
61
+ ## Starting the bot
62
+ To start the bot, run the following command:
57
63
 
58
64
  ```bash
59
65
  npx reciple
@@ -62,5 +68,4 @@ npx reciple
62
68
  > ## Fun Fact
63
69
  > The name reciple is from a minecraft bug. The bug was a misspelling of the word `recipe`. [View Mojang Bug Report](https://bugs.mojang.com/browse/MC-225837)
64
70
 
65
- # Save the Earth
66
71
  [#letTheEarthBreathe](https://rebellion.global/)
package/bin/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  export * from './reciple/classes/RecipleClient';
2
2
  export * from './reciple/classes/RecipleConfig';
3
+ export * from './reciple/classes/MessageCommandOptionManager';
3
4
  export * from './reciple/classes/builders/InteractionCommandBuilder';
4
5
  export * from './reciple/classes/builders/MessageCommandBuilder';
5
6
  export * from './reciple/classes/builders/MessageCommandOptionBuilder';
6
- export * from './reciple/classes/builders/MessageCommandOptions';
7
- export * from './reciple/hasPermissions';
7
+ export * from './reciple/types/builders';
8
+ export * from './reciple/types/commands';
9
+ export * from './reciple/permissions';
8
10
  export * from './reciple/flags';
9
11
  export * from './reciple/isIgnoredChannel';
10
12
  export * from './reciple/logger';
package/bin/index.js CHANGED
@@ -16,11 +16,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./reciple/classes/RecipleClient"), exports);
18
18
  __exportStar(require("./reciple/classes/RecipleConfig"), exports);
19
+ __exportStar(require("./reciple/classes/MessageCommandOptionManager"), exports);
19
20
  __exportStar(require("./reciple/classes/builders/InteractionCommandBuilder"), exports);
20
21
  __exportStar(require("./reciple/classes/builders/MessageCommandBuilder"), exports);
21
22
  __exportStar(require("./reciple/classes/builders/MessageCommandOptionBuilder"), exports);
22
- __exportStar(require("./reciple/classes/builders/MessageCommandOptions"), exports);
23
- __exportStar(require("./reciple/hasPermissions"), exports);
23
+ __exportStar(require("./reciple/types/builders"), exports);
24
+ __exportStar(require("./reciple/types/commands"), exports);
25
+ __exportStar(require("./reciple/permissions"), exports);
24
26
  __exportStar(require("./reciple/flags"), exports);
25
27
  __exportStar(require("./reciple/isIgnoredChannel"), exports);
26
28
  __exportStar(require("./reciple/logger"), exports);
@@ -0,0 +1,36 @@
1
+ import { Guild, TextBasedChannel, User } from 'discord.js';
2
+ import { RecipleCommandBuilders } from '../types/builders';
3
+ export interface CooledDownUser {
4
+ user: User;
5
+ command: string;
6
+ type: RecipleCommandBuilders["builder"];
7
+ guild?: Guild | null;
8
+ channel?: TextBasedChannel;
9
+ expireTime: number;
10
+ }
11
+ export declare class CommandCooldownManager extends Array<CooledDownUser> {
12
+ /**
13
+ * Alias for `CommandCooldownManager#push()`
14
+ */
15
+ add(...options: CooledDownUser[]): number;
16
+ /**
17
+ * Remove cooldown from specific user, channel or guild
18
+ */
19
+ remove(options: Partial<CooledDownUser>, limit?: number): void;
20
+ /**
21
+ * Check if the given user is cooled-down
22
+ */
23
+ isCooledDown(options: Partial<Omit<CooledDownUser, 'expireTime'>>): boolean;
24
+ /**
25
+ * Clear non cooled-down users from this array
26
+ */
27
+ clean(options?: Partial<Omit<CooledDownUser, 'expireTime'>>): void;
28
+ /**
29
+ * Get someone's cooldown data
30
+ */
31
+ get(options: Partial<Omit<CooledDownUser, 'expireTime'>>): CooledDownUser | undefined;
32
+ /**
33
+ * Check if the options are valid
34
+ */
35
+ static checkOptions(options: Partial<Omit<CooledDownUser, 'expireTime'>>, data: CooledDownUser): boolean;
36
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommandCooldownManager = void 0;
4
+ class CommandCooldownManager extends Array {
5
+ /**
6
+ * Alias for `CommandCooldownManager#push()`
7
+ */
8
+ add(...options) {
9
+ return this.push(...options);
10
+ }
11
+ /**
12
+ * Remove cooldown from specific user, channel or guild
13
+ */
14
+ remove(options, limit = 0) {
15
+ if (!Object.keys(options).length)
16
+ throw new TypeError('Provide atleast one option to remove cooldown data.');
17
+ let i = 0;
18
+ for (const index in this) {
19
+ if (!CommandCooldownManager.checkOptions(options, this[index]))
20
+ continue;
21
+ if (options.expireTime && this[index].expireTime > Date.now())
22
+ continue;
23
+ if (limit && i >= limit)
24
+ continue;
25
+ this.splice(Number(index));
26
+ i++;
27
+ }
28
+ }
29
+ /**
30
+ * Check if the given user is cooled-down
31
+ */
32
+ isCooledDown(options) {
33
+ const data = this.get(options);
34
+ if (!data)
35
+ return false;
36
+ this.remove(Object.assign(Object.assign({}, data), { channel: undefined, guild: undefined, type: undefined, command: undefined }));
37
+ if (data.expireTime < Date.now())
38
+ return false;
39
+ return true;
40
+ }
41
+ /**
42
+ * Clear non cooled-down users from this array
43
+ */
44
+ clean(options) {
45
+ for (const index in this) {
46
+ if (options && !CommandCooldownManager.checkOptions(options, this[index]))
47
+ return;
48
+ if (this[index].expireTime > Date.now())
49
+ return;
50
+ this.slice(Number(index));
51
+ }
52
+ }
53
+ /**
54
+ * Get someone's cooldown data
55
+ */
56
+ get(options) {
57
+ return this.find(data => CommandCooldownManager.checkOptions(options, data));
58
+ }
59
+ /**
60
+ * Check if the options are valid
61
+ */
62
+ static checkOptions(options, data) {
63
+ var _a, _b;
64
+ if ((options === null || options === void 0 ? void 0 : options.user) && options.user.id !== data.user.id)
65
+ return false;
66
+ if ((options === null || options === void 0 ? void 0 : options.guild) && options.guild.id !== ((_a = data.guild) === null || _a === void 0 ? void 0 : _a.id))
67
+ return false;
68
+ if ((options === null || options === void 0 ? void 0 : options.channel) && options.channel.id !== ((_b = data.channel) === null || _b === void 0 ? void 0 : _b.id))
69
+ return false;
70
+ if ((options === null || options === void 0 ? void 0 : options.command) && options.command !== data.command)
71
+ return false;
72
+ if ((options === null || options === void 0 ? void 0 : options.type) && options.type !== data.type)
73
+ return false;
74
+ return true;
75
+ }
76
+ }
77
+ exports.CommandCooldownManager = CommandCooldownManager;
@@ -1,5 +1,5 @@
1
- import { MessageCommandValidatedOption } from './MessageCommandBuilder';
2
- export declare class MessageCommandOptions extends Array<MessageCommandValidatedOption> {
1
+ import { MessageCommandValidatedOption } from './builders/MessageCommandBuilder';
2
+ export declare class MessageCommandOptionManager extends Array<MessageCommandValidatedOption> {
3
3
  constructor(options: MessageCommandValidatedOption[]);
4
4
  /**
5
5
  * Get the option info
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MessageCommandOptions = void 0;
4
- class MessageCommandOptions extends Array {
3
+ exports.MessageCommandOptionManager = void 0;
4
+ class MessageCommandOptionManager extends Array {
5
5
  constructor(options) {
6
6
  super();
7
7
  this.push(...options);
@@ -20,4 +20,4 @@ class MessageCommandOptions extends Array {
20
20
  return (_a = option === null || option === void 0 ? void 0 : option.value) !== null && _a !== void 0 ? _a : null;
21
21
  }
22
22
  }
23
- exports.MessageCommandOptions = MessageCommandOptions;
23
+ exports.MessageCommandOptionManager = MessageCommandOptionManager;
@@ -1,10 +1,12 @@
1
- import { InteractionCommandBuilder, RecipleInteractionCommandExecute } from './builders/InteractionCommandBuilder';
2
- import { interactionCommandBuilders } from '../registerInteractionCommands';
3
- import { MessageCommandBuilder, RecipleMessageCommandExecute } from './builders/MessageCommandBuilder';
1
+ import { InteractionCommandBuilder, RecipleInteractionCommandExecuteData } from './builders/InteractionCommandBuilder';
2
+ import { MessageCommandBuilder, RecipleMessageCommandExecuteData } from './builders/MessageCommandBuilder';
3
+ import { InteractionBuilder } from '../registerInteractionCommands';
4
+ import { RecipleCommandBuilders } from '../types/builders';
5
+ import { CommandCooldownManager } from './CommandCooldownManager';
6
+ import { RecipleModule, RecipleScript } from '../modules';
4
7
  import { Logger as ILogger } from 'fallout-utility';
5
8
  import { Config } from './RecipleConfig';
6
9
  import { ApplicationCommandDataResolvable, Awaitable, Client, ClientEvents, ClientOptions, CommandInteraction, Interaction, Message } from 'discord.js';
7
- import { recipleCommandBuilders, RecipleModule, RecipleScript } from '../modules';
8
10
  export interface RecipleClientOptions extends ClientOptions {
9
11
  config?: Config;
10
12
  }
@@ -17,8 +19,8 @@ export interface RecipleClientCommands {
17
19
  };
18
20
  }
19
21
  export interface RecipleClientEvents extends ClientEvents {
20
- recipleMessageCommandCreate: [command: RecipleMessageCommandExecute];
21
- recipleInteractionCommandCreate: [command: RecipleInteractionCommandExecute];
22
+ recipleMessageCommandCreate: [executeData: RecipleMessageCommandExecuteData];
23
+ recipleInteractionCommandCreate: [executeData: RecipleInteractionCommandExecuteData];
22
24
  recipleReplyError: [error: unknown];
23
25
  }
24
26
  export interface RecipleClient<Ready extends boolean = boolean> extends Client<Ready> {
@@ -37,7 +39,8 @@ export interface RecipleClient<Ready extends boolean = boolean> extends Client<R
37
39
  export declare class RecipleClient<Ready extends boolean = boolean> extends Client<Ready> {
38
40
  config: Config;
39
41
  commands: RecipleClientCommands;
40
- otherApplicationCommandData: (interactionCommandBuilders | ApplicationCommandDataResolvable)[];
42
+ otherApplicationCommandData: (InteractionBuilder | ApplicationCommandDataResolvable)[];
43
+ commandCooldowns: CommandCooldownManager;
41
44
  modules: RecipleModule[];
42
45
  logger: ILogger;
43
46
  version: string;
@@ -57,7 +60,7 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
57
60
  /**
58
61
  * Add interaction or message command to client
59
62
  */
60
- addCommand(command: recipleCommandBuilders): RecipleClient<Ready>;
63
+ addCommand(command: RecipleCommandBuilders): RecipleClient<Ready>;
61
64
  /**
62
65
  * Listed to command executions
63
66
  */
@@ -65,11 +68,11 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
65
68
  /**
66
69
  * Execute a Message command
67
70
  */
68
- messageCommandExecute(message: Message, prefix?: string): Promise<void | RecipleMessageCommandExecute>;
71
+ messageCommandExecute(message: Message, prefix?: string): Promise<void | RecipleMessageCommandExecuteData>;
69
72
  /**
70
73
  * Execute an Interaction command
71
74
  */
72
- interactionCommandExecute(interaction: Interaction | CommandInteraction): Promise<void | RecipleInteractionCommandExecute>;
75
+ interactionCommandExecute(interaction: Interaction | CommandInteraction): Promise<void | RecipleInteractionCommandExecuteData>;
73
76
  /**
74
77
  * Get a message from config
75
78
  */
@@ -86,7 +89,7 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
86
89
  /**
87
90
  * Emits the "recipleReplyError" event
88
91
  */
89
- private replyError;
92
+ private _replyError;
90
93
  /**
91
94
  * Error message when a command fails to execute
92
95
  */
@@ -1,10 +1,5 @@
1
1
  "use strict";
2
- // Dear precious programmer,
3
- // If you're trying to understand this code, please, consider that
4
- // at the time of writing this code, It was written the way humans
5
- // can understand it but I transformed into a dog at Apr 12th 2022
6
- // and accidentally made it unreadable for humans. So, if you're
7
- // trying to understand this code, please, consider being a dog first.
2
+ // Not cool code
8
3
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
4
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
5
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -17,15 +12,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
12
  Object.defineProperty(exports, "__esModule", { value: true });
18
13
  exports.RecipleClient = void 0;
19
14
  const registerInteractionCommands_1 = require("../registerInteractionCommands");
15
+ const permissions_1 = require("../permissions");
16
+ const CommandCooldownManager_1 = require("./CommandCooldownManager");
17
+ const MessageCommandOptionManager_1 = require("./MessageCommandOptionManager");
18
+ const modules_1 = require("../modules");
20
19
  const fallout_utility_1 = require("fallout-utility");
20
+ const RecipleConfig_1 = require("./RecipleConfig");
21
21
  const isIgnoredChannel_1 = require("../isIgnoredChannel");
22
- const hasPermissions_1 = require("../hasPermissions");
23
22
  const version_1 = require("../version");
24
23
  const logger_1 = require("../logger");
25
- const RecipleConfig_1 = require("./RecipleConfig");
26
24
  const discord_js_1 = require("discord.js");
27
- const modules_1 = require("../modules");
28
- const MessageCommandOptions_1 = require("./builders/MessageCommandOptions");
29
25
  class RecipleClient extends discord_js_1.Client {
30
26
  constructor(options) {
31
27
  var _a, _b, _c;
@@ -33,6 +29,7 @@ class RecipleClient extends discord_js_1.Client {
33
29
  this.config = RecipleConfig_1.RecipleConfig.getDefaultConfig();
34
30
  this.commands = { MESSAGE_COMMANDS: {}, INTERACTION_COMMANDS: {} };
35
31
  this.otherApplicationCommandData = [];
32
+ this.commandCooldowns = new CommandCooldownManager_1.CommandCooldownManager();
36
33
  this.modules = [];
37
34
  this.version = version_1.version;
38
35
  this.logger = (0, logger_1.logger)(!!((_a = options.config) === null || _a === void 0 ? void 0 : _a.fileLogging.stringifyLoggedJSON), !!((_b = options.config) === null || _b === void 0 ? void 0 : _b.fileLogging.debugmode));
@@ -71,7 +68,7 @@ class RecipleClient extends discord_js_1.Client {
71
68
  this.logger.error(`Error loading ${(_a = module_.info.filename) !== null && _a !== void 0 ? _a : 'unknown module'}:`);
72
69
  this.logger.error(err);
73
70
  }
74
- this.modules = this.modules.filter((r, i) => i.toString() !== m.toString());
71
+ this.modules = this.modules.filter((_r, i) => i.toString() !== m.toString());
75
72
  });
76
73
  }
77
74
  if (typeof ((_b = module_.script) === null || _b === void 0 ? void 0 : _b.commands) !== 'undefined') {
@@ -155,36 +152,69 @@ class RecipleClient extends discord_js_1.Client {
155
152
  const command = this.findCommand(parseCommand.command, 'MESSAGE_COMMAND');
156
153
  if (!command)
157
154
  return;
158
- if ((0, hasPermissions_1.hasPermissions)(command.name, (_a = message.member) === null || _a === void 0 ? void 0 : _a.permissions, this.config.permissions.messageCommands, command)) {
155
+ const commandOptions = command.getCommandOptionValues(parseCommand);
156
+ const executeData = {
157
+ message: message,
158
+ options: new MessageCommandOptionManager_1.MessageCommandOptionManager(commandOptions),
159
+ command: parseCommand,
160
+ builder: command,
161
+ client: this
162
+ };
163
+ if ((0, permissions_1.userHasCommandPermissions)(command.name, (_a = message.member) === null || _a === void 0 ? void 0 : _a.permissions, this.config.permissions.messageCommands, command)) {
159
164
  if (!command.allowExecuteInDM && message.channel.type === 'DM'
160
165
  || !command.allowExecuteByBots
161
166
  && (message.author.bot || message.author.system)
162
167
  || (0, isIgnoredChannel_1.isIgnoredChannel)(message.channelId, this.config.ignoredChannels))
163
168
  return;
164
- const commandOptions = command.getCommandOptionValues(parseCommand);
165
169
  if (command.validateOptions) {
166
170
  if (commandOptions.some(o => o.invalid)) {
167
- yield message.reply(this.getMessage('invalidArguments', 'Invalid argument(s) given.')).catch(er => this.replyError(er));
171
+ if (!(command === null || command === void 0 ? void 0 : command.halt) || !(yield command.halt({ executeData, reason: 'INVALID_ARGUMENTS', invalidArguments: new MessageCommandOptionManager_1.MessageCommandOptionManager(executeData.options.filter(o => o.invalid)) }))) {
172
+ message.reply(this.getMessage('invalidArguments', 'Invalid argument(s) given.')).catch(er => this._replyError(er));
173
+ }
168
174
  return;
169
175
  }
170
176
  if (commandOptions.some(o => o.missing)) {
171
- yield message.reply(this.getMessage('notEnoughArguments', 'Not enough arguments.')).catch(er => this.replyError(er));
177
+ if (!command.halt || !(yield command.halt({ executeData, reason: 'MISSING_ARGUMENTS', missingArguments: new MessageCommandOptionManager_1.MessageCommandOptionManager(executeData.options.filter(o => o.missing)) }))) {
178
+ message.reply(this.getMessage('notEnoughArguments', 'Not enough arguments.')).catch(er => this._replyError(er));
179
+ }
172
180
  return;
173
181
  }
174
182
  }
175
- const options = {
176
- message: message,
177
- options: new MessageCommandOptions_1.MessageCommandOptions(commandOptions),
178
- command: parseCommand,
179
- builder: command,
180
- client: this
183
+ if (message.guild && !(0, permissions_1.botHasExecutePermissions)(message.guild, command.requiredBotPermissions)) {
184
+ if (!command.halt || !(yield command.halt({ executeData, reason: 'MISSING_BOT_PERMISSIONS' }))) {
185
+ message.reply(this.getMessage('insufficientBotPerms', 'Insufficient bot permissions.')).catch(er => this._replyError(er));
186
+ }
187
+ return;
188
+ }
189
+ const userCooldown = {
190
+ user: message.author,
191
+ command: command.name,
192
+ channel: message.channel,
193
+ guild: message.guild,
194
+ type: 'MESSAGE_COMMAND'
181
195
  };
182
- yield Promise.resolve(command.execute(options)).catch(err => this._commandExecuteError(err, options));
183
- this.emit('recipleMessageCommandCreate', options);
184
- return options;
196
+ if (this.config.commands.messageCommand.enableCooldown && command.cooldown && !this.commandCooldowns.isCooledDown(userCooldown)) {
197
+ this.commandCooldowns.add(Object.assign(Object.assign({}, userCooldown), { expireTime: Date.now() + command.cooldown }));
198
+ }
199
+ else if (this.config.commands.messageCommand.enableCooldown && command.cooldown) {
200
+ if (!command.halt || !(yield command.halt(Object.assign({ executeData, reason: 'COOLDOWN' }, this.commandCooldowns.get(userCooldown))))) {
201
+ yield message.reply(this.getMessage('cooldown', 'You cannot execute this command right now due to the cooldown.')).catch(er => this._replyError(er));
202
+ }
203
+ return;
204
+ }
205
+ try {
206
+ yield Promise.resolve(command.execute(executeData)).catch((err) => __awaiter(this, void 0, void 0, function* () { return !command.halt || !(yield command.halt({ executeData, reason: 'ERROR', error: err })) ? this._commandExecuteError(err, executeData) : void 0; }));
207
+ this.emit('recipleMessageCommandCreate', executeData);
208
+ return executeData;
209
+ }
210
+ catch (err) {
211
+ if (!command.halt || !(yield command.halt({ executeData, reason: 'ERROR', error: err }))) {
212
+ this._commandExecuteError(err, executeData);
213
+ }
214
+ }
185
215
  }
186
- else {
187
- yield message.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this.replyError(er));
216
+ else if (!command.halt || !(yield command.halt({ executeData, reason: 'MISSING_MEMBER_PERMISSIONS' }))) {
217
+ message.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this._replyError(er));
188
218
  }
189
219
  });
190
220
  }
@@ -192,28 +222,56 @@ class RecipleClient extends discord_js_1.Client {
192
222
  * Execute an Interaction command
193
223
  */
194
224
  interactionCommandExecute(interaction) {
195
- var _a;
225
+ var _a, _b;
196
226
  return __awaiter(this, void 0, void 0, function* () {
197
227
  if (!interaction || !interaction.isCommand() || !this.isReady())
198
228
  return;
199
229
  const command = this.findCommand(interaction.commandName, 'INTERACTION_COMMAND');
200
230
  if (!command)
201
231
  return;
202
- if ((0, hasPermissions_1.hasPermissions)(command.name, (_a = interaction.memberPermissions) !== null && _a !== void 0 ? _a : undefined, this.config.permissions.interactionCommands, command)) {
232
+ const executeData = {
233
+ interaction: interaction,
234
+ builder: command,
235
+ client: this
236
+ };
237
+ if ((0, permissions_1.userHasCommandPermissions)(command.name, (_a = interaction.memberPermissions) !== null && _a !== void 0 ? _a : undefined, this.config.permissions.interactionCommands, command)) {
203
238
  if (!command || (0, isIgnoredChannel_1.isIgnoredChannel)(interaction.channelId, this.config.ignoredChannels))
204
239
  return;
205
- const options = {
206
- interaction: interaction,
207
- command: command,
208
- builder: command,
209
- client: this
240
+ if (interaction.guild && !(0, permissions_1.botHasExecutePermissions)(interaction.guild, command.requiredBotPermissions)) {
241
+ if (!command.halt || !(yield command.halt({ executeData, reason: 'MISSING_BOT_PERMISSIONS' }))) {
242
+ yield interaction.reply(this.getMessage('insufficientBotPerms', 'Insufficient bot permissions.')).catch(er => this._replyError(er));
243
+ }
244
+ return;
245
+ }
246
+ const userCooldown = {
247
+ user: interaction.user,
248
+ command: command.name,
249
+ channel: (_b = interaction.channel) !== null && _b !== void 0 ? _b : undefined,
250
+ guild: interaction.guild,
251
+ type: 'INTERACTION_COMMAND'
210
252
  };
211
- yield Promise.resolve(command.execute(options)).catch(err => this._commandExecuteError(err, options));
212
- this.emit('recipleInteractionCommandCreate', options);
213
- return options;
253
+ if (this.config.commands.interactionCommand.enableCooldown && command.cooldown && !this.commandCooldowns.isCooledDown(userCooldown)) {
254
+ this.commandCooldowns.add(Object.assign(Object.assign({}, userCooldown), { expireTime: Date.now() + command.cooldown }));
255
+ }
256
+ else if (this.config.commands.interactionCommand.enableCooldown && command.cooldown) {
257
+ if (!command.halt || !(yield command.halt(Object.assign({ executeData, reason: 'COOLDOWN' }, this.commandCooldowns.get(userCooldown))))) {
258
+ yield interaction.reply(this.getMessage('cooldown', 'You cannot execute this command right now due to the cooldown.')).catch(er => this._replyError(er));
259
+ }
260
+ return;
261
+ }
262
+ try {
263
+ yield Promise.resolve(command.execute(executeData)).catch((err) => __awaiter(this, void 0, void 0, function* () { return !command.halt || !(yield command.halt({ executeData, reason: 'ERROR', error: err })) ? this._commandExecuteError(err, executeData) : void 0; }));
264
+ this.emit('recipleInteractionCommandCreate', executeData);
265
+ return executeData;
266
+ }
267
+ catch (err) {
268
+ if (!command.halt || !(yield command.halt({ executeData, reason: 'ERROR', error: err }))) {
269
+ this._commandExecuteError(err, executeData);
270
+ }
271
+ }
214
272
  }
215
- else {
216
- yield interaction.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this.replyError(er));
273
+ else if (!command.halt || !(yield command.halt({ executeData, reason: 'MISSING_MEMBER_PERMISSIONS' }))) {
274
+ yield interaction.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this._replyError(er));
217
275
  }
218
276
  });
219
277
  }
@@ -246,7 +304,7 @@ class RecipleClient extends discord_js_1.Client {
246
304
  /**
247
305
  * Emits the "recipleReplyError" event
248
306
  */
249
- replyError(error) {
307
+ _replyError(error) {
250
308
  this.emit('recipleReplyError', error);
251
309
  }
252
310
  /**
@@ -263,12 +321,12 @@ class RecipleClient extends discord_js_1.Client {
263
321
  if (command === null || command === void 0 ? void 0 : command.message) {
264
322
  if (!this.config.commands.messageCommand.replyOnError)
265
323
  return;
266
- yield command.message.reply(this.getMessage('error', 'An error occurred.')).catch(er => this.replyError(er));
324
+ yield command.message.reply(this.getMessage('error', 'An error occurred.')).catch(er => this._replyError(er));
267
325
  }
268
326
  else if (command === null || command === void 0 ? void 0 : command.interaction) {
269
327
  if (!this.config.commands.interactionCommand.replyOnError)
270
328
  return;
271
- yield command.interaction.followUp(this.getMessage('error', 'An error occurred.')).catch(er => this.replyError(er));
329
+ yield command.interaction.followUp(this.getMessage('error', 'An error occurred.')).catch(er => this._replyError(er));
272
330
  }
273
331
  });
274
332
  }
@@ -1,7 +1,7 @@
1
- import { ClientOptions, PermissionFlags, PermissionString } from 'discord.js';
1
+ import { ClientOptions, PermissionResolvable } from 'discord.js';
2
2
  export interface ConfigCommandPermissions {
3
3
  command: string;
4
- permissions: (PermissionFlags | PermissionString)[];
4
+ permissions: PermissionResolvable[];
5
5
  }
6
6
  export interface Config {
7
7
  token: string;
@@ -11,12 +11,14 @@ export interface Config {
11
11
  enabled: boolean;
12
12
  replyOnError: boolean;
13
13
  allowCommandAlias: boolean;
14
+ enableCooldown: boolean;
14
15
  commandArgumentSeparator: string;
15
16
  };
16
17
  interactionCommand: {
17
18
  enabled: boolean;
18
19
  replyOnError: boolean;
19
20
  registerCommands: boolean;
21
+ enableCooldown: boolean;
20
22
  setRequiredPermissions: boolean;
21
23
  guilds: string[] | string;
22
24
  };
@@ -33,7 +33,7 @@ class RecipleConfig {
33
33
  this.config = yaml_1.default.parse(defaultConfig);
34
34
  if (this.config && this.config.token === 'TOKEN') {
35
35
  this.config.token = this.askToken() || this.config.token;
36
- (0, fs_1.writeFileSync)(this.configPath, (0, fallout_utility_1.replaceAll)(defaultConfig, 'TOKEN', this.config.token), 'utf-8');
36
+ (0, fs_1.writeFileSync)(this.configPath, (0, fallout_utility_1.replaceAll)(defaultConfig, ' TOKEN', ` ${this.config.token}`), 'utf-8');
37
37
  }
38
38
  return this;
39
39
  }
@@ -1,23 +1,35 @@
1
- import { CommandInteraction, PermissionFlags, PermissionString } from 'discord.js';
1
+ import { Awaitable, CommandInteraction, PermissionResolvable } from 'discord.js';
2
+ import { RecipleHaltedCommandData } from '../../types/commands';
2
3
  import { SlashCommandBuilder } from '@discordjs/builders';
3
4
  import { RecipleClient } from '../RecipleClient';
4
- export interface RecipleInteractionCommandExecute {
5
+ export interface RecipleInteractionCommandExecuteData {
5
6
  interaction: CommandInteraction;
6
- command: InteractionCommandBuilder;
7
7
  builder: InteractionCommandBuilder;
8
8
  client: RecipleClient<true>;
9
9
  }
10
10
  export declare class InteractionCommandBuilder extends SlashCommandBuilder {
11
11
  readonly builder = "INTERACTION_COMMAND";
12
- requiredPermissions: (PermissionFlags | PermissionString)[];
12
+ cooldown: number;
13
+ requiredBotPermissions: PermissionResolvable[];
14
+ RequiredUserPermissions: PermissionResolvable[];
13
15
  allowExecuteInDM: boolean;
14
- execute: (options: RecipleInteractionCommandExecute) => void;
16
+ halt?: (haltData: RecipleHaltedCommandData<InteractionCommandBuilder>) => Awaitable<boolean>;
17
+ execute: (executeData: RecipleInteractionCommandExecuteData) => Awaitable<void>;
15
18
  /**
16
- * Set required permissions before executing the command
19
+ * Sets the execute cooldown for this command.
20
+ * - `0` means no cooldown
17
21
  */
18
- setRequiredPermissions(requiredPermissions: (keyof PermissionFlags)[]): InteractionCommandBuilder;
22
+ setCooldown(cooldown: number): InteractionCommandBuilder;
23
+ /**
24
+ * Set required permissions to execute the command
25
+ */
26
+ setRequiredMemberPermissions(...permissions: PermissionResolvable[]): InteractionCommandBuilder;
27
+ /**
28
+ * Function when the command is interupted before execution
29
+ */
30
+ setHalt(halt?: (haltData: RecipleHaltedCommandData<InteractionCommandBuilder>) => Awaitable<boolean>): InteractionCommandBuilder;
19
31
  /**
20
32
  * Function when the command is executed
21
33
  */
22
- setExecute(execute: (options: RecipleInteractionCommandExecute) => void): InteractionCommandBuilder;
34
+ setExecute(execute: (executeData: RecipleInteractionCommandExecuteData) => void): InteractionCommandBuilder;
23
35
  }
@@ -6,17 +6,32 @@ class InteractionCommandBuilder extends builders_1.SlashCommandBuilder {
6
6
  constructor() {
7
7
  super(...arguments);
8
8
  this.builder = 'INTERACTION_COMMAND';
9
- this.requiredPermissions = [];
9
+ this.cooldown = 0;
10
+ this.requiredBotPermissions = [];
11
+ this.RequiredUserPermissions = [];
10
12
  this.allowExecuteInDM = true;
11
13
  this.execute = () => { };
12
14
  }
13
15
  /**
14
- * Set required permissions before executing the command
16
+ * Sets the execute cooldown for this command.
17
+ * - `0` means no cooldown
15
18
  */
16
- setRequiredPermissions(requiredPermissions) {
17
- if (!requiredPermissions || !Array.isArray(requiredPermissions))
18
- throw new Error('requiredPermissions must be an array.');
19
- this.requiredPermissions = requiredPermissions;
19
+ setCooldown(cooldown) {
20
+ this.cooldown = cooldown;
21
+ return this;
22
+ }
23
+ /**
24
+ * Set required permissions to execute the command
25
+ */
26
+ setRequiredMemberPermissions(...permissions) {
27
+ this.RequiredUserPermissions = permissions;
28
+ return this;
29
+ }
30
+ /**
31
+ * Function when the command is interupted before execution
32
+ */
33
+ setHalt(halt) {
34
+ this.halt = halt ? halt : undefined;
20
35
  return this;
21
36
  }
22
37
  /**
@@ -1,11 +1,12 @@
1
1
  import { MessageCommandOptionBuilder } from './MessageCommandOptionBuilder';
2
- import { Message, PermissionFlags, PermissionString } from 'discord.js';
2
+ import { MessageCommandOptionManager } from '../MessageCommandOptionManager';
3
+ import { Awaitable, Message, PermissionResolvable } from 'discord.js';
4
+ import { RecipleHaltedCommandData } from '../../types/commands';
3
5
  import { Command as CommandMessage } from 'fallout-utility';
4
6
  import { RecipleClient } from '../RecipleClient';
5
- import { MessageCommandOptions } from './MessageCommandOptions';
6
- export interface RecipleMessageCommandExecute {
7
+ export interface RecipleMessageCommandExecuteData {
7
8
  message: Message;
8
- options: MessageCommandOptions;
9
+ options: MessageCommandOptionManager;
9
10
  command: CommandMessage;
10
11
  builder: MessageCommandBuilder;
11
12
  client: RecipleClient<true>;
@@ -20,14 +21,17 @@ export interface MessageCommandValidatedOption {
20
21
  export declare class MessageCommandBuilder {
21
22
  readonly builder = "MESSAGE_COMMAND";
22
23
  name: string;
24
+ cooldown: number;
23
25
  description: string;
24
26
  aliases: string[];
25
27
  options: MessageCommandOptionBuilder[];
26
28
  validateOptions: boolean;
27
- requiredPermissions: (PermissionFlags | PermissionString)[];
29
+ requiredBotPermissions: PermissionResolvable[];
30
+ RequiredUserPermissions: PermissionResolvable[];
28
31
  allowExecuteInDM: boolean;
29
32
  allowExecuteByBots: boolean;
30
- execute: (options: RecipleMessageCommandExecute) => void;
33
+ halt?: (haltData: RecipleHaltedCommandData<MessageCommandBuilder>) => Awaitable<boolean>;
34
+ execute: (executeData: RecipleMessageCommandExecuteData) => void;
31
35
  /**
32
36
  * Sets the command name
33
37
  */
@@ -36,14 +40,23 @@ export declare class MessageCommandBuilder {
36
40
  * Sets the command description
37
41
  */
38
42
  setDescription(description: string): MessageCommandBuilder;
43
+ /**
44
+ * Sets the execute cooldown for this command.
45
+ * - `0` means no cooldown
46
+ */
47
+ setCooldown(cooldown: number): MessageCommandBuilder;
39
48
  /**
40
49
  * Add aliases to the command
41
50
  */
42
51
  addAliases(...aliases: string[]): MessageCommandBuilder;
43
52
  /**
44
- * Sets the default required permissions to execute this command
53
+ * Set required per
54
+ */
55
+ setRequiredBotPermissions(...permissions: PermissionResolvable[]): MessageCommandBuilder;
56
+ /**
57
+ * Set required user permissions to execute the command
45
58
  */
46
- setRequiredPermissions(permissions: (PermissionFlags | PermissionString)[]): MessageCommandBuilder;
59
+ setRequiredMemberPermissions(...permissions: PermissionResolvable[]): MessageCommandBuilder;
47
60
  /**
48
61
  * Set if command can be executed in dms
49
62
  */
@@ -52,10 +65,14 @@ export declare class MessageCommandBuilder {
52
65
  * Allow command to be executed by bots
53
66
  */
54
67
  setAllowExecuteByBots(allowExecuteByBots: boolean): MessageCommandBuilder;
68
+ /**
69
+ * Function when the command is interupted before execution
70
+ */
71
+ setHalt(halt?: (haltData: RecipleHaltedCommandData<MessageCommandBuilder>) => Awaitable<boolean>): MessageCommandBuilder;
55
72
  /**
56
73
  * Function when the command is executed
57
74
  */
58
- setExecute(execute: (options: RecipleMessageCommandExecute) => void): MessageCommandBuilder;
75
+ setExecute(execute: (executeData: RecipleMessageCommandExecuteData) => void): MessageCommandBuilder;
59
76
  /**
60
77
  * Add option to the command
61
78
  */
@@ -6,11 +6,13 @@ class MessageCommandBuilder {
6
6
  constructor() {
7
7
  this.builder = 'MESSAGE_COMMAND';
8
8
  this.name = '';
9
+ this.cooldown = 0;
9
10
  this.description = '';
10
11
  this.aliases = [];
11
12
  this.options = [];
12
13
  this.validateOptions = false;
13
- this.requiredPermissions = [];
14
+ this.requiredBotPermissions = [];
15
+ this.RequiredUserPermissions = [];
14
16
  this.allowExecuteInDM = true;
15
17
  this.allowExecuteByBots = false;
16
18
  this.execute = () => { };
@@ -33,6 +35,14 @@ class MessageCommandBuilder {
33
35
  this.description = description;
34
36
  return this;
35
37
  }
38
+ /**
39
+ * Sets the execute cooldown for this command.
40
+ * - `0` means no cooldown
41
+ */
42
+ setCooldown(cooldown) {
43
+ this.cooldown = cooldown;
44
+ return this;
45
+ }
36
46
  /**
37
47
  * Add aliases to the command
38
48
  */
@@ -47,12 +57,17 @@ class MessageCommandBuilder {
47
57
  return this;
48
58
  }
49
59
  /**
50
- * Sets the default required permissions to execute this command
60
+ * Set required per
61
+ */
62
+ setRequiredBotPermissions(...permissions) {
63
+ this.requiredBotPermissions = permissions;
64
+ return this;
65
+ }
66
+ /**
67
+ * Set required user permissions to execute the command
51
68
  */
52
- setRequiredPermissions(permissions) {
53
- if (!permissions || !Array.isArray(permissions))
54
- throw new TypeError('permissions must be an array.');
55
- this.requiredPermissions = permissions;
69
+ setRequiredMemberPermissions(...permissions) {
70
+ this.RequiredUserPermissions = permissions;
56
71
  return this;
57
72
  }
58
73
  /**
@@ -73,6 +88,13 @@ class MessageCommandBuilder {
73
88
  this.allowExecuteByBots = allowExecuteByBots;
74
89
  return this;
75
90
  }
91
+ /**
92
+ * Function when the command is interupted before execution
93
+ */
94
+ setHalt(halt) {
95
+ this.halt = halt ? halt : undefined;
96
+ return this;
97
+ }
76
98
  /**
77
99
  * Function when the command is executed
78
100
  */
@@ -1,15 +1,12 @@
1
- import { InteractionCommandBuilder, RecipleInteractionCommandExecute } from './classes/builders/InteractionCommandBuilder';
2
- import { MessageCommandBuilder, RecipleMessageCommandExecute } from './classes/builders/MessageCommandBuilder';
1
+ import { RecipleCommandBuilders } from './types/builders';
3
2
  import { RecipleClient } from './classes/RecipleClient';
4
- export declare type recipleCommandBuilders = MessageCommandBuilder | InteractionCommandBuilder;
5
- export declare type recipleCommandBuildersExecute = RecipleInteractionCommandExecute | RecipleMessageCommandExecute;
6
- export declare type loadedModules = {
7
- commands: recipleCommandBuilders[];
3
+ export declare type LoadedModules = {
4
+ commands: RecipleCommandBuilders[];
8
5
  modules: RecipleModule[];
9
6
  };
10
7
  export declare class RecipleScript {
11
8
  versions: string | string[];
12
- commands?: recipleCommandBuilders[];
9
+ commands?: RecipleCommandBuilders[];
13
10
  onLoad?(reciple: RecipleClient): void | Promise<void>;
14
11
  onStart(reciple: RecipleClient): boolean | Promise<boolean>;
15
12
  }
@@ -24,4 +21,4 @@ export interface RecipleModule {
24
21
  /**
25
22
  * Load modules from folder
26
23
  */
27
- export declare function loadModules(client: RecipleClient, folder?: string): Promise<loadedModules>;
24
+ export declare function loadModules(client: RecipleClient, folder?: string): Promise<LoadedModules>;
@@ -0,0 +1,8 @@
1
+ import { Guild, PermissionResolvable, Permissions } from 'discord.js';
2
+ import { RecipleCommandBuilders } from './types/builders';
3
+ import { Config } from './classes/RecipleConfig';
4
+ /**
5
+ * Check if the user has permissions to execute the given command name
6
+ */
7
+ export declare function userHasCommandPermissions(commandName: string, memberPermissions?: Permissions, configConmmandPermissions?: Config['permissions']['messageCommands'] | Config['permissions']['interactionCommands'], builder?: RecipleCommandBuilders): boolean;
8
+ export declare function botHasExecutePermissions(guild?: Guild, requiredPermissions?: PermissionResolvable[]): boolean;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.botHasExecutePermissions = exports.userHasCommandPermissions = void 0;
4
+ /**
5
+ * Check if the user has permissions to execute the given command name
6
+ */
7
+ function userHasCommandPermissions(commandName, memberPermissions, configConmmandPermissions, builder) {
8
+ var _a, _b;
9
+ if (!(configConmmandPermissions === null || configConmmandPermissions === void 0 ? void 0 : configConmmandPermissions.enabled))
10
+ return true;
11
+ const command = (_a = configConmmandPermissions.commands.find(c => c.command.toLowerCase() === commandName.toLowerCase())) !== null && _a !== void 0 ? _a : { permissions: (_b = builder === null || builder === void 0 ? void 0 : builder.RequiredUserPermissions) !== null && _b !== void 0 ? _b : [] };
12
+ if (!command.permissions.length)
13
+ return true;
14
+ return memberPermissions ? memberPermissions.has(command.permissions) : false;
15
+ }
16
+ exports.userHasCommandPermissions = userHasCommandPermissions;
17
+ function botHasExecutePermissions(guild, requiredPermissions) {
18
+ var _a;
19
+ if (!(requiredPermissions === null || requiredPermissions === void 0 ? void 0 : requiredPermissions.length))
20
+ return true;
21
+ return (guild === null || guild === void 0 ? void 0 : guild.me) ? (_a = guild.me) === null || _a === void 0 ? void 0 : _a.permissions.has(requiredPermissions) : false;
22
+ }
23
+ exports.botHasExecutePermissions = botHasExecutePermissions;
@@ -2,8 +2,8 @@ import { InteractionCommandBuilder } from './classes/builders/InteractionCommand
2
2
  import { ApplicationCommandDataResolvable } from 'discord.js';
3
3
  import { RecipleClient } from './classes/RecipleClient';
4
4
  import { ContextMenuCommandBuilder, SlashCommandBuilder, SlashCommandSubcommandBuilder, SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandsOnlyBuilder } from '@discordjs/builders';
5
- export declare type interactionCommandBuilders = InteractionCommandBuilder | ContextMenuCommandBuilder | SlashCommandBuilder | SlashCommandSubcommandBuilder | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandGroupBuilder | SlashCommandSubcommandsOnlyBuilder;
5
+ export declare type InteractionBuilder = InteractionCommandBuilder | ContextMenuCommandBuilder | SlashCommandBuilder | SlashCommandSubcommandBuilder | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandGroupBuilder | SlashCommandSubcommandsOnlyBuilder;
6
6
  /**
7
7
  * Register interaction commands
8
8
  */
9
- export declare function registerInteractionCommands(client: RecipleClient, cmds?: (interactionCommandBuilders | ApplicationCommandDataResolvable)[], overwriteGuilds?: string | string[]): Promise<void>;
9
+ export declare function registerInteractionCommands(client: RecipleClient, cmds?: (InteractionBuilder | ApplicationCommandDataResolvable)[], overwriteGuilds?: string | string[]): Promise<void>;
@@ -24,8 +24,8 @@ function registerInteractionCommands(client, cmds, overwriteGuilds) {
24
24
  if ((cmd === null || cmd === void 0 ? void 0 : cmd.builder) === 'INTERACTION_COMMAND' && client.config.commands.interactionCommand.setRequiredPermissions) {
25
25
  const permissions = (_d = (((_a = client.config.permissions) === null || _a === void 0 ? void 0 : _a.interactionCommands.enabled) ?
26
26
  (_c = (_b = client.config.permissions) === null || _b === void 0 ? void 0 : _b.interactionCommands.commands.find(cmd_ => cmd_.command.toLowerCase() === cmd.name.toLowerCase())) === null || _c === void 0 ? void 0 : _c.permissions :
27
- undefined)) !== null && _d !== void 0 ? _d : cmd.requiredPermissions;
28
- cmd.setRequiredPermissions(permissions);
27
+ undefined)) !== null && _d !== void 0 ? _d : cmd.requiredBotPermissions;
28
+ cmd.setRequiredMemberPermissions(permissions);
29
29
  client.commands.INTERACTION_COMMANDS[cmd.name] = cmd;
30
30
  if (client.isClientLogsEnabled())
31
31
  client.logger.debug(`Set required permissions for ${cmd.name}`);
@@ -0,0 +1,4 @@
1
+ import { InteractionCommandBuilder, RecipleInteractionCommandExecuteData } from '../classes/builders/InteractionCommandBuilder';
2
+ import { MessageCommandBuilder, RecipleMessageCommandExecuteData } from '../classes/builders/MessageCommandBuilder';
3
+ export declare type RecipleCommandBuilders = MessageCommandBuilder | InteractionCommandBuilder;
4
+ export declare type RecipleCommandBuildersExecuteData = RecipleInteractionCommandExecuteData | RecipleMessageCommandExecuteData;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,31 @@
1
+ import { InteractionCommandBuilder, RecipleInteractionCommandExecuteData } from '../classes/builders/InteractionCommandBuilder';
2
+ import { RecipleMessageCommandExecuteData } from '../classes/builders/MessageCommandBuilder';
3
+ import { MessageCommandOptionManager } from '../classes/MessageCommandOptionManager';
4
+ import { CooledDownUser } from '../classes/CommandCooldownManager';
5
+ import { RecipleCommandBuilders } from '../types/builders';
6
+ export declare type CommandHaltReason<Builder extends RecipleCommandBuilders> = RecipleHaltedCommandData<Builder>["reason"];
7
+ export declare type RecipleHaltedCommandData<Builder extends RecipleCommandBuilders> = CommandErrorData<Builder> | CommandCooldownData<Builder> | CommandInvalidArguments<Builder> | CommandMissingArguments<Builder> | CommandMissingMemberPermissions<Builder> | CommandMissingBotPermissions<Builder>;
8
+ export interface CommandHaltBaseData<Builder extends RecipleCommandBuilders> {
9
+ executeData: Builder extends InteractionCommandBuilder ? RecipleInteractionCommandExecuteData : RecipleMessageCommandExecuteData;
10
+ }
11
+ export interface CommandErrorData<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder> {
12
+ reason: 'ERROR';
13
+ error: any;
14
+ }
15
+ export interface CommandCooldownData<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder>, CooledDownUser {
16
+ reason: 'COOLDOWN';
17
+ }
18
+ export interface CommandInvalidArguments<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder> {
19
+ reason: 'INVALID_ARGUMENTS';
20
+ invalidArguments: MessageCommandOptionManager;
21
+ }
22
+ export interface CommandMissingArguments<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder> {
23
+ reason: 'MISSING_ARGUMENTS';
24
+ missingArguments: MessageCommandOptionManager;
25
+ }
26
+ export interface CommandMissingMemberPermissions<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder> {
27
+ reason: 'MISSING_MEMBER_PERMISSIONS';
28
+ }
29
+ export interface CommandMissingBotPermissions<Builder extends RecipleCommandBuilders> extends CommandHaltBaseData<Builder> {
30
+ reason: 'MISSING_BOT_PERMISSIONS';
31
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -8,7 +8,7 @@ const semver_1 = __importDefault(require("semver"));
8
8
  /**
9
9
  * Current reciple version
10
10
  */
11
- exports.version = require('../../package.json').version;
11
+ exports.version = `${semver_1.default.coerce(require('../../package.json').version)}`;
12
12
  /**
13
13
  * Check if the version is valid
14
14
  */
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "reciple",
3
- "version": "1.7.1",
4
- "description": "A Discord.js bot",
3
+ "version": "2.0.2",
4
+ "description": "Handler for Discord.js",
5
5
  "author": "FalloutStudios",
6
- "homepage": "https://falloutstudios.github.io/Reciple",
6
+ "homepage": "https://reciple.js.org",
7
+ "bugs": {
8
+ "url": "https://github.com/FalloutStudios/reciple/issues"
9
+ },
7
10
  "license": "GPL-3.0",
8
11
  "main": "bin/index.js",
9
12
  "bin": {
@@ -21,13 +24,15 @@
21
24
  ],
22
25
  "scripts": {
23
26
  "clean": "rm -rf bin",
24
- "build": "yarn clean && npx tsc && npm un reciple -g && npm i ./ -g && yarn build:docs",
25
- "build:publish": "yarn run build && yarn publish",
26
- "test": "yarn run build && yarn test:start",
27
+ "build": "yarn run clean && npx tsc && yarn run reinstall",
28
+ "build:publish": "yarn run build && yarn publish && yarn run publish:docs",
29
+ "build:pub-prerelease": "yarn run build && yarn publish --tag pre",
30
+ "reinstall": "npm un reciple -g && npm i ./ -g",
31
+ "publish:docs": "yarn run build:docs && yarn run update:docs",
32
+ "test": "yarn run build && yarn run test:start",
27
33
  "test:start": "cd test && npx reciple",
28
- "postpublish": "yarn build:docs && yarn update:docs",
29
- "build:docs": "cd docs && yarn build",
30
- "update:docs": "cd docs && yarn update"
34
+ "build:docs": "cd docs && yarn run build",
35
+ "update:docs": "cd docs && yarn run update"
31
36
  },
32
37
  "dependencies": {
33
38
  "chalk": "4.1.2",
@@ -13,8 +13,10 @@ commands:
13
13
  enabled: true
14
14
  # reply when an error occured
15
15
  replyOnError: false
16
+ # Enable the use of command cooldowns
17
+ enableCooldown: false
16
18
  # Allow executing commands via aliases
17
- allowCommandAlias: false
19
+ allowCommandAlias: true
18
20
  # command argument separator
19
21
  commandArgumentSeparator: ' '
20
22
  interactionCommand:
@@ -22,6 +24,8 @@ commands:
22
24
  enabled: true
23
25
  # reply when an error occured
24
26
  replyOnError: false
27
+ # Enable the use of command cooldowns
28
+ enableCooldown: false
25
29
  # register interaction commands on bot ready
26
30
  registerCommands: true
27
31
  # set required permissions for interaction commands
@@ -80,9 +84,15 @@ client:
80
84
  messages:
81
85
  notEnoughArguments: 'Not enough arguments.'
82
86
  invalidArguments: 'Invalid argument(s) given.'
87
+ insufficientBotPerms:
88
+ content: 'Insufficient bot permissions.'
89
+ ephemeral: true
83
90
  noPermissions:
84
91
  content: 'You do not have permission to use this command.'
85
92
  ephemeral: true
93
+ cooldown:
94
+ content: 'You cannot execute this command right now due to the cooldown.'
95
+ ephemeral: true
86
96
  error:
87
97
  content: 'An error occurred.'
88
98
  ephemeral: true
@@ -1,7 +0,0 @@
1
- import { Permissions } from 'discord.js';
2
- import { recipleCommandBuilders } from './modules';
3
- import { Config } from './classes/RecipleConfig';
4
- /**
5
- * Check if the user has permissions to execute the given command name
6
- */
7
- export declare function hasPermissions(commandName: string, memberPermissions?: Permissions, configConmmandPermissions?: Config['permissions']['messageCommands'] | Config['permissions']['interactionCommands'], builder?: recipleCommandBuilders): boolean;
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasPermissions = void 0;
4
- /**
5
- * Check if the user has permissions to execute the given command name
6
- */
7
- function hasPermissions(commandName, memberPermissions, configConmmandPermissions, builder) {
8
- var _a, _b;
9
- if (!(configConmmandPermissions === null || configConmmandPermissions === void 0 ? void 0 : configConmmandPermissions.enabled))
10
- return true;
11
- const command = (_a = configConmmandPermissions.commands.find(c => c.command.toLowerCase() === commandName.toLowerCase())) !== null && _a !== void 0 ? _a : { permissions: (_b = builder === null || builder === void 0 ? void 0 : builder.requiredPermissions) !== null && _b !== void 0 ? _b : [] };
12
- if (!command.permissions.length)
13
- return true;
14
- return memberPermissions ? memberPermissions.has(command.permissions) : false;
15
- }
16
- exports.hasPermissions = hasPermissions;