reciple 1.6.2 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,15 @@
1
1
  <h1 align="center">
2
- <img src="https://i.imgur.com/8pYGOWW.png" width="50%">
2
+ <img src="https://i.imgur.com/DWM0tJL.png" width="50%">
3
3
  <br>
4
4
  <img alt="Lines of code" src="https://img.shields.io/tokei/lines/github/FalloutStudios/Reciple">
5
5
  <img alt="GitHub" src="https://img.shields.io/github/license/FalloutStudios/Reciple">
6
6
  <a href="https://www.codefactor.io/repository/github/falloutstudios/reciple/overview/main"><img src="https://www.codefactor.io/repository/github/falloutstudios/reciple/badge/main" alt="CodeFactor"></a>
7
7
  </h1>
8
8
 
9
- A simple modular Discord bot made with Discord.js written in TypeScript.
9
+ A simple Dicord.js command handler that just works.
10
10
 
11
+ # Join Discord
12
+ [![Discord Invite](https://i.imgur.com/GffJByO.png)](https://discord.gg/2CattJYNpw)
11
13
 
12
14
  ## Installation
13
15
  To install the bot, run the following command:
package/bin/bin.js CHANGED
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  };
12
12
  var _a, _b;
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- const Config_1 = require("./reciple/classes/Config");
14
+ const RecipleConfig_1 = require("./reciple/classes/RecipleConfig");
15
15
  const RecipleClient_1 = require("./reciple/classes/RecipleClient");
16
16
  const fs_1 = require("fs");
17
17
  const version_1 = require("./reciple/version");
@@ -28,13 +28,16 @@ if ((0, fs_1.readdirSync)('./').filter(f => !f.startsWith('.') && allowedFiles.i
28
28
  if (ask.toString().toLowerCase() !== 'y')
29
29
  process.exit(0);
30
30
  }
31
- const config = new Config_1.RecipleConfig((_b = flags_1.flags.config) !== null && _b !== void 0 ? _b : './reciple.yml').parseConfig().getConfig();
31
+ const config = new RecipleConfig_1.RecipleConfig((_b = flags_1.flags.config) !== null && _b !== void 0 ? _b : './reciple.yml').parseConfig().getConfig();
32
32
  const client = new RecipleClient_1.RecipleClient(Object.assign({ config: config }, config.client));
33
+ if (config.fileLogging.clientLogs)
34
+ client.logger.info('Reciple Client v' + version_1.version + ' is starting...');
33
35
  (() => __awaiter(void 0, void 0, void 0, function* () {
34
36
  yield client.startModules();
35
37
  client.on('ready', () => __awaiter(void 0, void 0, void 0, function* () {
36
38
  var _c;
37
- client.logger.warn(`Logged in as ${((_c = client.user) === null || _c === void 0 ? void 0 : _c.tag) || 'Unknown'}!`);
39
+ if (client.isClientLogsEnabled())
40
+ client.logger.warn(`Logged in as ${((_c = client.user) === null || _c === void 0 ? void 0 : _c.tag) || 'Unknown'}!`);
38
41
  yield client.loadModules();
39
42
  client.addCommandListeners();
40
43
  }));
package/bin/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
- import discord from 'discord.js';
2
- export declare const discordjs: typeof discord;
3
1
  export * from './reciple/classes/RecipleClient';
4
- export * from './reciple/classes/Config';
2
+ export * from './reciple/classes/RecipleConfig';
5
3
  export * from './reciple/classes/builders/InteractionCommandBuilder';
6
4
  export * from './reciple/classes/builders/MessageCommandBuilder';
7
5
  export * from './reciple/classes/builders/MessageCommandOptionBuilder';
package/bin/index.js CHANGED
@@ -13,15 +13,9 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  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
- var __importDefault = (this && this.__importDefault) || function (mod) {
17
- return (mod && mod.__esModule) ? mod : { "default": mod };
18
- };
19
16
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.discordjs = void 0;
21
- const discord_js_1 = __importDefault(require("discord.js"));
22
- exports.discordjs = discord_js_1.default;
23
17
  __exportStar(require("./reciple/classes/RecipleClient"), exports);
24
- __exportStar(require("./reciple/classes/Config"), exports);
18
+ __exportStar(require("./reciple/classes/RecipleConfig"), exports);
25
19
  __exportStar(require("./reciple/classes/builders/InteractionCommandBuilder"), exports);
26
20
  __exportStar(require("./reciple/classes/builders/MessageCommandBuilder"), exports);
27
21
  __exportStar(require("./reciple/classes/builders/MessageCommandOptionBuilder"), exports);
@@ -2,11 +2,11 @@ import { InteractionCommandBuilder, RecipleInteractionCommandExecute } from './b
2
2
  import { interactionCommandBuilders } from '../registerInteractionCommands';
3
3
  import { MessageCommandBuilder, RecipleMessageCommandExecute } from './builders/MessageCommandBuilder';
4
4
  import { Logger as ILogger } from 'fallout-utility';
5
- import { Config } from './Config';
5
+ import { Config } from './RecipleConfig';
6
6
  import { ApplicationCommandDataResolvable, Awaitable, Client, ClientEvents, ClientOptions, CommandInteraction, Interaction, Message } from 'discord.js';
7
7
  import { recipleCommandBuilders, RecipleModule, RecipleScript } from '../modules';
8
8
  export interface RecipleClientOptions extends ClientOptions {
9
- config: Config;
9
+ config?: Config;
10
10
  }
11
11
  export interface RecipleClientCommands {
12
12
  MESSAGE_COMMANDS: {
@@ -19,6 +19,7 @@ export interface RecipleClientCommands {
19
19
  export interface RecipleClientEvents extends ClientEvents {
20
20
  recipleMessageCommandCreate: [command: RecipleMessageCommandExecute];
21
21
  recipleInteractionCommandCreate: [command: RecipleInteractionCommandExecute];
22
+ recipleReplyError: [error: unknown];
22
23
  }
23
24
  export interface RecipleClient<Ready extends boolean = boolean> extends Client<Ready> {
24
25
  on<E extends keyof RecipleClientEvents>(event: E, listener: (...args: RecipleClientEvents[E]) => Awaitable<void>): this;
@@ -41,13 +42,53 @@ export declare class RecipleClient<Ready extends boolean = boolean> extends Clie
41
42
  logger: ILogger;
42
43
  version: string;
43
44
  constructor(options: RecipleClientOptions);
44
- startModules(): Promise<RecipleClient<Ready>>;
45
+ /**
46
+ * Load modules
47
+ */
48
+ startModules(folder?: string): Promise<RecipleClient<Ready>>;
49
+ /**
50
+ * Execute `onLoad()` from client modules and register interaction commands if enabled
51
+ */
45
52
  loadModules(): Promise<RecipleClient<Ready>>;
46
- addModule(script: RecipleScript, registerCommands?: boolean): Promise<void>;
53
+ /**
54
+ * Add module
55
+ */
56
+ addModule(script: RecipleScript, registerCommands?: boolean, info?: RecipleModule['info']): Promise<void>;
57
+ /**
58
+ * Add interaction or message command to client
59
+ */
47
60
  addCommand(command: recipleCommandBuilders): RecipleClient<Ready>;
61
+ /**
62
+ * Listed to command executions
63
+ */
48
64
  addCommandListeners(): RecipleClient<Ready>;
65
+ /**
66
+ * Execute a Message command
67
+ */
49
68
  messageCommandExecute(message: Message, prefix?: string): Promise<void | RecipleMessageCommandExecute>;
69
+ /**
70
+ * Execute an Interaction command
71
+ */
50
72
  interactionCommandExecute(interaction: Interaction | CommandInteraction): Promise<void | RecipleInteractionCommandExecute>;
73
+ /**
74
+ * Get a message from config
75
+ */
51
76
  getMessage<T = unknown>(messageKey: string, defaultMessage?: T): T;
77
+ /**
78
+ * Get command builder by name or alias if it's a message command
79
+ */
80
+ findCommand(command: string, type: MessageCommandBuilder["builder"]): MessageCommandBuilder | undefined;
81
+ findCommand(command: string, type: InteractionCommandBuilder["builder"]): InteractionCommandBuilder | undefined;
82
+ /**
83
+ * Returns true if client logs is enabled
84
+ */
85
+ isClientLogsEnabled(): boolean;
86
+ /**
87
+ * Emits the "recipleReplyError" event
88
+ */
89
+ private replyError;
90
+ /**
91
+ * Error message when a command fails to execute
92
+ */
52
93
  private _commandExecuteError;
53
94
  }
@@ -22,44 +22,55 @@ const isIgnoredChannel_1 = require("../isIgnoredChannel");
22
22
  const hasPermissions_1 = require("../hasPermissions");
23
23
  const version_1 = require("../version");
24
24
  const logger_1 = require("../logger");
25
+ const RecipleConfig_1 = require("./RecipleConfig");
25
26
  const discord_js_1 = require("discord.js");
26
27
  const modules_1 = require("../modules");
27
28
  const MessageCommandOptions_1 = require("./builders/MessageCommandOptions");
28
29
  class RecipleClient extends discord_js_1.Client {
29
30
  constructor(options) {
31
+ var _a, _b, _c;
30
32
  super(options);
33
+ this.config = RecipleConfig_1.RecipleConfig.getDefaultConfig();
31
34
  this.commands = { MESSAGE_COMMANDS: {}, INTERACTION_COMMANDS: {} };
32
35
  this.otherApplicationCommandData = [];
33
36
  this.modules = [];
34
37
  this.version = version_1.version;
35
- this.logger = (0, logger_1.logger)(!!options.config.fileLogging.stringifyLoggedJSON, !!options.config.fileLogging.debugmode);
38
+ 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));
36
39
  if (!options.config)
37
40
  throw new Error('Config is not defined.');
38
- this.config = options.config;
41
+ this.config = Object.assign(Object.assign({}, this.config), ((_c = options.config) !== null && _c !== void 0 ? _c : {}));
39
42
  if (this.config.fileLogging.enabled)
40
43
  this.logger.logFile(this.config.fileLogging.logFilePath, false);
41
- this.logger.info('Reciple Client v' + version_1.version + ' is starting...');
42
44
  }
43
- startModules() {
45
+ /**
46
+ * Load modules
47
+ */
48
+ startModules(folder) {
44
49
  return __awaiter(this, void 0, void 0, function* () {
45
- this.logger.info('Loading modules...');
46
- const modules = yield (0, modules_1.loadModules)(this);
50
+ if (this.isClientLogsEnabled())
51
+ this.logger.info(`Loading Modules from ${folder !== null && folder !== void 0 ? folder : this.config.modulesFolder}`);
52
+ const modules = yield (0, modules_1.loadModules)(this, folder);
47
53
  if (!modules)
48
54
  throw new Error('Failed to load modules.');
49
55
  this.modules = modules.modules;
50
56
  return this;
51
57
  });
52
58
  }
59
+ /**
60
+ * Execute `onLoad()` from client modules and register interaction commands if enabled
61
+ */
53
62
  loadModules() {
54
63
  var _a, _b;
55
64
  return __awaiter(this, void 0, void 0, function* () {
56
- for (let m in this.modules) {
65
+ for (const m in this.modules) {
57
66
  const module_ = this.modules[m];
58
67
  if (typeof ((_a = module_.script) === null || _a === void 0 ? void 0 : _a.onLoad) === 'function') {
59
68
  yield Promise.resolve(module_.script.onLoad(this)).catch(err => {
60
69
  var _a;
61
- this.logger.error(`Error loading ${(_a = module_.info.filename) !== null && _a !== void 0 ? _a : 'unknown module'}:`);
62
- this.logger.error(err);
70
+ if (this.isClientLogsEnabled()) {
71
+ this.logger.error(`Error loading ${(_a = module_.info.filename) !== null && _a !== void 0 ? _a : 'unknown module'}:`);
72
+ this.logger.error(err);
73
+ }
63
74
  this.modules = this.modules.filter((r, i) => i.toString() !== m.toString());
64
75
  });
65
76
  }
@@ -69,29 +80,31 @@ class RecipleClient extends discord_js_1.Client {
69
80
  }
70
81
  }
71
82
  }
72
- this.logger.info(`${this.modules.length} modules loaded.`);
73
- this.logger.info(`${Object.keys(this.commands.MESSAGE_COMMANDS).length} message commands loaded.`);
74
- this.logger.info(`${Object.keys(this.commands.INTERACTION_COMMANDS).length} interaction commands loaded.`);
75
- if (!this.config.commands.interactionCommand.registerCommands)
76
- return this;
77
- yield (0, registerInteractionCommands_1.registerInteractionCommands)(this, [...Object.values(this.commands.INTERACTION_COMMANDS), ...this.otherApplicationCommandData]);
83
+ if (this.isClientLogsEnabled()) {
84
+ this.logger.info(`${this.modules.length} modules loaded.`);
85
+ this.logger.info(`${Object.keys(this.commands.MESSAGE_COMMANDS).length} message commands loaded.`);
86
+ this.logger.info(`${Object.keys(this.commands.INTERACTION_COMMANDS).length} interaction commands loaded.`);
87
+ }
88
+ if (this.config.commands.interactionCommand.registerCommands) {
89
+ yield (0, registerInteractionCommands_1.registerInteractionCommands)(this, [...Object.values(this.commands.INTERACTION_COMMANDS), ...this.otherApplicationCommandData]);
90
+ }
78
91
  return this;
79
92
  });
80
93
  }
81
- addModule(script, registerCommands = true) {
94
+ /**
95
+ * Add module
96
+ */
97
+ addModule(script, registerCommands = true, info) {
82
98
  var _a;
83
99
  return __awaiter(this, void 0, void 0, function* () {
84
100
  this.modules.push({
85
101
  script,
86
- info: {
87
- filename: undefined,
88
- versions: typeof script.versions == 'string' ? [script.versions] : script.versions,
89
- path: undefined
90
- }
102
+ info: Object.assign({ filename: undefined, versions: typeof script.versions == 'string' ? [script.versions] : script.versions, path: undefined }, info)
91
103
  });
92
104
  if (typeof (script === null || script === void 0 ? void 0 : script.onLoad) === 'function')
93
105
  yield Promise.resolve(script.onLoad(this));
94
- this.logger.info(`${this.modules.length} modules loaded.`);
106
+ if (this.isClientLogsEnabled())
107
+ this.logger.info(`${this.modules.length} modules loaded.`);
95
108
  for (const command of (_a = script.commands) !== null && _a !== void 0 ? _a : []) {
96
109
  if (!command.name)
97
110
  continue;
@@ -102,6 +115,9 @@ class RecipleClient extends discord_js_1.Client {
102
115
  yield (0, registerInteractionCommands_1.registerInteractionCommands)(this, [...Object.values(this.commands.INTERACTION_COMMANDS), ...this.otherApplicationCommandData]);
103
116
  });
104
117
  }
118
+ /**
119
+ * Add interaction or message command to client
120
+ */
105
121
  addCommand(command) {
106
122
  var _a;
107
123
  if (command.builder === 'MESSAGE_COMMAND') {
@@ -110,11 +126,14 @@ class RecipleClient extends discord_js_1.Client {
110
126
  else if (command.builder === 'INTERACTION_COMMAND') {
111
127
  this.commands.INTERACTION_COMMANDS[command.name] = command;
112
128
  }
113
- else {
129
+ else if (this.isClientLogsEnabled()) {
114
130
  this.logger.error(`Unknow command "${(_a = typeof command) !== null && _a !== void 0 ? _a : 'unknown'}".`);
115
131
  }
116
132
  return this;
117
133
  }
134
+ /**
135
+ * Listed to command executions
136
+ */
118
137
  addCommandListeners() {
119
138
  if (this.config.commands.messageCommand.enabled)
120
139
  this.on('messageCreate', (message) => { this.messageCommandExecute(message); });
@@ -122,20 +141,21 @@ class RecipleClient extends discord_js_1.Client {
122
141
  this.on('interactionCreate', (interaction) => { this.interactionCommandExecute(interaction); });
123
142
  return this;
124
143
  }
144
+ /**
145
+ * Execute a Message command
146
+ */
125
147
  messageCommandExecute(message, prefix) {
126
- var _a, _b;
148
+ var _a;
127
149
  return __awaiter(this, void 0, void 0, function* () {
128
150
  if (!message.content || !this.isReady())
129
151
  return;
130
152
  const parseCommand = (0, fallout_utility_1.getCommand)(message.content, prefix || this.config.prefix || '!', this.config.commands.messageCommand.commandArgumentSeparator || ' ');
131
153
  if (!parseCommand || !(parseCommand === null || parseCommand === void 0 ? void 0 : parseCommand.command))
132
154
  return;
133
- const command = (_a = this.commands.MESSAGE_COMMANDS[parseCommand.command.toLowerCase()]) !== null && _a !== void 0 ? _a : (this.config.commands.messageCommand.allowCommandAlias
134
- ? Object.values(this.commands.MESSAGE_COMMANDS).find(c => c.aliases.some(a => { var _a; return a == ((_a = parseCommand.command) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }))
135
- : undefined);
155
+ const command = this.findCommand(parseCommand.command, 'MESSAGE_COMMAND');
136
156
  if (!command)
137
157
  return;
138
- if ((0, hasPermissions_1.hasPermissions)(command.name, (_b = message.member) === null || _b === void 0 ? void 0 : _b.permissions, this.config.permissions.messageCommands, command)) {
158
+ if ((0, hasPermissions_1.hasPermissions)(command.name, (_a = message.member) === null || _a === void 0 ? void 0 : _a.permissions, this.config.permissions.messageCommands, command)) {
139
159
  if (!command.allowExecuteInDM && message.channel.type === 'DM'
140
160
  || !command.allowExecuteByBots
141
161
  && (message.author.bot || message.author.system)
@@ -144,11 +164,11 @@ class RecipleClient extends discord_js_1.Client {
144
164
  const commandOptions = command.getCommandOptionValues(parseCommand);
145
165
  if (command.validateOptions) {
146
166
  if (commandOptions.some(o => o.invalid)) {
147
- yield message.reply(this.getMessage('invalidArguments', 'Invalid argument(s) given.')).catch(err => this.logger.debug(err));
167
+ yield message.reply(this.getMessage('invalidArguments', 'Invalid argument(s) given.')).catch(er => this.replyError(er));
148
168
  return;
149
169
  }
150
170
  if (commandOptions.some(o => o.missing)) {
151
- yield message.reply(this.getMessage('notEnoughArguments', 'Not enough arguments.')).catch(err => this.logger.debug(err));
171
+ yield message.reply(this.getMessage('notEnoughArguments', 'Not enough arguments.')).catch(er => this.replyError(er));
152
172
  return;
153
173
  }
154
174
  }
@@ -164,23 +184,23 @@ class RecipleClient extends discord_js_1.Client {
164
184
  return options;
165
185
  }
166
186
  else {
167
- yield message.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(err => this.logger.debug(err));
187
+ yield message.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this.replyError(er));
168
188
  }
169
189
  });
170
190
  }
191
+ /**
192
+ * Execute an Interaction command
193
+ */
171
194
  interactionCommandExecute(interaction) {
172
195
  var _a;
173
196
  return __awaiter(this, void 0, void 0, function* () {
174
197
  if (!interaction || !interaction.isCommand() || !this.isReady())
175
198
  return;
176
- const command = this.commands.INTERACTION_COMMANDS[interaction.commandName];
199
+ const command = this.findCommand(interaction.commandName, 'INTERACTION_COMMAND');
177
200
  if (!command)
178
201
  return;
179
202
  if ((0, hasPermissions_1.hasPermissions)(command.name, (_a = interaction.memberPermissions) !== null && _a !== void 0 ? _a : undefined, this.config.permissions.interactionCommands, command)) {
180
- // TODO: Deprecated allowEcuteInDM
181
- if (!command.allowExecuteInDM && !interaction.inCachedGuild() || (0, isIgnoredChannel_1.isIgnoredChannel)(interaction.channelId, this.config.ignoredChannels))
182
- return;
183
- if (!command)
203
+ if (!command || (0, isIgnoredChannel_1.isIgnoredChannel)(interaction.channelId, this.config.ignoredChannels))
184
204
  return;
185
205
  const options = {
186
206
  interaction: interaction,
@@ -193,29 +213,62 @@ class RecipleClient extends discord_js_1.Client {
193
213
  return options;
194
214
  }
195
215
  else {
196
- yield interaction.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(err => this.logger.debug(err));
216
+ yield interaction.reply(this.getMessage('noPermissions', 'You do not have permission to use this command.')).catch(er => this.replyError(er));
197
217
  }
198
218
  });
199
219
  }
220
+ /**
221
+ * Get a message from config
222
+ */
200
223
  getMessage(messageKey, defaultMessage) {
201
224
  var _a, _b;
202
225
  return (_b = (_a = this.config.messages[messageKey]) !== null && _a !== void 0 ? _a : defaultMessage) !== null && _b !== void 0 ? _b : messageKey;
203
226
  }
227
+ findCommand(command, type) {
228
+ var _a;
229
+ switch (type) {
230
+ case 'INTERACTION_COMMAND':
231
+ return this.commands.INTERACTION_COMMANDS[command];
232
+ case 'MESSAGE_COMMAND':
233
+ return (_a = this.commands.MESSAGE_COMMANDS[command.toLowerCase()]) !== null && _a !== void 0 ? _a : (this.config.commands.messageCommand.allowCommandAlias
234
+ ? Object.values(this.commands.MESSAGE_COMMANDS).find(c => c.aliases.some(a => a == (command === null || command === void 0 ? void 0 : command.toLowerCase())))
235
+ : undefined);
236
+ default:
237
+ throw new TypeError('Unknown command type');
238
+ }
239
+ }
240
+ /**
241
+ * Returns true if client logs is enabled
242
+ */
243
+ isClientLogsEnabled() {
244
+ return !!this.config.fileLogging.clientLogs;
245
+ }
246
+ /**
247
+ * Emits the "recipleReplyError" event
248
+ */
249
+ replyError(error) {
250
+ this.emit('recipleReplyError', error);
251
+ }
252
+ /**
253
+ * Error message when a command fails to execute
254
+ */
204
255
  _commandExecuteError(err, command) {
205
256
  return __awaiter(this, void 0, void 0, function* () {
206
- this.logger.error(`An error occured executing ${command.builder.builder == 'MESSAGE_COMMAND' ? 'message' : 'interaction'} command "${command.builder.name}"`);
207
- this.logger.error(err);
257
+ if (this.isClientLogsEnabled()) {
258
+ this.logger.error(`An error occured executing ${command.builder.builder == 'MESSAGE_COMMAND' ? 'message' : 'interaction'} command "${command.builder.name}"`);
259
+ this.logger.error(err);
260
+ }
208
261
  if (!err || !command)
209
262
  return;
210
263
  if (command === null || command === void 0 ? void 0 : command.message) {
211
264
  if (!this.config.commands.messageCommand.replyOnError)
212
265
  return;
213
- yield command.message.reply(this.getMessage('error', 'An error occurred.')).catch(e => this.logger.debug(e));
266
+ yield command.message.reply(this.getMessage('error', 'An error occurred.')).catch(er => this.replyError(er));
214
267
  }
215
268
  else if (command === null || command === void 0 ? void 0 : command.interaction) {
216
269
  if (!this.config.commands.interactionCommand.replyOnError)
217
270
  return;
218
- yield command.interaction.followUp(this.getMessage('error', 'An error occurred.')).catch(e => this.logger.debug(e));
271
+ yield command.interaction.followUp(this.getMessage('error', 'An error occurred.')).catch(er => this.replyError(er));
219
272
  }
220
273
  });
221
274
  }
@@ -39,6 +39,7 @@ export interface Config {
39
39
  fileLogging: {
40
40
  enabled: boolean;
41
41
  debugmode: boolean;
42
+ clientLogs: boolean;
42
43
  stringifyLoggedJSON: boolean;
43
44
  logFilePath: string;
44
45
  };
@@ -53,10 +54,30 @@ export interface Config {
53
54
  export declare class RecipleConfig {
54
55
  config?: Config;
55
56
  configPath: string;
57
+ static defaultConfigPath: string;
56
58
  constructor(configPath: string);
59
+ /**
60
+ * Parse the config file
61
+ */
57
62
  parseConfig(): RecipleConfig;
63
+ /**
64
+ * Returns the parsed config file
65
+ */
58
66
  getConfig(): Config;
67
+ /**
68
+ * Parse token from config
69
+ */
59
70
  parseToken(askIfNull?: boolean): string | null;
71
+ /**
72
+ * Check if the config version is supported
73
+ */
60
74
  private isSupportedConfig;
75
+ /**
76
+ * Ask for a token
77
+ */
61
78
  private askToken;
79
+ /**
80
+ * Get default config
81
+ */
82
+ static getDefaultConfig(): Config;
62
83
  }
@@ -17,10 +17,13 @@ class RecipleConfig {
17
17
  throw new Error('Config path is not defined');
18
18
  this.configPath = configPath;
19
19
  }
20
+ /**
21
+ * Parse the config file
22
+ */
20
23
  parseConfig() {
21
24
  var _a;
22
25
  if (!(0, fs_1.existsSync)(this.configPath)) {
23
- const defaultConfigPath = path_1.default.join(__dirname, '../../../resource/reciple.yml');
26
+ const defaultConfigPath = RecipleConfig.defaultConfigPath;
24
27
  if (!(0, fs_1.existsSync)(defaultConfigPath))
25
28
  throw new Error('Default Config file not found. Please reinstall Reciple.');
26
29
  const defaultConfig = (0, fallout_utility_1.replaceAll)((0, fs_1.readFileSync)(defaultConfigPath, 'utf-8'), 'VERSION', version_1.version);
@@ -42,12 +45,18 @@ class RecipleConfig {
42
45
  throw new Error('Unsupported config version. Your config version: ' + (((_a = this.config) === null || _a === void 0 ? void 0 : _a.version) || 'No version specified.') + ', Reciple version: ' + version_1.version);
43
46
  return this;
44
47
  }
48
+ /**
49
+ * Returns the parsed config file
50
+ */
45
51
  getConfig() {
46
52
  if (!this.config)
47
53
  throw new Error('Config is not parsed.');
48
54
  this.config.token = this.parseToken() || 'TOKEN';
49
55
  return this.config;
50
56
  }
57
+ /**
58
+ * Parse token from config
59
+ */
51
60
  parseToken(askIfNull = true) {
52
61
  var _a, _b;
53
62
  let token = flags_1.token || null;
@@ -64,12 +73,27 @@ class RecipleConfig {
64
73
  }
65
74
  return token || (askIfNull ? this.askToken() : null);
66
75
  }
76
+ /**
77
+ * Check if the config version is supported
78
+ */
67
79
  isSupportedConfig() {
68
80
  var _a;
69
81
  return (0, version_1.isSupportedVersion)(((_a = this.config) === null || _a === void 0 ? void 0 : _a.version) || '0.0.0', version_1.version);
70
82
  }
83
+ /**
84
+ * Ask for a token
85
+ */
71
86
  askToken() {
72
87
  return flags_1.token || (0, fallout_utility_1.input)({ 'text': 'Bot Token >>> ', echo: '*', repeatIfEmpty: true, exitStrings: ['exit', 'quit', ''], sigint: true }) || null;
73
88
  }
89
+ /**
90
+ * Get default config
91
+ */
92
+ static getDefaultConfig() {
93
+ if (!(0, fs_1.existsSync)(this.defaultConfigPath))
94
+ throw new Error("Default config file does not exists.");
95
+ return yaml_1.default.parse((0, fs_1.readFileSync)(this.defaultConfigPath, 'utf-8'));
96
+ }
74
97
  }
75
98
  exports.RecipleConfig = RecipleConfig;
99
+ RecipleConfig.defaultConfigPath = path_1.default.join(__dirname, '../../../resource/reciple.yml');
@@ -16,11 +16,6 @@ export declare class InteractionCommandBuilder extends SlashCommandBuilder {
16
16
  * Set required permissions before executing the command
17
17
  */
18
18
  setRequiredPermissions(requiredPermissions: (keyof PermissionFlags)[]): InteractionCommandBuilder;
19
- /**
20
- * Set if command can be executed in dms
21
- * @deprecated use `InteractionCommandBuilder.setDMPermission()` instead
22
- */
23
- setAllowExecuteInDM(allowExecuteInDM: boolean): InteractionCommandBuilder;
24
19
  /**
25
20
  * Function when the command is executed
26
21
  */
@@ -19,18 +19,6 @@ class InteractionCommandBuilder extends builders_1.SlashCommandBuilder {
19
19
  this.requiredPermissions = requiredPermissions;
20
20
  return this;
21
21
  }
22
- /**
23
- * Set if command can be executed in dms
24
- * @deprecated use `InteractionCommandBuilder.setDMPermission()` instead
25
- */
26
- setAllowExecuteInDM(allowExecuteInDM) {
27
- // TODO: Deprecated this
28
- if (typeof allowExecuteInDM !== 'boolean')
29
- throw new Error('allowExecuteInDM must be a boolean.');
30
- this.allowExecuteInDM = allowExecuteInDM;
31
- process.emitWarning('InteractionCommandBuilder#setAllowExecuteInDM() method is deprecated in favor of setting SlashCommandBuilder#setDMPermission()', 'Deprecation Warning');
32
- return this;
33
- }
34
22
  /**
35
23
  * Function when the command is executed
36
24
  */
@@ -1,9 +1,8 @@
1
1
  import { MessageCommandOptionBuilder } from './MessageCommandOptionBuilder';
2
2
  import { Message, PermissionFlags, PermissionString } from 'discord.js';
3
- import { Command } from 'fallout-utility';
3
+ import { Command as CommandMessage } from 'fallout-utility';
4
4
  import { RecipleClient } from '../RecipleClient';
5
5
  import { MessageCommandOptions } from './MessageCommandOptions';
6
- export declare type CommandMessage = Command;
7
6
  export interface RecipleMessageCommandExecute {
8
7
  message: Message;
9
8
  options: MessageCommandOptions;
@@ -1,2 +1,8 @@
1
+ /**
2
+ * Used flags
3
+ */
1
4
  export declare const flags: import("commander").OptionValues;
2
- export declare const token: any;
5
+ /**
6
+ * Temporary token flag
7
+ */
8
+ export declare const token: string | undefined;
@@ -2,10 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.token = exports.flags = void 0;
4
4
  const commander_1 = require("commander");
5
+ /**
6
+ * Used flags
7
+ */
5
8
  exports.flags = commander_1.program
6
9
  .option('-t, --token <token>', 'Replace used bot token')
7
10
  .option('-c, --config <config>', 'Change path to config file')
8
11
  .option('-D, --debugmode', 'Enabled debug mode')
9
12
  .option('-v, --version', 'Display version')
10
13
  .parse().opts();
14
+ /**
15
+ * Temporary token flag
16
+ */
11
17
  exports.token = exports.flags.token;
@@ -1,4 +1,7 @@
1
1
  import { Permissions } from 'discord.js';
2
2
  import { recipleCommandBuilders } from './modules';
3
- import { Config } from './classes/Config';
3
+ import { Config } from './classes/RecipleConfig';
4
+ /**
5
+ * Check if the user has permissions to execute the given command name
6
+ */
4
7
  export declare function hasPermissions(commandName: string, memberPermissions?: Permissions, configConmmandPermissions?: Config['permissions']['messageCommands'] | Config['permissions']['interactionCommands'], builder?: recipleCommandBuilders): boolean;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.hasPermissions = void 0;
4
+ /**
5
+ * Check if the user has permissions to execute the given command name
6
+ */
4
7
  function hasPermissions(commandName, memberPermissions, configConmmandPermissions, builder) {
5
8
  var _a, _b;
6
9
  if (!(configConmmandPermissions === null || configConmmandPermissions === void 0 ? void 0 : configConmmandPermissions.enabled))
@@ -1,2 +1,5 @@
1
- import { Config } from './classes/Config';
1
+ import { Config } from './classes/RecipleConfig';
2
+ /**
3
+ * Check if the channel id is ignored in config file
4
+ */
2
5
  export declare function isIgnoredChannel(channelId: string, ignoredChannelsConfig?: Config["ignoredChannels"]): boolean;
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isIgnoredChannel = void 0;
4
+ /**
5
+ * Check if the channel id is ignored in config file
6
+ */
4
7
  function isIgnoredChannel(channelId, ignoredChannelsConfig) {
5
8
  if (!(ignoredChannelsConfig === null || ignoredChannelsConfig === void 0 ? void 0 : ignoredChannelsConfig.enabled))
6
9
  return false;
@@ -1,2 +1,5 @@
1
1
  import { Logger } from 'fallout-utility';
2
- export declare function logger(stringifyJSON: boolean, debugmode?: boolean): Logger;
2
+ /**
3
+ * Create new logger
4
+ */
5
+ export declare function logger(stringifyJSON: boolean, debugmode?: boolean, colorizeMessage?: boolean): Logger;
@@ -1,13 +1,33 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.logger = void 0;
4
7
  const fallout_utility_1 = require("fallout-utility");
5
8
  const flags_1 = require("./flags");
6
- function logger(stringifyJSON, debugmode = false) {
7
- return new fallout_utility_1.Logger("Main", {
8
- addPrefixToEveryJsonNewLines: stringifyJSON,
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ /**
11
+ * Create new logger
12
+ */
13
+ function logger(stringifyJSON, debugmode = false, colorizeMessage = true) {
14
+ var _a;
15
+ return new fallout_utility_1.Logger({
9
16
  stringifyJSON: stringifyJSON,
10
- setDebugging: flags_1.flags.debugmode || debugmode
17
+ enableDebugMode: (_a = flags_1.flags.debugmode) !== null && _a !== void 0 ? _a : debugmode,
18
+ loggerName: 'Main',
19
+ prefixes: {
20
+ [fallout_utility_1.LogLevels.INFO]: (name) => `[${chalk_1.default.bold("INFO" + (name ? chalk_1.default.dim(" - ") + name : ''))}]`,
21
+ [fallout_utility_1.LogLevels.WARN]: (name) => `[${chalk_1.default.bold.yellow("WARN" + (name ? chalk_1.default.dim(" - ") + name : ''))}]`,
22
+ [fallout_utility_1.LogLevels.ERROR]: (name) => `[${chalk_1.default.bold.red("ERROR" + (name ? chalk_1.default.dim(" - ") + name : ''))}]`,
23
+ [fallout_utility_1.LogLevels.DEBUG]: (name) => `[${chalk_1.default.bold.blue("DEBUG" + (name ? chalk_1.default.dim(" - ") + name : ''))}]`
24
+ },
25
+ colorMessages: {
26
+ [fallout_utility_1.LogLevels.INFO]: (message) => message,
27
+ [fallout_utility_1.LogLevels.WARN]: (message) => !colorizeMessage ? message : chalk_1.default.yellow(message),
28
+ [fallout_utility_1.LogLevels.ERROR]: (message) => !colorizeMessage ? message : chalk_1.default.red(message),
29
+ [fallout_utility_1.LogLevels.DEBUG]: (message) => !colorizeMessage ? message : chalk_1.default.blue(message)
30
+ }
11
31
  });
12
32
  }
13
33
  exports.logger = logger;
@@ -21,4 +21,7 @@ export interface RecipleModule {
21
21
  path?: string;
22
22
  };
23
23
  }
24
- export declare function loadModules(client: RecipleClient): Promise<loadedModules>;
24
+ /**
25
+ * Load modules from folder
26
+ */
27
+ export declare function loadModules(client: RecipleClient, folder?: string): Promise<loadedModules>;
@@ -17,12 +17,14 @@ const fs_1 = require("fs");
17
17
  const version_1 = require("./version");
18
18
  const wildcard_match_1 = __importDefault(require("wildcard-match"));
19
19
  const path_1 = __importDefault(require("path"));
20
- function loadModules(client) {
20
+ /**
21
+ * Load modules from folder
22
+ */
23
+ function loadModules(client, folder) {
21
24
  var _a, _b;
22
25
  return __awaiter(this, void 0, void 0, function* () {
23
26
  const response = { commands: [], modules: [] };
24
- const modulesDir = client.config.modulesFolder || './modules';
25
- const logger = client.logger;
27
+ const modulesDir = client.config.modulesFolder || folder || './modules';
26
28
  if (!(0, fs_1.existsSync)(modulesDir))
27
29
  (0, fs_1.mkdirSync)(modulesDir, { recursive: true });
28
30
  const ignoredFiles = (client.config.ignoredFiles || []).map(file => file.endsWith('.js') ? file : `${file}.js`);
@@ -51,17 +53,21 @@ function loadModules(client) {
51
53
  }
52
54
  }
53
55
  catch (error) {
54
- logger.error(`Failed to load module ${script}`);
55
- logger.error(error);
56
+ if (client.isClientLogsEnabled()) {
57
+ client.logger.error(`Failed to load module ${script}`);
58
+ client.logger.error(error);
59
+ }
56
60
  continue;
57
61
  }
58
62
  response.commands.push(...commands.filter((c) => {
59
63
  if (!c.name) {
60
- logger.error(`A ${c.builder} command name is not defined in ${script}`);
64
+ if (client.isClientLogsEnabled())
65
+ client.logger.error(`A ${c.builder} command name is not defined in ${script}`);
61
66
  return false;
62
67
  }
63
68
  if (c.builder === 'MESSAGE_COMMAND' && c.options.length && c.options.some(o => !o.name)) {
64
- logger.error(`A ${c.builder} option name is not defined in ${script}`);
69
+ if (client.isClientLogsEnabled())
70
+ client.logger.error(`A ${c.builder} option name is not defined in ${script}`);
65
71
  return false;
66
72
  }
67
73
  return true;
@@ -74,7 +80,8 @@ function loadModules(client) {
74
80
  path: modulePath
75
81
  }
76
82
  });
77
- logger.info(`Loaded module ${script}`);
83
+ if (client.isClientLogsEnabled())
84
+ client.logger.info(`Loaded module ${script}`);
78
85
  }
79
86
  return response;
80
87
  });
@@ -3,4 +3,7 @@ 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
5
  export declare type interactionCommandBuilders = InteractionCommandBuilder | ContextMenuCommandBuilder | SlashCommandBuilder | SlashCommandSubcommandBuilder | SlashCommandOptionsOnlyBuilder | SlashCommandSubcommandGroupBuilder | SlashCommandSubcommandsOnlyBuilder;
6
+ /**
7
+ * Register interaction commands
8
+ */
6
9
  export declare function registerInteractionCommands(client: RecipleClient, cmds?: (interactionCommandBuilders | ApplicationCommandDataResolvable)[], overwriteGuilds?: string | string[]): Promise<void>;
@@ -10,6 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.registerInteractionCommands = void 0;
13
+ /**
14
+ * Register interaction commands
15
+ */
13
16
  function registerInteractionCommands(client, cmds, overwriteGuilds) {
14
17
  var _a, _b, _c;
15
18
  return __awaiter(this, void 0, void 0, function* () {
@@ -24,7 +27,8 @@ function registerInteractionCommands(client, cmds, overwriteGuilds) {
24
27
  undefined)) !== null && _d !== void 0 ? _d : cmd.requiredPermissions;
25
28
  cmd.setRequiredPermissions(permissions);
26
29
  client.commands.INTERACTION_COMMANDS[cmd.name] = cmd;
27
- client.logger.debug(`Set required permissions for ${cmd.name}`);
30
+ if (client.isClientLogsEnabled())
31
+ client.logger.debug(`Set required permissions for ${cmd.name}`);
28
32
  return cmd.toJSON();
29
33
  }
30
34
  return c.toJSON();
@@ -33,17 +37,20 @@ function registerInteractionCommands(client, cmds, overwriteGuilds) {
33
37
  const guilds = typeof configGuilds === 'object' ? configGuilds : [configGuilds];
34
38
  if (!guilds || !(guilds === null || guilds === void 0 ? void 0 : guilds.length)) {
35
39
  (_b = client.application) === null || _b === void 0 ? void 0 : _b.commands.set(commands).then(() => {
36
- client.logger.warn('No guilds were specified for interaction commands. Registered commands for all guilds.');
37
- }).catch(e => client.logger.error(e));
40
+ if (client.isClientLogsEnabled())
41
+ client.logger.warn('No guilds were specified for interaction commands. Registered interaction commands globally.');
42
+ });
38
43
  }
39
44
  else {
40
- client.logger.warn(`Registering ${commands.length} interaction commands to ${guilds.length} guild(s).`);
45
+ if (client.isClientLogsEnabled())
46
+ client.logger.warn(`Registering ${commands.length} interaction commands to ${guilds.length} guild(s).`);
41
47
  for (const guild of guilds) {
42
48
  if (!guild)
43
49
  continue;
44
50
  (_c = client.application) === null || _c === void 0 ? void 0 : _c.commands.set(commands, guild).then(() => {
45
- client.logger.warn(`Registered ${commands.length} interaction command(s) for ${guild}.`);
46
- }).catch(e => client.logger.error(e));
51
+ if (client.isClientLogsEnabled())
52
+ client.logger.warn(`Registered ${commands.length} interaction command(s) for ${guild}.`);
53
+ });
47
54
  }
48
55
  }
49
56
  });
@@ -1,8 +1,20 @@
1
+ /**
2
+ * Current reciple version
3
+ */
1
4
  export declare const version: string;
5
+ /**
6
+ * Check if the version is valid
7
+ */
2
8
  export declare function isValidVersion(ver: string): boolean;
9
+ /**
10
+ * Parse the version string
11
+ */
3
12
  export declare function parseVersion(ver: string): {
4
13
  major: number;
5
14
  minor: number;
6
15
  patch: number;
7
16
  };
17
+ /**
18
+ * Check if the given version is supported by the given version range
19
+ */
8
20
  export declare function isSupportedVersion(versionRange: string, supportedVersion?: string): boolean;
@@ -5,11 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isSupportedVersion = exports.parseVersion = exports.isValidVersion = exports.version = void 0;
7
7
  const semver_1 = __importDefault(require("semver"));
8
+ /**
9
+ * Current reciple version
10
+ */
8
11
  exports.version = require('../../package.json').version;
12
+ /**
13
+ * Check if the version is valid
14
+ */
9
15
  function isValidVersion(ver) {
10
16
  return semver_1.default.valid(semver_1.default.coerce(ver)) !== null;
11
17
  }
12
18
  exports.isValidVersion = isValidVersion;
19
+ /**
20
+ * Parse the version string
21
+ */
13
22
  function parseVersion(ver) {
14
23
  var _a, _b;
15
24
  if (!isValidVersion(ver))
@@ -18,6 +27,9 @@ function parseVersion(ver) {
18
27
  return { major: parseInt(major), minor: parseInt(minor), patch: parseInt(patch) };
19
28
  }
20
29
  exports.parseVersion = parseVersion;
30
+ /**
31
+ * Check if the given version is supported by the given version range
32
+ */
21
33
  function isSupportedVersion(versionRange, supportedVersion) {
22
34
  supportedVersion = supportedVersion || exports.version;
23
35
  if (!isValidVersion(versionRange))
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "reciple",
3
- "version": "1.6.2",
3
+ "version": "1.7.1",
4
4
  "description": "A Discord.js bot",
5
5
  "author": "FalloutStudios",
6
+ "homepage": "https://falloutstudios.github.io/Reciple",
6
7
  "license": "GPL-3.0",
7
8
  "main": "bin/index.js",
8
9
  "bin": {
@@ -20,23 +21,30 @@
20
21
  ],
21
22
  "scripts": {
22
23
  "clean": "rm -rf bin",
23
- "build": "yarn clean && npx tsc && npm un reciple -g && npm i ./ -g",
24
+ "build": "yarn clean && npx tsc && npm un reciple -g && npm i ./ -g && yarn build:docs",
24
25
  "build:publish": "yarn run build && yarn publish",
25
26
  "test": "yarn run build && yarn test:start",
26
- "test:start": "cd test && npx reciple"
27
+ "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"
27
31
  },
28
32
  "dependencies": {
33
+ "chalk": "4.1.2",
29
34
  "commander": "^9.3.0",
30
- "discord.js": "^13.8.1",
31
35
  "dotenv": "^16.0.1",
32
- "fallout-utility": "^1.3.14",
36
+ "fallout-utility": "^1.4.2",
33
37
  "semver": "^7.3.7",
34
38
  "wildcard-match": "^5.1.2",
35
39
  "yaml": "^2.1.1"
36
40
  },
37
41
  "devDependencies": {
38
- "@types/node": "^18.0.0",
42
+ "@types/node": "^18.0.3",
39
43
  "@types/semver": "^7.3.10",
44
+ "discord.js": "^13.8.1",
40
45
  "typescript": "^4.7.4"
46
+ },
47
+ "peerDependencies": {
48
+ "discord.js": "13.8.x"
41
49
  }
42
50
  }
@@ -62,6 +62,8 @@ fileLogging:
62
62
  enabled: true
63
63
  # enable debug mode
64
64
  debugmode: false
65
+ # enable if reciple will use the logger
66
+ clientLogs: true
65
67
  # stringify logged JSONs
66
68
  stringifyLoggedJSON: false
67
69
  # log file path