xernerx 0.1.120-beta.2 → 0.1.120-beta.21

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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/main.cjs +1269 -266
  4. package/dist/main.cjs.map +1 -1
  5. package/dist/main.d.cts +651 -116
  6. package/dist/main.d.ts +651 -116
  7. package/dist/main.js +1257 -247
  8. package/dist/main.js.map +1 -1
  9. package/package.json +31 -18
  10. package/src/build/XernerxBaseBuilder.ts +21 -0
  11. package/src/build/XernerxEventBuilder.ts +39 -0
  12. package/src/build/XernerxMessageCommandBuilder.ts +60 -0
  13. package/src/build/XernerxSlashCommandBuilder.ts +290 -0
  14. package/src/client/XernerxClient.ts +173 -151
  15. package/src/client/XernerxShardClient.ts +89 -0
  16. package/src/events/clientReady.ts +96 -0
  17. package/src/events/entitlementCreate.ts +15 -0
  18. package/src/events/interactionCreate.ts +36 -0
  19. package/src/events/messageCreate.ts +60 -0
  20. package/src/events/messageDelete.ts +41 -0
  21. package/src/events/messageUpdate.ts +60 -0
  22. package/src/events/slashCommandInteraction.ts +55 -0
  23. package/src/handler/CommandHandler.ts +132 -0
  24. package/src/handler/EventHandler.ts +45 -0
  25. package/src/handler/Handler.ts +98 -0
  26. package/src/interfaces/XernerxClientOptions.ts +13 -0
  27. package/src/interfaces/XernerxClientStats.ts +15 -0
  28. package/src/interfaces/XernerxEventBuilderOptions.ts +9 -0
  29. package/src/interfaces/XernerxMessageCommandBuilderOptions.ts +8 -0
  30. package/src/interfaces/XernerxMessageCommandHandlerOptions.ts +15 -0
  31. package/src/interfaces/XernerxShardClientOptions.ts +5 -0
  32. package/src/interfaces/XernerxSlashCommand.ts +19 -0
  33. package/src/interfaces/XernerxSlashCommandBuilderOptions.ts +70 -0
  34. package/src/interfaces/XernerxSlashCommandHandlerOptions.ts +5 -0
  35. package/src/main.ts +21 -7
  36. package/src/model/XernerxGuild.ts +13 -0
  37. package/src/model/XernerxInteractionArguments.ts +92 -0
  38. package/src/model/XernerxMonitisation.ts +73 -0
  39. package/src/model/XernerxUser.ts +82 -0
  40. package/src/tools/XernerxBase.ts +16 -0
  41. package/src/tools/XernerxError.ts +16 -0
  42. package/src/tools/XernerxInfo.ts +13 -0
  43. package/src/tools/XernerxInitial.ts +28 -0
  44. package/src/tools/XernerxSuccess.ts +13 -0
  45. package/src/tools/XernerxWarn.ts +13 -0
  46. package/src/types/Events.d.ts +21 -0
  47. package/src/types/Interaction.d.ts +90 -0
  48. package/src/types/Message.d.ts +16 -0
  49. package/src/util/XernerxInteractionUtil.ts +82 -0
  50. package/src/util/XernerxMessageUtil.ts +105 -0
  51. package/src/util/XernerxUtil.ts +47 -0
  52. package/src/validators/XernerxBaseValidator.ts +82 -0
  53. package/src/validators/XernerxSlashCommandValidator.ts +11 -0
  54. package/dist/main.global.js +0 -88544
  55. package/dist/main.global.js.map +0 -1
  56. package/src/base/XernerxContextCommand.ts +0 -24
  57. package/src/base/XernerxEvent.ts +0 -21
  58. package/src/base/XernerxInhibitor.ts +0 -21
  59. package/src/base/XernerxMessageCommand.ts +0 -24
  60. package/src/base/XernerxSlashCommand.ts +0 -26
  61. package/src/handlers/CommandHandler.ts +0 -31
  62. package/src/handlers/Handler.ts +0 -57
  63. package/src/tools/XernerxLog.ts +0 -58
  64. package/src/types/interfaces.ts +0 -25
  65. package/src/types/types.ts +0 -29
  66. package/src/util/ClientUtil.ts +0 -29
  67. package/src/util/Util.ts +0 -11
  68. package/src/util/prompts.ts +0 -120
package/dist/main.cjs CHANGED
@@ -1,148 +1,200 @@
1
1
  'use strict';
2
2
 
3
- var Discord = require('discord.js');
4
- var zod = require('zod');
5
- var sharpyy2 = require('sharpyy');
3
+ var discordHybridSharding = require('discord-hybrid-sharding');
4
+ var sharpyy8 = require('sharpyy');
6
5
  var fs = require('fs');
6
+ var ora = require('ora');
7
+ var boxen = require('boxen');
8
+ var discord_js = require('discord.js');
9
+ var z2 = require('zod');
10
+ var core = require('@discordjs/core');
7
11
  var path = require('path');
8
12
 
9
13
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
14
 
11
- function _interopNamespace(e) {
12
- if (e && e.__esModule) return e;
13
- var n = Object.create(null);
14
- if (e) {
15
- Object.keys(e).forEach(function (k) {
16
- if (k !== 'default') {
17
- var d = Object.getOwnPropertyDescriptor(e, k);
18
- Object.defineProperty(n, k, d.get ? d : {
19
- enumerable: true,
20
- get: function () { return e[k]; }
21
- });
22
- }
23
- });
24
- }
25
- n.default = e;
26
- return Object.freeze(n);
27
- }
28
-
29
- var Discord__namespace = /*#__PURE__*/_interopNamespace(Discord);
30
- var sharpyy2__default = /*#__PURE__*/_interopDefault(sharpyy2);
31
- var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
32
- var path__namespace = /*#__PURE__*/_interopNamespace(path);
15
+ var sharpyy8__default = /*#__PURE__*/_interopDefault(sharpyy8);
16
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
17
+ var ora__default = /*#__PURE__*/_interopDefault(ora);
18
+ var boxen__default = /*#__PURE__*/_interopDefault(boxen);
19
+ var z2__default = /*#__PURE__*/_interopDefault(z2);
20
+ var path__default = /*#__PURE__*/_interopDefault(path);
33
21
 
34
22
  var __defProp = Object.defineProperty;
35
23
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
36
- var XernerxLog_default = new class XernerxLog {
24
+ var XernerxBase = class {
37
25
  static {
38
- __name(this, "XernerxLog");
26
+ __name(this, "XernerxBase");
39
27
  }
40
28
  constructor() {
41
- this.baseText = `${sharpyy2__default.default("XERNERX", "txRainbow", "bold")} | ${(/* @__PURE__ */ new Date()).toLocaleTimeString().split(/ /gim).map(
42
- (str) => str.split(":").map((str2) => isNaN(Number(str2)) ? str2 : sharpyy2__default.default(str2, "txCyan")).join(":")
43
- ).join(" ")} | ${sharpyy2__default.default(String(Math.round(process.memoryUsage().rss / 1e4) / 100), "txCyan")}mb |`;
29
+ this.base = () => `| ${sharpyy8__default.default("XERNERX", "txRainbow", "bold")} | ${(/* @__PURE__ */ new Date()).toLocaleTimeString().split("").map((c) => Number.isNaN(Number(c)) ? sharpyy8__default.default(c, "txWhite") : sharpyy8__default.default(c, "txCyan")).join("")} | ${sharpyy8__default.default(String(Math.round(process.memoryUsage().rss / 1e6)), "txCyan")}mb | `;
44
30
  }
45
- info(message) {
46
- return console.info(`\u2714\uFE0F |`, this.baseText, message);
31
+ };
32
+
33
+ // src/tools/XernerxInfo.ts
34
+ var XernerxInfo = class extends XernerxBase {
35
+ static {
36
+ __name(this, "XernerxInfo");
47
37
  }
48
- async error(message, error) {
49
- const { default: boxen } = await import('boxen');
50
- const errorMessage = boxen(error?.stack, { padding: 1, margin: 1, borderStyle: "round", borderColor: "red" });
51
- if (error) return console.error(`\u2757 |`, this.baseText, message, errorMessage);
52
- else return console.error(`\u2757 |`, this.baseText, message);
38
+ constructor(message) {
39
+ super();
40
+ ora__default.default().info(`${this.base()}${message}`);
53
41
  }
54
- warn(message, url) {
55
- console.warn(`\u26A0\uFE0F |`, this.baseText, message, url ? `Read more here ${sharpyy2.link("here", url)}` : "");
42
+ };
43
+ var XernerxError = class extends XernerxBase {
44
+ static {
45
+ __name(this, "XernerxError");
46
+ }
47
+ constructor(message, exit = 0) {
48
+ super();
49
+ ora__default.default().fail(`${this.base()}${sharpyy8__default.default(message, "txRed")}`);
50
+ exit ? process.exit(exit) : null;
51
+ }
52
+ };
53
+ var XernerxSuccess = class extends XernerxBase {
54
+ static {
55
+ __name(this, "XernerxSuccess");
56
+ }
57
+ constructor(message) {
58
+ super();
59
+ ora__default.default().succeed(`${this.base()}${message}`);
56
60
  }
57
- debug(message) {
58
- return console.debug(`\u{1F41B} |`, this.baseText, message);
61
+ };
62
+ var XernerxInitial = class extends XernerxBase {
63
+ static {
64
+ __name(this, "XernerxInitial");
59
65
  }
60
- async box(message, color, title) {
61
- const { default: boxen } = await import('boxen');
62
- const time = (/* @__PURE__ */ new Date()).toLocaleTimeString().split(/ /gim).map(
63
- (str) => str.split(":").map((str2) => isNaN(Number(str2)) ? str2 : sharpyy2__default.default(str2, "txCyan")).join(":")
64
- ).join(" ");
65
- return console.info(boxen(message, { padding: 1, margin: 1, borderStyle: "round", borderColor: color, title: `${time} - ${sharpyy2__default.default("XERNERX", "txRainbow", "bold")} - ${title || ""}` }));
66
+ constructor(type) {
67
+ super();
68
+ console.clear();
69
+ console.info(
70
+ boxen__default.default(sharpyy8__default.default("XERNERX", "txRainbow", "bold"), {
71
+ borderStyle: "round",
72
+ borderColor: "magenta",
73
+ textAlignment: "center",
74
+ fullscreen: /* @__PURE__ */ __name((width, height) => [width, 4], "fullscreen")
75
+ })
76
+ );
77
+ const spinner = ora__default.default().start(`${this.base()}${type == "Client" ? "Starting..." : "Sharding..."}`);
78
+ setInterval(() => spinner.text = `${this.base()}`, 500);
66
79
  }
67
- }();
80
+ };
68
81
 
69
- // src/util/prompts.ts
70
- var init = false;
71
- async function start(client) {
72
- if (init) return;
73
- if (client.settings.debug) XernerxLog_default.info("Debug mode enabled, preventing console clear and logging all handlings...");
74
- else console.clear();
75
- const { default: ora, spinners } = await import('ora');
76
- const { default: boxen } = await import('boxen');
77
- console.info(
78
- boxen(sharpyy2__default.default("XERNERX", "txRainbow", "bold", "underlines"), {
79
- padding: 1,
80
- margin: 1,
81
- borderStyle: "round",
82
- height: 3,
83
- align: "center",
84
- borderColor: "magenta",
85
- fullscreen: /* @__PURE__ */ __name((width, height) => [width - 5, height], "fullscreen")
86
- })
87
- );
88
- if (!client.options.intents.has("Guilds"))
89
- XernerxLog_default.warn("Your bot is signed in without the Guilds intent, this may cause issues with the bot.", new URL("https://discord.com/developers/docs/topics/gateway#gateway-intents"));
90
- const spinner = ora();
91
- spinner.spinner = spinners.dots12;
92
- spinner.start();
93
- let index = 0;
94
- setInterval(async () => {
95
- calculateStats(client);
96
- const time = (/* @__PURE__ */ new Date()).toLocaleTimeString().split(/ /gim).map(
97
- (str) => str.split(":").map((str2) => isNaN(Number(str2)) ? str2 : sharpyy2__default.default(str2, "txCyan")).join(":")
98
- ).join(" "), ram = `${sharpyy2__default.default(String(Math.round(process.memoryUsage().rss / 1e4) / 100), "txCyan")}mb`;
99
- const colors = ["red", "green", "yellow", "blue", "magenta", "cyan"];
100
- const baseText = `${sharpyy2__default.default("XERNERX", "txRainbow", "bold")} | ${time} | ${ram} | `;
101
- if (client.user) {
102
- spinner.color = colors[index];
103
- const counts = {
104
- local: client.commands.stats.slash.local + client.commands.stats.message.local + client.commands.stats.context.local,
105
- global: client.commands.stats.slash.global + client.commands.stats.message.global + client.commands.stats.context.global
106
- };
107
- spinner.text = boxen(
108
- Object.entries({
109
- "Name": sharpyy2__default.default(client.user.tag, "txBlue"),
110
- "Status": `${sharpyy2__default.default("Online", "txGreen")} | ${client.settings.global ? sharpyy2__default.default("Global", "txGreen") : sharpyy2__default.default("Local", "txRed")}`,
111
- "Uptime": client.util.uptime(client.uptime).split("").map((c) => isNaN(Number(c)) ? c : sharpyy2__default.default(c, "txCyan")).join(""),
112
- "Commands": client.settings.global ? `${counts.local ? `local: ${counts.local}` : ""}|${counts.global ? `global: ${counts.global}` : ""}` : counts.local + counts.global,
113
- "RAM Usage": ram,
114
- "Guilds": (await Promise.all(client.settings.guilds.map(async (id) => sharpyy2__default.default((await client.guilds.fetch(id))?.name || id, "txBlue")))).join(", "),
115
- "Owners": (await Promise.all(client.settings.owners.map(async (id) => sharpyy2__default.default((await client.users.fetch(id))?.username || id, "txBlue")))).join(", "),
116
- "GuildCount": sharpyy2__default.default(String(client.stats.guilds), "txCyan"),
117
- "UserCount": sharpyy2__default.default(String(client.stats.users), "txCyan"),
118
- "ShardCount": sharpyy2__default.default(String(client.stats.shardCount), "txCyan")
119
- }).map(([key, value]) => `${key}: ${value}`).join("\n"),
120
- {
121
- padding: 1,
122
- margin: 1,
123
- borderStyle: "round",
124
- borderColor: "magenta",
125
- title: time + " - " + sharpyy2__default.default("XERNERX", "txRainbow", "bold") + "\x1B[35m",
126
- height: 15,
127
- fullscreen: /* @__PURE__ */ __name((width, height) => [width - 5, height], "fullscreen")
128
- }
129
- );
130
- } else {
131
- spinner.color = "green";
132
- spinner.text = baseText + `Connecting to Discord${index == 0 ? "." : index == 1 ? ".." : index == 2 ? "..." : ""}`;
133
- }
134
- index++;
135
- if (index == colors.length - 1) index = 0;
136
- }, 250);
137
- init = true;
138
- }
139
- __name(start, "start");
140
- function calculateStats(client) {
141
- client.stats.guilds = client.guilds.cache.size;
142
- client.stats.users = client.users.cache.size;
143
- client.stats.shardCount = client.options.shardCount || null;
144
- }
145
- __name(calculateStats, "calculateStats");
82
+ // src/client/XernerxShardClient.ts
83
+ var XernerxShardClient = class extends discordHybridSharding.ClusterManager {
84
+ static {
85
+ __name(this, "XernerxShardClient");
86
+ }
87
+ constructor(options) {
88
+ new XernerxInitial("ShardClient");
89
+ try {
90
+ new XernerxInfo(`Loading ShardClient from ${sharpyy8__default.default(options.file, "bgGray")}`);
91
+ fs__default.default.readFileSync(options.file), "utf-8";
92
+ new XernerxSuccess(`ShardClient loaded successfully`);
93
+ } catch {
94
+ new XernerxError(`File ${sharpyy8__default.default(options.file, "bgGray")} not found.`, 1);
95
+ }
96
+ super(options.file, options);
97
+ this.onlineShards = /* @__PURE__ */ new Set();
98
+ this.stats = {
99
+ onlineSince: Number(/* @__PURE__ */ new Date()),
100
+ guildCount: null,
101
+ userCount: null,
102
+ shardCount: null,
103
+ voteCount: null,
104
+ shards: []
105
+ };
106
+ this.on("clusterCreate", (cluster) => {
107
+ new XernerxInfo(`${sharpyy8__default.default(`Shard ${cluster.id}`, "txCyan")} | Creating...`);
108
+ cluster.on("ready", () => {
109
+ this.onlineShards.add(cluster);
110
+ if (this.onlineShards.size == (this.totalClusters || this.totalShards)) this.#update();
111
+ });
112
+ cluster.on("disconnect", () => {
113
+ this.onlineShards.delete(cluster);
114
+ });
115
+ cluster.on("death", (error) => {
116
+ this.onlineShards.delete(cluster);
117
+ });
118
+ });
119
+ this.spawn({ timeout: -1 });
120
+ }
121
+ async #update() {
122
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
123
+ setInterval(async () => {
124
+ const stats = await this.fetchClientValues("stats");
125
+ const shards = await this.fetchClientValues("stats.shard");
126
+ this.stats.guildCount = stats[0].guildCount;
127
+ this.stats.userCount = stats[0].userCount;
128
+ this.stats.shardCount = stats[0].shardCount;
129
+ this.stats.voteCount = stats[0].voteCount;
130
+ this.stats.shards = shards;
131
+ }, 1e3);
132
+ await new Promise((resolve) => setTimeout(resolve, 4e3));
133
+ new XernerxSuccess(
134
+ `All Shards are online! Watching ${sharpyy8__default.default(String(this.stats.guildCount?.toLocaleString()), "txCyan")} guilds and users: ${sharpyy8__default.default(String(this.stats.userCount?.toLocaleString()), "txCyan")}, and ${sharpyy8__default.default(String(this.stats.shardCount?.toLocaleString()), "txCyan")} shards.`
135
+ );
136
+ }
137
+ };
138
+ var XernerxMonitisation = class extends core.MonetizationAPI {
139
+ static {
140
+ __name(this, "XernerxMonitisation");
141
+ }
142
+ constructor(client) {
143
+ super(client.rest);
144
+ this.client = client;
145
+ }
146
+ /**
147
+ * Consumes an entitlement for the current user.
148
+ *
149
+ * @param id - The unique identifier of the entitlement to be consumed.
150
+ * @param options - Optional request options specifying authentication or signaling method.
151
+ * @returns A promise that resolves when the entitlement is successfully consumed.
152
+ */
153
+ consume(id, options) {
154
+ return this.consumeEntitlement(this.client.user.id, id, options);
155
+ }
156
+ /**
157
+ * Retrieves entitlements for the current user.
158
+ *
159
+ * @param id - An optional query object to filter entitlements.
160
+ * @param options - Optional request options specifying authentication or signaling method.
161
+ * @returns A promise that resolves with the entitlements for the current user.
162
+ */
163
+ entitlements(id, options) {
164
+ return this.getEntitlements(this.client.user.id, id || {}, options);
165
+ }
166
+ /**
167
+ * Retrieves the Stock Keeping Units (SKUs) for the current user.
168
+ *
169
+ * @param options - Optional request options specifying authentication or signaling method.
170
+ * @returns A promise that resolves with the SKUs for the current user.
171
+ */
172
+ sku(options) {
173
+ return this.getSKUs(this.client.user.id, options);
174
+ }
175
+ /**
176
+ * Creates a test entitlement for a specified user and SKU.
177
+ *
178
+ * @param id - The unique identifier of the SKU for which the entitlement is to be created.
179
+ * @param user - The unique identifier of the user who will own the entitlement.
180
+ * @returns A promise that resolves with the created test entitlement, or undefined if the SKU is not found.
181
+ */
182
+ async create(id, user) {
183
+ const skus = await this.sku();
184
+ const sku = skus.find((s) => s.id === id);
185
+ if (!sku) return;
186
+ return await this.createTestEntitlement(this.client.user.id, { owner_id: user, owner_type: sku.type == 5 ? 2 : 1, sku_id: id });
187
+ }
188
+ /**
189
+ * Deletes a test entitlement for the current user.
190
+ *
191
+ * @param id - The unique identifier of the test entitlement to be deleted.
192
+ * @returns A promise that resolves when the test entitlement is successfully deleted.
193
+ */
194
+ delete(id) {
195
+ return this.deleteTestEntitlement(this.client.user.id, id);
196
+ }
197
+ };
146
198
  var Handler = class {
147
199
  static {
148
200
  __name(this, "Handler");
@@ -150,204 +202,1155 @@ var Handler = class {
150
202
  constructor(client) {
151
203
  this.client = client;
152
204
  }
153
- async readdir(directory) {
154
- const dirpath = path__namespace.resolve(directory);
155
- if (this.client.settings.debug) XernerxLog_default.debug(`Attempting to read directory ${sharpyy2.link(directory, new URL(dirpath))}`);
205
+ /**
206
+ * Loads JavaScript files from a specified directory.
207
+ *
208
+ * @param dir - The directory path from which to load the files.
209
+ * @returns An array of file paths for JavaScript files in the specified directory.
210
+ * Returns an empty array if an error occurs during the file reading process.
211
+ */
212
+ loadFiles(dir) {
156
213
  try {
157
- const files = fs__namespace.readdirSync(dirpath);
158
- return files.filter((file) => file.endsWith(".js") || file.endsWith(".mjs") || file.endsWith(".cjs"));
214
+ return fs__default.default.readdirSync(dir).filter((file) => file.endsWith(".js")).map((file) => path__default.default.join(dir, file));
159
215
  } catch (error) {
160
- XernerxLog_default.error(`Error reading directory ${sharpyy2.link(directory, new URL(dirpath))}:`, error);
216
+ new XernerxError(error.message, 0);
161
217
  return [];
162
218
  }
163
219
  }
164
- async load(filepath) {
165
- if (this.client.settings.debug) XernerxLog_default.debug(`Attempting to load ${sharpyy2.link(filepath, new URL(filepath))}`);
220
+ /**
221
+ * Asynchronously loads a JavaScript file and imports its default export.
222
+ *
223
+ * @param file - The path to the JavaScript file to be loaded.
224
+ * @returns A promise that resolves when the file is successfully loaded and imported.
225
+ * If the file does not have a default export, an error is thrown.
226
+ */
227
+ async loadFile(file) {
228
+ const filepath = path__default.default.resolve(file);
229
+ const filename = path__default.default.basename(filepath);
166
230
  try {
167
- const file = (await import(`file://${filepath}`))?.default || await import(`file://${filepath}`);
168
- const openFile = new file();
169
- const [collection, group] = openFile.collection.split(".");
170
- group ? this.client[group][collection].set(openFile._id, openFile) : this.client[collection].set(openFile._id, openFile);
171
- if (this.client.settings.debug) XernerxLog_default.debug(`Loaded ${sharpyy2.link(openFile._id, new URL(filepath))}`);
172
- return openFile;
231
+ const file2 = await import(`file://${filepath}`);
232
+ if (!file2.default) return new XernerxError(`${filename} | ${file2} does not have a default export.`, 0);
233
+ const builder = new file2.default(this.client);
234
+ builder.filepath = filepath;
235
+ builder.filename = filename;
236
+ this.importFile(builder);
173
237
  } catch (error) {
174
- XernerxLog_default.error(`Error loading ${sharpyy2.link(filepath, new URL(filepath))}:`, error);
175
- return null;
238
+ new XernerxError(`${filename} | ${error.message}`, 0);
239
+ }
240
+ }
241
+ /**
242
+ * Imports a file by registering it with the client based on its type.
243
+ *
244
+ * @param builder - An instance of XernerxEventBuilder, XernerxMessageCommandBuilder, or XernerxSlashCommandBuilder.
245
+ * This object contains the necessary information to register the file with the client.
246
+ * @param filename - An optional string representing the name of the file being imported.
247
+ * Used for error reporting if the builder ID is not unique.
248
+ * @returns The builder object after it has been registered with the client.
249
+ * If the builder is of type XernerxEvent, it is registered as an event listener.
250
+ * If the builder is of type XernerxMessageCommand or XernerxSlashCommand, it is registered as a command.
251
+ */
252
+ async importFile(builder, filename) {
253
+ if (builder.filetype === "XernerxEvent") {
254
+ if (this.client.events.has(builder.id)) return new XernerxError(`${filename} | ID must be unique`);
255
+ this.client.events.set(builder.id, builder);
256
+ builder.once ? this[builder.emitter].once(builder.name, (...args) => builder.run(...args)) : this[builder.emitter].on(builder.name, (...args) => builder.run(...args));
257
+ }
258
+ if (builder.filetype === "XernerxMessageCommand") {
259
+ this.client.commands.message.set(builder.id, builder);
260
+ }
261
+ if (builder.filetype === "XernerxSlashCommand") {
262
+ this.client.commands.slash.set(builder.id, builder);
176
263
  }
264
+ return builder;
177
265
  }
178
266
  };
179
- var CommandHandler = class extends Handler {
267
+
268
+ // src/handler/EventHandler.ts
269
+ var EventHandler = class extends Handler {
180
270
  static {
181
- __name(this, "CommandHandler");
271
+ __name(this, "EventHandler");
182
272
  }
183
273
  constructor(client) {
184
274
  super(client);
185
275
  }
186
- async loadSlashCommands(options) {
187
- if (!this.client.modules.options.slash) this.client.modules.options.slash = {};
188
- this.client.modules.options.slash.global = options.global ?? this.client.settings.global;
189
- for (const file of await this.readdir(options.directory)) {
190
- const command = await this.load(path__namespace.default.resolve(`${options.directory}/${file}`));
191
- if (!command) continue;
192
- if (command.filetype == "XernerxMessageCommand" || command.filetype == "XernerxSlashCommand" || command.filetype == "XernerxContextCommand") {
193
- if (!this.client.modules.options.slash.global) this.client.commands.stats.slash.local++;
194
- else if (!command.global) this.client.commands.stats.slash.local++;
195
- else this.client.commands.stats.slash.global++;
196
- }
276
+ /**
277
+ * Loads a single event file.
278
+ *
279
+ * @param file - The path to the event file to be loaded.
280
+ * @returns A promise that resolves when the event file has been successfully loaded.
281
+ */
282
+ async loadEvent(file) {
283
+ return this.loadFile(file);
284
+ }
285
+ /**
286
+ * Loads all event files from the specified directory and initializes them.
287
+ *
288
+ * @param options - An object containing options for loading events.
289
+ * @param options.directory - The directory path where event files are located.
290
+ * @returns A promise that resolves when all events have been loaded.
291
+ */
292
+ async loadEvents(options) {
293
+ const files = this.loadFiles(options.directory);
294
+ for (const file of files) {
295
+ await this.loadEvent(file);
197
296
  }
297
+ new XernerxSuccess(
298
+ `Loaded events: ${this.client.events.filter((event) => !event.id.startsWith("Xernerx")).map((event) => sharpyy8__default.default(event.id, "txYellow")).join(", ")}`
299
+ );
198
300
  }
199
- async loadMessageCommands(options) {
301
+ };
302
+
303
+ // src/build/XernerxBaseBuilder.ts
304
+ var XernerxBaseBuilder = class {
305
+ static {
306
+ __name(this, "XernerxBaseBuilder");
307
+ }
308
+ /**
309
+ * Constructs a new instance of the XernerxBaseBuilder class.
310
+ *
311
+ * @param id - A unique identifier for the builder instance.
312
+ * @param options - Configuration options for the builder, which can be either
313
+ * XernerxSlashCommandBuilderOptions or XernerxEventBuilderOptions.
314
+ */
315
+ constructor(id, options) {
316
+ this.id = id;
317
+ }
318
+ };
319
+ var XernerxWarn = class extends XernerxBase {
320
+ static {
321
+ __name(this, "XernerxWarn");
200
322
  }
201
- async loadContextCommands(options) {
323
+ constructor(message) {
324
+ super();
325
+ ora__default.default().warn(`${this.base()}${message}`);
202
326
  }
203
327
  };
204
328
 
205
- // src/util/Util.ts
206
- var Util = class {
329
+ // src/build/XernerxEventBuilder.ts
330
+ var XernerxEventBuilder = class extends XernerxBaseBuilder {
207
331
  static {
208
- __name(this, "Util");
332
+ __name(this, "XernerxEventBuilder");
209
333
  }
210
- constructor(client) {
334
+ constructor(id, options) {
335
+ super(id, options);
336
+ this.filetype = "XernerxEvent";
337
+ this.name = options.name;
338
+ this.emitter = options.emitter ?? "client";
339
+ this.once = options.once ?? false;
340
+ }
341
+ /**
342
+ * Executes the event logic. This method should be overridden in subclasses to provide specific event handling.
343
+ *
344
+ * @param args - A variable number of arguments that are passed to the event handler.
345
+ * These arguments are specific to the event being handled.
346
+ * @returns A promise that resolves when the event handling is complete.
347
+ * The resolved value can be any type, depending on the implementation in subclasses.
348
+ */
349
+ async run(...args) {
350
+ new XernerxWarn(`Event ${sharpyy8__default.default(`${this.id}`, "txYellow")} does not have a run method, and will therefore not work.`);
351
+ }
352
+ };
353
+ var XernerxUser = class extends discord_js.User {
354
+ static {
355
+ __name(this, "XernerxUser");
356
+ }
357
+ #monitisation;
358
+ constructor(client, user) {
359
+ super(client, user);
360
+ this.#monitisation = new XernerxMonitisation(client);
361
+ }
362
+ /**
363
+ * Checks if the user has any entitlements, indicating premium status.
364
+ *
365
+ * @param id - The ID of the user to check for premium entitlements.
366
+ * @returns A promise that resolves to a boolean indicating whether the user has any entitlements (true) or not (false).
367
+ */
368
+ async premium(id) {
369
+ const entitlements = await this.#monitisation.entitlements({ user_id: this.id });
370
+ if (!entitlements.length) return false;
371
+ return true;
372
+ }
373
+ /**
374
+ * Retrieves the entitlements for the user and maps them to their corresponding SKU.
375
+ *
376
+ * @returns A promise that resolves to an array of objects, each containing an entitlement and its associated SKU.
377
+ */
378
+ async entitlements() {
379
+ const entitlements = await this.#monitisation.entitlements({ user_id: this.id });
380
+ const SKU = await this.#monitisation.sku();
381
+ return entitlements.map((entitlement) => ({ entitlement, sku: SKU.find((sku) => sku.id === entitlement.sku_id) }));
382
+ }
383
+ /**
384
+ * Synchronizes the user's entitlements with the current SKU data and performs necessary actions
385
+ * such as consuming, deleting, or creating entitlements based on their type and the client's premium settings.
386
+ *
387
+ * @returns A promise that resolves to an array of error messages, if any occurred during the synchronization process.
388
+ */
389
+ async synchronize() {
390
+ const errors = [];
391
+ const client = this.client;
392
+ const skus = await this.#monitisation.sku();
393
+ const entitlements = await this.#monitisation.entitlements({ user_id: this.id });
394
+ for (const entitlement of entitlements) {
395
+ if (!client.premium.synchronize) continue;
396
+ const sku = skus.find((sku2) => sku2.id === entitlement.sku_id);
397
+ if (!sku) continue;
398
+ if (sku.type == discord_js.SKUType.Consumable && !entitlement.consumed && client.premium.consume) this.#monitisation.consume(entitlement.id).catch((e) => errors.push(e.message));
399
+ if (sku.type == discord_js.SKUType.Durable) ;
400
+ if (sku.type == discord_js.SKUType.Subscription && entitlement.type == discord_js.EntitlementType.ApplicationSubscription) this.#monitisation.delete(entitlement.id).catch((e) => errors.push(e.message));
401
+ if (sku.type == discord_js.SKUType.SubscriptionGroup && entitlement.type == discord_js.EntitlementType.ApplicationSubscription) this.#monitisation.delete(entitlement.id).catch((e) => errors.push(e.message));
402
+ }
403
+ for (const sku of skus) {
404
+ if (!client.premium.owners) continue;
405
+ if (sku.type == 5) {
406
+ await this.#monitisation.create(sku.id, this.id).catch((e) => errors.push(e.message));
407
+ }
408
+ }
409
+ return errors;
410
+ }
411
+ };
412
+
413
+ // src/util/XernerxUtil.ts
414
+ var XernerxBaseUtil = class {
415
+ static {
416
+ __name(this, "XernerxBaseUtil");
417
+ }
418
+ constructor(client, interaction) {
211
419
  this.client = client;
420
+ this.parsed = { command: null, alias: null, mention: null, prefix: null };
421
+ this.interaction = interaction;
422
+ }
423
+ /**
424
+ * Sends a message using a webhook in the current interaction's channel.
425
+ *
426
+ * @param options - The message content or options to send via the webhook. This can be a string, MessagePayload, or WebhookMessageCreateOptions.
427
+ * @returns A promise that resolves to the message sent by the webhook.
428
+ */
429
+ async webhook(options) {
430
+ if (!this.interaction.channel) return;
431
+ const webhooks = await this.interaction.channel.fetchWebhooks();
432
+ let webhook = await webhooks.find((wh) => wh.token);
433
+ if (!webhook)
434
+ webhook = this.interaction.channel.createWebhook({
435
+ name: this.client.user.username,
436
+ avatar: this.client.user.displayAvatarURL()
437
+ });
438
+ return await webhook.send(options);
212
439
  }
213
440
  };
214
441
 
215
- // src/util/ClientUtil.ts
216
- var ClientUtil = class extends Util {
442
+ // src/util/XernerxMessageUtil.ts
443
+ var XernerxMessageUtil = class extends XernerxBaseUtil {
217
444
  static {
218
- __name(this, "ClientUtil");
445
+ __name(this, "XernerxMessageUtil");
446
+ }
447
+ constructor(client, message) {
448
+ super(client, message);
449
+ this.message = message;
450
+ this.cache = this.client.cache.messages;
451
+ this.args = [];
452
+ this.#parse();
453
+ }
454
+ /**
455
+ * Parses the message content to extract command, alias, prefix, and arguments.
456
+ * It also checks if the message mentions the bot.
457
+ */
458
+ #parse() {
459
+ if (this.message.content.trim().startsWith(`<@${this.client.user.id}>`)) this.message.content = this.message.content.replace(`<@${this.client.user.id}>`, "").trimStart();
460
+ const [command, ...args] = this.message.content.split(this.client.handler.message.seperator || " ");
461
+ this.client.commands.message.map(({ name, prefix, alias }) => {
462
+ if (command.toLowerCase().endsWith(name.toLowerCase())) {
463
+ this.parsed.command = name;
464
+ this.parsed.alias = name;
465
+ }
466
+ alias.map((a) => command.toLowerCase().endsWith(a.toLowerCase()) ? this.parsed.alias = a : null);
467
+ prefix.map((p) => command.toLowerCase().startsWith(p.toLowerCase()) ? this.parsed.prefix = p : null);
468
+ });
469
+ this.client.handler.message.prefix?.map((p) => command.toLowerCase().startsWith(p.toLowerCase()) ? this.parsed.prefix = p : null);
470
+ this.parsed.mention = this.message.mentions.has(this.client.user.id);
471
+ this.args = args;
472
+ }
473
+ /**
474
+ * Sends a message to the channel or edits an existing message if applicable.
475
+ *
476
+ * @param options - The content or options for the message to be sent or edited.
477
+ * It can be a string, MessagePayload, MessageCreateOptions, or MessageEditOptions.
478
+ * @returns The sent or edited message, or null if the message ID is not found in the cache.
479
+ */
480
+ async send(options) {
481
+ if (this.cache.has(this.message.id) && this.client.handler.message.handleEdits) {
482
+ const id = this.cache.get(this.message.id);
483
+ if (!id) return null;
484
+ const msg2 = await this.message.channel.messages.fetch(id);
485
+ msg2.edit(options);
486
+ return msg2;
487
+ }
488
+ const msg = await this.message.channel.send(options);
489
+ this.cache.set(this.message.id, msg.id);
490
+ return msg;
491
+ }
492
+ /**
493
+ * Replies to the current message or edits an existing reply if applicable.
494
+ *
495
+ * @param options - The content or options for the reply message.
496
+ * It can be a string, MessagePayload, or MessageReplyOptions.
497
+ * @returns The sent or edited message, or null if the message ID is not found in the cache.
498
+ */
499
+ async reply(options) {
500
+ if (this.cache.has(this.message.id) && this.client.handler.message.handleEdits) {
501
+ const id = this.cache.get(this.message.id);
502
+ if (!id) return null;
503
+ const msg2 = await this.message.channel.messages.fetch(id);
504
+ msg2.edit(options);
505
+ return msg2;
506
+ }
507
+ const msg = await this.message.reply(options);
508
+ this.cache.set(this.message.id, msg.id);
509
+ return msg;
510
+ }
511
+ };
512
+
513
+ // src/events/messageCreate.ts
514
+ var XernerxMessageCreateEvent = class extends XernerxEventBuilder {
515
+ static {
516
+ __name(this, "XernerxMessageCreateEvent");
517
+ }
518
+ constructor() {
519
+ super("XernerxMessageCreateEvent", {
520
+ name: "messageCreate",
521
+ emitter: "client",
522
+ once: false
523
+ });
524
+ }
525
+ async run(message) {
526
+ this.client = message.client;
527
+ message.user = new XernerxUser(message.client, message.author);
528
+ message.util = new XernerxMessageUtil(this.client, message);
529
+ if (!message.content) return;
530
+ if (this.client.handler.message.ignore?.bots && message.author.bot) return;
531
+ if (this.client.handler.message.ignore?.self && message.author.id === this.client.user?.id) return;
532
+ if (this.client.handler.message.ignore?.system && message.system) return;
533
+ if (!message.util.parsed.command) return;
534
+ const command = this.client.commands.message.get(message.util.parsed.command);
535
+ if (!command) return;
536
+ if (this.client.handler.message.mention && !message.util.parsed.mention && !command?.prefix.includes(message.util.parsed.prefix) && !this.client.handler.message.prefix?.includes(message.util.parsed.prefix))
537
+ return;
538
+ try {
539
+ await message.client.emit("commandStart", message, {}, command);
540
+ await command?.exec(message, message.util.args);
541
+ await message.client.emit("commandFinish", message, {}, command);
542
+ } catch (error) {
543
+ await message.client.emit("commandError", message, {}, command, error);
544
+ }
545
+ }
546
+ };
547
+
548
+ // src/events/messageUpdate.ts
549
+ var XernerxMessageUpdateEvent = class extends XernerxEventBuilder {
550
+ static {
551
+ __name(this, "XernerxMessageUpdateEvent");
552
+ }
553
+ constructor() {
554
+ super("XernerxMessageUpdateEvent", {
555
+ name: "messageUpdate",
556
+ emitter: "client",
557
+ once: false
558
+ });
559
+ }
560
+ async run(oldMessage, message) {
561
+ this.client = message.client;
562
+ message.user = new XernerxUser(message.client, message.author);
563
+ message.util = new XernerxMessageUtil(this.client, message);
564
+ if (!message.content) return;
565
+ if (this.client.handler.message.ignore?.bots && message.author.bot) return;
566
+ if (this.client.handler.message.ignore?.self && message.author.id === this.client.user?.id) return;
567
+ if (this.client.handler.message.ignore?.system && message.system) return;
568
+ if (!message.util.parsed.command) return;
569
+ const command = this.client.commands.message.get(message.util.parsed.command);
570
+ if (!command) return;
571
+ if (this.client.handler.message.mention && !message.util.parsed.mention && !command?.prefix.includes(message.util.parsed.prefix) && !this.client.handler.message.prefix?.includes(message.util.parsed.prefix))
572
+ return;
573
+ try {
574
+ await message.client.emit("commandStart", message, {}, command);
575
+ await command?.exec(message, message.util.args);
576
+ await message.client.emit("commandFinish", message, {}, command);
577
+ } catch (error) {
578
+ await message.client.emit("commandError", message, {}, command, error);
579
+ }
580
+ }
581
+ };
582
+
583
+ // src/events/messageDelete.ts
584
+ var XernerxMessageDeleteEvent = class extends XernerxEventBuilder {
585
+ static {
586
+ __name(this, "XernerxMessageDeleteEvent");
587
+ }
588
+ constructor() {
589
+ super("XernerxMessageDeleteEvent", {
590
+ name: "messageDelete",
591
+ emitter: "client",
592
+ once: false
593
+ });
594
+ }
595
+ async run(message) {
596
+ this.client = message.client;
597
+ message.user = new XernerxUser(message.client, message.author);
598
+ message.util = new XernerxMessageUtil(this.client, message);
599
+ if (!this.client.handler.message.handleDeletions) return;
600
+ if (!this.client.cache.messages.has(message.id)) return;
601
+ const id = this.client.cache.messages.get(message.id);
602
+ if (!id) return;
603
+ try {
604
+ const msg = await message.channel.messages.fetch(id);
605
+ await msg.delete();
606
+ } catch (error) {
607
+ await this.client.emit("commandDelete", message, error);
608
+ }
609
+ }
610
+ };
611
+ var XernerxInteractionUtil = class extends XernerxBaseUtil {
612
+ static {
613
+ __name(this, "XernerxInteractionUtil");
614
+ }
615
+ constructor(client, interaction) {
616
+ super(client, interaction);
617
+ this.interaction = interaction;
618
+ this.cache = this.client.cache.slash;
619
+ }
620
+ /**
621
+ * Sends a message to the channel associated with the interaction.
622
+ *
623
+ * @param options - The content or options for the message to be sent. It can be a string, MessagePayload, or MessageCreateOptions.
624
+ * @returns A promise that resolves to the sent message.
625
+ * @throws {XernerxError} Throws an error if the options parameter is not provided.
626
+ */
627
+ async send(options) {
628
+ if (!options) throw new XernerxError(`Can't send a message without content.`);
629
+ return await this.interaction.channel.send(options);
630
+ }
631
+ /**
632
+ * Replies to the interaction with the provided options.
633
+ *
634
+ * @param options - The content or options for the reply. It can be a string, MessagePayload, or InteractionEditReplyOptions.
635
+ * @returns A promise that resolves to the sent message or the edited reply.
636
+ * @throws {XernerxError} Throws an error if the options parameter is not provided.
637
+ */
638
+ async reply(options) {
639
+ if (!options) throw new XernerxError(`Can't send a message without options.`);
640
+ return await (this.interaction.replied || this.interaction.deferred ? this.interaction.editReply(options) : this.interaction.reply(options));
641
+ }
642
+ /**
643
+ * Sends a message to the channel associated with the interaction with componentsV2 flag.
644
+ *
645
+ * @param options - The options for the message to be sent, including content and other message properties.
646
+ * @returns A promise that resolves to the sent message.
647
+ */
648
+ async send2(options) {
649
+ options.flags = discord_js.MessageFlags.IsComponentsV2;
650
+ return await this.send(options);
651
+ }
652
+ /**
653
+ * Replies to the interaction with the provided options, using the componentsV2 flag.
654
+ *
655
+ * @param options - The options for the reply, including content and other message properties.
656
+ * @returns A promise that resolves to the sent message or the edited reply.
657
+ */
658
+ async reply2(options) {
659
+ options.flags = discord_js.MessageFlags.IsComponentsV2;
660
+ return await this.reply(options);
661
+ }
662
+ };
663
+
664
+ // src/events/interactionCreate.ts
665
+ var XernerxInteractionCreateEvent = class extends XernerxEventBuilder {
666
+ static {
667
+ __name(this, "XernerxInteractionCreateEvent");
668
+ }
669
+ constructor() {
670
+ super("XernerxInteractionCreateEvent", {
671
+ name: "interactionCreate",
672
+ emitter: "client",
673
+ once: false
674
+ });
675
+ }
676
+ async run(interaction) {
677
+ this.client = interaction.client;
678
+ interaction.user = new XernerxUser(interaction.client, interaction.user);
679
+ interaction.util = new XernerxInteractionUtil(this.client, interaction);
680
+ if (interaction.isChatInputCommand()) return await interaction.client.emit("slashCommandInteraction", interaction);
681
+ if (interaction.isContextMenuCommand()) return await interaction.client.emit("contextCommandInteraction", interaction);
682
+ if (interaction.isAnySelectMenu()) return await interaction.client.emit("selectMenuInteraction", interaction);
683
+ if (interaction.isButton()) return await interaction.client.emit("buttonInteraction", interaction);
684
+ if (interaction.isModalSubmit()) return await interaction.client.emit("modalInteraction", interaction);
685
+ }
686
+ };
687
+ var XernerxClientReadyEvent = class extends XernerxEventBuilder {
688
+ static {
689
+ __name(this, "XernerxClientReadyEvent");
690
+ }
691
+ constructor() {
692
+ super("XernerxClientReadyEvent", {
693
+ name: "clientReady",
694
+ emitter: "client",
695
+ once: true
696
+ });
697
+ this.commands = {
698
+ global: [],
699
+ local: []
700
+ };
701
+ }
702
+ async run(client) {
703
+ if (client.settings.owners?.length) {
704
+ const owners = [];
705
+ if (client.premium?.synchronize) new XernerxInfo(`Synchronizing entitlements for premium owners...`);
706
+ for (const owner of client.settings.owners) {
707
+ const user = await client.users.fetch(owner);
708
+ new XernerxUser(client, user).synchronize();
709
+ owners.push(user);
710
+ }
711
+ if (client.premium?.synchronize) new XernerxSuccess(`Successfully synchronized entitlements for ${owners.map((owner) => owner.username).join(",")}`);
712
+ }
713
+ try {
714
+ const commands = [...client.commands.slash].map(([, command]) => command);
715
+ if (!client.settings.global) {
716
+ this.commands.global = [];
717
+ this.commands.local = commands;
718
+ } else {
719
+ this.commands.global = commands.filter((command) => command.deploy?.global);
720
+ this.commands.local = commands.filter((command) => !command.deploy?.global);
721
+ }
722
+ this.put(client);
723
+ new XernerxSuccess(`Successfully deployed slash commands ${client.settings.global ? "globally" : "locally"}`);
724
+ } catch (error) {
725
+ new XernerxError(error.message);
726
+ }
727
+ }
728
+ async put(client) {
729
+ const rest = new discord_js.REST({ version: discord_js.GatewayVersion }).setToken(client.token);
730
+ if (this.commands.global.length) {
731
+ if (!client.settings.global) return new XernerxInfo("Loading commands locally");
732
+ await rest.put(discord_js.Routes.applicationCommands(client.user?.id), { body: this.commands.global.map((command) => command.data.toJSON()) });
733
+ }
734
+ if (this.commands.local.length) {
735
+ const guilds = {};
736
+ for (const command of this.commands.local) {
737
+ command.deploy?.guilds?.map((id) => guilds[id] ? guilds[id].push(command) : guilds[id] = [command]);
738
+ }
739
+ if (!client.settings.guildId?.length && !Object.keys(guilds).length) return new XernerxError("Cannot locally deploy slash commands without a guild ID");
740
+ client.settings.guildId.map((id) => guilds[id] ? guilds[id] : guilds[id] = this.commands.local);
741
+ for (const [guildId, commands] of Object.entries(guilds)) {
742
+ await rest.put(discord_js.Routes.applicationGuildCommands(client.user?.id, guildId), { body: commands.map((command) => command.data.toJSON()) });
743
+ }
744
+ }
745
+ }
746
+ };
747
+
748
+ // src/model/XernerxInteractionArguments.ts
749
+ var XernerxInteractionArguments = class {
750
+ static {
751
+ __name(this, "XernerxInteractionArguments");
752
+ }
753
+ constructor(interaction, command) {
754
+ this.interaction = interaction;
755
+ this.command = command;
756
+ }
757
+ /**
758
+ * Retrieves the options from the current interaction based on the command structure.
759
+ *
760
+ * This method processes the command's groups, subcommands, and options to extract
761
+ * the relevant options from the interaction. It returns a record of option names
762
+ * and their corresponding values from the interaction.
763
+ *
764
+ * @returns {Record<string, any> | null} A record of option names and values if available, otherwise null.
765
+ */
766
+ options() {
767
+ const options = {};
768
+ if (this.command.groups) {
769
+ const group = this.command.groups.find((group2) => group2.name === this.group());
770
+ if (!group) return null;
771
+ const subcommand = group.subcommands.find((subcommand2) => subcommand2.name === this.subcommand());
772
+ if (!subcommand) return null;
773
+ for (const option of subcommand.options || []) {
774
+ options[option.name] = this.interaction.options.get(option.name);
775
+ }
776
+ }
777
+ if (this.command.subcommands) {
778
+ const subcommand = this.command.subcommands.find((subcommand2) => subcommand2.name === this.subcommand());
779
+ if (!subcommand) return null;
780
+ for (const option of subcommand?.options || []) {
781
+ options[option.name] = this.interaction.options.get(option.name);
782
+ }
783
+ }
784
+ if (this.command.options) {
785
+ for (const option of this.command.options) {
786
+ options[option.name] = this.interaction.options.get(option.name);
787
+ }
788
+ }
789
+ return options || null;
790
+ }
791
+ /**
792
+ * Retrieves the name of the subcommand from the current interaction.
793
+ *
794
+ * This method attempts to extract the subcommand name from the interaction options.
795
+ * If no subcommand is present or an error occurs, it returns null.
796
+ *
797
+ * @returns {string | null} The name of the subcommand if available, otherwise null.
798
+ */
799
+ subcommand() {
800
+ try {
801
+ return this.interaction.options.getSubcommand();
802
+ } catch {
803
+ return null;
804
+ }
805
+ }
806
+ /**
807
+ * Retrieves the name of the subcommand group from the current interaction.
808
+ *
809
+ * This method attempts to extract the subcommand group name from the interaction options.
810
+ * If no subcommand group is present or an error occurs, it returns null.
811
+ *
812
+ * @returns {string | null} The name of the subcommand group if available, otherwise null.
813
+ */
814
+ group() {
815
+ try {
816
+ return this.interaction.options.getSubcommandGroup();
817
+ } catch {
818
+ return null;
819
+ }
820
+ }
821
+ };
822
+
823
+ // src/validators/XernerxBaseValidator.ts
824
+ var XernerxBaseValidator = class {
825
+ static {
826
+ __name(this, "XernerxBaseValidator");
827
+ }
828
+ constructor(interaction, command) {
829
+ this.client = interaction.client;
830
+ this.interaction = interaction;
831
+ this.command = command;
832
+ this.satisified = true;
833
+ }
834
+ /**
835
+ * Checks if the command requires a premium subscription and validates the user's premium status.
836
+ * If the user does not have a premium subscription, it emits an error and sets the validation status to false.
837
+ *
838
+ * @returns A promise that resolves when the premium check is complete.
839
+ */
840
+ async premium() {
841
+ if (!this.command.premium) return;
842
+ const premium = await this.interaction.user.premium("");
843
+ if (!premium) {
844
+ this.emit({ type: "premiumCommand", message: "This command requires a premium subscription.", data: [] });
845
+ this.satisified = false;
846
+ }
847
+ }
848
+ /**
849
+ * Checks if the command is globally available or restricted to specific guilds.
850
+ * If the command is not available in the current guild, it emits an error and sets the validation status to false.
851
+ */
852
+ global() {
853
+ if (!this.interaction.guild) return;
854
+ if (!this.client.settings.global && !this.client.settings.guildId?.includes(this.interaction.guild?.id)) {
855
+ this.emit({ type: "localCommand", message: "This command is not available in this server.", data: this.client.settings.guildId });
856
+ this.satisified = false;
857
+ }
858
+ }
859
+ /**
860
+ * Emits an error event related to command execution.
861
+ *
862
+ * @param error - An object containing details about the error.
863
+ * @param error.type - The type of error that occurred.
864
+ * @param error.message - A descriptive message about the error.
865
+ * @param error.data - Optional additional data related to the error.
866
+ * @returns A promise that resolves when the error event has been emitted.
867
+ */
868
+ async emit(error) {
869
+ return await this.client.emit("commandBlock", this.interaction, this.command, error);
870
+ }
871
+ /**
872
+ * Validates the command by checking its global availability and premium status.
873
+ *
874
+ * @returns A promise that resolves to a boolean indicating whether all validation checks are satisfied.
875
+ */
876
+ async validate() {
877
+ await this.global();
878
+ await this.premium();
879
+ return this.satisified;
880
+ }
881
+ };
882
+
883
+ // src/validators/XernerxSlashCommandValidator.ts
884
+ var XernerxSlashCommandValidator = class extends XernerxBaseValidator {
885
+ static {
886
+ __name(this, "XernerxSlashCommandValidator");
887
+ }
888
+ constructor(interaction, command) {
889
+ super(interaction, command);
890
+ }
891
+ };
892
+
893
+ // src/events/slashCommandInteraction.ts
894
+ var XernerxSlashCommandInteractionEvent = class extends XernerxEventBuilder {
895
+ static {
896
+ __name(this, "XernerxSlashCommandInteractionEvent");
897
+ }
898
+ constructor() {
899
+ super("XernerxSlashCommandInteractionEvent", {
900
+ name: "slashCommandInteraction",
901
+ emitter: "client",
902
+ once: false
903
+ });
904
+ }
905
+ async run(interaction) {
906
+ const command = interaction.client.commands.slash.get(interaction.commandName);
907
+ if (!command) return;
908
+ new Promise(async (resolve) => {
909
+ if (interaction.isAutocomplete()) {
910
+ const focused = interaction.options.getFocused(true);
911
+ const options = interaction.options;
912
+ await command.autocomplete({ interaction, focused, options });
913
+ } else resolve(true);
914
+ }).then(async () => {
915
+ const args = new XernerxInteractionArguments(interaction, command);
916
+ const options = { options: args.options(), subcommand: args.subcommand(), group: args.subcommand() };
917
+ try {
918
+ await interaction.client.emit("commandStart", interaction, options, command);
919
+ const validation = new XernerxSlashCommandValidator(interaction, command);
920
+ if (!await validation.validate()) return;
921
+ if (command.defer) await interaction.deferReply();
922
+ if (await command.conditions({ interaction, ...options, command })) return;
923
+ await command.exec({ interaction, ...options, command });
924
+ await interaction.client.emit("commandFinish", interaction, options, command);
925
+ } catch (error) {
926
+ await interaction.client.emit("commandError", interaction, options, command, error);
927
+ }
928
+ });
929
+ }
930
+ };
931
+
932
+ // src/events/entitlementCreate.ts
933
+ var XernerxEntitlementCreateEvent = class extends XernerxEventBuilder {
934
+ static {
935
+ __name(this, "XernerxEntitlementCreateEvent");
936
+ }
937
+ constructor() {
938
+ super("XernerxEntitlementCreateEvent", {
939
+ name: "entitlementCreate",
940
+ emitter: "client",
941
+ once: false
942
+ });
943
+ }
944
+ async run(a, b, c) {
945
+ }
946
+ };
947
+
948
+ // src/handler/CommandHandler.ts
949
+ var CommandHandler = class extends Handler {
950
+ static {
951
+ __name(this, "CommandHandler");
219
952
  }
220
953
  constructor(client) {
221
954
  super(client);
955
+ this.loadEvents(XernerxEntitlementCreateEvent, XernerxClientReadyEvent);
956
+ }
957
+ /**
958
+ * Loads a message command from a specified file.
959
+ *
960
+ * @param file - The path to the file containing the message command to be loaded.
961
+ * @returns A promise that resolves when the file has been successfully loaded.
962
+ */
963
+ async loadMessageCommand(file) {
964
+ return await this.loadFile(file);
965
+ }
966
+ /**
967
+ * Loads message commands based on the provided options.
968
+ *
969
+ * @param options - Configuration options for loading message commands, including directory, prefix, mention, separator, handleEdits, handleDeletions, and ignore settings.
970
+ * @returns A promise that resolves when all message commands have been successfully loaded.
971
+ */
972
+ async loadMessageCommands(options) {
973
+ const config = z2.z.object({
974
+ directory: z2.z.string(),
975
+ prefix: z2.z.union([z2.z.string(), z2.z.array(z2.z.string())]).default([]),
976
+ mention: z2.z.boolean().default(false),
977
+ seperator: z2.z.string().default(" "),
978
+ handleEdits: z2.z.boolean().default(false),
979
+ handleDeletions: z2.z.boolean().default(false),
980
+ ignore: z2.z.object({
981
+ system: z2.z.boolean().default(true),
982
+ bots: z2.z.boolean().default(true),
983
+ self: z2.z.boolean().default(true)
984
+ }).default({ system: true, bots: true, self: true })
985
+ }).parse(options);
986
+ typeof config.prefix == "string" ? config.prefix = [config.prefix] : config.prefix;
987
+ this.client.handler.message = config;
988
+ const files = this.loadFiles(config.directory);
989
+ this.loadEvents(XernerxMessageCreateEvent, XernerxMessageUpdateEvent, XernerxMessageDeleteEvent);
990
+ if (!this.client.options.intents.has("GuildMessages")) new XernerxError(`Missing ${sharpyy8__default.default("GuildMessages", "txYellow")} intent, message commands will not work.`);
991
+ if (!this.client.options.intents.has("MessageContent") && !config.mention)
992
+ new XernerxError(`Missing ${sharpyy8__default.default("MessageContent", "txYellow")} intent and bot mention is turned off, message commands will not work.`);
993
+ if (!this.client.options.intents.has("MessageContent") && config.mention)
994
+ new XernerxWarn(`Missing ${sharpyy8__default.default("MessageContent", "txYellow")} intent, message commands can only be triggered by @mention.`);
995
+ for (const file of files) {
996
+ await this.loadMessageCommand(file);
997
+ }
998
+ new XernerxSuccess(`Loaded message commands: ${this.client.commands.message.map((command) => sharpyy8__default.default(command.id, "txYellow")).join(", ")}`);
999
+ }
1000
+ /**
1001
+ * Loads a slash command from a specified file.
1002
+ *
1003
+ * @param file - The path to the file containing the slash command to be loaded.
1004
+ * @returns A promise that resolves when the file has been successfully loaded.
1005
+ */
1006
+ async loadSlashCommand(file) {
1007
+ return await this.loadFile(file);
222
1008
  }
223
- uptime(timestamp) {
224
- if (!timestamp) timestamp = this.client.uptime || 0;
225
- let totalSeconds = timestamp / 1e3;
226
- let years = Math.floor(totalSeconds / 31536e3);
227
- totalSeconds %= 31536e3;
228
- let days = Math.floor(totalSeconds / 86400);
229
- totalSeconds %= 86400;
230
- let hours = Math.floor(totalSeconds / 3600);
231
- totalSeconds %= 3600;
232
- let minutes = Math.floor(totalSeconds / 60);
233
- let seconds = Math.floor(totalSeconds % 60);
234
- if (years >= 1) return `${years}y ${days}d ${hours}h ${minutes}m`;
235
- else if (days >= 1) return `${days}d ${hours}h ${minutes}m`;
236
- else if (hours >= 1) return `${hours}h ${minutes}m`;
237
- else if (minutes >= 1) return `${minutes}m ${seconds}s`;
238
- else return `${seconds}s`;
1009
+ /**
1010
+ * Loads slash commands based on the provided options.
1011
+ *
1012
+ * @param options - Configuration options for loading slash commands, including the directory where the command files are located.
1013
+ * @returns A promise that resolves when all slash commands have been successfully loaded.
1014
+ */
1015
+ async loadSlashCommands(options) {
1016
+ const config = z2.z.object({
1017
+ directory: z2.z.string()
1018
+ }).parse(options);
1019
+ this.client.handler.slash = config;
1020
+ const files = this.loadFiles(config.directory);
1021
+ for (const file of files) {
1022
+ await this.loadSlashCommand(file);
1023
+ }
1024
+ this.loadEvents(XernerxInteractionCreateEvent, XernerxSlashCommandInteractionEvent);
1025
+ new XernerxSuccess(`Loaded slash commands: ${this.client.commands.slash.map((command) => sharpyy8__default.default(command.id, "txYellow")).join(", ")}`);
1026
+ }
1027
+ /**
1028
+ * Loads and imports event files based on the provided event classes.
1029
+ *
1030
+ * @param args - An array of event classes extending XernerxEventBuilder. Each class represents an event to be loaded and imported.
1031
+ * @returns A promise that resolves when all specified events have been successfully imported.
1032
+ */
1033
+ async loadEvents(...args) {
1034
+ for (const event of args) {
1035
+ this.importFile(new event("", { name: "" }));
1036
+ }
239
1037
  }
240
1038
  };
241
1039
 
242
1040
  // src/client/XernerxClient.ts
243
- var XernerxClient = class extends Discord__namespace.Client {
1041
+ var XernerxClient = class extends discord_js.Client {
244
1042
  static {
245
1043
  __name(this, "XernerxClient");
246
1044
  }
247
- constructor(DiscordOptions, XernerxOptions, config) {
248
- super(DiscordOptions);
249
- this.settings = zod.z.object({
250
- // required settings
251
- token: zod.z.string(),
252
- // optional settings
253
- global: zod.z.boolean().default(false),
254
- owners: zod.z.array(zod.z.string()).default([]),
255
- guilds: zod.z.array(zod.z.string()).default([]),
256
- // dev settings
257
- debug: zod.z.boolean().default(false)
258
- }).parse({ ...XernerxOptions, ...config });
1045
+ constructor(options) {
1046
+ try {
1047
+ options.shards = discordHybridSharding.getInfo().SHARD_LIST;
1048
+ options.shardCount = discordHybridSharding.getInfo().TOTAL_SHARDS;
1049
+ } catch {
1050
+ new XernerxInitial("Client");
1051
+ }
1052
+ super(options);
1053
+ this.settings = z2__default.default.object({
1054
+ token: z2__default.default.string(),
1055
+ global: z2__default.default.boolean().default(false),
1056
+ guildId: z2__default.default.string().or(z2__default.default.array(z2__default.default.string()).max(5)).default([]),
1057
+ owners: z2__default.default.string().or(z2__default.default.array(z2__default.default.string()).max(5)).default([]),
1058
+ premium: z2__default.default.object({
1059
+ owners: z2__default.default.boolean().default(true),
1060
+ consume: z2__default.default.boolean().default(true),
1061
+ synchronize: z2__default.default.boolean().default(true)
1062
+ }).optional()
1063
+ }).parse(options);
1064
+ this.sharded = options.shardCount ? true : false;
1065
+ this.token = options.token;
1066
+ this.settings.guildId = typeof this.settings.guildId == "string" ? [this.settings.guildId] : this.settings.guildId;
1067
+ this.settings.owners = typeof this.settings.owners == "string" ? [this.settings.owners] : this.settings.owners;
1068
+ this.premium = this.settings.premium || {
1069
+ owners: true,
1070
+ consume: true,
1071
+ synchronize: true
1072
+ };
1073
+ delete this.settings.premium;
1074
+ this.monitisation = { skus: [] };
259
1075
  this.stats = {
260
- guilds: null,
261
- users: null,
262
- shardId: null,
1076
+ onlineSince: Number(/* @__PURE__ */ new Date()),
1077
+ guildCount: null,
1078
+ userCount: null,
263
1079
  shardCount: null,
264
- shards: null,
265
1080
  voteCount: null,
266
- votes: null
1081
+ shard: null
267
1082
  };
268
- this.util = new ClientUtil(this);
269
- start(this);
270
- this.modules = {
271
- commandHandler: new CommandHandler(this),
272
- options: {}
1083
+ this.cache = { messages: new discord_js.Collection(), slash: new discord_js.Collection() };
1084
+ this.handler = {
1085
+ message: { directory: null },
1086
+ slash: { directory: null }
273
1087
  };
274
- this.commands = {
275
- message: new Discord__namespace.Collection(),
276
- slash: new Discord__namespace.Collection(),
277
- context: new Discord__namespace.Collection(),
278
- stats: {
279
- slash: {
280
- local: 0,
281
- global: 0
282
- },
283
- message: {
284
- local: 0,
285
- global: 0
286
- },
287
- context: {
288
- local: 0,
289
- global: 0
290
- }
291
- }
292
- };
293
- this.events = new Discord__namespace.Collection();
294
- this.inhibitors = new Discord__namespace.Collection();
295
- this.connect();
1088
+ this.commands = { message: new discord_js.Collection(), slash: new discord_js.Collection() };
1089
+ this.events = new discord_js.Collection();
1090
+ if (this.sharded) this.cluster = new discordHybridSharding.ClusterClient(this);
1091
+ this.modules = { eventHandler: new EventHandler(this), commandHandler: new CommandHandler(this) };
296
1092
  }
1093
+ /**
1094
+ * Connects the client to Discord and initializes various client statistics and handlers.
1095
+ *
1096
+ * @returns A promise that resolves when the client successfully logs in, or rejects with an error message if the login fails.
1097
+ */
297
1098
  async connect() {
298
- this.deploy();
299
- this.login(this.settings.token);
300
- }
301
- async deploy() {
302
- this.once("ready", async (client) => {
303
- const commands = { local: [], global: [] };
304
- if (this.settings.global) {
305
- if (!this.modules.options.slash?.global) commands.global.push(...this.commands.slash);
306
- else {
307
- commands.global.push(...this.commands.slash.filter((c) => c.global));
308
- commands.local.push(...this.commands.slash.filter((c) => !c.global));
309
- }
310
- if (!this.modules.options.context?.global) commands.global.push(...this.commands.context);
311
- else {
312
- commands.global.push(...this.commands.context.filter((c) => c.global));
313
- commands.local.push(...this.commands.context.filter((c) => !c.global));
314
- }
315
- } else commands.local.push(...this.commands.context, ...this.commands.slash);
316
- for (const id of this.settings.guilds) {
317
- const guild = await this.guilds.fetch(id);
318
- if (!commands.local.length) break;
319
- if (this.settings.debug) XernerxLog_default.debug(`Attempting to deploy commands to guild: ${sharpyy2__default.default(guild.name, "txBlue")}`);
320
- this.rest.put(Discord__namespace.Routes.applicationGuildCommands(client.user.id, id), { body: commands.local.map(([id2, command]) => command.toJSON()) });
321
- await XernerxLog_default.box(
322
- commands.local.map(([id2]) => sharpyy2__default.default(id2, "txYellow")).join(", "),
323
- "red",
324
- `Deployed ${sharpyy2__default.default("local", "txRed", "bold")} commands in ${sharpyy2__default.default(guild.name, "txBlue")}`
1099
+ new XernerxInfo(`${this.cluster ? `${sharpyy8__default.default(`Shard ${this.cluster.id}`, "txCyan")} | ` : ""}Connecting...`);
1100
+ this.on("clientReady", async (client) => {
1101
+ this.monitisation.skus = await new XernerxMonitisation(client).sku();
1102
+ if (this.sharded && this.cluster) {
1103
+ this.stats.shard = {
1104
+ shardId: this.cluster.id,
1105
+ onlineSince: Number(/* @__PURE__ */ new Date()),
1106
+ guildCount: null,
1107
+ userCount: null
1108
+ };
1109
+ setInterval(async () => {
1110
+ if (!this.cluster || !this.stats.shard) return;
1111
+ this.stats.guildCount = (await this.cluster.broadcastEval("this.guilds.cache.size")).reduce((a, b) => a + b, 0);
1112
+ this.stats.userCount = (await this.cluster.broadcastEval("this.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0)")).reduce((a, b) => a + b, 0);
1113
+ this.stats.shardCount = discordHybridSharding.getInfo().TOTAL_SHARDS;
1114
+ this.stats.shard.guildCount = client.guilds.cache.size;
1115
+ this.stats.voteCount = 0;
1116
+ this.stats.shard.userCount = client.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0);
1117
+ }, 1e3);
1118
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
1119
+ new XernerxSuccess(
1120
+ `${sharpyy8__default.default(`Shard ${this.cluster.id}`, "txCyan")} | Signed in as ${sharpyy8__default.default(client.user?.tag, "txBlue")}, watching ${sharpyy8__default.default(String(this.stats.shard?.guildCount?.toLocaleString()), "txCyan")} guilds and users: ${sharpyy8__default.default(String(this.stats.shard?.userCount?.toLocaleString()), "txCyan")}`
1121
+ );
1122
+ } else {
1123
+ setInterval(() => {
1124
+ this.stats.guildCount = client.guilds.cache.size;
1125
+ this.stats.userCount = client.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0);
1126
+ this.stats.voteCount = 0;
1127
+ this.stats.shardCount = 0;
1128
+ }, 1e3);
1129
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
1130
+ new XernerxSuccess(
1131
+ `Signed in as ${sharpyy8__default.default(client.user?.tag, "txBlue")}, watching ${sharpyy8__default.default(String(this.stats.guildCount?.toLocaleString()), "txCyan")} guilds and users: ${sharpyy8__default.default(String(this.stats.userCount?.toLocaleString()), "txCyan")}`
325
1132
  );
326
- }
327
- if (this.settings.global) {
328
- if (this.settings.debug) XernerxLog_default.debug(`Attempting to deploy commands globally`);
329
- this.rest.put(Discord__namespace.Routes.applicationCommands(client.user.id), { body: [] });
330
- await XernerxLog_default.box(commands.global.map(([id]) => sharpyy2__default.default(id, "txYellow")).join(", "), "green", `Deployed ${sharpyy2__default.default("global", "txGreen", "bold")} commands`);
331
1133
  }
332
1134
  });
1135
+ return await this.login(this.token).catch((error) => new XernerxError(error.message, 1));
333
1136
  }
334
1137
  };
335
- var XernerxSlashCommand = class extends Discord__namespace.SlashCommandBuilder {
1138
+ var XernerxMessageCommandBuilder = class extends XernerxBaseBuilder {
336
1139
  static {
337
- __name(this, "XernerxSlashCommand");
1140
+ __name(this, "XernerxMessageCommandBuilder");
338
1141
  }
339
- constructor(options) {
340
- super();
341
- this._id = options.id;
342
- this.setName(options.name);
343
- this.setDescription(options.description);
344
- this.global = options.global ?? true;
1142
+ /**
1143
+ * Constructs an instance of XernerxMessageCommandBuilder.
1144
+ *
1145
+ * @param id - A unique identifier for the command.
1146
+ * @param options - An object containing configuration options for the command.
1147
+ * @param options.name - The name of the command.
1148
+ * @param options.alias - An alias or an array of aliases for the command.
1149
+ * @param options.prefix - A prefix or an array of prefixes for the command.
1150
+ * @param options.premium - An array indicating premium features or settings.
1151
+ */
1152
+ constructor(id, options) {
1153
+ super(id, options);
1154
+ options = z2.z.object({
1155
+ name: z2.z.string(),
1156
+ alias: z2.z.union([z2.z.string(), z2.z.array(z2.z.string())]).default([]),
1157
+ prefix: z2.z.union([z2.z.string(), z2.z.array(z2.z.string())]).default([]),
1158
+ premium: z2.z.any()
1159
+ }).parse(options);
1160
+ this.name = options.name;
1161
+ this.alias = typeof options.alias == "string" ? [options.alias] : options.alias;
1162
+ this.prefix = typeof options.prefix == "string" ? [options.prefix] : options.prefix;
1163
+ this.premium = options.premium;
1164
+ this.filetype = "XernerxMessageCommand";
1165
+ }
1166
+ /**
1167
+ * Executes the command logic. This function is intended to be overridden by subclasses.
1168
+ * If not overridden, it will log a warning indicating that the command will not respond.
1169
+ *
1170
+ * @param args - A variable number of arguments that can be passed to the command execution.
1171
+ * @returns A promise that resolves to any value, depending on the implementation.
1172
+ */
1173
+ async exec(...args) {
1174
+ new XernerxWarn(`${this.id} has no exec function, command will not respond.`);
1175
+ }
1176
+ };
1177
+ var XernerxSlashCommandBuilder = class extends XernerxBaseBuilder {
1178
+ static {
1179
+ __name(this, "XernerxSlashCommandBuilder");
1180
+ }
1181
+ constructor(id, options) {
1182
+ super(id, options);
1183
+ options = z2.z.object({
1184
+ // Discord
1185
+ name: z2.z.string(),
1186
+ locales: z2.z.record(z2.z.string(), z2.z.object({ name: z2.z.string(), description: z2.z.string() })).optional(),
1187
+ description: z2.z.string(),
1188
+ contexts: z2.z.array(z2.z.custom()).default(["Guild"]),
1189
+ integration: z2.z.array(z2.z.custom()).default(["GuildInstall"]),
1190
+ nsfw: z2.z.boolean().default(false),
1191
+ options: z2.z.any(),
1192
+ subcommands: z2.z.any(),
1193
+ groups: z2.z.any(),
1194
+ // Xernerx
1195
+ premium: z2.z.boolean().default(false),
1196
+ defer: z2.z.boolean().default(false),
1197
+ deploy: z2.z.object({ global: z2.z.boolean().default(true), guilds: z2.z.string().or(z2.z.array(z2.z.string())).default([]) }).optional(),
1198
+ info: z2.z.string().optional(),
1199
+ usage: z2.z.string().optional(),
1200
+ category: z2.z.string().optional(),
1201
+ cooldown: z2.z.number().min(0).default(0),
1202
+ strict: z2.z.object({
1203
+ owner: z2.z.boolean().default(false),
1204
+ users: z2.z.array(z2.z.string()).default([]),
1205
+ channels: z2.z.array(z2.z.string()).default([]),
1206
+ guilds: z2.z.array(z2.z.string()).default([]),
1207
+ types: z2.z.enum(discord_js.ChannelType).optional()
1208
+ }).optional(),
1209
+ ignore: z2.z.object({
1210
+ owner: z2.z.boolean().default(false),
1211
+ users: z2.z.array(z2.z.string()).default([]),
1212
+ channels: z2.z.array(z2.z.string()).default([]),
1213
+ guilds: z2.z.array(z2.z.string()).default([]),
1214
+ types: z2.z.enum(discord_js.ChannelType).optional()
1215
+ }).optional(),
1216
+ permissions: z2.z.object({
1217
+ client: z2.z.union([z2.z.array(z2.z.custom()), z2.z.number(), z2.z.bigint()]).nullable().default(null),
1218
+ user: z2.z.union([z2.z.array(z2.z.custom()), z2.z.number(), z2.z.bigint()]).nullable().default(null)
1219
+ }).default({ client: null, user: null })
1220
+ }).parse(options);
1221
+ this.name = options.name;
1222
+ this.description = options.description;
1223
+ this.info = options.info;
1224
+ this.usage = options.usage;
1225
+ this.category = options.category;
1226
+ this.cooldown = options.cooldown;
1227
+ this.premium = options.premium || false;
1228
+ this.defer = options.defer;
1229
+ this.deploy = {
1230
+ global: options.deploy?.global ?? true,
1231
+ guilds: typeof options.deploy?.guilds == "string" ? [options.deploy.guilds] : options.deploy?.guilds || []
1232
+ };
345
1233
  this.filetype = "XernerxSlashCommand";
346
- this.collection = "slash.commands";
1234
+ this.permissions = options.permissions;
1235
+ this.strict = options.strict;
1236
+ this.ignore = options.ignore;
1237
+ this.data = new discord_js.SlashCommandBuilder();
1238
+ this.data.setName(this.name);
1239
+ this.data.setDescription(this.description);
1240
+ this.data.setContexts(...options.contexts?.map((context) => discord_js.InteractionContextType[context]) || [discord_js.InteractionContextType.Guild]);
1241
+ this.data.setIntegrationTypes(
1242
+ ...options.integration?.map((integration) => discord_js.ApplicationIntegrationType[integration]) || [discord_js.ApplicationIntegrationType.GuildInstall]
1243
+ );
1244
+ if (Array.isArray(options.permissions?.user))
1245
+ this.data.setDefaultMemberPermissions(options.permissions?.user?.map((permission) => discord_js.PermissionFlagsBits[permission]).reduce((a, b) => a += b));
1246
+ else this.data.setDefaultMemberPermissions(options.permissions?.user || null);
1247
+ this.data.setNSFW(options.nsfw || false);
1248
+ for (const locale of Object.entries(options.locales || [])) {
1249
+ this.data.setNameLocalization(locale[0], locale[1].name);
1250
+ this.data.setDescriptionLocalization(locale[0], locale[1].description);
1251
+ }
1252
+ if (options.options && options?.options?.length > 0) {
1253
+ this.addArguments(this.data, options.options);
1254
+ this.options = options.options;
1255
+ }
1256
+ if (options.subcommands && options?.subcommands?.length > 0) {
1257
+ this.addSubcommands(this.data, options.subcommands);
1258
+ this.subcommands = options.subcommands;
1259
+ }
1260
+ if (options.groups && options?.groups?.length > 0) {
1261
+ this.addSubcommandGroups(options.groups);
1262
+ this.groups = options.groups;
1263
+ }
1264
+ this.client = this.client;
1265
+ }
1266
+ /**
1267
+ * Handles the autocomplete functionality for a slash command.
1268
+ *
1269
+ * @param args - The arguments for the autocomplete function, which include the context and options for the command.
1270
+ * @returns A promise that resolves to either void or any value, depending on the implementation.
1271
+ */
1272
+ async autocomplete(args) {
1273
+ }
1274
+ /**
1275
+ * Evaluates conditions for executing a slash command.
1276
+ *
1277
+ * @param args - The arguments for the conditions function, which include the context and options for the command.
1278
+ * @returns A promise that resolves to either void or any value, depending on the implementation.
1279
+ */
1280
+ async conditions(args) {
1281
+ }
1282
+ /**
1283
+ * Executes the slash command.
1284
+ *
1285
+ * @param args - The arguments for the exec function, which include the context and options for the command.
1286
+ * @returns A promise that resolves to either void or any value, depending on the implementation.
1287
+ */
1288
+ async exec(args) {
1289
+ new XernerxWarn(`${this.id} has no exec function, command will not respond.`);
1290
+ }
1291
+ addArguments(command, args) {
1292
+ for (const argument of args) {
1293
+ let slashCommandArgumentType = `${argument.type.charAt(0).toUpperCase()}${argument.type.slice(1).toLowerCase()}`;
1294
+ command[`add${slashCommandArgumentType}Option`]((option) => {
1295
+ option.setName(argument.name).setDescription(argument.description).setRequired(argument.required || false);
1296
+ for (const locale of Object.entries(argument.locales || [])) {
1297
+ option.setNameLocalization(locale[0], locale[1].name);
1298
+ option.setDescriptionLocalization(locale[0], locale[1].description);
1299
+ }
1300
+ if (slashCommandArgumentType === "String") {
1301
+ if (argument.choices) {
1302
+ for (const choice of argument.choices) {
1303
+ const locales = choice?.locales;
1304
+ option.addChoices({ ...choice, name_localizations: locales });
1305
+ }
1306
+ }
1307
+ if (argument.maxLength) option.setMaxLength(argument.maxLength);
1308
+ if (argument.minLength) option.setMinLength(argument.minLength);
1309
+ option.setAutocomplete(argument.autocomplete || false);
1310
+ }
1311
+ return option;
1312
+ });
1313
+ }
1314
+ }
1315
+ addSubcommands(method, subcommands) {
1316
+ for (const subcommand of subcommands) {
1317
+ let sub = new discord_js.SlashCommandSubcommandBuilder().setName(subcommand.name).setDescription(subcommand.description);
1318
+ for (const locale of Object.entries(subcommand.locales || [])) {
1319
+ sub.setNameLocalization(locale[0], locale[1].name);
1320
+ sub.setDescriptionLocalization(locale[0], locale[1].description);
1321
+ }
1322
+ if (subcommand.options && subcommand?.options?.length > 0) this.addArguments(sub, subcommand.options);
1323
+ method.addSubcommand(sub);
1324
+ }
1325
+ }
1326
+ /**
1327
+ * Adds subcommand groups to the slash command builder.
1328
+ *
1329
+ * @param groups - An array of subcommand groups to be added. Each group contains a name, description, locales, and subcommands.
1330
+ */
1331
+ addSubcommandGroups(groups) {
1332
+ for (const group of groups) {
1333
+ let subcommandGroup = new discord_js.SlashCommandSubcommandGroupBuilder().setName(group.name).setDescription(group.description);
1334
+ for (const locale of Object.entries(group.locales || [])) {
1335
+ subcommandGroup.setNameLocalization(locale[0], locale[1].name);
1336
+ subcommandGroup.setDescriptionLocalization(locale[0], locale[1].description);
1337
+ }
1338
+ if (group.subcommands?.length > 0) this.addSubcommands(subcommandGroup, group.subcommands);
1339
+ this.data.addSubcommandGroup(subcommandGroup);
1340
+ }
347
1341
  }
348
1342
  };
349
1343
 
350
1344
  exports.XernerxClient = XernerxClient;
351
- exports.XernerxSlashCommand = XernerxSlashCommand;
1345
+ exports.XernerxEventBuilder = XernerxEventBuilder;
1346
+ exports.XernerxMessageCommandBuilder = XernerxMessageCommandBuilder;
1347
+ exports.XernerxShardClient = XernerxShardClient;
1348
+ exports.XernerxSlashCommandBuilder = XernerxSlashCommandBuilder;
1349
+ Object.keys(discord_js).forEach(function (k) {
1350
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1351
+ enumerable: true,
1352
+ get: function () { return discord_js[k]; }
1353
+ });
1354
+ });
352
1355
  //# sourceMappingURL=main.cjs.map
353
1356
  //# sourceMappingURL=main.cjs.map