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