xernerx 4.1.0 → 4.2.0

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.
@@ -1,12 +1,12 @@
1
1
  import { Client, ClientOptions, Collection } from 'discord.js';
2
2
  import { XernerxOptions, ModuleOptions, XernerxCommands, XernerxCache } from '../types/interfaces.js';
3
3
  import ClientUtil from '../utils/ClientUtil.js';
4
- import { InhibitorBuilder } from '../main.js';
4
+ import { InhibitorBuilder, EventBuilder } from '../main.js';
5
5
  export default class XernerxClient extends Client {
6
6
  readonly settings: {
7
7
  ownerId: (string | string[]) & (string | string[] | undefined);
8
- local: string;
9
8
  global: boolean;
9
+ local?: string | undefined;
10
10
  permissions?:
11
11
  | {
12
12
  client: string[];
@@ -27,6 +27,7 @@ export default class XernerxClient extends Client {
27
27
  ready: boolean;
28
28
  error: boolean;
29
29
  info: boolean;
30
+ table: string[] | null;
30
31
  }
31
32
  | undefined;
32
33
  cooldown?:
@@ -38,7 +39,7 @@ export default class XernerxClient extends Client {
38
39
  };
39
40
  readonly config: unknown;
40
41
  readonly commands: XernerxCommands;
41
- readonly events: Collection<unknown, unknown>;
42
+ readonly events: Collection<string, EventBuilder>;
42
43
  readonly inhibitors: Collection<string, InhibitorBuilder>;
43
44
  readonly modules: ModuleOptions;
44
45
  readonly util: ClientUtil;
@@ -49,6 +50,6 @@ export default class XernerxClient extends Client {
49
50
  shardCount: number;
50
51
  };
51
52
  readonly cache: XernerxCache;
52
- constructor(discordOptions: ClientOptions, xernerxOptions: XernerxOptions, config: unknown);
53
+ constructor(discordOptions: ClientOptions, xernerxOptions: XernerxOptions, config?: unknown);
53
54
  connect(token: string): void;
54
55
  }
@@ -8,20 +8,11 @@ import XernerxLog from '../tools/XernerxLog.js';
8
8
  import ClientUtil from '../utils/ClientUtil.js';
9
9
  import ExtensionHandler from '../handlers/ExtensionHandler.js';
10
10
  export default class XernerxClient extends Client {
11
- settings;
12
- config;
13
- commands;
14
- events;
15
- inhibitors;
16
- modules;
17
- util;
18
- stats;
19
- cache;
20
11
  constructor(discordOptions, xernerxOptions, config) {
21
12
  super(discordOptions);
22
13
  this.settings = z
23
14
  .object({
24
- local: z.string(),
15
+ local: z.string().optional(),
25
16
  global: z.boolean().default(false),
26
17
  ownerId: z.string().or(z.array(z.string())).default([]),
27
18
  permissions: z
@@ -44,6 +35,7 @@ export default class XernerxClient extends Client {
44
35
  ready: z.boolean().default(false),
45
36
  info: z.boolean().default(false),
46
37
  error: z.boolean().default(false),
38
+ table: z.array(z.string()).or(z.null()).default(null),
47
39
  })
48
40
  .optional(),
49
41
  cooldown: z
@@ -1,33 +1,33 @@
1
1
  import { GatewayVersion, REST, Routes } from 'discord.js';
2
2
  import XernerxLog from '../tools/XernerxLog.js';
3
- const commands = { slash: [], context: [], retries: 0 };
3
+ import XernerxError from '../tools/XernerxError.js';
4
+ const commands = { slash: [], context: [] };
4
5
  export default function deploy(client, type) {
5
6
  client.prependOnceListener('ready', (client) => {
6
7
  commands[type] = client.commands[type].map((command) => command.data.toJSON());
7
- if (commands.retries % 2) {
8
- try {
9
- if (client.settings.global) {
10
- put(client, client.settings.global, [...commands.slash, ...commands.context]);
11
- put(client, !client.settings.global, []);
12
- } else {
13
- put(client, !client.settings.global, [...commands.slash, ...commands.context]);
14
- put(client, client.settings.global, []);
15
- }
16
- } catch (error) {
17
- new XernerxLog(client).error(`An error occurred while deploying the interaction commands!`, error);
18
- } finally {
19
- new XernerxLog(client).info(
20
- `Deployed ${[client.commands.message.size, client.commands.slash.size, client.commands.context.size].reduce((a, b) => (a += b))} Commands ${
21
- client.settings.global ? 'globally' : 'locally'
22
- }.`
23
- );
8
+ if (!(!!client.modules.options.slash && !!client.modules.options.context && commands.slash.length > 0 && commands.context.length > 0)) return;
9
+ try {
10
+ if (client.settings.global) {
11
+ put(client, client.settings.global, [...commands.slash, ...commands.context]);
12
+ put(client, !client.settings.global, []);
13
+ } else {
14
+ put(client, !client.settings.global, [...commands.slash, ...commands.context]);
15
+ put(client, client.settings.global, []);
24
16
  }
17
+ } catch (error) {
18
+ new XernerxLog(client).error(`An error occurred while deploying the interaction commands!`, error);
19
+ } finally {
20
+ new XernerxLog(client).info(
21
+ `Deployed ${[client.commands.message.size, client.commands.slash.size, client.commands.context.size].reduce((a, b) => (a += b))} Commands ${
22
+ client.settings.global ? 'globally' : 'locally'
23
+ }.`
24
+ );
25
25
  }
26
- commands.retries++;
27
26
  });
28
27
  }
29
28
  function put(client, global, body) {
30
29
  const rest = new REST({ version: GatewayVersion }).setToken(client.token);
31
- if (!global) rest.put(Routes.applicationGuildCommands(client.user?.id, client.settings.local), { body });
30
+ if (!global && !client.settings?.local) throw new XernerxError(`No guild ID provided as local guild!`);
31
+ if (!global && client.settings?.local) rest.put(Routes.applicationGuildCommands(client.user?.id, client.settings.local), { body });
32
32
  else rest.put(Routes.applicationCommands(client.user?.id), { body });
33
33
  }
@@ -63,6 +63,7 @@ export default class CommandHandler extends Handler {
63
63
  // return reload(this.client, 'message');
64
64
  // }
65
65
  loadSlashCommands(options) {
66
+ if (!this.client.settings.local) new XernerxLog(this.client).warn(`Slash commands might not work as you haven't specified a local guild ID.`);
66
67
  options = z
67
68
  .object({
68
69
  directory: z.string(),
@@ -99,6 +100,7 @@ export default class CommandHandler extends Handler {
99
100
  });
100
101
  }
101
102
  loadContextCommands(options) {
103
+ if (!this.client.settings.local) new XernerxLog(this.client).warn(`Context commands might not work as you haven't specified a local guild ID.`);
102
104
  options = z
103
105
  .object({
104
106
  directory: z.string(),
@@ -135,6 +137,7 @@ export default class CommandHandler extends Handler {
135
137
  });
136
138
  }
137
139
  async messageCommandRun(message, message2) {
140
+ const filetype = 'MessageCommand';
138
141
  if (message.author.bot) return;
139
142
  message.util = new MessageUtil(this.client, message);
140
143
  message.user = await xernerxUser(message, this.client);
@@ -153,9 +156,10 @@ export default class CommandHandler extends Handler {
153
156
  if (message.content && this.client.modules.options.message) {
154
157
  const commands = this.client.commands.message;
155
158
  const prefixes = Array.isArray(this.client.modules.options.message.prefix) ? this.client.modules.options.message.prefix : [this.client.modules.options.message.prefix];
156
- let commandName,
159
+ let commandName = null,
157
160
  cmd,
158
- alias = null;
161
+ commandAlias = null,
162
+ commandPrefix = null;
159
163
  commands.map((command) => {
160
164
  let prefix = null;
161
165
  if (command.regex && message.content.match(command.regex)) {
@@ -179,24 +183,30 @@ export default class CommandHandler extends Handler {
179
183
  ?.trim()
180
184
  ?.toLowerCase() || '';
181
185
  if (!this.client.commands.message.has(commandName) && command.aliases?.includes(commandName)) {
182
- alias = commandName;
186
+ commandAlias = commandName;
183
187
  commandName = command.name;
184
188
  }
189
+ commandAlias = commandAlias ? commandAlias : commandName;
190
+ commandPrefix = prefix;
185
191
  });
186
192
  if (!cmd && this.client.modules.options.message.allowMention) {
187
193
  if (message.mentions.users.has(this.client.user?.id) || message.mentions.repliedUser?.id === this.client.user?.id) {
188
- commandName = message.content.replace(`<@${this.client.user?.id}>`, '').trim().split(/ +/).shift()?.toLowerCase();
194
+ commandName = message.content.replace(`<@${this.client.user?.id}>`, '').trim().split(/ +/).shift()?.toLowerCase() || null;
189
195
  }
190
196
  }
191
- if (!commandName) commandName = '';
192
197
  if (this.client.commands.message.has(commandName)) cmd = this.client.commands.message.get(commandName);
193
198
  if (await inhibitorValidation(message, cmd)) return;
194
- if (!cmd) return this.client.emit('commandNotFound');
195
- message.util.alias = alias === commandName ? null : alias;
196
- this.exec(cmd, message, await messageArguments(message, cmd), 'MessageCommand');
199
+ if (!cmd) return this.client.emit('commandNotFound', message, filetype);
200
+ message.util.parsed = {
201
+ alias: commandAlias,
202
+ prefix: commandPrefix,
203
+ };
204
+ this.client.emit('commandStart', message, filetype);
205
+ this.exec(cmd, message, await messageArguments(message, cmd), filetype);
197
206
  }
198
207
  }
199
208
  async slashCommandRun(interaction) {
209
+ const filetype = 'SlashCommand';
200
210
  interaction.util = new InteractionUtil(this.client, interaction);
201
211
  interaction.user = await xernerxUser(interaction, this.client);
202
212
  let cmd = null;
@@ -210,24 +220,29 @@ export default class CommandHandler extends Handler {
210
220
  await cmd.autocomplete(interaction, focused, options);
211
221
  } else resolve(true);
212
222
  })
213
- .then(async () => await this.exec(cmd, interaction, await interactionArguments(interaction, cmd), 'SlashCommand'))
214
- .catch((error) => this.client.emit('commandError', interaction, error, cmd.filetype));
223
+ .then(async () => {
224
+ this.client.emit('commandStart', interaction, filetype);
225
+ await this.exec(cmd, interaction, await interactionArguments(interaction, cmd), filetype);
226
+ })
227
+ .catch((error) => this.client.emit('commandError', interaction, error, filetype));
215
228
  }
216
229
  async contextCommandRun(interaction) {
230
+ const filetype = 'ContextCommand';
217
231
  interaction.util = new InteractionUtil(this.client, interaction);
218
232
  interaction.user = await xernerxUser(interaction, this.client);
219
233
  let cmd;
220
234
  if (this.client.commands.context.has(interaction.commandName)) cmd = this.client.commands.context.get(interaction.commandName);
221
235
  if (await inhibitorValidation(interaction, cmd)) return;
222
- if (!cmd) return this.client.emit('commandNotFound', interaction);
223
- this.exec(cmd, interaction, await interactionArguments(interaction, cmd), 'ContextCommand');
236
+ if (!cmd) return this.client.emit('commandNotFound', interaction, filetype);
237
+ this.client.emit('commandStart', interaction, filetype);
238
+ this.exec(cmd, interaction, await interactionArguments(interaction, cmd), filetype);
224
239
  }
225
240
  async exec(cmd, event, args, type) {
226
241
  try {
227
242
  if (await commandValidation(event, cmd)) return;
228
243
  if (cmd.conditions && (await cmd.conditions(event, args))) return;
229
244
  cmd.exec(event, args);
230
- this.client.emit('commandExecute', event, type);
245
+ this.client.emit('commandFinish', event, type);
231
246
  } catch (error) {
232
247
  new XernerxLog(this.client).error(`An error occurred executing ${cmd.name}`, error);
233
248
  this.client.emit('commandError', event, error, type);
package/dist/main.d.ts CHANGED
@@ -10,5 +10,5 @@ export * from 'discord.js';
10
10
  export * from 'dumfunctions';
11
11
  import ExtensionBuilder from 'xernerx-extension-builder';
12
12
  import Discord from 'discord.js';
13
- declare const version = '4.1.0';
13
+ declare const version = '4.2.0';
14
14
  export { XernerxClient, MessageCommandBuilder, SlashCommandBuilder, ContextCommandBuilder, EventBuilder, InhibitorBuilder, ExtensionBuilder, Discord, version, XernerxLog };
package/dist/main.js CHANGED
@@ -10,5 +10,5 @@ export * from 'discord.js';
10
10
  export * from 'dumfunctions';
11
11
  import ExtensionBuilder from 'xernerx-extension-builder';
12
12
  import Discord from 'discord.js';
13
- const version = '4.1.0';
13
+ const version = '4.2.0';
14
14
  export { XernerxClient, MessageCommandBuilder, SlashCommandBuilder, ContextCommandBuilder, EventBuilder, InhibitorBuilder, ExtensionBuilder, Discord, version, XernerxLog };
@@ -5,6 +5,7 @@ export default class XernerxLog {
5
5
  private readonly errorLog;
6
6
  private readonly infoLog;
7
7
  private readonly readyLog;
8
+ private readonly tableLog;
8
9
  constructor(client: XernerxClient);
9
10
  info(message: string, force?: boolean): void | null;
10
11
  warn(message: string): void | null;
@@ -1,14 +1,11 @@
1
1
  import { Style } from 'dumfunctions';
2
2
  export default class XernerxLog {
3
- client;
4
- errorLog;
5
- infoLog;
6
- readyLog;
7
3
  constructor(client) {
8
4
  this.client = client;
9
5
  this.errorLog = client.settings.log?.error;
10
6
  this.infoLog = client.settings.log?.info;
11
7
  this.readyLog = client.settings.log?.ready;
8
+ this.tableLog = client.settings.log?.table;
12
9
  }
13
10
  info(message, force = false) {
14
11
  return this.infoLog || force ? console.info(`${Style.log('✔️ | Xernerx', { color: Style.TextColor.Purple })} | ${message}`) : null;
@@ -20,11 +17,32 @@ export default class XernerxLog {
20
17
  return this.errorLog ? console.error(`${Style.log('❗ | Xernerx', { color: Style.TextColor.Red })} | ${message}${error ? ` | ${error.stack}` : ''}`) : null;
21
18
  }
22
19
  ready() {
23
- this.client.prependOnceListener('ready', async (synced) =>
20
+ this.client.prependOnceListener('ready', async (synced) => {
24
21
  this.info(
25
- `${synced.user.tag} is now online, watching ${(await this.client.guilds.fetch()).size} guilds, using ${await this.client.guilds.fetch(this.client.settings.local)} as local guild.`,
22
+ `${synced.user.tag} is now online, watching ${(await this.client.guilds.fetch()).size} guilds, using ${
23
+ this.client.settings.local ? await this.client.guilds.fetch(this.client.settings.local) : 'none'
24
+ } as local guild.`,
26
25
  this.readyLog
27
- )
28
- );
26
+ );
27
+ const files = [];
28
+ for (const [id, data] of this.client.commands.message) {
29
+ files.push(data);
30
+ }
31
+ for (const [id, data] of this.client.commands.slash) {
32
+ files.push(data);
33
+ }
34
+ for (const [id, data] of this.client.commands.context) {
35
+ files.push(data);
36
+ }
37
+ for (const [id, data] of this.client.events) {
38
+ files.push(data);
39
+ }
40
+ for (const [id, data] of this.client.inhibitors) {
41
+ files.push(data);
42
+ }
43
+ if (this.tableLog) {
44
+ console.table(files, this.tableLog);
45
+ }
46
+ });
29
47
  }
30
48
  }
@@ -11,13 +11,18 @@ export interface XernerxMember extends GuildMember {
11
11
  export interface XernerxGuild extends Guild {}
12
12
  export interface XernerxGuildChannel extends GuildChannel {}
13
13
  export interface XernerxDMChannel extends DMChannel {}
14
- interface XernerxCommand {
15
- util: InteractionUtil | MessageUtil;
16
- }
14
+ interface XernerxCommand {}
17
15
  export interface XernerxMessage extends Message, XernerxCommand {
18
16
  user: XernerxUser;
17
+ util: MessageUtil;
18
+ }
19
+ export interface XernerxSlashInteraction extends ChatInputCommandInteraction, XernerxCommand {
20
+ util: InteractionUtil;
21
+ }
22
+ export interface XernerxUserContextInteraction extends UserContextMenuCommandInteraction, XernerxCommand {
23
+ util: InteractionUtil;
24
+ }
25
+ export interface XernerxMessageContextInteraction extends MessageContextMenuCommandInteraction, XernerxCommand {
26
+ util: InteractionUtil;
19
27
  }
20
- export interface XernerxSlashInteraction extends ChatInputCommandInteraction, XernerxCommand {}
21
- export interface XernerxUserContextInteraction extends UserContextMenuCommandInteraction, XernerxCommand {}
22
- export interface XernerxMessageContextInteraction extends MessageContextMenuCommandInteraction, XernerxCommand {}
23
28
  export {};
@@ -9,25 +9,29 @@ import SlashCommandBuilder from '../build/SlashCommandBuilder.js';
9
9
  import { Locales, MessageCommandArgumentType, PermissionNames, SlashCommandArgumentType, EventType, InhibitorType } from './types.js';
10
10
  import ExtensionHandler from '../handlers/ExtensionHandler.js';
11
11
  export interface XernerxOptions {
12
- ownerId: string;
13
- permissions: {
14
- client: Array<string>;
15
- user: Array<string>;
16
- dm: boolean;
17
- };
18
- ignore: {
19
- owner: boolean;
20
- users: Array<string>;
21
- channels: Array<string>;
22
- guilds: Array<string>;
23
- };
24
- log: {
25
- ready: boolean;
26
- error: boolean;
27
- };
28
- cooldown: {
29
- command: number;
30
- cache: number;
12
+ local?: string;
13
+ global?: boolean;
14
+ ownerId?: string | Array<string>;
15
+ permissions?: {
16
+ client?: Array<string>;
17
+ user?: Array<string>;
18
+ dm?: boolean;
19
+ };
20
+ ignore?: {
21
+ owner?: boolean;
22
+ users?: Array<string>;
23
+ channels?: Array<string>;
24
+ guilds?: Array<string>;
25
+ };
26
+ log?: {
27
+ ready?: boolean;
28
+ info?: boolean;
29
+ error?: boolean;
30
+ table?: Array<'name' | 'aliases' | 'description' | 'fileType' | 'category'>;
31
+ };
32
+ cooldown?: {
33
+ command?: number;
34
+ cache?: number;
31
35
  };
32
36
  }
33
37
  export interface ModuleOptions {
@@ -1,8 +1,9 @@
1
- import XernerxClient from '../main.js';
1
+ import XernerxClient from '../client/XernerxClient.js';
2
2
  import { PresenceOptions } from '../types/interfaces.js';
3
3
  import Util from './Util.js';
4
4
  export default class ClientUtil extends Util {
5
5
  hasVoted?: Function;
6
6
  constructor(client: XernerxClient);
7
7
  setPresence(options: PresenceOptions): import('discord.js').ClientPresence | undefined;
8
+ resolveChannel(query: string | Record<string, string>): Promise<import('discord.js').Channel | null>;
8
9
  }
@@ -1,11 +1,20 @@
1
1
  import setPresence from '../functions/setPresence.js';
2
2
  import Util from './Util.js';
3
3
  export default class ClientUtil extends Util {
4
- hasVoted;
5
4
  constructor(client) {
6
5
  super(client);
7
6
  }
8
7
  setPresence(options) {
9
8
  return setPresence(this.client, options);
10
9
  }
10
+ async resolveChannel(query) {
11
+ if (typeof query == 'object') query = query.id;
12
+ try {
13
+ let channel = this.client.channels.cache.find((channel) => (channel.name == query.toLowerCase() || channel.id == query.toLowerCase() ? channel : null)) || null;
14
+ if (!channel) channel = (await this.client.channels.fetch(query)) || null;
15
+ return channel;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
11
20
  }
@@ -4,7 +4,10 @@ import { XernerxMessage } from '../types/extenders.js';
4
4
  import Util from './Util.js';
5
5
  export default class MessageUtil extends Util {
6
6
  private readonly message;
7
- alias: string | null;
7
+ parsed: {
8
+ alias: null | string;
9
+ prefix: null | string;
10
+ };
8
11
  constructor(client: XernerxClient, message: XernerxMessage);
9
12
  reply(content: MessagePayload): Promise<import('discord.js').Message<boolean> | undefined>;
10
13
  webhookReply(content: MessagePayload, url?: URL, user?: User): Promise<void>;
@@ -5,11 +5,13 @@ import sendWebhook from '../functions/sendWebhook.js';
5
5
  import XernerxError from '../tools/XernerxError.js';
6
6
  export default class MessageUtil extends Util {
7
7
  message;
8
- alias;
9
8
  constructor(client, message) {
10
9
  super(client);
11
10
  this.message = message;
12
- this.alias = null;
11
+ this.parsed = {
12
+ alias: null,
13
+ prefix: null,
14
+ };
13
15
  }
14
16
  async reply(content) {
15
17
  if (this.client.cache.messages.has(this.message.id)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xernerx",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "A bot framework for discord.js.",
5
5
  "main": "dist/main.js",
6
6
  "type": "module",