vimcord 1.0.28 → 1.0.30
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/dist/index.cjs +1604 -1570
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +83 -47
- package/dist/index.d.ts +83 -47
- package/dist/index.js +1566 -1531
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
BUILTIN_ContextCommandHandler: () => BUILTIN_ContextCommandHandler,
|
|
34
|
+
BUILTIN_PrefixCommandHandler: () => BUILTIN_PrefixCommandHandler,
|
|
35
|
+
BUILTIN_SlashCommandHandler: () => BUILTIN_SlashCommandHandler,
|
|
33
36
|
BaseCommandBuilder: () => BaseCommandBuilder,
|
|
34
37
|
BaseCommandManager: () => BaseCommandManager,
|
|
35
38
|
BetterCollector: () => BetterCollector,
|
|
@@ -68,7 +71,6 @@ __export(index_exports, {
|
|
|
68
71
|
VimcordCLI: () => VimcordCLI,
|
|
69
72
|
__zero: () => __zero,
|
|
70
73
|
cleanMention: () => cleanMention,
|
|
71
|
-
clientInstances: () => clientInstances,
|
|
72
74
|
createClient: () => createClient,
|
|
73
75
|
createMongoPlugin: () => createMongoPlugin,
|
|
74
76
|
createMongoSchema: () => createMongoSchema,
|
|
@@ -87,9 +89,7 @@ __export(index_exports, {
|
|
|
87
89
|
fetchMessage: () => fetchMessage,
|
|
88
90
|
fetchRole: () => fetchRole,
|
|
89
91
|
fetchUser: () => fetchUser,
|
|
90
|
-
formatThousands: () => formatThousands,
|
|
91
92
|
getCallerFileName: () => getCallerFileName,
|
|
92
|
-
getClientInstances: () => getClientInstances,
|
|
93
93
|
getFirstMentionId: () => getFirstMentionId,
|
|
94
94
|
getMessageMention: () => getMessageMention,
|
|
95
95
|
getProcessDir: () => getProcessDir,
|
|
@@ -99,7 +99,6 @@ __export(index_exports, {
|
|
|
99
99
|
isMentionOrSnowflake: () => isMentionOrSnowflake,
|
|
100
100
|
logger: () => logger,
|
|
101
101
|
prompt: () => prompt,
|
|
102
|
-
retryExponentialBackoff: () => retryExponentialBackoff,
|
|
103
102
|
sendCommandErrorEmbed: () => sendCommandErrorEmbed,
|
|
104
103
|
useClient: () => useClient,
|
|
105
104
|
useReadyClient: () => useReadyClient,
|
|
@@ -528,6 +527,10 @@ var ContextCommandBuilder = class extends BaseCommandBuilder {
|
|
|
528
527
|
// src/utils/dir.ts
|
|
529
528
|
var import_node_path = __toESM(require("path"));
|
|
530
529
|
var import_qznt = require("qznt");
|
|
530
|
+
function getCallerFileName() {
|
|
531
|
+
const stack = new Error().stack?.split("\n");
|
|
532
|
+
return stack?.at(4)?.split("at file")?.at(1)?.split("/").at(-1)?.split(":").at(0)?.split(".").at(0);
|
|
533
|
+
}
|
|
531
534
|
function getProcessDir() {
|
|
532
535
|
const mainPath = process.argv[1];
|
|
533
536
|
if (!mainPath) return "";
|
|
@@ -537,9 +540,7 @@ async function importModulesFromDir(dir, suffix) {
|
|
|
537
540
|
const cwd = getProcessDir();
|
|
538
541
|
const MODULE_RELATIVE_PATH = import_node_path.default.join(cwd, dir);
|
|
539
542
|
const MODULE_LOG_PATH = dir;
|
|
540
|
-
const files = import_qznt.$.fs.readDir(MODULE_RELATIVE_PATH).filter(
|
|
541
|
-
(fn) => fn.endsWith(`${suffix ? `.${suffix}` : ""}.js`) || fn.endsWith(`${suffix ? `.${suffix}` : ""}.ts`)
|
|
542
|
-
);
|
|
543
|
+
const files = import_qznt.$.fs.readDir(MODULE_RELATIVE_PATH).filter((fn) => fn.endsWith(`${suffix ? `.${suffix}` : ""}.js`) || fn.endsWith(`${suffix ? `.${suffix}` : ""}.ts`));
|
|
543
544
|
if (!files.length) {
|
|
544
545
|
return [];
|
|
545
546
|
}
|
|
@@ -564,10 +565,6 @@ async function importModulesFromDir(dir, suffix) {
|
|
|
564
565
|
}
|
|
565
566
|
return filteredModules;
|
|
566
567
|
}
|
|
567
|
-
function getCallerFileName() {
|
|
568
|
-
const stack = new Error().stack?.split("\n");
|
|
569
|
-
return stack?.at(4)?.split("at file")?.at(1)?.split("/").at(-1)?.split(":").at(0)?.split(".").at(0);
|
|
570
|
-
}
|
|
571
568
|
|
|
572
569
|
// src/builders/event.builder.ts
|
|
573
570
|
var import_node_crypto2 = require("crypto");
|
|
@@ -923,7 +920,7 @@ var SlashCommandBuilder = class extends BaseCommandBuilder {
|
|
|
923
920
|
};
|
|
924
921
|
|
|
925
922
|
// src/client.ts
|
|
926
|
-
var
|
|
923
|
+
var import_discord11 = require("discord.js");
|
|
927
924
|
var import_dotenv = __toESM(require("dotenv"));
|
|
928
925
|
|
|
929
926
|
// src/configs/tools.config.ts
|
|
@@ -1044,1280 +1041,1551 @@ function createVimcordContextCommandConfig(options = {}) {
|
|
|
1044
1041
|
return import_lodash10.default.merge(defaultConfig5, options);
|
|
1045
1042
|
}
|
|
1046
1043
|
|
|
1047
|
-
// src/
|
|
1048
|
-
var
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
var
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
const { prefixEmoji = null, prefix = null, minLevel = 0 /* DEBUG */, showTimestamp = true } = options || {};
|
|
1073
|
-
this.logPrefixEmoji = prefixEmoji;
|
|
1074
|
-
this.logPrefix = prefix;
|
|
1075
|
-
this.minLevel = minLevel;
|
|
1076
|
-
this.showTimestamp = showTimestamp;
|
|
1077
|
-
this.colorScheme = {
|
|
1078
|
-
...LOGGER_COLORS,
|
|
1079
|
-
...options?.colors
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
formatTimestamp() {
|
|
1083
|
-
if (!this.showTimestamp) return "";
|
|
1084
|
-
const now = /* @__PURE__ */ new Date();
|
|
1085
|
-
const time = now.toLocaleTimeString("en-US", {
|
|
1086
|
-
hour12: false,
|
|
1087
|
-
hour: "2-digit",
|
|
1088
|
-
minute: "2-digit",
|
|
1089
|
-
second: "2-digit"
|
|
1090
|
-
});
|
|
1091
|
-
return import_chalk.default.hex(this.colorScheme.muted)(`[${time}]`);
|
|
1092
|
-
}
|
|
1093
|
-
formatPrefix() {
|
|
1094
|
-
if (!this.logPrefix) return "";
|
|
1095
|
-
return import_chalk.default.bold.hex(this.colorScheme.primary)(
|
|
1096
|
-
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
1097
|
-
);
|
|
1044
|
+
// src/utils/sendCommandErrorEmbed.ts
|
|
1045
|
+
var import_discord6 = require("discord.js");
|
|
1046
|
+
|
|
1047
|
+
// src/tools/BetterEmbed.ts
|
|
1048
|
+
var import_discord5 = require("discord.js");
|
|
1049
|
+
|
|
1050
|
+
// src/tools/dynaSend.ts
|
|
1051
|
+
var import_discord4 = require("discord.js");
|
|
1052
|
+
|
|
1053
|
+
// src/tools/types.ts
|
|
1054
|
+
var SendMethod = /* @__PURE__ */ ((SendMethod2) => {
|
|
1055
|
+
SendMethod2[SendMethod2["Reply"] = 0] = "Reply";
|
|
1056
|
+
SendMethod2[SendMethod2["EditReply"] = 1] = "EditReply";
|
|
1057
|
+
SendMethod2[SendMethod2["FollowUp"] = 2] = "FollowUp";
|
|
1058
|
+
SendMethod2[SendMethod2["Channel"] = 3] = "Channel";
|
|
1059
|
+
SendMethod2[SendMethod2["MessageReply"] = 4] = "MessageReply";
|
|
1060
|
+
SendMethod2[SendMethod2["MessageEdit"] = 5] = "MessageEdit";
|
|
1061
|
+
SendMethod2[SendMethod2["User"] = 6] = "User";
|
|
1062
|
+
return SendMethod2;
|
|
1063
|
+
})(SendMethod || {});
|
|
1064
|
+
|
|
1065
|
+
// src/tools/dynaSend.ts
|
|
1066
|
+
var DynaSend = class {
|
|
1067
|
+
static forceArray(value) {
|
|
1068
|
+
return Array.isArray(value) ? value : [value];
|
|
1098
1069
|
}
|
|
1099
|
-
|
|
1100
|
-
return
|
|
1070
|
+
static isInteractionCallback(obj) {
|
|
1071
|
+
return obj instanceof import_discord4.InteractionCallbackResponse;
|
|
1101
1072
|
}
|
|
1102
|
-
|
|
1103
|
-
return
|
|
1073
|
+
static filterFlags(flags, excludeFlags) {
|
|
1074
|
+
if (!flags) return void 0;
|
|
1075
|
+
const flagArray = this.forceArray(flags);
|
|
1076
|
+
return flagArray.filter((flag) => !excludeFlags.includes(flag));
|
|
1104
1077
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1078
|
+
static detectSendMethod(handler) {
|
|
1079
|
+
if (handler instanceof import_discord4.BaseInteraction) {
|
|
1080
|
+
return handler.replied || handler.deferred ? 1 /* EditReply */ : 0 /* Reply */;
|
|
1081
|
+
}
|
|
1082
|
+
if (handler instanceof import_discord4.BaseChannel) return 3 /* Channel */;
|
|
1083
|
+
if (handler instanceof import_discord4.Message) return 4 /* MessageReply */;
|
|
1084
|
+
if (handler instanceof import_discord4.GuildMember || handler instanceof import_discord4.User) return 6 /* User */;
|
|
1085
|
+
throw new Error("[DynaSend] Unable to determine send method for handler type");
|
|
1107
1086
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1087
|
+
static validateSendMethod(handler, method) {
|
|
1088
|
+
const interactionMethods = [0 /* Reply */, 1 /* EditReply */, 2 /* FollowUp */];
|
|
1089
|
+
if (interactionMethods.includes(method) && !(handler instanceof import_discord4.BaseInteraction)) {
|
|
1090
|
+
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires BaseInteraction handler`);
|
|
1091
|
+
}
|
|
1092
|
+
if (method === 3 /* Channel */ && !(handler instanceof import_discord4.BaseChannel)) {
|
|
1093
|
+
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires BaseChannel handler`);
|
|
1094
|
+
}
|
|
1095
|
+
if ([4 /* MessageReply */, 5 /* MessageEdit */].includes(method) && !(handler instanceof import_discord4.Message)) {
|
|
1096
|
+
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires Message handler`);
|
|
1097
|
+
}
|
|
1098
|
+
if (method === 6 /* User */ && !(handler instanceof import_discord4.GuildMember || handler instanceof import_discord4.User)) {
|
|
1099
|
+
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires User or GuildMember handler`);
|
|
1100
|
+
}
|
|
1110
1101
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1102
|
+
static createMessageData(options, method) {
|
|
1103
|
+
const baseData = {
|
|
1104
|
+
content: options.content,
|
|
1105
|
+
embeds: options.embeds,
|
|
1106
|
+
components: options.components,
|
|
1107
|
+
files: options.files,
|
|
1108
|
+
allowedMentions: options.allowedMentions,
|
|
1109
|
+
tts: options.tts
|
|
1110
|
+
};
|
|
1111
|
+
switch (method) {
|
|
1112
|
+
case 0 /* Reply */:
|
|
1113
|
+
return {
|
|
1114
|
+
...baseData,
|
|
1115
|
+
flags: options.flags,
|
|
1116
|
+
withResponse: options.withResponse,
|
|
1117
|
+
poll: options.poll
|
|
1116
1118
|
};
|
|
1117
|
-
|
|
1119
|
+
case 1 /* EditReply */:
|
|
1120
|
+
return {
|
|
1121
|
+
...baseData,
|
|
1122
|
+
flags: this.filterFlags(options.flags, ["Ephemeral", "SuppressNotifications"]),
|
|
1123
|
+
withResponse: options.withResponse,
|
|
1124
|
+
poll: options.poll
|
|
1125
|
+
};
|
|
1126
|
+
case 2 /* FollowUp */:
|
|
1127
|
+
return {
|
|
1128
|
+
...baseData,
|
|
1129
|
+
flags: options.flags,
|
|
1130
|
+
withResponse: options.withResponse,
|
|
1131
|
+
poll: options.poll
|
|
1132
|
+
};
|
|
1133
|
+
case 3 /* Channel */:
|
|
1134
|
+
return {
|
|
1135
|
+
...baseData,
|
|
1136
|
+
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1137
|
+
poll: options.poll,
|
|
1138
|
+
stickers: options.stickers,
|
|
1139
|
+
reply: options.reply
|
|
1140
|
+
};
|
|
1141
|
+
case 4 /* MessageReply */:
|
|
1142
|
+
return {
|
|
1143
|
+
...baseData,
|
|
1144
|
+
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1145
|
+
poll: options.poll,
|
|
1146
|
+
stickers: options.stickers
|
|
1147
|
+
};
|
|
1148
|
+
case 5 /* MessageEdit */:
|
|
1149
|
+
return {
|
|
1150
|
+
...baseData,
|
|
1151
|
+
flags: this.filterFlags(options.flags, ["Ephemeral", "SuppressNotifications"])
|
|
1152
|
+
};
|
|
1153
|
+
case 6 /* User */:
|
|
1154
|
+
return {
|
|
1155
|
+
...baseData,
|
|
1156
|
+
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1157
|
+
poll: options.poll,
|
|
1158
|
+
forward: options.forward,
|
|
1159
|
+
stickers: options.stickers
|
|
1160
|
+
};
|
|
1161
|
+
default:
|
|
1162
|
+
return baseData;
|
|
1118
1163
|
}
|
|
1119
|
-
return this;
|
|
1120
|
-
}
|
|
1121
|
-
setPrefix(prefix) {
|
|
1122
|
-
this.logPrefix = prefix;
|
|
1123
|
-
return this;
|
|
1124
|
-
}
|
|
1125
|
-
setPrefixEmoji(prefixEmoji) {
|
|
1126
|
-
this.logPrefixEmoji = prefixEmoji;
|
|
1127
|
-
return this;
|
|
1128
1164
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1165
|
+
static async executeSend(handler, method, data) {
|
|
1166
|
+
try {
|
|
1167
|
+
switch (method) {
|
|
1168
|
+
case 0 /* Reply */: {
|
|
1169
|
+
const response = await handler.reply(data);
|
|
1170
|
+
return this.isInteractionCallback(response) ? response.resource?.message ?? null : null;
|
|
1171
|
+
}
|
|
1172
|
+
case 1 /* EditReply */:
|
|
1173
|
+
return await handler.editReply(data);
|
|
1174
|
+
case 2 /* FollowUp */:
|
|
1175
|
+
return await handler.followUp(data);
|
|
1176
|
+
case 3 /* Channel */:
|
|
1177
|
+
return await handler.send(data);
|
|
1178
|
+
case 4 /* MessageReply */:
|
|
1179
|
+
return await handler.reply(data);
|
|
1180
|
+
case 5 /* MessageEdit */: {
|
|
1181
|
+
const message = handler;
|
|
1182
|
+
if (!message.editable) {
|
|
1183
|
+
console.warn("[DynaSend] Message is not editable");
|
|
1184
|
+
return null;
|
|
1185
|
+
}
|
|
1186
|
+
return await message.edit(data);
|
|
1187
|
+
}
|
|
1188
|
+
case 6 /* User */:
|
|
1189
|
+
return await handler.send(data);
|
|
1190
|
+
default:
|
|
1191
|
+
throw new Error(`[DynaSend] Unknown send method '${method}'`);
|
|
1192
|
+
}
|
|
1193
|
+
} catch (error) {
|
|
1194
|
+
console.error(`[DynaSend] Error with method '${SendMethod[method]}':`, error);
|
|
1195
|
+
return null;
|
|
1196
|
+
}
|
|
1132
1197
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1198
|
+
static scheduleDelete(message, delay) {
|
|
1199
|
+
if (delay < 1e3) {
|
|
1200
|
+
console.warn(`[DynaSend] Delete delay is less than 1 second (${delay}ms). Is this intentional?`);
|
|
1201
|
+
}
|
|
1202
|
+
setTimeout(async () => {
|
|
1203
|
+
try {
|
|
1204
|
+
if (message.deletable) {
|
|
1205
|
+
await message.delete();
|
|
1206
|
+
}
|
|
1207
|
+
} catch (error) {
|
|
1208
|
+
console.error("[DynaSend] Error deleting message:", error);
|
|
1209
|
+
}
|
|
1210
|
+
}, delay);
|
|
1136
1211
|
}
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1212
|
+
static async send(handler, options) {
|
|
1213
|
+
const sendMethod = options.sendMethod ?? this.detectSendMethod(handler);
|
|
1214
|
+
this.validateSendMethod(handler, sendMethod);
|
|
1215
|
+
const messageData = this.createMessageData(options, sendMethod);
|
|
1216
|
+
const message = await this.executeSend(handler, sendMethod, messageData);
|
|
1217
|
+
if (options.deleteAfter && message) {
|
|
1218
|
+
this.scheduleDelete(message, options.deleteAfter);
|
|
1219
|
+
}
|
|
1220
|
+
return message;
|
|
1143
1221
|
}
|
|
1144
|
-
|
|
1145
|
-
|
|
1222
|
+
};
|
|
1223
|
+
async function dynaSend(handler, options) {
|
|
1224
|
+
return DynaSend.send(handler, options);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// src/tools/BetterEmbed.ts
|
|
1228
|
+
var BetterEmbed = class _BetterEmbed {
|
|
1229
|
+
embed = new import_discord5.EmbedBuilder();
|
|
1230
|
+
data;
|
|
1231
|
+
config;
|
|
1232
|
+
/** A powerful wrapper for `EmbedBuilder` that introduces useful features
|
|
1233
|
+
*
|
|
1234
|
+
* Auto-shorthand context formatting (_ACF_) is enabled by default
|
|
1235
|
+
*
|
|
1236
|
+
* All functions utilize _ACF_ unless `BetterEmbed.acf` is set to `false`
|
|
1237
|
+
*
|
|
1238
|
+
* ___Use a blackslash___ `\` ___to escape any context___
|
|
1239
|
+
*
|
|
1240
|
+
* \- - - Author Context - - -
|
|
1241
|
+
* - __`$USER`__: _author's mention (@xsqu1znt)_
|
|
1242
|
+
* - __`$USER_NAME`__: _author's username_
|
|
1243
|
+
* - __`$DISPLAY_NAME`__: _author's display name (requires `GuildMember` context)_
|
|
1244
|
+
* - __`$USER_AVATAR`__: _author's avatar_
|
|
1245
|
+
*
|
|
1246
|
+
* \- - - Client Context - - -
|
|
1247
|
+
*
|
|
1248
|
+
* - __`$BOT_AVATAR`__: _bot's avatar_
|
|
1249
|
+
*
|
|
1250
|
+
* \- - - Shorthand Context - - -
|
|
1251
|
+
* - __`$YEAR`__: _YYYY_
|
|
1252
|
+
* - __`$MONTH`__: _MM_
|
|
1253
|
+
* - __`$DAY`__: _DD_
|
|
1254
|
+
* - __`$year`__: _YY_
|
|
1255
|
+
* - __`$month`__: _M or MM_
|
|
1256
|
+
* - __`$day`__: _D or DD_ */
|
|
1257
|
+
constructor(data = {}) {
|
|
1258
|
+
this.config = data.config || globalVimcordToolsConfig;
|
|
1259
|
+
this.data = {
|
|
1260
|
+
context: data.context || null,
|
|
1261
|
+
author: data.author || null,
|
|
1262
|
+
title: data.title || null,
|
|
1263
|
+
thumbnailUrl: data.thumbnailUrl || null,
|
|
1264
|
+
description: data.description || null,
|
|
1265
|
+
imageUrl: data.imageUrl || null,
|
|
1266
|
+
footer: data.footer || null,
|
|
1267
|
+
fields: data.fields || [],
|
|
1268
|
+
color: data.color ?? (this.config.devMode ? this.config.embedColorDev : this.config.embedColor),
|
|
1269
|
+
timestamp: data.timestamp || null,
|
|
1270
|
+
acf: data.acf ?? true
|
|
1271
|
+
};
|
|
1272
|
+
this.build();
|
|
1146
1273
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
this.formatPrefix(),
|
|
1152
|
-
import_chalk.default.hex(this.colorScheme.muted)("DEBUG"),
|
|
1153
|
-
import_chalk.default.dim(message),
|
|
1154
|
-
...args
|
|
1155
|
-
);
|
|
1274
|
+
build() {
|
|
1275
|
+
this.normalizeData();
|
|
1276
|
+
this.applyContextFormatting();
|
|
1277
|
+
this.configureEmbed();
|
|
1156
1278
|
}
|
|
1157
|
-
|
|
1158
|
-
if (
|
|
1159
|
-
|
|
1279
|
+
normalizeData() {
|
|
1280
|
+
if (typeof this.data.author === "string") {
|
|
1281
|
+
this.data.author = { text: this.data.author };
|
|
1282
|
+
}
|
|
1283
|
+
if (typeof this.data.title === "string") {
|
|
1284
|
+
this.data.title = { text: this.data.title };
|
|
1285
|
+
}
|
|
1286
|
+
if (typeof this.data.footer === "string") {
|
|
1287
|
+
this.data.footer = { text: this.data.footer };
|
|
1288
|
+
}
|
|
1289
|
+
if (this.data.timestamp === true) {
|
|
1290
|
+
this.data.timestamp = Date.now();
|
|
1291
|
+
}
|
|
1160
1292
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
this.formatPrefix(),
|
|
1166
|
-
import_chalk.default.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
1167
|
-
import_chalk.default.hex(this.colorScheme.success)(message),
|
|
1168
|
-
...args
|
|
1169
|
-
);
|
|
1293
|
+
getContextUser() {
|
|
1294
|
+
const context = this.data.context;
|
|
1295
|
+
if (!context) return null;
|
|
1296
|
+
return context.user || context.interaction?.member || context.interaction?.user || context.message?.member || context.message?.author || null;
|
|
1170
1297
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
this.formatPrefix(),
|
|
1176
|
-
import_chalk.default.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
1177
|
-
import_chalk.default.hex(this.colorScheme.warn)(message),
|
|
1178
|
-
...args
|
|
1179
|
-
);
|
|
1298
|
+
getContextClient() {
|
|
1299
|
+
const context = this.data.context;
|
|
1300
|
+
if (!context) return null;
|
|
1301
|
+
return context.client || context.interaction?.client || context.message?.client || null;
|
|
1180
1302
|
}
|
|
1181
|
-
|
|
1182
|
-
if (!this.
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1303
|
+
applyContextFormatting(str) {
|
|
1304
|
+
if (!this.data.acf) return;
|
|
1305
|
+
const user = this.getContextUser();
|
|
1306
|
+
const guildMember = user instanceof import_discord5.GuildMember ? user : null;
|
|
1307
|
+
const actualUser = guildMember?.user || (user instanceof import_discord5.User ? user : null);
|
|
1308
|
+
const client = this.getContextClient();
|
|
1309
|
+
const formatString = (str2) => {
|
|
1310
|
+
if (!str2 || !str2.includes("$")) return str2;
|
|
1311
|
+
return str2.replace(/(?<!\\)\$USER\b/g, actualUser?.toString() || "$USER").replace(/(?<!\\)\$USER_NAME\b/g, actualUser?.username || "$USER_NAME").replace(/(?<!\\)\$USER_AVATAR\b/g, actualUser?.avatarURL() || "$USER_AVATAR").replace(/(?<!\\)\$DISPLAY_NAME\b/g, guildMember?.displayName || "$DISPLAY_NAME").replace(/(?<!\\)\$BOT_AVATAR\b/g, client?.user?.avatarURL() || "$BOT_AVATAR").replace(/(?<!\\)\$INVIS\b/g, "\u200B").replace(/(?<!\\)\$YEAR/g, (/* @__PURE__ */ new Date()).getFullYear().toString()).replace(/(?<!\\)\$MONTH/g, String((/* @__PURE__ */ new Date()).getMonth() + 1).padStart(2, "0")).replace(/(?<!\\)\$DAY/g, String((/* @__PURE__ */ new Date()).getDate()).padStart(2, "0")).replace(/(?<!\\)\$year/g, String((/* @__PURE__ */ new Date()).getFullYear()).slice(-2)).replace(/(?<!\\)\$month/g, String((/* @__PURE__ */ new Date()).getMonth() + 1).padStart(2, "0")).replace(/(?<!\\)\$day/g, String((/* @__PURE__ */ new Date()).getDate()).padStart(2, "0")).replace(/(?<!\\|<)@([0-9]+)(?!>)/g, "<@$1>").replace(/(?<!\\|<)@&([0-9]+)(?!>)/g, "<@&$1>").replace(/(?<!\\|<)#([0-9]+)(?!>)/g, "<#$1>");
|
|
1312
|
+
};
|
|
1313
|
+
if (str) {
|
|
1314
|
+
return formatString(str);
|
|
1192
1315
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
`
|
|
1316
|
+
if (this.data.author && typeof this.data.author === "object") {
|
|
1317
|
+
this.data.author.text = formatString(this.data.author.text);
|
|
1318
|
+
if (this.data.author.icon === true && actualUser) {
|
|
1319
|
+
this.data.author.icon = actualUser.avatarURL();
|
|
1320
|
+
} else if (typeof this.data.author.icon === "string") {
|
|
1321
|
+
this.data.author.icon = formatString(this.data.author.icon);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
if (this.data.title && typeof this.data.title === "object") {
|
|
1325
|
+
this.data.title.text = formatString(this.data.title.text);
|
|
1326
|
+
}
|
|
1327
|
+
if (this.data.description) {
|
|
1328
|
+
this.data.description = formatString(
|
|
1329
|
+
Array.isArray(this.data.description) ? this.data.description.filter((s) => s !== null && s !== void 0).join("\n") : this.data.description
|
|
1208
1330
|
);
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
import_chalk.default.hex(this.colorScheme.muted)("\u2502 ") + import_chalk.default.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + import_chalk.default.hex(this.colorScheme.muted)(" \u2502")
|
|
1225
|
-
);
|
|
1226
|
-
console.log(import_chalk.default.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
1331
|
+
}
|
|
1332
|
+
if (this.data.footer && typeof this.data.footer === "object") {
|
|
1333
|
+
this.data.footer.text = formatString(this.data.footer.text);
|
|
1334
|
+
}
|
|
1335
|
+
if (this.data.thumbnailUrl) {
|
|
1336
|
+
this.data.thumbnailUrl = formatString(this.data.thumbnailUrl);
|
|
1337
|
+
}
|
|
1338
|
+
if (this.data.imageUrl) {
|
|
1339
|
+
this.data.imageUrl = formatString(this.data.imageUrl);
|
|
1340
|
+
}
|
|
1341
|
+
this.data.fields = this.data.fields.filter(Boolean).map((field) => ({
|
|
1342
|
+
...field,
|
|
1343
|
+
name: formatString(field.name),
|
|
1344
|
+
value: formatString(field.value)
|
|
1345
|
+
}));
|
|
1227
1346
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
function cleanMention(str) {
|
|
1239
|
-
return str ? str.replaceAll(/[<@#&>]/g, "").trim() : void 0;
|
|
1240
|
-
}
|
|
1241
|
-
async function getMessageMention(message, content, type, index = 0, idOnly) {
|
|
1242
|
-
const args = content?.split(" ");
|
|
1243
|
-
const arg = isMentionOrSnowflake(args?.[index]) ? cleanMention(args?.[index]) : void 0;
|
|
1244
|
-
switch (type) {
|
|
1245
|
-
case "user":
|
|
1246
|
-
const userMention2 = message.mentions.users.at(index) || null;
|
|
1247
|
-
if (!userMention2 && arg) {
|
|
1248
|
-
return idOnly ? arg : await fetchUser(message.client, arg);
|
|
1249
|
-
} else {
|
|
1250
|
-
return idOnly ? userMention2?.id || null : userMention2;
|
|
1347
|
+
configureEmbed() {
|
|
1348
|
+
if (this.data.author && typeof this.data.author === "object" && this.data.author.text) {
|
|
1349
|
+
try {
|
|
1350
|
+
this.embed.setAuthor({
|
|
1351
|
+
name: this.data.author.text,
|
|
1352
|
+
iconURL: typeof this.data.author.icon === "string" ? this.data.author.icon : void 0,
|
|
1353
|
+
url: this.data.author.hyperlink || void 0
|
|
1354
|
+
});
|
|
1355
|
+
} catch (error) {
|
|
1356
|
+
console.error("[BetterEmbed] Invalid author configuration:", error);
|
|
1251
1357
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
return idOnly ? channelMention?.id || null : channelMention;
|
|
1358
|
+
}
|
|
1359
|
+
if (this.data.title && typeof this.data.title === "object" && this.data.title.text) {
|
|
1360
|
+
try {
|
|
1361
|
+
this.embed.setTitle(this.data.title.text);
|
|
1362
|
+
if (this.data.title.hyperlink) {
|
|
1363
|
+
this.embed.setURL(this.data.title.hyperlink);
|
|
1364
|
+
}
|
|
1365
|
+
} catch (error) {
|
|
1366
|
+
console.error("[BetterEmbed] Invalid title configuration:", error);
|
|
1262
1367
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1368
|
+
}
|
|
1369
|
+
if (this.data.description) {
|
|
1370
|
+
this.embed.setDescription(
|
|
1371
|
+
Array.isArray(this.data.description) ? this.data.description.join("\n") : this.data.description
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
if (this.data.thumbnailUrl) {
|
|
1375
|
+
try {
|
|
1376
|
+
this.embed.setThumbnail(this.data.thumbnailUrl);
|
|
1377
|
+
} catch (error) {
|
|
1378
|
+
console.error("[BetterEmbed] Invalid thumbnail URL:", error);
|
|
1269
1379
|
}
|
|
1270
|
-
default:
|
|
1271
|
-
return null;
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
function getFirstMentionId(options) {
|
|
1275
|
-
let mentionId = "";
|
|
1276
|
-
if (options.message) {
|
|
1277
|
-
switch (options.type) {
|
|
1278
|
-
case "user":
|
|
1279
|
-
mentionId = options.message.mentions.users.first()?.id || "";
|
|
1280
|
-
break;
|
|
1281
|
-
case "channel":
|
|
1282
|
-
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
1283
|
-
break;
|
|
1284
|
-
case "role":
|
|
1285
|
-
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
1286
|
-
break;
|
|
1287
1380
|
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
|
-
if (!userId) return null;
|
|
1294
|
-
return client.users.cache.get(__zero(userId)) || await client.users.fetch(__zero(userId)).catch(() => null);
|
|
1295
|
-
}
|
|
1296
|
-
async function fetchGuild(client, guildId) {
|
|
1297
|
-
if (!guildId) return null;
|
|
1298
|
-
return client.guilds.cache.get(__zero(guildId)) || await client.guilds.fetch(__zero(guildId)).catch(() => null);
|
|
1299
|
-
}
|
|
1300
|
-
async function fetchMember(guild, memberId) {
|
|
1301
|
-
if (!memberId) return null;
|
|
1302
|
-
return guild.members.cache.get(__zero(memberId)) || await guild.members.fetch(__zero(memberId)).catch(() => null);
|
|
1303
|
-
}
|
|
1304
|
-
async function fetchChannel(guild, channelId, type) {
|
|
1305
|
-
if (!channelId) return null;
|
|
1306
|
-
const channel = guild.channels.cache.get(__zero(channelId)) || await guild.channels.fetch(__zero(channelId)).catch(() => null);
|
|
1307
|
-
if (type && channel?.type !== type) return null;
|
|
1308
|
-
return channel;
|
|
1309
|
-
}
|
|
1310
|
-
async function fetchRole(guild, roleId) {
|
|
1311
|
-
if (!roleId) return null;
|
|
1312
|
-
return guild.roles.cache.get(__zero(roleId)) || await guild.roles.fetch(__zero(roleId)).catch(() => null) || null;
|
|
1313
|
-
}
|
|
1314
|
-
async function fetchMessage(channel, messageId) {
|
|
1315
|
-
if (!messageId) return null;
|
|
1316
|
-
return channel.messages.cache.get(__zero(messageId)) || await channel.messages.fetch(__zero(messageId)).catch(() => null) || null;
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
|
-
// src/types/status.ts
|
|
1320
|
-
var import_discord4 = require("discord.js");
|
|
1321
|
-
var import_lodash11 = __toESM(require("lodash"));
|
|
1322
|
-
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
1323
|
-
StatusType2["DND"] = "dnd";
|
|
1324
|
-
StatusType2["Idle"] = "idle";
|
|
1325
|
-
StatusType2["Online"] = "online";
|
|
1326
|
-
StatusType2["Invisible"] = "invisible";
|
|
1327
|
-
return StatusType2;
|
|
1328
|
-
})(StatusType || {});
|
|
1329
|
-
var defaultPresence = {
|
|
1330
|
-
production: {
|
|
1331
|
-
interval: 6e4,
|
|
1332
|
-
randomize: false,
|
|
1333
|
-
activity: [
|
|
1334
|
-
{ status: "online" /* Online */, type: import_discord4.ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
1335
|
-
{ status: "online" /* Online */, type: import_discord4.ActivityType.Custom, name: "Join our community!" },
|
|
1336
|
-
{ status: "online" /* Online */, type: import_discord4.ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
1337
|
-
]
|
|
1338
|
-
},
|
|
1339
|
-
development: {
|
|
1340
|
-
activity: { status: "dnd" /* DND */, type: import_discord4.ActivityType.Custom, name: "In development!" }
|
|
1341
|
-
}
|
|
1342
|
-
};
|
|
1343
|
-
function createVimcordStatusConfig(options = {}) {
|
|
1344
|
-
return import_lodash11.default.merge(defaultPresence, options);
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
// src/utils/number.ts
|
|
1348
|
-
function formatThousands(num, sep = ",") {
|
|
1349
|
-
return `${num}`.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, sep);
|
|
1350
|
-
}
|
|
1351
|
-
|
|
1352
|
-
// src/modules/status.manager.ts
|
|
1353
|
-
var import_node_events = __toESM(require("events"));
|
|
1354
|
-
var import_qznt2 = require("qznt");
|
|
1355
|
-
var StatusManager = class {
|
|
1356
|
-
client;
|
|
1357
|
-
logger;
|
|
1358
|
-
emitter = new import_node_events.default();
|
|
1359
|
-
lastActivity = null;
|
|
1360
|
-
lastActivityIndex = 0;
|
|
1361
|
-
task = null;
|
|
1362
|
-
constructor(client) {
|
|
1363
|
-
this.client = client;
|
|
1364
|
-
this.logger = new Logger({ prefixEmoji: "\u{1F4AC}", prefix: `StatusManager (i${this.client.clientId})` });
|
|
1365
|
-
this.emitter.on("changed", (activity) => {
|
|
1366
|
-
if (this.client.config.app.verbose) {
|
|
1367
|
-
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
1381
|
+
if (this.data.imageUrl) {
|
|
1382
|
+
try {
|
|
1383
|
+
this.embed.setImage(this.data.imageUrl);
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
console.error("[BetterEmbed] Invalid image URL:", error);
|
|
1368
1386
|
}
|
|
1369
|
-
}
|
|
1370
|
-
this.
|
|
1371
|
-
|
|
1372
|
-
this.
|
|
1387
|
+
}
|
|
1388
|
+
if (this.data.footer && typeof this.data.footer === "object" && this.data.footer.text) {
|
|
1389
|
+
try {
|
|
1390
|
+
this.embed.setFooter({
|
|
1391
|
+
text: this.data.footer.text,
|
|
1392
|
+
iconURL: typeof this.data.footer.icon === "string" ? this.data.footer.icon : void 0
|
|
1393
|
+
});
|
|
1394
|
+
} catch (error) {
|
|
1395
|
+
console.error("[BetterEmbed] Invalid footer configuration:", error);
|
|
1373
1396
|
}
|
|
1374
|
-
}
|
|
1397
|
+
}
|
|
1398
|
+
if (this.data.color) {
|
|
1399
|
+
try {
|
|
1400
|
+
const color = Array.isArray(this.data.color) ? this.data.color[Math.floor(Math.random() * this.data.color.length)] ?? null : this.data.color;
|
|
1401
|
+
this.embed.setColor(color);
|
|
1402
|
+
} catch (error) {
|
|
1403
|
+
console.error("[BetterEmbed] Invalid color:", error);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
if (this.data.timestamp && this.data.timestamp !== true) {
|
|
1407
|
+
try {
|
|
1408
|
+
this.embed.setTimestamp(this.data.timestamp);
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
console.error("[BetterEmbed] Invalid timestamp:", error);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
if (this.data.fields.length > 0) {
|
|
1414
|
+
const validFields = this.data.fields.slice(0, 25);
|
|
1415
|
+
if (this.data.fields.length > 25) {
|
|
1416
|
+
console.warn("[BetterEmbed] Only first 25 fields will be used (Discord limit)");
|
|
1417
|
+
}
|
|
1418
|
+
this.embed.setFields(validFields);
|
|
1419
|
+
}
|
|
1375
1420
|
}
|
|
1376
|
-
|
|
1377
|
-
this.
|
|
1378
|
-
this.
|
|
1379
|
-
this.lastActivity = null;
|
|
1380
|
-
this.lastActivityIndex = 0;
|
|
1421
|
+
setAuthor(author) {
|
|
1422
|
+
this.data.author = author;
|
|
1423
|
+
this.build();
|
|
1381
1424
|
return this;
|
|
1382
1425
|
}
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
return
|
|
1387
|
-
}
|
|
1388
|
-
async formatActivityName(name) {
|
|
1389
|
-
name = name.replace("$USER_COUNT", formatThousands(this.client.users.cache.size)).replace("$GUILD_COUNT", formatThousands(this.client.guilds.cache.size)).replace(
|
|
1390
|
-
"$INVITE",
|
|
1391
|
-
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
1392
|
-
);
|
|
1393
|
-
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
1394
|
-
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
1395
|
-
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
1396
|
-
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", formatThousands(guild.members.cache.size));
|
|
1397
|
-
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
1398
|
-
}
|
|
1399
|
-
return name;
|
|
1426
|
+
setTitle(title) {
|
|
1427
|
+
this.data.title = title;
|
|
1428
|
+
this.build();
|
|
1429
|
+
return this;
|
|
1400
1430
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
1406
|
-
this.emitter.emit("changed", activity);
|
|
1431
|
+
setDescription(description) {
|
|
1432
|
+
this.data.description = description;
|
|
1433
|
+
this.build();
|
|
1434
|
+
return this;
|
|
1407
1435
|
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
this.lastActivity = activity;
|
|
1413
|
-
} else {
|
|
1414
|
-
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
1415
|
-
this.lastActivityIndex = activityIndex;
|
|
1416
|
-
activity = clientStatus.activity[activityIndex];
|
|
1417
|
-
}
|
|
1418
|
-
await this.setActivity(activity);
|
|
1419
|
-
this.emitter.emit("rotation", activity);
|
|
1436
|
+
setThumbnail(url) {
|
|
1437
|
+
this.data.thumbnailUrl = url;
|
|
1438
|
+
this.build();
|
|
1439
|
+
return this;
|
|
1420
1440
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
this.
|
|
1424
|
-
this
|
|
1425
|
-
this.task = new import_qznt2.$.Loop(() => this.statusRotationTask(clientStatus), import_qznt2.$.math.ms(clientStatus.interval), true);
|
|
1426
|
-
this.start();
|
|
1441
|
+
setImage(url) {
|
|
1442
|
+
this.data.imageUrl = url;
|
|
1443
|
+
this.build();
|
|
1444
|
+
return this;
|
|
1427
1445
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
this.emitter.emit("started", this.task);
|
|
1432
|
-
}
|
|
1446
|
+
setFooter(footer) {
|
|
1447
|
+
this.data.footer = footer;
|
|
1448
|
+
this.build();
|
|
1433
1449
|
return this;
|
|
1434
1450
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
this.emitter.emit("paused", this.task);
|
|
1439
|
-
}
|
|
1451
|
+
setColor(color) {
|
|
1452
|
+
this.data.color = color;
|
|
1453
|
+
this.build();
|
|
1440
1454
|
return this;
|
|
1441
1455
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
if (!clientStatus.interval) {
|
|
1451
|
-
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
1452
|
-
} else {
|
|
1453
|
-
await this.scheduleStatusRotation(clientStatus);
|
|
1454
|
-
}
|
|
1456
|
+
setTimestamp(timestamp) {
|
|
1457
|
+
this.data.timestamp = timestamp;
|
|
1458
|
+
this.build();
|
|
1459
|
+
return this;
|
|
1460
|
+
}
|
|
1461
|
+
addFields(fields) {
|
|
1462
|
+
this.data.fields = [...this.data.fields, ...fields];
|
|
1463
|
+
this.build();
|
|
1455
1464
|
return this;
|
|
1456
1465
|
}
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
this.task = null;
|
|
1461
|
-
this.emitter.emit("destroyed");
|
|
1462
|
-
await this.clear();
|
|
1463
|
-
}
|
|
1466
|
+
setFields(fields) {
|
|
1467
|
+
this.data.fields = fields;
|
|
1468
|
+
this.build();
|
|
1464
1469
|
return this;
|
|
1465
1470
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
this.
|
|
1469
|
-
client.user.setActivity({ name: "" });
|
|
1470
|
-
this.emitter.emit("cleared");
|
|
1471
|
+
spliceFields(index, deleteCount, ...fields) {
|
|
1472
|
+
this.data.fields.splice(index, deleteCount, ...fields);
|
|
1473
|
+
this.build();
|
|
1471
1474
|
return this;
|
|
1472
1475
|
}
|
|
1476
|
+
clone(overrides = {}) {
|
|
1477
|
+
return new _BetterEmbed({ ...this.data, ...overrides });
|
|
1478
|
+
}
|
|
1479
|
+
toJSON() {
|
|
1480
|
+
return this.embed.toJSON();
|
|
1481
|
+
}
|
|
1482
|
+
async send(handler, options = {}, overrides) {
|
|
1483
|
+
this.build();
|
|
1484
|
+
if (options.content && this.data.acf) {
|
|
1485
|
+
options.content = this.applyContextFormatting(options.content);
|
|
1486
|
+
}
|
|
1487
|
+
return await dynaSend(handler, {
|
|
1488
|
+
...options,
|
|
1489
|
+
embeds: [
|
|
1490
|
+
overrides ? this.clone(overrides) : this,
|
|
1491
|
+
...Array.isArray(options?.embeds) ? options?.embeds : options?.embeds ? [options?.embeds] : []
|
|
1492
|
+
]
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1473
1495
|
};
|
|
1474
1496
|
|
|
1475
|
-
// src/
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1497
|
+
// src/utils/sendCommandErrorEmbed.ts
|
|
1498
|
+
async function sendCommandErrorEmbed(client, error, guild, messageOrInteraction) {
|
|
1499
|
+
if (!client.features.enableCommandErrorMessage) return null;
|
|
1500
|
+
const config = typeof client.features.enableCommandErrorMessage !== "boolean" ? client.features.enableCommandErrorMessage : void 0;
|
|
1501
|
+
const buttons = {
|
|
1502
|
+
supportServer: new import_discord6.ButtonBuilder({
|
|
1503
|
+
url: config?.inviteUrl || client.config.staff.guild.inviteUrl || "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
1504
|
+
// may or may not be a rickroll
|
|
1505
|
+
label: config?.inviteButtonLabel || "Support Support",
|
|
1506
|
+
style: import_discord6.ButtonStyle.Link
|
|
1507
|
+
}),
|
|
1508
|
+
details: new import_discord6.ButtonBuilder({
|
|
1509
|
+
customId: "btn_details",
|
|
1510
|
+
label: config?.detailButtonLabel || "Details",
|
|
1511
|
+
style: import_discord6.ButtonStyle.Secondary
|
|
1512
|
+
})
|
|
1513
|
+
};
|
|
1514
|
+
const actionRow = new import_discord6.ActionRowBuilder({
|
|
1515
|
+
components: config?.inviteUrl && guild?.id !== (config.inviteUrl || client.config.staff.guild.id) ? [buttons.supportServer, buttons.details] : [buttons.details]
|
|
1516
|
+
});
|
|
1517
|
+
const embed_error = config?.embed?.(new BetterEmbed(), error, guild) || new BetterEmbed({
|
|
1518
|
+
color: "Red",
|
|
1519
|
+
title: "Something went wrong",
|
|
1520
|
+
description: "If you keep encountering this error, please report it."
|
|
1521
|
+
});
|
|
1522
|
+
const msg = await embed_error.send(messageOrInteraction, {
|
|
1523
|
+
components: [actionRow],
|
|
1524
|
+
flags: config?.ephemeral ? "Ephemeral" : void 0,
|
|
1525
|
+
deleteAfter: config?.deleteAfter
|
|
1526
|
+
});
|
|
1527
|
+
if (!msg) return null;
|
|
1528
|
+
const collector = msg.createMessageComponentCollector({
|
|
1529
|
+
componentType: import_discord6.ComponentType.Button,
|
|
1530
|
+
idle: config?.detailButtonIdleTimeout ?? 3e4,
|
|
1531
|
+
filter: (i) => i.customId === "btn_details"
|
|
1532
|
+
});
|
|
1533
|
+
collector.on("collect", (i) => {
|
|
1534
|
+
const attachment = new import_discord6.AttachmentBuilder(Buffer.from(`${error.message}
|
|
1535
|
+
|
|
1536
|
+
${error.stack}`), {
|
|
1537
|
+
name: "error.txt"
|
|
1538
|
+
});
|
|
1539
|
+
i.reply({ files: [attachment], flags: "Ephemeral" });
|
|
1540
|
+
});
|
|
1541
|
+
collector.on("end", () => {
|
|
1542
|
+
buttons.details.setDisabled(true);
|
|
1543
|
+
embed_error.send(messageOrInteraction, {
|
|
1544
|
+
sendMethod: messageOrInteraction instanceof import_discord6.Message ? 5 /* MessageEdit */ : void 0,
|
|
1545
|
+
components: [actionRow]
|
|
1546
|
+
});
|
|
1547
|
+
});
|
|
1548
|
+
return msg;
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
// src/modules/builtins/builtin.slashCommandHandler.ts
|
|
1552
|
+
var BUILTIN_SlashCommandHandler = new EventBuilder({
|
|
1553
|
+
event: "interactionCreate",
|
|
1554
|
+
name: "SlashCommandHandler",
|
|
1555
|
+
async execute(client, interaction) {
|
|
1556
|
+
if (!interaction.isChatInputCommand()) return;
|
|
1557
|
+
const command = client.commands.slash.get(interaction.commandName);
|
|
1558
|
+
if (!command) {
|
|
1559
|
+
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
1560
|
+
if (interaction.replied || interaction.deferred) {
|
|
1561
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1562
|
+
}
|
|
1563
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1564
|
+
}
|
|
1565
|
+
try {
|
|
1566
|
+
return await command.run(client, client, interaction);
|
|
1567
|
+
} catch (err) {
|
|
1568
|
+
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
1569
|
+
throw err;
|
|
1506
1570
|
}
|
|
1507
1571
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1572
|
+
});
|
|
1573
|
+
|
|
1574
|
+
// src/modules/builtins/builtin.prefixCommandHandler.ts
|
|
1575
|
+
var import_discord7 = require("discord.js");
|
|
1576
|
+
var BUILTIN_PrefixCommandHandler = new EventBuilder({
|
|
1577
|
+
event: "messageCreate",
|
|
1578
|
+
name: "PrefixCommandHandler",
|
|
1579
|
+
async execute(client, message) {
|
|
1580
|
+
if (message.author.bot || !message.guild) return;
|
|
1581
|
+
const config = client.config.prefixCommands;
|
|
1582
|
+
let activePrefix = config.defaultPrefix;
|
|
1583
|
+
if (config.guildPrefixResolver) {
|
|
1584
|
+
try {
|
|
1585
|
+
const customPrefix = await config.guildPrefixResolver(client, message.guild.id);
|
|
1586
|
+
if (customPrefix) activePrefix = customPrefix;
|
|
1587
|
+
} catch (err) {
|
|
1588
|
+
client.logger.error(`Error in guildPrefixResolver for guild ${message.guild.id}:`, err);
|
|
1519
1589
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1590
|
+
}
|
|
1591
|
+
let prefixUsed;
|
|
1592
|
+
if (message.content.startsWith(activePrefix)) {
|
|
1593
|
+
prefixUsed = activePrefix;
|
|
1594
|
+
} else if (config.allowMentionAsPrefix) {
|
|
1595
|
+
const mention = (0, import_discord7.userMention)(client.user.id);
|
|
1596
|
+
if (message.content.startsWith(mention)) {
|
|
1597
|
+
prefixUsed = message.content.startsWith(`${mention} `) ? `${mention} ` : mention;
|
|
1523
1598
|
}
|
|
1524
|
-
const deployment = "deployment" in cmd.options ? cmd.options.deployment ?? {} : {};
|
|
1525
|
-
const isProperEnv = !deployment.environments || deployment.environments.includes(isDev ? "development" : "production");
|
|
1526
|
-
if (!isProperEnv) continue;
|
|
1527
|
-
if (options.globalOnly && deployment.global === false) continue;
|
|
1528
|
-
matchedCommands.set(commandName, cmd);
|
|
1529
1599
|
}
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1600
|
+
if (!prefixUsed) return;
|
|
1601
|
+
const contentWithoutPrefix = message.content.slice(prefixUsed.length).trim();
|
|
1602
|
+
const args = contentWithoutPrefix.split(/\s+/);
|
|
1603
|
+
const trigger = args.shift();
|
|
1604
|
+
if (!trigger) return;
|
|
1605
|
+
const command = client.commands.prefix.get(trigger);
|
|
1606
|
+
if (!command) return;
|
|
1607
|
+
message.content = args.join(" ");
|
|
1608
|
+
try {
|
|
1609
|
+
return await command.run(client, client, message);
|
|
1610
|
+
} catch (err) {
|
|
1611
|
+
await sendCommandErrorEmbed(client, err, message.guild, message);
|
|
1612
|
+
throw err;
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
1616
|
+
|
|
1617
|
+
// src/modules/builtins/builtin.contextCommandHandler.ts
|
|
1618
|
+
var BUILTIN_ContextCommandHandler = new EventBuilder({
|
|
1619
|
+
event: "interactionCreate",
|
|
1620
|
+
name: "ContextCommandHandler",
|
|
1621
|
+
async execute(client, interaction) {
|
|
1622
|
+
if (!interaction.isContextMenuCommand()) return;
|
|
1623
|
+
const command = client.commands.context.get(interaction.commandName);
|
|
1624
|
+
if (!command) {
|
|
1625
|
+
const content = `**${interaction.commandName}** is not a registered context command.`;
|
|
1626
|
+
if (interaction.replied || interaction.deferred) {
|
|
1627
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1628
|
+
}
|
|
1629
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1630
|
+
}
|
|
1631
|
+
try {
|
|
1632
|
+
return await command.run(client, client, interaction);
|
|
1633
|
+
} catch (err) {
|
|
1634
|
+
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
1635
|
+
throw err;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
// src/tools/Logger.ts
|
|
1641
|
+
var import_chalk = __toESM(require("chalk"));
|
|
1642
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
1643
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
1644
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
1645
|
+
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
1646
|
+
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
1647
|
+
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
1648
|
+
return LogLevel2;
|
|
1649
|
+
})(LogLevel || {});
|
|
1650
|
+
var LOGGER_COLORS = {
|
|
1651
|
+
primary: "#5865F2",
|
|
1652
|
+
success: "#57F287",
|
|
1653
|
+
warn: "#FEE75C",
|
|
1654
|
+
danger: "#ED4245",
|
|
1655
|
+
muted: "#747F8D",
|
|
1656
|
+
text: "#FFFFFF"
|
|
1657
|
+
};
|
|
1658
|
+
var Logger = class {
|
|
1659
|
+
logPrefixEmoji;
|
|
1660
|
+
logPrefix;
|
|
1661
|
+
minLevel;
|
|
1662
|
+
showTimestamp;
|
|
1663
|
+
colorScheme;
|
|
1664
|
+
constructor(options) {
|
|
1665
|
+
const { prefixEmoji = null, prefix = null, minLevel = 0 /* DEBUG */, showTimestamp = true } = options || {};
|
|
1666
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
1667
|
+
this.logPrefix = prefix;
|
|
1668
|
+
this.minLevel = minLevel;
|
|
1669
|
+
this.showTimestamp = showTimestamp;
|
|
1670
|
+
this.colorScheme = {
|
|
1671
|
+
...LOGGER_COLORS,
|
|
1672
|
+
...options?.colors
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
formatTimestamp() {
|
|
1676
|
+
if (!this.showTimestamp) return "";
|
|
1677
|
+
const now = /* @__PURE__ */ new Date();
|
|
1678
|
+
const time = now.toLocaleTimeString("en-US", {
|
|
1679
|
+
hour12: false,
|
|
1680
|
+
hour: "2-digit",
|
|
1681
|
+
minute: "2-digit",
|
|
1682
|
+
second: "2-digit"
|
|
1534
1683
|
});
|
|
1684
|
+
return import_chalk.default.hex(this.colorScheme.muted)(`[${time}]`);
|
|
1535
1685
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1686
|
+
formatPrefix() {
|
|
1687
|
+
if (!this.logPrefix) return "";
|
|
1688
|
+
return import_chalk.default.bold.hex(this.colorScheme.primary)(
|
|
1689
|
+
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
1690
|
+
);
|
|
1691
|
+
}
|
|
1692
|
+
shouldLog(level) {
|
|
1693
|
+
return level >= this.minLevel;
|
|
1694
|
+
}
|
|
1695
|
+
get prefixEmoji() {
|
|
1696
|
+
return this.logPrefixEmoji;
|
|
1697
|
+
}
|
|
1698
|
+
get prefix() {
|
|
1699
|
+
return this.logPrefix;
|
|
1700
|
+
}
|
|
1701
|
+
get colors() {
|
|
1702
|
+
return this.colorScheme;
|
|
1703
|
+
}
|
|
1704
|
+
extend(extras) {
|
|
1705
|
+
for (const [key, fn] of Object.entries(extras)) {
|
|
1706
|
+
if (typeof fn === "function") {
|
|
1707
|
+
this[key] = function(...args) {
|
|
1708
|
+
return fn.call(this, ...args);
|
|
1550
1709
|
};
|
|
1551
|
-
categories.set(metadata.category, entry);
|
|
1552
1710
|
}
|
|
1553
|
-
entry.commands.push(cmd);
|
|
1554
1711
|
}
|
|
1555
|
-
return
|
|
1556
|
-
cat.commands.sort((a, b) => {
|
|
1557
|
-
const commandNameA = "builder" in a ? a.builder.name : a.options.name;
|
|
1558
|
-
const commandNameB = "builder" in b ? b.builder.name : b.options.name;
|
|
1559
|
-
return commandNameA.localeCompare(commandNameB);
|
|
1560
|
-
});
|
|
1561
|
-
return cat;
|
|
1562
|
-
});
|
|
1712
|
+
return this;
|
|
1563
1713
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
* @param set Replaces imported command modules with the ones found.
|
|
1568
|
-
*/
|
|
1569
|
-
async importFrom(dir, set = false) {
|
|
1570
|
-
if (set) this.commands.clear();
|
|
1571
|
-
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1572
|
-
const modules = [];
|
|
1573
|
-
for (const _dir of dirs) {
|
|
1574
|
-
const results = await importModulesFromDir(_dir, this.moduleSuffix);
|
|
1575
|
-
modules.push(...results.map(({ module: module2 }) => module2.default));
|
|
1576
|
-
}
|
|
1577
|
-
for (const module2 of modules) {
|
|
1578
|
-
const commandName = "builder" in module2 ? module2.builder.name : module2.options.name;
|
|
1579
|
-
this.commands.set(commandName, module2);
|
|
1580
|
-
}
|
|
1581
|
-
let moduleType;
|
|
1582
|
-
switch (this.type) {
|
|
1583
|
-
case 0 /* Slash */:
|
|
1584
|
-
moduleType = "Prefix Commands";
|
|
1585
|
-
break;
|
|
1586
|
-
case 2 /* Context */:
|
|
1587
|
-
moduleType = "Context Commands";
|
|
1588
|
-
break;
|
|
1589
|
-
case 1 /* Prefix */:
|
|
1590
|
-
moduleType = "Prefix Commands";
|
|
1591
|
-
break;
|
|
1592
|
-
}
|
|
1593
|
-
this.client.logger.moduleLoaded(moduleType, modules.length);
|
|
1594
|
-
return this.commands;
|
|
1714
|
+
setPrefix(prefix) {
|
|
1715
|
+
this.logPrefix = prefix;
|
|
1716
|
+
return this;
|
|
1595
1717
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
super(client, 0 /* Slash */, client.config.app.moduleSuffixes.slashCommand);
|
|
1718
|
+
setPrefixEmoji(prefixEmoji) {
|
|
1719
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
1720
|
+
return this;
|
|
1600
1721
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
super(client, 2 /* Context */, client.config.app.moduleSuffixes.contextCommand);
|
|
1722
|
+
setMinLevel(minLevel) {
|
|
1723
|
+
this.minLevel = minLevel;
|
|
1724
|
+
return this;
|
|
1605
1725
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
super(client, 1 /* Prefix */, client.config.app.moduleSuffixes.prefixCommand);
|
|
1726
|
+
setShowTimestamp(show) {
|
|
1727
|
+
this.showTimestamp = show;
|
|
1728
|
+
return this;
|
|
1610
1729
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
constructor(client) {
|
|
1618
|
-
this.client = client;
|
|
1619
|
-
this.slash = new SlashCommandManager(client);
|
|
1620
|
-
this.prefix = new PrefixCommandManager(client);
|
|
1621
|
-
this.context = new ContextCommandManager(client);
|
|
1730
|
+
setColors(colors) {
|
|
1731
|
+
this.colorScheme = {
|
|
1732
|
+
...LOGGER_COLORS,
|
|
1733
|
+
...colors
|
|
1734
|
+
};
|
|
1735
|
+
return this;
|
|
1622
1736
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1737
|
+
log(message, ...args) {
|
|
1738
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), message, ...args);
|
|
1625
1739
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
return;
|
|
1636
|
-
}
|
|
1637
|
-
console.log(`[CommandManager] Registering (${commands.length}) commands globally...`);
|
|
1638
|
-
try {
|
|
1639
|
-
await client.rest.put(import_discord5.Routes.applicationCommands(client.user.id), { body: commands });
|
|
1640
|
-
console.log(`[CommandManager] \u2714 Registered app commands globally`);
|
|
1641
|
-
} catch (err) {
|
|
1642
|
-
console.error(`[CommandManager] \u2716 Failed to register app commands globally`, err);
|
|
1643
|
-
}
|
|
1740
|
+
debug(message, ...args) {
|
|
1741
|
+
if (!this.shouldLog(0 /* DEBUG */)) return;
|
|
1742
|
+
console.log(
|
|
1743
|
+
this.formatTimestamp(),
|
|
1744
|
+
this.formatPrefix(),
|
|
1745
|
+
import_chalk.default.hex(this.colorScheme.muted)("DEBUG"),
|
|
1746
|
+
import_chalk.default.dim(message),
|
|
1747
|
+
...args
|
|
1748
|
+
);
|
|
1644
1749
|
}
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1750
|
+
info(message, ...args) {
|
|
1751
|
+
if (!this.shouldLog(1 /* INFO */)) return;
|
|
1752
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.hex("#87CEEB")("INFO"), message, ...args);
|
|
1753
|
+
}
|
|
1754
|
+
success(message, ...args) {
|
|
1755
|
+
if (!this.shouldLog(2 /* SUCCESS */)) return;
|
|
1756
|
+
console.log(
|
|
1757
|
+
this.formatTimestamp(),
|
|
1758
|
+
this.formatPrefix(),
|
|
1759
|
+
import_chalk.default.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
1760
|
+
import_chalk.default.hex(this.colorScheme.success)(message),
|
|
1761
|
+
...args
|
|
1762
|
+
);
|
|
1763
|
+
}
|
|
1764
|
+
warn(message, ...args) {
|
|
1765
|
+
if (!this.shouldLog(3 /* WARN */)) return;
|
|
1766
|
+
console.warn(
|
|
1767
|
+
this.formatTimestamp(),
|
|
1768
|
+
this.formatPrefix(),
|
|
1769
|
+
import_chalk.default.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
1770
|
+
import_chalk.default.hex(this.colorScheme.warn)(message),
|
|
1771
|
+
...args
|
|
1772
|
+
);
|
|
1773
|
+
}
|
|
1774
|
+
error(message, error, ...args) {
|
|
1775
|
+
if (!this.shouldLog(4 /* ERROR */)) return;
|
|
1776
|
+
console.error(
|
|
1777
|
+
this.formatTimestamp(),
|
|
1778
|
+
this.formatPrefix(),
|
|
1779
|
+
import_chalk.default.bold.hex(this.colorScheme.danger)("\u2715 ERROR"),
|
|
1780
|
+
import_chalk.default.hex(this.colorScheme.danger)(message),
|
|
1781
|
+
...args
|
|
1782
|
+
);
|
|
1783
|
+
if (error && error.stack) {
|
|
1784
|
+
console.error(import_chalk.default.dim(error.stack));
|
|
1656
1785
|
}
|
|
1657
1786
|
}
|
|
1658
|
-
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1787
|
+
loader(message) {
|
|
1788
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1789
|
+
let i = 0;
|
|
1790
|
+
const interval = setInterval(() => {
|
|
1791
|
+
process.stdout.write(
|
|
1792
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.warn)(frames[i])} ${message}`
|
|
1793
|
+
);
|
|
1794
|
+
i = (i + 1) % frames.length;
|
|
1795
|
+
}, 100);
|
|
1796
|
+
return (newMessage) => {
|
|
1797
|
+
clearInterval(interval);
|
|
1798
|
+
process.stdout.write(
|
|
1799
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.success)("\u2713")} ${newMessage || message}
|
|
1800
|
+
`
|
|
1801
|
+
);
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
table(title, data) {
|
|
1805
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.bold(title));
|
|
1806
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
1807
|
+
const formattedKey = import_chalk.default.hex(this.colorScheme.warn)(` ${key}`);
|
|
1808
|
+
const formattedValue = import_chalk.default.hex(this.colorScheme.muted)(value);
|
|
1809
|
+
console.log(`${formattedKey.padEnd(25)} ${formattedValue}`);
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
section(title) {
|
|
1813
|
+
const line = "\u2500".repeat(Math.max(30, title.length + 4));
|
|
1814
|
+
console.log(import_chalk.default.hex(this.colorScheme.muted)(`
|
|
1815
|
+
\u250C\u2500${line}\u2500\u2510`));
|
|
1816
|
+
console.log(
|
|
1817
|
+
import_chalk.default.hex(this.colorScheme.muted)("\u2502 ") + import_chalk.default.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + import_chalk.default.hex(this.colorScheme.muted)(" \u2502")
|
|
1818
|
+
);
|
|
1819
|
+
console.log(import_chalk.default.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
var logger = new Logger();
|
|
1823
|
+
|
|
1824
|
+
// src/tools/utils.ts
|
|
1825
|
+
function __zero(str) {
|
|
1826
|
+
return str?.length ? str : "0";
|
|
1827
|
+
}
|
|
1828
|
+
function isMentionOrSnowflake(str) {
|
|
1829
|
+
return str ? str.match(/<@[#&]?[\d]{6,}>/) || str.match(/\d{6,}/) ? true : false : false;
|
|
1830
|
+
}
|
|
1831
|
+
function cleanMention(str) {
|
|
1832
|
+
return str ? str.replaceAll(/[<@#&>]/g, "").trim() : void 0;
|
|
1833
|
+
}
|
|
1834
|
+
async function getMessageMention(message, content, type, index = 0, idOnly) {
|
|
1835
|
+
const args = content?.split(" ");
|
|
1836
|
+
const arg = isMentionOrSnowflake(args?.[index]) ? cleanMention(args?.[index]) : void 0;
|
|
1837
|
+
switch (type) {
|
|
1838
|
+
case "user":
|
|
1839
|
+
const userMention2 = message.mentions.users.at(index) || null;
|
|
1840
|
+
if (!userMention2 && arg) {
|
|
1841
|
+
return idOnly ? arg : await fetchUser(message.client, arg);
|
|
1842
|
+
} else {
|
|
1843
|
+
return idOnly ? userMention2?.id || null : userMention2;
|
|
1844
|
+
}
|
|
1845
|
+
case "member":
|
|
1846
|
+
if (!message.guild) return null;
|
|
1847
|
+
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
1848
|
+
return idOnly ? member?.id || null : member;
|
|
1849
|
+
case "channel":
|
|
1850
|
+
const channelMention = message.mentions.channels.at(index) || null;
|
|
1851
|
+
if (!channelMention && arg) {
|
|
1852
|
+
return idOnly ? arg : message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
1853
|
+
} else {
|
|
1854
|
+
return idOnly ? channelMention?.id || null : channelMention;
|
|
1855
|
+
}
|
|
1856
|
+
case "role":
|
|
1857
|
+
const roleMention = message.mentions.roles.at(index) || null;
|
|
1858
|
+
if (!roleMention && arg) {
|
|
1859
|
+
return idOnly ? arg : message.guild ? await fetchRole(message.guild, arg) : null;
|
|
1860
|
+
} else {
|
|
1861
|
+
return idOnly ? roleMention?.id || null : roleMention;
|
|
1862
|
+
}
|
|
1863
|
+
default:
|
|
1864
|
+
return null;
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
function getFirstMentionId(options) {
|
|
1868
|
+
let mentionId = "";
|
|
1869
|
+
if (options.message) {
|
|
1870
|
+
switch (options.type) {
|
|
1871
|
+
case "user":
|
|
1872
|
+
mentionId = options.message.mentions.users.first()?.id || "";
|
|
1873
|
+
break;
|
|
1874
|
+
case "channel":
|
|
1875
|
+
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
1876
|
+
break;
|
|
1877
|
+
case "role":
|
|
1878
|
+
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
1879
|
+
break;
|
|
1668
1880
|
}
|
|
1669
|
-
const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
|
|
1670
|
-
console.log(`[CommandManager] Registering (${commands.length}) commands for ${guildIds.length} guilds...`);
|
|
1671
|
-
await Promise.all(
|
|
1672
|
-
guildIds.map(
|
|
1673
|
-
(guildId) => client.rest.put(import_discord5.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
|
|
1674
|
-
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
1675
|
-
console.log(`[CommandManager] \u2714 Set app commands in guild: ${guildId} (${gName})`);
|
|
1676
|
-
}).catch((err) => {
|
|
1677
|
-
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
1678
|
-
console.log(`[CommandManager] \u2716 Failed to set app commands in guild: ${guildId} (${gName})`, err);
|
|
1679
|
-
})
|
|
1680
|
-
)
|
|
1681
|
-
);
|
|
1682
1881
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1882
|
+
const firstArg = options.content?.split(" ")[0] || "";
|
|
1883
|
+
return mentionId || isMentionOrSnowflake(firstArg) ? cleanMention(firstArg) : "";
|
|
1884
|
+
}
|
|
1885
|
+
async function fetchUser(client, userId) {
|
|
1886
|
+
if (!userId) return null;
|
|
1887
|
+
return client.users.cache.get(__zero(userId)) || await client.users.fetch(__zero(userId)).catch(() => null);
|
|
1888
|
+
}
|
|
1889
|
+
async function fetchGuild(client, guildId) {
|
|
1890
|
+
if (!guildId) return null;
|
|
1891
|
+
return client.guilds.cache.get(__zero(guildId)) || await client.guilds.fetch(__zero(guildId)).catch(() => null);
|
|
1892
|
+
}
|
|
1893
|
+
async function fetchMember(guild, memberId) {
|
|
1894
|
+
if (!memberId) return null;
|
|
1895
|
+
return guild.members.cache.get(__zero(memberId)) || await guild.members.fetch(__zero(memberId)).catch(() => null);
|
|
1896
|
+
}
|
|
1897
|
+
async function fetchChannel(guild, channelId, type) {
|
|
1898
|
+
if (!channelId) return null;
|
|
1899
|
+
const channel = guild.channels.cache.get(__zero(channelId)) || await guild.channels.fetch(__zero(channelId)).catch(() => null);
|
|
1900
|
+
if (type && channel?.type !== type) return null;
|
|
1901
|
+
return channel;
|
|
1902
|
+
}
|
|
1903
|
+
async function fetchRole(guild, roleId) {
|
|
1904
|
+
if (!roleId) return null;
|
|
1905
|
+
return guild.roles.cache.get(__zero(roleId)) || await guild.roles.fetch(__zero(roleId)).catch(() => null) || null;
|
|
1906
|
+
}
|
|
1907
|
+
async function fetchMessage(channel, messageId) {
|
|
1908
|
+
if (!messageId) return null;
|
|
1909
|
+
return channel.messages.cache.get(__zero(messageId)) || await channel.messages.fetch(__zero(messageId)).catch(() => null) || null;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
// src/types/status.ts
|
|
1913
|
+
var import_discord8 = require("discord.js");
|
|
1914
|
+
var import_lodash11 = __toESM(require("lodash"));
|
|
1915
|
+
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
1916
|
+
StatusType2["DND"] = "dnd";
|
|
1917
|
+
StatusType2["Idle"] = "idle";
|
|
1918
|
+
StatusType2["Online"] = "online";
|
|
1919
|
+
StatusType2["Invisible"] = "invisible";
|
|
1920
|
+
return StatusType2;
|
|
1921
|
+
})(StatusType || {});
|
|
1922
|
+
var defaultPresence = {
|
|
1923
|
+
production: {
|
|
1924
|
+
interval: 6e4,
|
|
1925
|
+
randomize: false,
|
|
1926
|
+
activity: [
|
|
1927
|
+
{ status: "online" /* Online */, type: import_discord8.ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
1928
|
+
{ status: "online" /* Online */, type: import_discord8.ActivityType.Custom, name: "Join our community!" },
|
|
1929
|
+
{ status: "online" /* Online */, type: import_discord8.ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
1930
|
+
]
|
|
1931
|
+
},
|
|
1932
|
+
development: {
|
|
1933
|
+
activity: { status: "dnd" /* DND */, type: import_discord8.ActivityType.Custom, name: "In development!" }
|
|
1696
1934
|
}
|
|
1697
1935
|
};
|
|
1936
|
+
function createVimcordStatusConfig(options = {}) {
|
|
1937
|
+
return import_lodash11.default.merge(defaultPresence, options);
|
|
1938
|
+
}
|
|
1698
1939
|
|
|
1699
|
-
// src/modules/
|
|
1700
|
-
var
|
|
1701
|
-
var
|
|
1940
|
+
// src/modules/status.manager.ts
|
|
1941
|
+
var import_node_events = __toESM(require("events"));
|
|
1942
|
+
var import_qznt2 = require("qznt");
|
|
1943
|
+
var StatusManager = class {
|
|
1702
1944
|
client;
|
|
1703
|
-
events = /* @__PURE__ */ new Map();
|
|
1704
1945
|
logger;
|
|
1946
|
+
emitter = new import_node_events.default();
|
|
1947
|
+
lastActivity = null;
|
|
1948
|
+
lastActivityIndex = 0;
|
|
1949
|
+
task = null;
|
|
1705
1950
|
constructor(client) {
|
|
1706
1951
|
this.client = client;
|
|
1707
|
-
this.logger = new Logger({ prefixEmoji: "\u{
|
|
1708
|
-
|
|
1709
|
-
client.on(
|
|
1710
|
-
event.toString(),
|
|
1711
|
-
async (...args) => this.executeEvents.apply(this, [event, ...args])
|
|
1712
|
-
);
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
register(...events) {
|
|
1716
|
-
for (const event of events) {
|
|
1717
|
-
this.events.set(event.name, event);
|
|
1952
|
+
this.logger = new Logger({ prefixEmoji: "\u{1F4AC}", prefix: `StatusManager (i${this.client.clientId})` });
|
|
1953
|
+
this.emitter.on("changed", (activity) => {
|
|
1718
1954
|
if (this.client.config.app.verbose) {
|
|
1719
|
-
this.logger.debug(`
|
|
1955
|
+
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
1720
1956
|
}
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
|
-
unregister(...names) {
|
|
1724
|
-
for (const name of names) {
|
|
1725
|
-
const event = this.events.get(name);
|
|
1726
|
-
if (!event) continue;
|
|
1727
|
-
this.events.delete(name);
|
|
1957
|
+
});
|
|
1958
|
+
this.emitter.on("cleared", () => {
|
|
1728
1959
|
if (this.client.config.app.verbose) {
|
|
1729
|
-
this.logger.debug(
|
|
1960
|
+
this.logger.debug("Status cleared");
|
|
1730
1961
|
}
|
|
1731
|
-
}
|
|
1962
|
+
});
|
|
1732
1963
|
}
|
|
1733
|
-
|
|
1734
|
-
this.
|
|
1735
|
-
this.
|
|
1964
|
+
clearData() {
|
|
1965
|
+
this.task?.stop();
|
|
1966
|
+
this.task = null;
|
|
1967
|
+
this.lastActivity = null;
|
|
1968
|
+
this.lastActivityIndex = 0;
|
|
1969
|
+
return this;
|
|
1736
1970
|
}
|
|
1737
|
-
|
|
1738
|
-
|
|
1971
|
+
async getReadyClient() {
|
|
1972
|
+
const client = await this.client.waitForReady();
|
|
1973
|
+
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
1974
|
+
return client;
|
|
1739
1975
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1976
|
+
async formatActivityName(name) {
|
|
1977
|
+
name = name.replace("$USER_COUNT", import_qznt2.$.format.number(this.client.users.cache.size)).replace("$GUILD_COUNT", import_qznt2.$.format.number(this.client.guilds.cache.size)).replace(
|
|
1978
|
+
"$INVITE",
|
|
1979
|
+
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
1980
|
+
);
|
|
1981
|
+
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
1982
|
+
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
1983
|
+
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
1984
|
+
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", import_qznt2.$.format.number(guild.members.cache.size));
|
|
1985
|
+
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
1986
|
+
}
|
|
1987
|
+
return name;
|
|
1742
1988
|
}
|
|
1743
|
-
|
|
1744
|
-
|
|
1989
|
+
async setActivity(activity) {
|
|
1990
|
+
const client = await this.getReadyClient();
|
|
1991
|
+
activity.name = await this.formatActivityName(activity.name);
|
|
1992
|
+
client.user.setStatus(activity.status);
|
|
1993
|
+
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
1994
|
+
this.emitter.emit("changed", activity);
|
|
1745
1995
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1996
|
+
async statusRotationTask(clientStatus) {
|
|
1997
|
+
let activity;
|
|
1998
|
+
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
1999
|
+
activity = import_qznt2.$.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
2000
|
+
this.lastActivity = activity;
|
|
2001
|
+
} else {
|
|
2002
|
+
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
2003
|
+
this.lastActivityIndex = activityIndex;
|
|
2004
|
+
activity = clientStatus.activity[activityIndex];
|
|
2005
|
+
}
|
|
2006
|
+
await this.setActivity(activity);
|
|
2007
|
+
this.emitter.emit("rotation", activity);
|
|
1748
2008
|
}
|
|
1749
|
-
async
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
try {
|
|
1756
|
-
await event.execute?.(this.client, ...args);
|
|
1757
|
-
if (event.once) {
|
|
1758
|
-
this.unregister(event.name);
|
|
1759
|
-
}
|
|
1760
|
-
} catch (err) {
|
|
1761
|
-
this.logger.error(`'${event.name}' failed to execute`, err);
|
|
1762
|
-
}
|
|
1763
|
-
})
|
|
1764
|
-
);
|
|
2009
|
+
async scheduleStatusRotation(clientStatus) {
|
|
2010
|
+
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
2011
|
+
this.task?.stop();
|
|
2012
|
+
this.task = null;
|
|
2013
|
+
this.task = new import_qznt2.$.Loop(() => this.statusRotationTask(clientStatus), import_qznt2.$.math.ms(clientStatus.interval), true);
|
|
2014
|
+
this.start();
|
|
1765
2015
|
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
2016
|
+
start() {
|
|
2017
|
+
if (this.task) {
|
|
2018
|
+
this.task.start();
|
|
2019
|
+
this.emitter.emit("started", this.task);
|
|
2020
|
+
}
|
|
2021
|
+
return this;
|
|
2022
|
+
}
|
|
2023
|
+
pause() {
|
|
2024
|
+
if (this.task) {
|
|
2025
|
+
this.task.stop();
|
|
2026
|
+
this.emitter.emit("paused", this.task);
|
|
2027
|
+
}
|
|
2028
|
+
return this;
|
|
2029
|
+
}
|
|
2030
|
+
async set(status) {
|
|
2031
|
+
const statusConfig = createVimcordStatusConfig(status);
|
|
2032
|
+
let clientStatus;
|
|
2033
|
+
if (this.client.config.app.devMode) {
|
|
2034
|
+
clientStatus = statusConfig.development;
|
|
2035
|
+
} else {
|
|
2036
|
+
clientStatus = statusConfig.production;
|
|
1774
2037
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
ignoredEvents++;
|
|
1780
|
-
} else {
|
|
1781
|
-
importedEvents++;
|
|
1782
|
-
}
|
|
1783
|
-
this.register(event.module.default);
|
|
2038
|
+
if (!clientStatus.interval) {
|
|
2039
|
+
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2040
|
+
} else {
|
|
2041
|
+
await this.scheduleStatusRotation(clientStatus);
|
|
1784
2042
|
}
|
|
1785
|
-
this
|
|
1786
|
-
|
|
2043
|
+
return this;
|
|
2044
|
+
}
|
|
2045
|
+
async destroy() {
|
|
2046
|
+
if (this.task) {
|
|
2047
|
+
this.task.stop();
|
|
2048
|
+
this.task = null;
|
|
2049
|
+
this.emitter.emit("destroyed");
|
|
2050
|
+
await this.clear();
|
|
2051
|
+
}
|
|
2052
|
+
return this;
|
|
2053
|
+
}
|
|
2054
|
+
async clear() {
|
|
2055
|
+
const client = await this.getReadyClient();
|
|
2056
|
+
this.clearData();
|
|
2057
|
+
client.user.setActivity({ name: "" });
|
|
2058
|
+
this.emitter.emit("cleared");
|
|
2059
|
+
return this;
|
|
1787
2060
|
}
|
|
1788
2061
|
};
|
|
1789
2062
|
|
|
1790
|
-
// src/
|
|
2063
|
+
// src/modules/command.manager.ts
|
|
1791
2064
|
var import_discord9 = require("discord.js");
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
SendMethod2[SendMethod2["Reply"] = 0] = "Reply";
|
|
1802
|
-
SendMethod2[SendMethod2["EditReply"] = 1] = "EditReply";
|
|
1803
|
-
SendMethod2[SendMethod2["FollowUp"] = 2] = "FollowUp";
|
|
1804
|
-
SendMethod2[SendMethod2["Channel"] = 3] = "Channel";
|
|
1805
|
-
SendMethod2[SendMethod2["MessageReply"] = 4] = "MessageReply";
|
|
1806
|
-
SendMethod2[SendMethod2["MessageEdit"] = 5] = "MessageEdit";
|
|
1807
|
-
SendMethod2[SendMethod2["User"] = 6] = "User";
|
|
1808
|
-
return SendMethod2;
|
|
1809
|
-
})(SendMethod || {});
|
|
1810
|
-
|
|
1811
|
-
// src/tools/dynaSend.ts
|
|
1812
|
-
var DynaSend = class {
|
|
1813
|
-
static forceArray(value) {
|
|
1814
|
-
return Array.isArray(value) ? value : [value];
|
|
1815
|
-
}
|
|
1816
|
-
static isInteractionCallback(obj) {
|
|
1817
|
-
return obj instanceof import_discord7.InteractionCallbackResponse;
|
|
1818
|
-
}
|
|
1819
|
-
static filterFlags(flags, excludeFlags) {
|
|
1820
|
-
if (!flags) return void 0;
|
|
1821
|
-
const flagArray = this.forceArray(flags);
|
|
1822
|
-
return flagArray.filter((flag) => !excludeFlags.includes(flag));
|
|
2065
|
+
var BaseCommandManager = class {
|
|
2066
|
+
type;
|
|
2067
|
+
client;
|
|
2068
|
+
commands = /* @__PURE__ */ new Map();
|
|
2069
|
+
moduleSuffix;
|
|
2070
|
+
constructor(client, type, moduleSuffix) {
|
|
2071
|
+
this.type = type;
|
|
2072
|
+
this.client = client;
|
|
2073
|
+
this.moduleSuffix = moduleSuffix;
|
|
1823
2074
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
2075
|
+
/**
|
|
2076
|
+
* Gets a command by name.
|
|
2077
|
+
*/
|
|
2078
|
+
get(name) {
|
|
2079
|
+
if (this.type === 1 /* Prefix */) {
|
|
2080
|
+
const config = this.client.config.prefixCommands;
|
|
2081
|
+
const search = config.allowCaseInsensitiveCommandNames ? name.toLowerCase() : name;
|
|
2082
|
+
return Array.from(this.commands.values()).find((cmd) => {
|
|
2083
|
+
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2084
|
+
const trigger = config.allowCaseInsensitiveCommandNames ? commandName.toLowerCase() : commandName;
|
|
2085
|
+
if (trigger === search) return true;
|
|
2086
|
+
if ("aliases" in cmd.options) {
|
|
2087
|
+
return cmd.options.aliases?.some(
|
|
2088
|
+
(a) => config.allowCaseInsensitiveCommandNames ? a.toLowerCase() === search : a === search
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2092
|
+
} else {
|
|
2093
|
+
return this.commands.get(name);
|
|
1827
2094
|
}
|
|
1828
|
-
if (handler instanceof import_discord7.BaseChannel) return 3 /* Channel */;
|
|
1829
|
-
if (handler instanceof import_discord7.Message) return 4 /* MessageReply */;
|
|
1830
|
-
if (handler instanceof import_discord7.GuildMember || handler instanceof import_discord7.User) return 6 /* User */;
|
|
1831
|
-
throw new Error("[DynaSend] Unable to determine send method for handler type");
|
|
1832
2095
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
2096
|
+
/**
|
|
2097
|
+
* Gets/filters commands and orders them alphabetically.
|
|
2098
|
+
*/
|
|
2099
|
+
getAll(options = {}) {
|
|
2100
|
+
const matchedCommands = /* @__PURE__ */ new Map();
|
|
2101
|
+
const isDev = this.client.config.app.devMode;
|
|
2102
|
+
for (const cmd of this.commands.values()) {
|
|
2103
|
+
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2104
|
+
if (options.names || options.fuzzyNames) {
|
|
2105
|
+
const nameMatched = options.names?.includes(commandName) || options.fuzzyNames?.some((fuzzy) => commandName.includes(fuzzy));
|
|
2106
|
+
if (!nameMatched) continue;
|
|
2107
|
+
}
|
|
2108
|
+
if (options.ignoreDeploymentOptions) {
|
|
2109
|
+
matchedCommands.set(commandName, cmd);
|
|
2110
|
+
continue;
|
|
2111
|
+
}
|
|
2112
|
+
const deployment = "deployment" in cmd.options ? cmd.options.deployment ?? {} : {};
|
|
2113
|
+
const isProperEnv = !deployment.environments || deployment.environments.includes(isDev ? "development" : "production");
|
|
2114
|
+
if (!isProperEnv) continue;
|
|
2115
|
+
if (options.globalOnly && deployment.global === false) continue;
|
|
2116
|
+
matchedCommands.set(commandName, cmd);
|
|
1846
2117
|
}
|
|
2118
|
+
return Array.from(matchedCommands.values()).sort((a, b) => {
|
|
2119
|
+
const commandNameA = "builder" in a ? a.builder.name : a.options.name;
|
|
2120
|
+
const commandNameB = "builder" in b ? b.builder.name : b.options.name;
|
|
2121
|
+
return commandNameA.localeCompare(commandNameB);
|
|
2122
|
+
});
|
|
1847
2123
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
withResponse: options.withResponse,
|
|
1863
|
-
poll: options.poll
|
|
1864
|
-
};
|
|
1865
|
-
case 1 /* EditReply */:
|
|
1866
|
-
return {
|
|
1867
|
-
...baseData,
|
|
1868
|
-
flags: this.filterFlags(options.flags, ["Ephemeral", "SuppressNotifications"]),
|
|
1869
|
-
withResponse: options.withResponse,
|
|
1870
|
-
poll: options.poll
|
|
1871
|
-
};
|
|
1872
|
-
case 2 /* FollowUp */:
|
|
1873
|
-
return {
|
|
1874
|
-
...baseData,
|
|
1875
|
-
flags: options.flags,
|
|
1876
|
-
withResponse: options.withResponse,
|
|
1877
|
-
poll: options.poll
|
|
1878
|
-
};
|
|
1879
|
-
case 3 /* Channel */:
|
|
1880
|
-
return {
|
|
1881
|
-
...baseData,
|
|
1882
|
-
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1883
|
-
poll: options.poll,
|
|
1884
|
-
stickers: options.stickers,
|
|
1885
|
-
reply: options.reply
|
|
1886
|
-
};
|
|
1887
|
-
case 4 /* MessageReply */:
|
|
1888
|
-
return {
|
|
1889
|
-
...baseData,
|
|
1890
|
-
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1891
|
-
poll: options.poll,
|
|
1892
|
-
stickers: options.stickers
|
|
1893
|
-
};
|
|
1894
|
-
case 5 /* MessageEdit */:
|
|
1895
|
-
return {
|
|
1896
|
-
...baseData,
|
|
1897
|
-
flags: this.filterFlags(options.flags, ["Ephemeral", "SuppressNotifications"])
|
|
1898
|
-
};
|
|
1899
|
-
case 6 /* User */:
|
|
1900
|
-
return {
|
|
1901
|
-
...baseData,
|
|
1902
|
-
flags: this.filterFlags(options.flags, ["Ephemeral"]),
|
|
1903
|
-
poll: options.poll,
|
|
1904
|
-
forward: options.forward,
|
|
1905
|
-
stickers: options.stickers
|
|
2124
|
+
/**
|
|
2125
|
+
* Groups commands by category alphabetically.
|
|
2126
|
+
*/
|
|
2127
|
+
sortByCategory() {
|
|
2128
|
+
const categories = /* @__PURE__ */ new Map();
|
|
2129
|
+
for (const cmd of this.commands.values()) {
|
|
2130
|
+
const metadata = cmd.options.metadata;
|
|
2131
|
+
if (!metadata?.category) continue;
|
|
2132
|
+
let entry = categories.get(metadata.category);
|
|
2133
|
+
if (!entry) {
|
|
2134
|
+
entry = {
|
|
2135
|
+
name: metadata.category,
|
|
2136
|
+
emoji: metadata.categoryEmoji,
|
|
2137
|
+
commands: []
|
|
1906
2138
|
};
|
|
1907
|
-
|
|
1908
|
-
|
|
2139
|
+
categories.set(metadata.category, entry);
|
|
2140
|
+
}
|
|
2141
|
+
entry.commands.push(cmd);
|
|
1909
2142
|
}
|
|
2143
|
+
return Array.from(categories.values()).sort((a, b) => a.name.localeCompare(b.name)).map((cat) => {
|
|
2144
|
+
cat.commands.sort((a, b) => {
|
|
2145
|
+
const commandNameA = "builder" in a ? a.builder.name : a.options.name;
|
|
2146
|
+
const commandNameB = "builder" in b ? b.builder.name : b.options.name;
|
|
2147
|
+
return commandNameA.localeCompare(commandNameB);
|
|
2148
|
+
});
|
|
2149
|
+
return cat;
|
|
2150
|
+
});
|
|
1910
2151
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
return await handler.send(data);
|
|
1924
|
-
case 4 /* MessageReply */:
|
|
1925
|
-
return await handler.reply(data);
|
|
1926
|
-
case 5 /* MessageEdit */: {
|
|
1927
|
-
const message = handler;
|
|
1928
|
-
if (!message.editable) {
|
|
1929
|
-
console.warn("[DynaSend] Message is not editable");
|
|
1930
|
-
return null;
|
|
1931
|
-
}
|
|
1932
|
-
return await message.edit(data);
|
|
1933
|
-
}
|
|
1934
|
-
case 6 /* User */:
|
|
1935
|
-
return await handler.send(data);
|
|
1936
|
-
default:
|
|
1937
|
-
throw new Error(`[DynaSend] Unknown send method '${method}'`);
|
|
1938
|
-
}
|
|
1939
|
-
} catch (error) {
|
|
1940
|
-
console.error(`[DynaSend] Error with method '${SendMethod[method]}':`, error);
|
|
1941
|
-
return null;
|
|
2152
|
+
/**
|
|
2153
|
+
* Imports command modules from a directory.
|
|
2154
|
+
* @param dir Path of one or more folders.
|
|
2155
|
+
* @param set Replaces imported command modules with the ones found.
|
|
2156
|
+
*/
|
|
2157
|
+
async importFrom(dir, set = false) {
|
|
2158
|
+
if (set) this.commands.clear();
|
|
2159
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
2160
|
+
const modules = [];
|
|
2161
|
+
for (const _dir of dirs) {
|
|
2162
|
+
const results = await importModulesFromDir(_dir, this.moduleSuffix);
|
|
2163
|
+
modules.push(...results.map(({ module: module2 }) => module2.default));
|
|
1942
2164
|
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
console.warn(`[DynaSend] Delete delay is less than 1 second (${delay}ms). Is this intentional?`);
|
|
2165
|
+
for (const module2 of modules) {
|
|
2166
|
+
const commandName = "builder" in module2 ? module2.builder.name : module2.options.name;
|
|
2167
|
+
this.commands.set(commandName, module2);
|
|
1947
2168
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
const sendMethod = options.sendMethod ?? this.detectSendMethod(handler);
|
|
1960
|
-
this.validateSendMethod(handler, sendMethod);
|
|
1961
|
-
const messageData = this.createMessageData(options, sendMethod);
|
|
1962
|
-
const message = await this.executeSend(handler, sendMethod, messageData);
|
|
1963
|
-
if (options.deleteAfter && message) {
|
|
1964
|
-
this.scheduleDelete(message, options.deleteAfter);
|
|
2169
|
+
let moduleType;
|
|
2170
|
+
switch (this.type) {
|
|
2171
|
+
case 0 /* Slash */:
|
|
2172
|
+
moduleType = "Prefix Commands";
|
|
2173
|
+
break;
|
|
2174
|
+
case 2 /* Context */:
|
|
2175
|
+
moduleType = "Context Commands";
|
|
2176
|
+
break;
|
|
2177
|
+
case 1 /* Prefix */:
|
|
2178
|
+
moduleType = "Prefix Commands";
|
|
2179
|
+
break;
|
|
1965
2180
|
}
|
|
1966
|
-
|
|
2181
|
+
this.client.logger.moduleLoaded(moduleType, modules.length);
|
|
2182
|
+
return this.commands;
|
|
1967
2183
|
}
|
|
1968
2184
|
};
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
// src/tools/BetterEmbed.ts
|
|
1974
|
-
var BetterEmbed = class _BetterEmbed {
|
|
1975
|
-
embed = new import_discord8.EmbedBuilder();
|
|
1976
|
-
data;
|
|
1977
|
-
config;
|
|
1978
|
-
/** A powerful wrapper for `EmbedBuilder` that introduces useful features
|
|
1979
|
-
*
|
|
1980
|
-
* Auto-shorthand context formatting (_ACF_) is enabled by default
|
|
1981
|
-
*
|
|
1982
|
-
* All functions utilize _ACF_ unless `BetterEmbed.acf` is set to `false`
|
|
1983
|
-
*
|
|
1984
|
-
* ___Use a blackslash___ `\` ___to escape any context___
|
|
1985
|
-
*
|
|
1986
|
-
* \- - - Author Context - - -
|
|
1987
|
-
* - __`$USER`__: _author's mention (@xsqu1znt)_
|
|
1988
|
-
* - __`$USER_NAME`__: _author's username_
|
|
1989
|
-
* - __`$DISPLAY_NAME`__: _author's display name (requires `GuildMember` context)_
|
|
1990
|
-
* - __`$USER_AVATAR`__: _author's avatar_
|
|
1991
|
-
*
|
|
1992
|
-
* \- - - Client Context - - -
|
|
1993
|
-
*
|
|
1994
|
-
* - __`$BOT_AVATAR`__: _bot's avatar_
|
|
1995
|
-
*
|
|
1996
|
-
* \- - - Shorthand Context - - -
|
|
1997
|
-
* - __`$YEAR`__: _YYYY_
|
|
1998
|
-
* - __`$MONTH`__: _MM_
|
|
1999
|
-
* - __`$DAY`__: _DD_
|
|
2000
|
-
* - __`$year`__: _YY_
|
|
2001
|
-
* - __`$month`__: _M or MM_
|
|
2002
|
-
* - __`$day`__: _D or DD_ */
|
|
2003
|
-
constructor(data = {}) {
|
|
2004
|
-
this.config = data.config || globalVimcordToolsConfig;
|
|
2005
|
-
this.data = {
|
|
2006
|
-
context: data.context || null,
|
|
2007
|
-
author: data.author || null,
|
|
2008
|
-
title: data.title || null,
|
|
2009
|
-
thumbnailUrl: data.thumbnailUrl || null,
|
|
2010
|
-
description: data.description || null,
|
|
2011
|
-
imageUrl: data.imageUrl || null,
|
|
2012
|
-
footer: data.footer || null,
|
|
2013
|
-
fields: data.fields || [],
|
|
2014
|
-
color: data.color ?? (this.config.devMode ? this.config.embedColorDev : this.config.embedColor),
|
|
2015
|
-
timestamp: data.timestamp || null,
|
|
2016
|
-
acf: data.acf ?? true
|
|
2017
|
-
};
|
|
2018
|
-
this.build();
|
|
2185
|
+
var SlashCommandManager = class extends BaseCommandManager {
|
|
2186
|
+
constructor(client) {
|
|
2187
|
+
super(client, 0 /* Slash */, client.config.app.moduleSuffixes.slashCommand);
|
|
2019
2188
|
}
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2189
|
+
};
|
|
2190
|
+
var ContextCommandManager = class extends BaseCommandManager {
|
|
2191
|
+
constructor(client) {
|
|
2192
|
+
super(client, 2 /* Context */, client.config.app.moduleSuffixes.contextCommand);
|
|
2024
2193
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
if (typeof this.data.title === "string") {
|
|
2030
|
-
this.data.title = { text: this.data.title };
|
|
2031
|
-
}
|
|
2032
|
-
if (typeof this.data.footer === "string") {
|
|
2033
|
-
this.data.footer = { text: this.data.footer };
|
|
2034
|
-
}
|
|
2035
|
-
if (this.data.timestamp === true) {
|
|
2036
|
-
this.data.timestamp = Date.now();
|
|
2037
|
-
}
|
|
2194
|
+
};
|
|
2195
|
+
var PrefixCommandManager = class extends BaseCommandManager {
|
|
2196
|
+
constructor(client) {
|
|
2197
|
+
super(client, 1 /* Prefix */, client.config.app.moduleSuffixes.prefixCommand);
|
|
2038
2198
|
}
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2199
|
+
};
|
|
2200
|
+
var CommandManager = class {
|
|
2201
|
+
client;
|
|
2202
|
+
slash;
|
|
2203
|
+
prefix;
|
|
2204
|
+
context;
|
|
2205
|
+
constructor(client) {
|
|
2206
|
+
this.client = client;
|
|
2207
|
+
this.slash = new SlashCommandManager(client);
|
|
2208
|
+
this.prefix = new PrefixCommandManager(client);
|
|
2209
|
+
this.context = new ContextCommandManager(client);
|
|
2043
2210
|
}
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
if (!context) return null;
|
|
2047
|
-
return context.client || context.interaction?.client || context.message?.client || null;
|
|
2211
|
+
getAllAppCommands(options = {}) {
|
|
2212
|
+
return [...this.slash.getAll(options), ...this.context.getAll(options)];
|
|
2048
2213
|
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
const client = this.getContextClient();
|
|
2055
|
-
const formatString = (str2) => {
|
|
2056
|
-
if (!str2 || !str2.includes("$")) return str2;
|
|
2057
|
-
return str2.replace(/(?<!\\)\$USER\b/g, actualUser?.toString() || "$USER").replace(/(?<!\\)\$USER_NAME\b/g, actualUser?.username || "$USER_NAME").replace(/(?<!\\)\$USER_AVATAR\b/g, actualUser?.avatarURL() || "$USER_AVATAR").replace(/(?<!\\)\$DISPLAY_NAME\b/g, guildMember?.displayName || "$DISPLAY_NAME").replace(/(?<!\\)\$BOT_AVATAR\b/g, client?.user?.avatarURL() || "$BOT_AVATAR").replace(/(?<!\\)\$INVIS\b/g, "\u200B").replace(/(?<!\\)\$YEAR/g, (/* @__PURE__ */ new Date()).getFullYear().toString()).replace(/(?<!\\)\$MONTH/g, String((/* @__PURE__ */ new Date()).getMonth() + 1).padStart(2, "0")).replace(/(?<!\\)\$DAY/g, String((/* @__PURE__ */ new Date()).getDate()).padStart(2, "0")).replace(/(?<!\\)\$year/g, String((/* @__PURE__ */ new Date()).getFullYear()).slice(-2)).replace(/(?<!\\)\$month/g, String((/* @__PURE__ */ new Date()).getMonth() + 1).padStart(2, "0")).replace(/(?<!\\)\$day/g, String((/* @__PURE__ */ new Date()).getDate()).padStart(2, "0")).replace(/(?<!\\|<)@([0-9]+)(?!>)/g, "<@$1>").replace(/(?<!\\|<)@&([0-9]+)(?!>)/g, "<@&$1>").replace(/(?<!\\|<)#([0-9]+)(?!>)/g, "<#$1>");
|
|
2058
|
-
};
|
|
2059
|
-
if (str) {
|
|
2060
|
-
return formatString(str);
|
|
2061
|
-
}
|
|
2062
|
-
if (this.data.author && typeof this.data.author === "object") {
|
|
2063
|
-
this.data.author.text = formatString(this.data.author.text);
|
|
2064
|
-
if (this.data.author.icon === true && actualUser) {
|
|
2065
|
-
this.data.author.icon = actualUser.avatarURL();
|
|
2066
|
-
} else if (typeof this.data.author.icon === "string") {
|
|
2067
|
-
this.data.author.icon = formatString(this.data.author.icon);
|
|
2068
|
-
}
|
|
2069
|
-
}
|
|
2070
|
-
if (this.data.title && typeof this.data.title === "object") {
|
|
2071
|
-
this.data.title.text = formatString(this.data.title.text);
|
|
2072
|
-
}
|
|
2073
|
-
if (this.data.description) {
|
|
2074
|
-
this.data.description = formatString(
|
|
2075
|
-
Array.isArray(this.data.description) ? this.data.description.filter((s) => s !== null && s !== void 0).join("\n") : this.data.description
|
|
2076
|
-
);
|
|
2077
|
-
}
|
|
2078
|
-
if (this.data.footer && typeof this.data.footer === "object") {
|
|
2079
|
-
this.data.footer.text = formatString(this.data.footer.text);
|
|
2214
|
+
async registerGlobal(options = {}) {
|
|
2215
|
+
const client = await this.client.waitForReady();
|
|
2216
|
+
if (!client.rest) {
|
|
2217
|
+
console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
|
|
2218
|
+
return;
|
|
2080
2219
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2220
|
+
const commands = this.getAllAppCommands(options);
|
|
2221
|
+
if (!commands.length) {
|
|
2222
|
+
console.log("[CommandManager] No commands to register globally");
|
|
2223
|
+
return;
|
|
2083
2224
|
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2225
|
+
console.log(`[CommandManager] Registering (${commands.length}) commands globally...`);
|
|
2226
|
+
try {
|
|
2227
|
+
await client.rest.put(import_discord9.Routes.applicationCommands(client.user.id), { body: commands });
|
|
2228
|
+
console.log(`[CommandManager] \u2714 Registered app commands globally`);
|
|
2229
|
+
} catch (err) {
|
|
2230
|
+
console.error(`[CommandManager] \u2716 Failed to register app commands globally`, err);
|
|
2086
2231
|
}
|
|
2087
|
-
this.data.fields = this.data.fields.filter(Boolean).map((field) => ({
|
|
2088
|
-
...field,
|
|
2089
|
-
name: formatString(field.name),
|
|
2090
|
-
value: formatString(field.value)
|
|
2091
|
-
}));
|
|
2092
2232
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
iconURL: typeof this.data.author.icon === "string" ? this.data.author.icon : void 0,
|
|
2099
|
-
url: this.data.author.hyperlink || void 0
|
|
2100
|
-
});
|
|
2101
|
-
} catch (error) {
|
|
2102
|
-
console.error("[BetterEmbed] Invalid author configuration:", error);
|
|
2103
|
-
}
|
|
2104
|
-
}
|
|
2105
|
-
if (this.data.title && typeof this.data.title === "object" && this.data.title.text) {
|
|
2106
|
-
try {
|
|
2107
|
-
this.embed.setTitle(this.data.title.text);
|
|
2108
|
-
if (this.data.title.hyperlink) {
|
|
2109
|
-
this.embed.setURL(this.data.title.hyperlink);
|
|
2110
|
-
}
|
|
2111
|
-
} catch (error) {
|
|
2112
|
-
console.error("[BetterEmbed] Invalid title configuration:", error);
|
|
2113
|
-
}
|
|
2233
|
+
async unregisterGlobal() {
|
|
2234
|
+
const client = await this.client.waitForReady();
|
|
2235
|
+
if (!client.rest) {
|
|
2236
|
+
console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
|
|
2237
|
+
return;
|
|
2114
2238
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2239
|
+
try {
|
|
2240
|
+
await client.rest.put(import_discord9.Routes.applicationCommands(client.user.id), { body: [] });
|
|
2241
|
+
console.log(`[CommandManager] \u2714 Removed app commands globally`);
|
|
2242
|
+
} catch (err) {
|
|
2243
|
+
console.error(`[CommandManager] \u2716 Failed to remove app commands globally`, err);
|
|
2119
2244
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2245
|
+
}
|
|
2246
|
+
async registerGuild(options = {}) {
|
|
2247
|
+
const client = await this.client.waitForReady();
|
|
2248
|
+
if (!client.rest) {
|
|
2249
|
+
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2250
|
+
return;
|
|
2126
2251
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
console.error("[BetterEmbed] Invalid image URL:", error);
|
|
2132
|
-
}
|
|
2252
|
+
const commands = this.getAllAppCommands(options);
|
|
2253
|
+
if (!commands.length) {
|
|
2254
|
+
console.log("[CommandManager] No commands to register by guild");
|
|
2255
|
+
return;
|
|
2133
2256
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2257
|
+
const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
|
|
2258
|
+
console.log(`[CommandManager] Registering (${commands.length}) commands for ${guildIds.length} guilds...`);
|
|
2259
|
+
await Promise.all(
|
|
2260
|
+
guildIds.map(
|
|
2261
|
+
(guildId) => client.rest.put(import_discord9.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
|
|
2262
|
+
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
2263
|
+
console.log(`[CommandManager] \u2714 Set app commands in guild: ${guildId} (${gName})`);
|
|
2264
|
+
}).catch((err) => {
|
|
2265
|
+
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
2266
|
+
console.log(`[CommandManager] \u2716 Failed to set app commands in guild: ${guildId} (${gName})`, err);
|
|
2267
|
+
})
|
|
2268
|
+
)
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2271
|
+
async unregisterGuild(options = {}) {
|
|
2272
|
+
const client = await this.client.waitForReady();
|
|
2273
|
+
if (!client.rest) {
|
|
2274
|
+
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2275
|
+
return;
|
|
2143
2276
|
}
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2277
|
+
const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
|
|
2278
|
+
console.log(`[CommandManager] Unregistering commands from ${guildIds.length} guilds...`);
|
|
2279
|
+
await Promise.all(
|
|
2280
|
+
guildIds.map(
|
|
2281
|
+
(guildId) => client.rest.put(import_discord9.Routes.applicationGuildCommands(client.user.id, guildId), { body: [] }).then(() => console.log(`[CommandManager] \u2714 Removed app commands in guild: ${guildId}`)).catch((err) => console.log(`[CommandManager] \u2716 Failed to remove app commands in guild: ${guildId}`, err))
|
|
2282
|
+
)
|
|
2283
|
+
);
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2287
|
+
// src/modules/event.manager.ts
|
|
2288
|
+
var import_discord10 = require("discord.js");
|
|
2289
|
+
var EventManager = class {
|
|
2290
|
+
client;
|
|
2291
|
+
events = /* @__PURE__ */ new Map();
|
|
2292
|
+
logger;
|
|
2293
|
+
constructor(client) {
|
|
2294
|
+
this.client = client;
|
|
2295
|
+
this.logger = new Logger({ prefixEmoji: "\u{1F4CB}", prefix: `EventManager (i${this.client.clientId})` });
|
|
2296
|
+
for (const event of Object.values(import_discord10.Events)) {
|
|
2297
|
+
client.on(
|
|
2298
|
+
event.toString(),
|
|
2299
|
+
async (...args) => this.executeEvents.apply(this, [event, ...args])
|
|
2300
|
+
);
|
|
2151
2301
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2302
|
+
}
|
|
2303
|
+
register(...events) {
|
|
2304
|
+
for (const event of events) {
|
|
2305
|
+
this.events.set(event.name, event);
|
|
2306
|
+
if (this.client.config.app.verbose) {
|
|
2307
|
+
this.logger.debug(`'${event.name}' registered for EventType '${event.event}'`);
|
|
2157
2308
|
}
|
|
2158
2309
|
}
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2310
|
+
}
|
|
2311
|
+
unregister(...names) {
|
|
2312
|
+
for (const name of names) {
|
|
2313
|
+
const event = this.events.get(name);
|
|
2314
|
+
if (!event) continue;
|
|
2315
|
+
this.events.delete(name);
|
|
2316
|
+
if (this.client.config.app.verbose) {
|
|
2317
|
+
this.logger.debug(`'${event.name}' unregistered for EventType '${event.event}'`);
|
|
2163
2318
|
}
|
|
2164
|
-
this.embed.setFields(validFields);
|
|
2165
2319
|
}
|
|
2166
2320
|
}
|
|
2167
|
-
|
|
2168
|
-
this.
|
|
2169
|
-
this.
|
|
2170
|
-
return this;
|
|
2321
|
+
clear() {
|
|
2322
|
+
this.events.forEach((e) => this.unregister(e.name));
|
|
2323
|
+
this.events.clear();
|
|
2171
2324
|
}
|
|
2172
|
-
|
|
2173
|
-
this.
|
|
2174
|
-
this.build();
|
|
2175
|
-
return this;
|
|
2325
|
+
get(name) {
|
|
2326
|
+
return this.events.get(name);
|
|
2176
2327
|
}
|
|
2177
|
-
|
|
2178
|
-
this.
|
|
2179
|
-
this.build();
|
|
2180
|
-
return this;
|
|
2328
|
+
getByTag(tag) {
|
|
2329
|
+
return Array.from(this.events.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2181
2330
|
}
|
|
2182
|
-
|
|
2183
|
-
this.
|
|
2184
|
-
this.build();
|
|
2185
|
-
return this;
|
|
2331
|
+
getByCategory(category) {
|
|
2332
|
+
return Array.from(this.events.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
2186
2333
|
}
|
|
2187
|
-
|
|
2188
|
-
this.
|
|
2189
|
-
this.build();
|
|
2190
|
-
return this;
|
|
2334
|
+
getByEvent(eventType) {
|
|
2335
|
+
return Array.from(this.events.values()).filter((event) => event.event === eventType);
|
|
2191
2336
|
}
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2337
|
+
async executeEvents(eventType, ...args) {
|
|
2338
|
+
const events = this.getByEvent(eventType);
|
|
2339
|
+
if (!events.length) return;
|
|
2340
|
+
const sortedEvents = events.sort((a, b) => b.priority - a.priority);
|
|
2341
|
+
await Promise.all(
|
|
2342
|
+
sortedEvents.map(async (event) => {
|
|
2343
|
+
try {
|
|
2344
|
+
await event.execute?.(this.client, ...args);
|
|
2345
|
+
if (event.once) {
|
|
2346
|
+
this.unregister(event.name);
|
|
2347
|
+
}
|
|
2348
|
+
} catch (err) {
|
|
2349
|
+
this.logger.error(`'${event.name}' failed to execute`, err);
|
|
2350
|
+
}
|
|
2351
|
+
})
|
|
2352
|
+
);
|
|
2196
2353
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2354
|
+
/** Import event modules that end with `.event` */
|
|
2355
|
+
async importFrom(dir, replaceAll) {
|
|
2356
|
+
dir = Array.isArray(dir) ? dir : [dir];
|
|
2357
|
+
const eventModules = await Promise.all(
|
|
2358
|
+
dir.map((dir2) => importModulesFromDir(dir2, "event"))
|
|
2359
|
+
);
|
|
2360
|
+
if (replaceAll) {
|
|
2361
|
+
this.clear();
|
|
2362
|
+
}
|
|
2363
|
+
let importedEvents = 0;
|
|
2364
|
+
let ignoredEvents = 0;
|
|
2365
|
+
for (const event of eventModules.flat()) {
|
|
2366
|
+
if (!event.module.default.enabled) {
|
|
2367
|
+
ignoredEvents++;
|
|
2368
|
+
} else {
|
|
2369
|
+
importedEvents++;
|
|
2370
|
+
}
|
|
2371
|
+
this.register(event.module.default);
|
|
2372
|
+
}
|
|
2373
|
+
this.client.logger.moduleLoaded("Event Handlers", importedEvents, ignoredEvents);
|
|
2374
|
+
return this.events;
|
|
2201
2375
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2376
|
+
};
|
|
2377
|
+
|
|
2378
|
+
// package.json
|
|
2379
|
+
var version = "1.0.30";
|
|
2380
|
+
|
|
2381
|
+
// src/client.ts
|
|
2382
|
+
var import_node_crypto3 = require("crypto");
|
|
2383
|
+
var import_qznt4 = require("qznt");
|
|
2384
|
+
|
|
2385
|
+
// src/utils/VimcordCLI.ts
|
|
2386
|
+
var import_node_readline = require("readline");
|
|
2387
|
+
var import_qznt3 = require("qznt");
|
|
2388
|
+
|
|
2389
|
+
// src/utils/clientUtils.ts
|
|
2390
|
+
function useClient(clientId = 0) {
|
|
2391
|
+
return Vimcord.instances.get(clientId);
|
|
2392
|
+
}
|
|
2393
|
+
async function useReadyClient(clientId = 0) {
|
|
2394
|
+
return useClient(clientId)?.waitForReady();
|
|
2395
|
+
}
|
|
2396
|
+
function createClient(options, features = {}, config = {}) {
|
|
2397
|
+
return new Vimcord(options, features, config);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
// src/utils/VimcordCLI.ts
|
|
2401
|
+
var VimcordCLI = class {
|
|
2402
|
+
rl;
|
|
2403
|
+
options;
|
|
2404
|
+
commands = /* @__PURE__ */ new Map();
|
|
2405
|
+
logger = new Logger({ prefixEmoji: "\u{1F680}", prefix: "CLI", showTimestamp: false });
|
|
2406
|
+
constructor(options) {
|
|
2407
|
+
this.options = options;
|
|
2408
|
+
this.rl = (0, import_node_readline.createInterface)({
|
|
2409
|
+
input: process.stdin,
|
|
2410
|
+
output: process.stdout,
|
|
2411
|
+
terminal: false
|
|
2412
|
+
});
|
|
2413
|
+
this.rl.on("line", (line) => {
|
|
2414
|
+
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
2415
|
+
if (!isCommand) return;
|
|
2416
|
+
const command = this.commands.get(commandName);
|
|
2417
|
+
if (!command) {
|
|
2418
|
+
const nearestMatches = Array.from(this.commands.keys()).filter(
|
|
2419
|
+
(cmd) => cmd.toLowerCase().includes(commandName.toLowerCase())
|
|
2420
|
+
);
|
|
2421
|
+
return this.logger.error(
|
|
2422
|
+
`Unknown command '${commandName}'${nearestMatches.length ? `. Did you mean ${nearestMatches.length > 1 ? `[${nearestMatches.map((m) => `'${this.options.prefix}${m}'`).join(", ")}]` : `'${this.options.prefix}${nearestMatches[0]}'`}?` : ""}`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
command.fn(args, content);
|
|
2426
|
+
});
|
|
2206
2427
|
}
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2428
|
+
parseLine(line) {
|
|
2429
|
+
if (line.startsWith(this.options.prefix)) {
|
|
2430
|
+
line = line.slice(this.options.prefix.length);
|
|
2431
|
+
} else {
|
|
2432
|
+
return { isCommand: false };
|
|
2433
|
+
}
|
|
2434
|
+
const args = line.split(" ").map((s) => s.trim());
|
|
2435
|
+
const commandName = args.shift();
|
|
2436
|
+
return { isCommand: true, commandName, content: args.join(" "), args };
|
|
2211
2437
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2438
|
+
getClientInstance(line) {
|
|
2439
|
+
const clientIndex = import_qznt3.$.str.getFlag(line, "--client", 1) || import_qznt3.$.str.getFlag(line, "-c", 1);
|
|
2440
|
+
if (clientIndex) {
|
|
2441
|
+
const idx = Number(clientIndex);
|
|
2442
|
+
if (isNaN(idx)) {
|
|
2443
|
+
CLI.logger.error(`'${clientIndex}' is not a valid number`);
|
|
2444
|
+
return void 0;
|
|
2445
|
+
}
|
|
2446
|
+
const client = useClient(idx);
|
|
2447
|
+
if (!client) {
|
|
2448
|
+
CLI.logger.error("Client instance not found");
|
|
2449
|
+
return void 0;
|
|
2450
|
+
}
|
|
2451
|
+
return client;
|
|
2452
|
+
} else {
|
|
2453
|
+
const client = useClient(0);
|
|
2454
|
+
if (!client) {
|
|
2455
|
+
CLI.logger.error("Client instance not found");
|
|
2456
|
+
return void 0;
|
|
2457
|
+
}
|
|
2458
|
+
return client;
|
|
2459
|
+
}
|
|
2216
2460
|
}
|
|
2217
|
-
|
|
2218
|
-
this.
|
|
2219
|
-
|
|
2220
|
-
|
|
2461
|
+
addCommand(commandName, description, fn) {
|
|
2462
|
+
this.commands.set(commandName, { description, fn });
|
|
2463
|
+
}
|
|
2464
|
+
removeCommand(commandName) {
|
|
2465
|
+
if (!this.commands.has(commandName)) return false;
|
|
2466
|
+
this.commands.delete(commandName);
|
|
2467
|
+
return true;
|
|
2468
|
+
}
|
|
2469
|
+
};
|
|
2470
|
+
var initCalled = false;
|
|
2471
|
+
var CLI = new VimcordCLI({ prefix: "/" });
|
|
2472
|
+
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
2473
|
+
const prefix = CLI.options.prefix;
|
|
2474
|
+
const helpList = {};
|
|
2475
|
+
for (const cmd of CLI.commands.entries()) {
|
|
2476
|
+
const commandName = cmd[0];
|
|
2477
|
+
const commandDescription = cmd[1].description;
|
|
2478
|
+
helpList[`${prefix}${commandName}`] = `~ ${commandDescription}`;
|
|
2479
|
+
}
|
|
2480
|
+
CLI.logger.table("(help)", helpList);
|
|
2481
|
+
});
|
|
2482
|
+
CLI.addCommand("register", "Register app commands (slash & context) globally, or per guild", async (args, content) => {
|
|
2483
|
+
const client = CLI.getClientInstance(content);
|
|
2484
|
+
if (!client) return;
|
|
2485
|
+
const mode = args[0]?.toLowerCase() || "";
|
|
2486
|
+
if (!["guild", "global"].includes(mode)) {
|
|
2487
|
+
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
2221
2488
|
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2489
|
+
let guildIds = (import_qznt3.$.str.getFlag(content, "--guilds", 1) || import_qznt3.$.str.getFlag(content, "-g", 1) || "").replaceAll(/["']/g, "").split(" ").filter(Boolean).map((s) => s.replaceAll(",", "").trim());
|
|
2490
|
+
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
2491
|
+
switch (mode) {
|
|
2492
|
+
case "guild":
|
|
2493
|
+
CLI.logger.info("Registering guild commands...");
|
|
2494
|
+
await client.commands.registerGuild({ guilds: guildIds });
|
|
2495
|
+
break;
|
|
2496
|
+
case "global":
|
|
2497
|
+
CLI.logger.info("Registering global commands...");
|
|
2498
|
+
await client.commands.registerGlobal();
|
|
2499
|
+
break;
|
|
2224
2500
|
}
|
|
2225
|
-
|
|
2226
|
-
|
|
2501
|
+
});
|
|
2502
|
+
CLI.addCommand("unregister", "Unregister app commands globally, or per guild", async (args, content) => {
|
|
2503
|
+
const client = CLI.getClientInstance(content);
|
|
2504
|
+
if (!client) return;
|
|
2505
|
+
const mode = args[0]?.toLowerCase() || "";
|
|
2506
|
+
if (!["guild", "global"].includes(mode)) {
|
|
2507
|
+
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
2227
2508
|
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
});
|
|
2509
|
+
let guildIds = (import_qznt3.$.str.getFlag(content, "--guilds", 1) || import_qznt3.$.str.getFlag(content, "-g", 1) || "").replaceAll(/["']/g, "").split(" ").filter(Boolean).map((s) => s.replaceAll(",", "").trim());
|
|
2510
|
+
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
2511
|
+
switch (mode) {
|
|
2512
|
+
case "guild":
|
|
2513
|
+
CLI.logger.info("Unregistering guild commands...");
|
|
2514
|
+
await client.commands.unregisterGuild({ guilds: guildIds });
|
|
2515
|
+
break;
|
|
2516
|
+
case "global":
|
|
2517
|
+
CLI.logger.info("Unregistering global commands...");
|
|
2518
|
+
await client.commands.unregisterGlobal();
|
|
2519
|
+
break;
|
|
2240
2520
|
}
|
|
2241
|
-
};
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
label: config?.inviteButtonLabel || "Support Support",
|
|
2252
|
-
style: import_discord9.ButtonStyle.Link
|
|
2253
|
-
}),
|
|
2254
|
-
details: new import_discord9.ButtonBuilder({
|
|
2255
|
-
customId: "btn_details",
|
|
2256
|
-
label: config?.detailButtonLabel || "Details",
|
|
2257
|
-
style: import_discord9.ButtonStyle.Secondary
|
|
2258
|
-
})
|
|
2259
|
-
};
|
|
2260
|
-
const actionRow = new import_discord9.ActionRowBuilder({
|
|
2261
|
-
components: config?.inviteUrl && guild?.id !== (config.inviteUrl || client.config.staff.guild.id) ? [buttons.supportServer, buttons.details] : [buttons.details]
|
|
2262
|
-
});
|
|
2263
|
-
const embed_error = config?.embed?.(new BetterEmbed(), error, guild) || new BetterEmbed({
|
|
2264
|
-
color: "Red",
|
|
2265
|
-
title: "Something went wrong",
|
|
2266
|
-
description: "If you keep encountering this error, please report it."
|
|
2267
|
-
});
|
|
2268
|
-
const msg = await embed_error.send(messageOrInteraction, {
|
|
2269
|
-
components: [actionRow],
|
|
2270
|
-
flags: config?.ephemeral ? "Ephemeral" : void 0,
|
|
2271
|
-
deleteAfter: config?.deleteAfter
|
|
2272
|
-
});
|
|
2273
|
-
if (!msg) return null;
|
|
2274
|
-
const collector = msg.createMessageComponentCollector({
|
|
2275
|
-
componentType: import_discord9.ComponentType.Button,
|
|
2276
|
-
idle: config?.detailButtonIdleTimeout ?? 3e4,
|
|
2277
|
-
filter: (i) => i.customId === "btn_details"
|
|
2278
|
-
});
|
|
2279
|
-
collector.on("collect", (i) => {
|
|
2280
|
-
const attachment = new import_discord9.AttachmentBuilder(Buffer.from(`${error.message}
|
|
2281
|
-
|
|
2282
|
-
${error.stack}`), {
|
|
2283
|
-
name: "error.txt"
|
|
2284
|
-
});
|
|
2285
|
-
i.reply({ files: [attachment], flags: "Ephemeral" });
|
|
2286
|
-
});
|
|
2287
|
-
collector.on("end", () => {
|
|
2288
|
-
buttons.details.setDisabled(true);
|
|
2289
|
-
embed_error.send(messageOrInteraction, {
|
|
2290
|
-
sendMethod: messageOrInteraction instanceof import_discord9.Message ? 5 /* MessageEdit */ : void 0,
|
|
2291
|
-
components: [actionRow]
|
|
2292
|
-
});
|
|
2521
|
+
});
|
|
2522
|
+
CLI.addCommand("stats", "View statistics about a client instance", (args, content) => {
|
|
2523
|
+
const client = CLI.getClientInstance(content);
|
|
2524
|
+
if (!client) return;
|
|
2525
|
+
CLI.logger.table(`(stats) ~ ${client.config.app.name}`, {
|
|
2526
|
+
"Guilds:": import_qznt3.$.format.number(client.guilds.cache.size),
|
|
2527
|
+
"Ping:": `${client.ws.ping || 0}ms`,
|
|
2528
|
+
"Uptime:": `${import_qznt3.$.math.secs(client.uptime || 0)}s`,
|
|
2529
|
+
"Process Uptime:": `${Math.floor(process.uptime())}s`,
|
|
2530
|
+
"Memory Usage:": `${(process.memoryUsage().rss / 1024 / 1024).toFixed(2)} MB`
|
|
2293
2531
|
});
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2532
|
+
});
|
|
2533
|
+
CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
2534
|
+
const client = CLI.getClientInstance(content);
|
|
2535
|
+
if (!client) return;
|
|
2536
|
+
const mode = (args[0] || "slash").toLowerCase();
|
|
2537
|
+
switch (mode) {
|
|
2538
|
+
case "slash": {
|
|
2539
|
+
const commands = Array.from(client.commands.slash.commands.values());
|
|
2540
|
+
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
2541
|
+
const tableData = {};
|
|
2542
|
+
for (const cmd of commands) {
|
|
2543
|
+
tableData[`/${cmd.builder.name}`] = `~ ${cmd.builder.description || "No description"}`;
|
|
2544
|
+
}
|
|
2545
|
+
return CLI.logger.table(`(cmds) ~ slash (${import_qznt3.$.format.number(commands.length)})`, tableData);
|
|
2546
|
+
}
|
|
2547
|
+
case "prefix": {
|
|
2548
|
+
const commands = Array.from(client.commands.prefix.commands.values());
|
|
2549
|
+
commands.sort((a, b) => {
|
|
2550
|
+
const nameA = a.toConfig().name;
|
|
2551
|
+
const nameB = b.toConfig().name;
|
|
2552
|
+
return nameA.localeCompare(nameB);
|
|
2553
|
+
});
|
|
2554
|
+
const tableData = {};
|
|
2555
|
+
const defaultPrefix = client.config.prefixCommands.defaultPrefix;
|
|
2556
|
+
for (const cmd of commands) {
|
|
2557
|
+
const config = cmd.toConfig();
|
|
2558
|
+
const aliasIndicator = config.aliases?.length ? ` [${config.aliases.join(", ")}]` : "";
|
|
2559
|
+
tableData[`${defaultPrefix}${config.name}${aliasIndicator}`] = `~ ${config.description || "No description"}`;
|
|
2560
|
+
}
|
|
2561
|
+
return CLI.logger.table(`(cmds) ~ prefix (${import_qznt3.$.format.number(commands.length)})`, tableData);
|
|
2562
|
+
}
|
|
2563
|
+
case "ctx": {
|
|
2564
|
+
const commands = Array.from(client.commands.context.commands.values());
|
|
2565
|
+
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
2566
|
+
const tableData = {};
|
|
2567
|
+
for (const cmd of commands) {
|
|
2568
|
+
const type = cmd.builder.type === 2 ? "User" : "Msg";
|
|
2569
|
+
tableData[`[${type}] ${cmd.builder.name}`] = "";
|
|
2570
|
+
}
|
|
2571
|
+
return CLI.logger.table(`(cmds) ~ ctx (${import_qznt3.$.format.number(commands.length)})`, tableData);
|
|
2307
2572
|
}
|
|
2573
|
+
default:
|
|
2574
|
+
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
2308
2575
|
}
|
|
2576
|
+
});
|
|
2577
|
+
function initCLI() {
|
|
2578
|
+
if (initCalled) return;
|
|
2579
|
+
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2580
|
+
initCalled = true;
|
|
2309
2581
|
}
|
|
2310
2582
|
|
|
2311
|
-
// package.json
|
|
2312
|
-
var version = "1.0.27";
|
|
2313
|
-
|
|
2314
2583
|
// src/client.ts
|
|
2315
|
-
var import_node_crypto3 = require("crypto");
|
|
2316
2584
|
var import_chalk2 = __toESM(require("chalk"));
|
|
2317
|
-
var
|
|
2318
|
-
|
|
2585
|
+
var Vimcord = class _Vimcord extends import_discord11.Client {
|
|
2586
|
+
static instances = /* @__PURE__ */ new Map();
|
|
2319
2587
|
uuid = (0, import_node_crypto3.randomUUID)();
|
|
2320
|
-
clientId =
|
|
2588
|
+
clientId = _Vimcord.instances.size;
|
|
2321
2589
|
clientOptions;
|
|
2322
2590
|
features;
|
|
2323
2591
|
config;
|
|
@@ -2420,13 +2688,16 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2420
2688
|
this.on("error", (err) => this.logger.error("Client Error", err));
|
|
2421
2689
|
this.on("shardError", (err) => this.logger.error("Client Shard Error", err));
|
|
2422
2690
|
}
|
|
2423
|
-
this.
|
|
2691
|
+
if (!this.config.app.disableBanner === false) {
|
|
2692
|
+
this.logger.clientBanner(this);
|
|
2693
|
+
}
|
|
2424
2694
|
this.once("clientReady", (client) => {
|
|
2425
2695
|
this.logger.clientReady(client.user.tag, client.guilds.cache.size);
|
|
2426
2696
|
});
|
|
2427
|
-
|
|
2697
|
+
_Vimcord.instances.set(this.clientId, this);
|
|
2698
|
+
initCLI();
|
|
2428
2699
|
}
|
|
2429
|
-
/** Returns the options, features, and config of this client */
|
|
2700
|
+
/** Returns the options, features, and config of this client. */
|
|
2430
2701
|
toJSON() {
|
|
2431
2702
|
return {
|
|
2432
2703
|
options: this.clientOptions,
|
|
@@ -2434,7 +2705,7 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2434
2705
|
config: this.config
|
|
2435
2706
|
};
|
|
2436
2707
|
}
|
|
2437
|
-
/**
|
|
2708
|
+
/** Makes a clone of this client. */
|
|
2438
2709
|
clone() {
|
|
2439
2710
|
const { options, features, config } = this.toJSON();
|
|
2440
2711
|
return new _Vimcord(options, features, config);
|
|
@@ -2450,31 +2721,31 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2450
2721
|
this.config.staff = createVimcordStaffConfig(options);
|
|
2451
2722
|
return this;
|
|
2452
2723
|
}
|
|
2453
|
-
configureSlashCommands(options) {
|
|
2724
|
+
configureSlashCommands(options = {}) {
|
|
2454
2725
|
this.config.slashCommands = createVimcordSlashCommandConfig(options);
|
|
2455
2726
|
return this;
|
|
2456
2727
|
}
|
|
2457
|
-
configurePrefixCommands(options) {
|
|
2728
|
+
configurePrefixCommands(options = {}) {
|
|
2458
2729
|
this.config.prefixCommands = createVimcordPrefixCommandConfig(options);
|
|
2459
2730
|
return this;
|
|
2460
2731
|
}
|
|
2461
|
-
configureContextCommands(options) {
|
|
2732
|
+
configureContextCommands(options = {}) {
|
|
2462
2733
|
this.config.contextCommands = createVimcordContextCommandConfig(options);
|
|
2463
2734
|
return this;
|
|
2464
2735
|
}
|
|
2465
|
-
async
|
|
2736
|
+
async importEventModules(dir, replaceAll) {
|
|
2466
2737
|
await this.events.importFrom(dir, replaceAll);
|
|
2467
2738
|
return this;
|
|
2468
2739
|
}
|
|
2469
|
-
async
|
|
2740
|
+
async importSlashCommandModules(dir, replaceAll) {
|
|
2470
2741
|
await this.commands.slash.importFrom(dir, replaceAll);
|
|
2471
2742
|
return this;
|
|
2472
2743
|
}
|
|
2473
|
-
async
|
|
2744
|
+
async importPrefixCommandModules(dir, replaceAll) {
|
|
2474
2745
|
await this.commands.prefix.importFrom(dir, replaceAll);
|
|
2475
2746
|
return this;
|
|
2476
2747
|
}
|
|
2477
|
-
async
|
|
2748
|
+
async importContextCommandModules(dir, replaceAll) {
|
|
2478
2749
|
await this.commands.context.importFrom(dir, replaceAll);
|
|
2479
2750
|
return this;
|
|
2480
2751
|
}
|
|
@@ -2483,10 +2754,13 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2483
2754
|
this.logger.database("Using", db.moduleName);
|
|
2484
2755
|
return this.db.connect();
|
|
2485
2756
|
}
|
|
2486
|
-
async
|
|
2757
|
+
async waitForReady() {
|
|
2487
2758
|
if (this.isReady()) return this;
|
|
2488
2759
|
return new Promise((resolve, reject) => {
|
|
2489
|
-
const timeout = setTimeout(
|
|
2760
|
+
const timeout = setTimeout(
|
|
2761
|
+
() => reject(new Error(`Client (i${this.clientId}) timed out waiting for ready`)),
|
|
2762
|
+
6e4
|
|
2763
|
+
);
|
|
2490
2764
|
this.once("clientReady", () => {
|
|
2491
2765
|
clearTimeout(timeout);
|
|
2492
2766
|
resolve(this);
|
|
@@ -2502,20 +2776,20 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2502
2776
|
if (this.features.importModules) {
|
|
2503
2777
|
const importModules = this.features.importModules;
|
|
2504
2778
|
await Promise.all([
|
|
2505
|
-
importModules.events && this.
|
|
2506
|
-
importModules.slashCommands && this.
|
|
2507
|
-
importModules.prefixCommands && this.
|
|
2508
|
-
importModules.contextCommands && this.
|
|
2779
|
+
importModules.events && this.importEventModules(importModules.events),
|
|
2780
|
+
importModules.slashCommands && this.importSlashCommandModules(importModules.slashCommands),
|
|
2781
|
+
importModules.prefixCommands && this.importPrefixCommandModules(importModules.prefixCommands),
|
|
2782
|
+
importModules.contextCommands && this.importContextCommandModules(importModules.contextCommands)
|
|
2509
2783
|
]);
|
|
2510
2784
|
}
|
|
2511
2785
|
if (this.features.useDefaultSlashCommandHandler) {
|
|
2512
|
-
this.events.register(
|
|
2513
|
-
}
|
|
2514
|
-
if (this.features.useDefaultPrefixCommandHandler) {
|
|
2515
|
-
this.events.register(defaultPrefixCommandHandler);
|
|
2786
|
+
this.events.register(BUILTIN_SlashCommandHandler);
|
|
2516
2787
|
}
|
|
2517
2788
|
if (this.features.useDefaultContextCommandHandler) {
|
|
2518
|
-
this.events.register(
|
|
2789
|
+
this.events.register(BUILTIN_ContextCommandHandler);
|
|
2790
|
+
}
|
|
2791
|
+
if (this.features.useDefaultPrefixCommandHandler) {
|
|
2792
|
+
this.events.register(BUILTIN_PrefixCommandHandler);
|
|
2519
2793
|
}
|
|
2520
2794
|
return this;
|
|
2521
2795
|
}
|
|
@@ -2535,161 +2809,107 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2535
2809
|
await tokenOrPreHook(this);
|
|
2536
2810
|
} else {
|
|
2537
2811
|
await preHook?.(this);
|
|
2538
|
-
}
|
|
2539
|
-
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2540
|
-
const loginResult = await
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
);
|
|
2553
|
-
return null;
|
|
2554
|
-
} finally {
|
|
2555
|
-
this.clientStartingPromise = null;
|
|
2556
|
-
}
|
|
2557
|
-
};
|
|
2558
|
-
this.clientStartingPromise = main();
|
|
2559
|
-
return this.clientStartingPromise;
|
|
2560
|
-
}
|
|
2561
|
-
async kill() {
|
|
2562
|
-
await super.destroy();
|
|
2563
|
-
const idx = clientInstances.indexOf(this);
|
|
2564
|
-
if (idx >= 0) clientInstances.splice(idx, 1);
|
|
2565
|
-
this.logger.debug("\u{1F6AA} Logged out of Discord");
|
|
2566
|
-
}
|
|
2567
|
-
/** Shortcut for {@link fetchUser tools.fetchUser} */
|
|
2568
|
-
async fetchUser(id) {
|
|
2569
|
-
const client = await this.whenReady();
|
|
2570
|
-
return fetchUser(client, id);
|
|
2571
|
-
}
|
|
2572
|
-
/** Shortcut for {@link fetchGuild tools.fetchGuild} */
|
|
2573
|
-
async fetchGuild(id) {
|
|
2574
|
-
const client = await this.whenReady();
|
|
2575
|
-
return fetchGuild(client, id);
|
|
2576
|
-
}
|
|
2577
|
-
};
|
|
2578
|
-
var defaultPrefixCommandHandler = new EventBuilder({
|
|
2579
|
-
event: "messageCreate",
|
|
2580
|
-
name: "PrefixCommandHandler",
|
|
2581
|
-
async execute(client, message) {
|
|
2582
|
-
if (message.author.bot || !message.guild) return;
|
|
2583
|
-
const config = client.config.prefixCommands;
|
|
2584
|
-
let activePrefix = config.defaultPrefix;
|
|
2585
|
-
if (config.guildPrefixResolver) {
|
|
2586
|
-
try {
|
|
2587
|
-
const customPrefix = await config.guildPrefixResolver(client, message.guild.id);
|
|
2588
|
-
if (customPrefix) activePrefix = customPrefix;
|
|
2589
|
-
} catch (err) {
|
|
2590
|
-
client.logger.error(`Error in guildPrefixResolver for guild ${message.guild.id}:`, err);
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
let prefixUsed;
|
|
2594
|
-
if (message.content.startsWith(activePrefix)) {
|
|
2595
|
-
prefixUsed = activePrefix;
|
|
2596
|
-
} else if (config.allowMentionAsPrefix) {
|
|
2597
|
-
const mention = (0, import_discord10.userMention)(client.user.id);
|
|
2598
|
-
if (message.content.startsWith(mention)) {
|
|
2599
|
-
prefixUsed = message.content.startsWith(`${mention} `) ? `${mention} ` : mention;
|
|
2600
|
-
}
|
|
2601
|
-
}
|
|
2602
|
-
if (!prefixUsed) return;
|
|
2603
|
-
const contentWithoutPrefix = message.content.slice(prefixUsed.length).trim();
|
|
2604
|
-
const args = contentWithoutPrefix.split(/\s+/);
|
|
2605
|
-
const trigger = args.shift();
|
|
2606
|
-
if (!trigger) return;
|
|
2607
|
-
const command = client.commands.prefix.get(trigger);
|
|
2608
|
-
if (!command) return;
|
|
2609
|
-
message.content = args.join(" ");
|
|
2610
|
-
try {
|
|
2611
|
-
return await command.run(client, client, message);
|
|
2612
|
-
} catch (err) {
|
|
2613
|
-
await sendCommandErrorEmbed(client, err, message.guild, message);
|
|
2614
|
-
throw err;
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
});
|
|
2618
|
-
var defaultSlashCommandHandler = new EventBuilder({
|
|
2619
|
-
event: "interactionCreate",
|
|
2620
|
-
name: "SlashCommandHandler",
|
|
2621
|
-
async execute(client, interaction) {
|
|
2622
|
-
if (!interaction.isChatInputCommand()) return;
|
|
2623
|
-
const command = client.commands.slash.get(interaction.commandName);
|
|
2624
|
-
if (!command) {
|
|
2625
|
-
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
2626
|
-
if (interaction.replied || interaction.deferred) {
|
|
2627
|
-
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
2628
|
-
}
|
|
2629
|
-
return interaction.reply({ content, flags: "Ephemeral" });
|
|
2630
|
-
}
|
|
2631
|
-
try {
|
|
2632
|
-
return await command.run(client, client, interaction);
|
|
2633
|
-
} catch (err) {
|
|
2634
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2635
|
-
throw err;
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2638
|
-
});
|
|
2639
|
-
var defaultContextCommandHandler = new EventBuilder({
|
|
2640
|
-
event: "interactionCreate",
|
|
2641
|
-
name: "ContextCommandHandler",
|
|
2642
|
-
async execute(client, interaction) {
|
|
2643
|
-
if (!interaction.isContextMenuCommand()) return;
|
|
2644
|
-
const command = client.commands.context.get(interaction.commandName);
|
|
2645
|
-
if (!command) {
|
|
2646
|
-
const content = `**${interaction.commandName}** is not a registered context command.`;
|
|
2647
|
-
if (interaction.replied || interaction.deferred) {
|
|
2648
|
-
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
2812
|
+
}
|
|
2813
|
+
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2814
|
+
const loginResult = await import_qznt4.$.async.retry(() => super.login(token), this.features.loginAttempts ?? 3, 1e3);
|
|
2815
|
+
stopLoader("Connected to Discord ");
|
|
2816
|
+
this.config.app.verbose && this.logger.debug("\u23F3 Waiting for ready...");
|
|
2817
|
+
return loginResult;
|
|
2818
|
+
} catch (err) {
|
|
2819
|
+
this.logger.error(
|
|
2820
|
+
`Failed to log into Discord after ${this.features.loginAttempts} attempt(s))`,
|
|
2821
|
+
err
|
|
2822
|
+
);
|
|
2823
|
+
return null;
|
|
2824
|
+
} finally {
|
|
2825
|
+
this.clientStartingPromise = null;
|
|
2649
2826
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
return await command.run(client, client, interaction);
|
|
2654
|
-
} catch (err) {
|
|
2655
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2656
|
-
throw err;
|
|
2657
|
-
}
|
|
2827
|
+
};
|
|
2828
|
+
this.clientStartingPromise = main();
|
|
2829
|
+
return this.clientStartingPromise;
|
|
2658
2830
|
}
|
|
2659
|
-
|
|
2831
|
+
async kill() {
|
|
2832
|
+
await super.destroy();
|
|
2833
|
+
_Vimcord.instances.delete(this.clientId);
|
|
2834
|
+
this.logger.debug("\u{1F6AA} Logged out of Discord");
|
|
2835
|
+
}
|
|
2836
|
+
/** Shortcut for {@link fetchUser tools.fetchUser} */
|
|
2837
|
+
async fetchUser(id) {
|
|
2838
|
+
const client = await this.waitForReady();
|
|
2839
|
+
return fetchUser(client, id);
|
|
2840
|
+
}
|
|
2841
|
+
/** Shortcut for {@link fetchGuild tools.fetchGuild} */
|
|
2842
|
+
async fetchGuild(id) {
|
|
2843
|
+
const client = await this.waitForReady();
|
|
2844
|
+
return fetchGuild(client, id);
|
|
2845
|
+
}
|
|
2846
|
+
};
|
|
2660
2847
|
|
|
2661
2848
|
// src/modules/db/mongo/mongo.ts
|
|
2662
2849
|
var import_mongoose = __toESM(require("mongoose"));
|
|
2663
2850
|
var import_node_events2 = __toESM(require("events"));
|
|
2664
|
-
var
|
|
2851
|
+
var import_qznt5 = require("qznt");
|
|
2665
2852
|
try {
|
|
2666
2853
|
import("mongoose");
|
|
2667
2854
|
} catch {
|
|
2668
2855
|
throw new Error("MongoDatabase requires the mongoose package, install it with `npm install mongoose`");
|
|
2669
2856
|
}
|
|
2670
|
-
var instances = /* @__PURE__ */ new Map();
|
|
2671
|
-
var emitter = new import_node_events2.default();
|
|
2672
2857
|
var MongoDatabase = class _MongoDatabase {
|
|
2858
|
+
static instances = /* @__PURE__ */ new Map();
|
|
2859
|
+
static emitter = new import_node_events2.default();
|
|
2673
2860
|
moduleName = "MongoDatabase";
|
|
2674
2861
|
clientId;
|
|
2675
2862
|
client;
|
|
2676
2863
|
mongoose;
|
|
2677
2864
|
isConnecting = false;
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2865
|
+
/**
|
|
2866
|
+
* Returns an instance of MongoDatabase.
|
|
2867
|
+
* @param clientId [default: 0]
|
|
2868
|
+
*/
|
|
2869
|
+
static getInstance(clientId) {
|
|
2870
|
+
const id = (typeof clientId === "number" ? clientId : clientId?.clientId) ?? 0;
|
|
2871
|
+
return _MongoDatabase.instances.get(id);
|
|
2681
2872
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2873
|
+
/**
|
|
2874
|
+
* Waits for a MongoDatabase instance to be ready. First waiting for the instance to initialize if it doesn't exist.
|
|
2875
|
+
* @param clientId [default: 0]
|
|
2876
|
+
* @param timeoutMs [default: 60000]
|
|
2877
|
+
*/
|
|
2878
|
+
static async getReadyInstance(clientId, timeoutMs = 6e4) {
|
|
2879
|
+
const existing = _MongoDatabase.getInstance(clientId);
|
|
2880
|
+
if (existing) return await existing.waitForReady();
|
|
2881
|
+
return new Promise((resolve, reject) => {
|
|
2882
|
+
const timeout = setTimeout(() => {
|
|
2883
|
+
_MongoDatabase.emitter.off("ready", listener);
|
|
2884
|
+
reject(
|
|
2885
|
+
new Error(
|
|
2886
|
+
`MongoDatabase instance (${clientId}) failed to initialize within ${timeoutMs / 1e3}s. Check your connection logic.`
|
|
2887
|
+
)
|
|
2888
|
+
);
|
|
2889
|
+
}, timeoutMs);
|
|
2890
|
+
const listener = (db) => {
|
|
2891
|
+
if (db.clientId === clientId) {
|
|
2892
|
+
clearTimeout(timeout);
|
|
2893
|
+
_MongoDatabase.emitter.off("ready", listener);
|
|
2894
|
+
resolve(db);
|
|
2895
|
+
}
|
|
2896
|
+
};
|
|
2897
|
+
_MongoDatabase.emitter.on("ready", listener);
|
|
2898
|
+
});
|
|
2684
2899
|
}
|
|
2685
|
-
|
|
2686
|
-
|
|
2900
|
+
/**
|
|
2901
|
+
* Starts a new Mongo client session.
|
|
2902
|
+
* @param options Options for the new session
|
|
2903
|
+
* @param clientId [default: 0]
|
|
2904
|
+
*/
|
|
2905
|
+
static async startSession(options, clientId) {
|
|
2906
|
+
return (await _MongoDatabase.getReadyInstance(clientId))?.startSession(options);
|
|
2687
2907
|
}
|
|
2688
2908
|
constructor(client, options) {
|
|
2689
2909
|
this.client = client;
|
|
2690
2910
|
this.mongoose = new import_mongoose.default.Mongoose(options);
|
|
2691
2911
|
this.clientId = this.client.clientId;
|
|
2692
|
-
instances.set(this.clientId, this);
|
|
2912
|
+
_MongoDatabase.instances.set(this.clientId, this);
|
|
2693
2913
|
}
|
|
2694
2914
|
get connection() {
|
|
2695
2915
|
return this.mongoose.connection;
|
|
@@ -2699,7 +2919,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2699
2919
|
}
|
|
2700
2920
|
async waitForReady() {
|
|
2701
2921
|
if (!this.isReady && this.isConnecting) {
|
|
2702
|
-
return new Promise((resolve) => emitter.once("ready", (db) => resolve(db)));
|
|
2922
|
+
return new Promise((resolve) => _MongoDatabase.emitter.once("ready", (db) => resolve(db)));
|
|
2703
2923
|
}
|
|
2704
2924
|
return this;
|
|
2705
2925
|
}
|
|
@@ -2709,7 +2929,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2709
2929
|
return true;
|
|
2710
2930
|
}
|
|
2711
2931
|
if (!this.isReady && this.isConnecting) {
|
|
2712
|
-
return new Promise((resolve) => emitter.once("ready", () => resolve(true)));
|
|
2932
|
+
return new Promise((resolve) => _MongoDatabase.emitter.once("ready", () => resolve(true)));
|
|
2713
2933
|
}
|
|
2714
2934
|
const connectionUri = uri ?? (this.client.config.app.devMode ? process.env.MONGO_URI_DEV : process.env.MONGO_URI);
|
|
2715
2935
|
options = { ...options, maxRetries: options.maxRetries ?? 3 };
|
|
@@ -2721,11 +2941,11 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2721
2941
|
this.isConnecting = true;
|
|
2722
2942
|
try {
|
|
2723
2943
|
const stopLoader = this.client.logger.loader("Connecting to MongoDB...");
|
|
2724
|
-
await
|
|
2944
|
+
await import_qznt5.$.async.retry(
|
|
2725
2945
|
() => this.mongoose.connect(connectionUri, { autoIndex: true, ...connectionOptions }),
|
|
2726
2946
|
maxRetries
|
|
2727
2947
|
);
|
|
2728
|
-
emitter.emit("ready", this);
|
|
2948
|
+
_MongoDatabase.emitter.emit("ready", this);
|
|
2729
2949
|
stopLoader("Connected to MongoDB ");
|
|
2730
2950
|
} catch (err) {
|
|
2731
2951
|
this.client.logger.error(`Failed to connect to MongoDB after ${maxRetries} attempt(s)`, err);
|
|
@@ -2758,7 +2978,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2758
2978
|
// src/modules/db/mongo/mongoSchema.builder.ts
|
|
2759
2979
|
var import_mongoose2 = require("mongoose");
|
|
2760
2980
|
var import_node_crypto4 = require("crypto");
|
|
2761
|
-
var
|
|
2981
|
+
var import_qznt6 = require("qznt");
|
|
2762
2982
|
try {
|
|
2763
2983
|
import("mongoose");
|
|
2764
2984
|
} catch {
|
|
@@ -2795,7 +3015,7 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2795
3015
|
this.schema = new import_mongoose2.Schema(definition, { versionKey: false });
|
|
2796
3016
|
this.logger = new Logger({
|
|
2797
3017
|
prefixEmoji: "\u{1F96D}",
|
|
2798
|
-
prefix: `MongoSchema (
|
|
3018
|
+
prefix: `MongoSchema (i${instanceId}) [${collection}]`,
|
|
2799
3019
|
colors: { primary: "#F29B58" }
|
|
2800
3020
|
});
|
|
2801
3021
|
for (const plugin of _MongoSchemaBuilder.globalPlugins) {
|
|
@@ -2805,7 +3025,7 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2805
3025
|
async getModel() {
|
|
2806
3026
|
if (this.model) return this.model;
|
|
2807
3027
|
if (this.compilingModel) return this.compilingModel;
|
|
2808
|
-
|
|
3028
|
+
const fn = async () => {
|
|
2809
3029
|
this.db = await MongoDatabase.getReadyInstance(this.instanceId) || null;
|
|
2810
3030
|
if (!this.db) {
|
|
2811
3031
|
throw new Error(`MongoDatabase instance (${this.instanceId}) not found for schema ${this.collection}`);
|
|
@@ -2814,10 +3034,11 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2814
3034
|
if (this.db?.client.config.app.verbose) {
|
|
2815
3035
|
this.logger.debug(`Compiled! | ${this.db?.client.config.app.name}`);
|
|
2816
3036
|
}
|
|
3037
|
+
this.compilingModel = null;
|
|
2817
3038
|
return this.model;
|
|
2818
|
-
}
|
|
3039
|
+
};
|
|
3040
|
+
this.compilingModel = fn();
|
|
2819
3041
|
const res = await this.compilingModel;
|
|
2820
|
-
this.compilingModel = null;
|
|
2821
3042
|
return res;
|
|
2822
3043
|
}
|
|
2823
3044
|
extend(extras) {
|
|
@@ -2843,7 +3064,7 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2843
3064
|
* @param maxRetries [default: 3]
|
|
2844
3065
|
*/
|
|
2845
3066
|
async execute(fn, maxRetries = 3) {
|
|
2846
|
-
return await
|
|
3067
|
+
return await import_qznt6.$.async.retry(async () => {
|
|
2847
3068
|
const model = await this.getModel();
|
|
2848
3069
|
return await fn(model);
|
|
2849
3070
|
}, maxRetries);
|
|
@@ -3132,9 +3353,9 @@ var BetterCollector = class _BetterCollector {
|
|
|
3132
3353
|
};
|
|
3133
3354
|
|
|
3134
3355
|
// src/tools/BetterContainer.ts
|
|
3135
|
-
var
|
|
3356
|
+
var import_discord12 = require("discord.js");
|
|
3136
3357
|
var BetterContainer = class {
|
|
3137
|
-
container = new
|
|
3358
|
+
container = new import_discord12.ContainerBuilder();
|
|
3138
3359
|
data;
|
|
3139
3360
|
config;
|
|
3140
3361
|
constructor(data = {}) {
|
|
@@ -3202,8 +3423,8 @@ var BetterContainer = class {
|
|
|
3202
3423
|
)
|
|
3203
3424
|
);
|
|
3204
3425
|
}
|
|
3205
|
-
if (data.thumbnail) sb.setThumbnailAccessory(new
|
|
3206
|
-
if (data.button) sb.setButtonAccessory(new
|
|
3426
|
+
if (data.thumbnail) sb.setThumbnailAccessory(new import_discord12.ThumbnailBuilder(data.thumbnail));
|
|
3427
|
+
if (data.button) sb.setButtonAccessory(new import_discord12.ButtonBuilder(data.button));
|
|
3207
3428
|
return sb;
|
|
3208
3429
|
});
|
|
3209
3430
|
return this;
|
|
@@ -3227,11 +3448,8 @@ var BetterContainer = class {
|
|
|
3227
3448
|
};
|
|
3228
3449
|
|
|
3229
3450
|
// src/tools/BetterModal.ts
|
|
3230
|
-
var
|
|
3231
|
-
|
|
3232
|
-
const chars = "ABCDEFGHJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
3233
|
-
return Array.from({ length }, () => chars.charAt(Math.floor(Math.random() * chars.length))).join("");
|
|
3234
|
-
}
|
|
3451
|
+
var import_discord13 = require("discord.js");
|
|
3452
|
+
var import_qznt7 = require("qznt");
|
|
3235
3453
|
var BetterModal = class {
|
|
3236
3454
|
id;
|
|
3237
3455
|
options;
|
|
@@ -3241,7 +3459,7 @@ var BetterModal = class {
|
|
|
3241
3459
|
constructor(options = {}) {
|
|
3242
3460
|
this.id = options.id || this.createModalId();
|
|
3243
3461
|
this.options = options;
|
|
3244
|
-
this.modal = new
|
|
3462
|
+
this.modal = new import_discord13.ModalBuilder().setCustomId(this.id);
|
|
3245
3463
|
this.config = options.config || globalVimcordToolsConfig;
|
|
3246
3464
|
if (options.title) {
|
|
3247
3465
|
this.setTitle(options.title);
|
|
@@ -3251,10 +3469,10 @@ var BetterModal = class {
|
|
|
3251
3469
|
}
|
|
3252
3470
|
}
|
|
3253
3471
|
createModalId() {
|
|
3254
|
-
return `modal:${
|
|
3472
|
+
return `modal:${import_qznt7.$.rnd.str(10, "alpha", { casing: "mixed" })}-${Date.now()}`;
|
|
3255
3473
|
}
|
|
3256
3474
|
createComponentId() {
|
|
3257
|
-
return `modal-component:${
|
|
3475
|
+
return `modal-component:${this.id}-${import_qznt7.$.rnd.str(4, "alpha", { casing: "mixed" })}-${Date.now().toString().slice(-4)}`;
|
|
3258
3476
|
}
|
|
3259
3477
|
validateComponentLength() {
|
|
3260
3478
|
if (this.components.size >= 5) throw new Error("Modal can only have 5 components");
|
|
@@ -3299,9 +3517,9 @@ var BetterModal = class {
|
|
|
3299
3517
|
this.validateComponentLength();
|
|
3300
3518
|
let { label, description, custom_id, ...rest } = data;
|
|
3301
3519
|
custom_id ||= this.createComponentId();
|
|
3302
|
-
const textInputComponent = new
|
|
3303
|
-
if (!rest.style) textInputComponent.setStyle(
|
|
3304
|
-
const labelComponent = new
|
|
3520
|
+
const textInputComponent = new import_discord13.TextInputBuilder(rest).setCustomId(custom_id);
|
|
3521
|
+
if (!rest.style) textInputComponent.setStyle(import_discord13.TextInputStyle.Short);
|
|
3522
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setTextInputComponent(textInputComponent);
|
|
3305
3523
|
if (description) labelComponent.setDescription(description);
|
|
3306
3524
|
this.components.set(custom_id, labelComponent);
|
|
3307
3525
|
return this;
|
|
@@ -3310,8 +3528,8 @@ var BetterModal = class {
|
|
|
3310
3528
|
this.validateComponentLength();
|
|
3311
3529
|
let { label, description, custom_id, ...rest } = data;
|
|
3312
3530
|
custom_id ||= this.createComponentId();
|
|
3313
|
-
const stringSelectComponent = new
|
|
3314
|
-
const labelComponent = new
|
|
3531
|
+
const stringSelectComponent = new import_discord13.StringSelectMenuBuilder(rest).setCustomId(custom_id);
|
|
3532
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setStringSelectMenuComponent(stringSelectComponent);
|
|
3315
3533
|
if (description) labelComponent.setDescription(description);
|
|
3316
3534
|
this.components.set(custom_id, labelComponent);
|
|
3317
3535
|
return this;
|
|
@@ -3320,8 +3538,8 @@ var BetterModal = class {
|
|
|
3320
3538
|
this.validateComponentLength();
|
|
3321
3539
|
let { label, description, custom_id, ...rest } = data;
|
|
3322
3540
|
custom_id ||= this.createComponentId();
|
|
3323
|
-
const channelSelectComponent = new
|
|
3324
|
-
const labelComponent = new
|
|
3541
|
+
const channelSelectComponent = new import_discord13.ChannelSelectMenuBuilder(rest).setCustomId(custom_id);
|
|
3542
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setChannelSelectMenuComponent(channelSelectComponent);
|
|
3325
3543
|
if (description) labelComponent.setDescription(description);
|
|
3326
3544
|
this.components.set(custom_id, labelComponent);
|
|
3327
3545
|
return this;
|
|
@@ -3330,8 +3548,8 @@ var BetterModal = class {
|
|
|
3330
3548
|
this.validateComponentLength();
|
|
3331
3549
|
let { label, description, custom_id, ...rest } = data;
|
|
3332
3550
|
custom_id ||= this.createComponentId();
|
|
3333
|
-
const userSelectComponent = new
|
|
3334
|
-
const labelComponent = new
|
|
3551
|
+
const userSelectComponent = new import_discord13.UserSelectMenuBuilder(rest).setCustomId(custom_id);
|
|
3552
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setUserSelectMenuComponent(userSelectComponent);
|
|
3335
3553
|
if (description) labelComponent.setDescription(description);
|
|
3336
3554
|
this.components.set(custom_id, labelComponent);
|
|
3337
3555
|
return this;
|
|
@@ -3340,8 +3558,8 @@ var BetterModal = class {
|
|
|
3340
3558
|
this.validateComponentLength();
|
|
3341
3559
|
let { label, description, custom_id, ...rest } = data;
|
|
3342
3560
|
custom_id ||= this.createComponentId();
|
|
3343
|
-
const roleSelectComponent = new
|
|
3344
|
-
const labelComponent = new
|
|
3561
|
+
const roleSelectComponent = new import_discord13.RoleSelectMenuBuilder(rest).setCustomId(custom_id);
|
|
3562
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setRoleSelectMenuComponent(roleSelectComponent);
|
|
3345
3563
|
if (description) labelComponent.setDescription(description);
|
|
3346
3564
|
this.components.set(custom_id, labelComponent);
|
|
3347
3565
|
return this;
|
|
@@ -3350,8 +3568,8 @@ var BetterModal = class {
|
|
|
3350
3568
|
this.validateComponentLength();
|
|
3351
3569
|
let { label, description, custom_id, ...rest } = data;
|
|
3352
3570
|
custom_id ||= this.createComponentId();
|
|
3353
|
-
const mentionableSelectComponent = new
|
|
3354
|
-
const labelComponent = new
|
|
3571
|
+
const mentionableSelectComponent = new import_discord13.MentionableSelectMenuBuilder(rest).setCustomId(custom_id);
|
|
3572
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setMentionableSelectMenuComponent(mentionableSelectComponent);
|
|
3355
3573
|
if (description) labelComponent.setDescription(description);
|
|
3356
3574
|
this.components.set(custom_id, labelComponent);
|
|
3357
3575
|
return this;
|
|
@@ -3360,13 +3578,16 @@ var BetterModal = class {
|
|
|
3360
3578
|
this.validateComponentLength();
|
|
3361
3579
|
let { label, description, custom_id, ...rest } = data;
|
|
3362
3580
|
custom_id ||= this.createComponentId();
|
|
3363
|
-
const fileUploadComponent = new
|
|
3364
|
-
const labelComponent = new
|
|
3581
|
+
const fileUploadComponent = new import_discord13.FileUploadBuilder(rest).setCustomId(custom_id);
|
|
3582
|
+
const labelComponent = new import_discord13.LabelBuilder().setLabel(label).setFileUploadComponent(fileUploadComponent);
|
|
3365
3583
|
if (description) labelComponent.setDescription(description);
|
|
3366
3584
|
this.components.set(custom_id, labelComponent);
|
|
3367
3585
|
return this;
|
|
3368
3586
|
}
|
|
3369
|
-
/**
|
|
3587
|
+
/**
|
|
3588
|
+
* Shows the modal via interaction.
|
|
3589
|
+
* @param interaction The interaction used to show the modal
|
|
3590
|
+
*/
|
|
3370
3591
|
async show(interaction) {
|
|
3371
3592
|
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3372
3593
|
if (!this.modal.data.title) throw new Error("Modal must have a title");
|
|
@@ -3375,18 +3596,22 @@ var BetterModal = class {
|
|
|
3375
3596
|
console.error("Modal failed to send", err);
|
|
3376
3597
|
});
|
|
3377
3598
|
}
|
|
3378
|
-
/**
|
|
3599
|
+
/**
|
|
3600
|
+
* Waits for the modal to be submitted and returns the component data.
|
|
3379
3601
|
* @param interaction The interaction used to show the modal
|
|
3380
3602
|
* @param options Options */
|
|
3381
3603
|
async awaitSubmit(interaction, options) {
|
|
3382
3604
|
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3383
3605
|
try {
|
|
3384
3606
|
const modalSubmit = await interaction.awaitModalSubmit({
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3607
|
+
filter: (i) => i.customId === this.id,
|
|
3608
|
+
time: options?.timeout ?? this.config.timeouts.modalSubmit,
|
|
3609
|
+
...options
|
|
3388
3610
|
});
|
|
3389
|
-
|
|
3611
|
+
if (options?.autoDefer) {
|
|
3612
|
+
await modalSubmit.deferUpdate();
|
|
3613
|
+
}
|
|
3614
|
+
const fields = /* @__PURE__ */ new Map();
|
|
3390
3615
|
const values = [];
|
|
3391
3616
|
for (const [customId] of this.components) {
|
|
3392
3617
|
let value = null;
|
|
@@ -3401,23 +3626,34 @@ var BetterModal = class {
|
|
|
3401
3626
|
} catch {
|
|
3402
3627
|
}
|
|
3403
3628
|
}
|
|
3404
|
-
fields
|
|
3629
|
+
fields.set(customId, value);
|
|
3405
3630
|
values.push(value);
|
|
3406
3631
|
}
|
|
3407
|
-
return {
|
|
3632
|
+
return {
|
|
3633
|
+
getField(customId) {
|
|
3634
|
+
return fields.get(customId);
|
|
3635
|
+
},
|
|
3636
|
+
values,
|
|
3637
|
+
interaction: modalSubmit,
|
|
3638
|
+
reply: (options2) => dynaSend(modalSubmit, options2),
|
|
3639
|
+
deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2)
|
|
3640
|
+
};
|
|
3408
3641
|
} catch (error) {
|
|
3409
3642
|
return null;
|
|
3410
3643
|
}
|
|
3411
3644
|
}
|
|
3645
|
+
/**
|
|
3646
|
+
* Shows the modal and waits for the modal to be submitted, returning the component data.
|
|
3647
|
+
* @param interaction The interaction used to show the modal
|
|
3648
|
+
* @param options Options */
|
|
3412
3649
|
async showAndAwait(interaction, options) {
|
|
3413
|
-
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3414
3650
|
await this.show(interaction);
|
|
3415
3651
|
return this.awaitSubmit(interaction, options);
|
|
3416
3652
|
}
|
|
3417
3653
|
};
|
|
3418
3654
|
|
|
3419
3655
|
// src/tools/Paginator.ts
|
|
3420
|
-
var
|
|
3656
|
+
var import_discord14 = require("discord.js");
|
|
3421
3657
|
var import_node_events3 = __toESM(require("events"));
|
|
3422
3658
|
var PaginationType = /* @__PURE__ */ ((PaginationType2) => {
|
|
3423
3659
|
PaginationType2[PaginationType2["Short"] = 0] = "Short";
|
|
@@ -3438,7 +3674,7 @@ function wrapPositive(num, max) {
|
|
|
3438
3674
|
}
|
|
3439
3675
|
function createNavButton(id, config) {
|
|
3440
3676
|
const data = config.paginator.buttons[id];
|
|
3441
|
-
const btn = new
|
|
3677
|
+
const btn = new import_discord14.ButtonBuilder({ customId: `btn_${id}`, style: import_discord14.ButtonStyle.Secondary });
|
|
3442
3678
|
if (data.label) {
|
|
3443
3679
|
btn.setLabel(data.label);
|
|
3444
3680
|
} else {
|
|
@@ -3447,7 +3683,7 @@ function createNavButton(id, config) {
|
|
|
3447
3683
|
return btn;
|
|
3448
3684
|
}
|
|
3449
3685
|
function isEmbed(item) {
|
|
3450
|
-
return item instanceof
|
|
3686
|
+
return item instanceof import_discord14.EmbedBuilder || item instanceof BetterEmbed;
|
|
3451
3687
|
}
|
|
3452
3688
|
function resolvePages(pages) {
|
|
3453
3689
|
if (Array.isArray(pages)) {
|
|
@@ -3484,7 +3720,7 @@ var Paginator = class {
|
|
|
3484
3720
|
navigation: { reactions: [], isRequired: false, isLong: false, canJump: false },
|
|
3485
3721
|
collectors: { component: null, reaction: null },
|
|
3486
3722
|
components: {
|
|
3487
|
-
chapterSelect: new
|
|
3723
|
+
chapterSelect: new import_discord14.StringSelectMenuBuilder({ customId: "ssm_chapterSelect" }),
|
|
3488
3724
|
navigation: {
|
|
3489
3725
|
first: createNavButton("first", this.config),
|
|
3490
3726
|
back: createNavButton("back", this.config),
|
|
@@ -3493,8 +3729,8 @@ var Paginator = class {
|
|
|
3493
3729
|
last: createNavButton("last", this.config)
|
|
3494
3730
|
},
|
|
3495
3731
|
actionRows: {
|
|
3496
|
-
chapterSelect: new
|
|
3497
|
-
navigation: new
|
|
3732
|
+
chapterSelect: new import_discord14.ActionRowBuilder(),
|
|
3733
|
+
navigation: new import_discord14.ActionRowBuilder()
|
|
3498
3734
|
}
|
|
3499
3735
|
}
|
|
3500
3736
|
};
|
|
@@ -3594,9 +3830,9 @@ var Paginator = class {
|
|
|
3594
3830
|
sendOptions.content = page;
|
|
3595
3831
|
} else if (isEmbed(page)) {
|
|
3596
3832
|
sendOptions.embeds.push(page);
|
|
3597
|
-
} else if (page instanceof
|
|
3833
|
+
} else if (page instanceof import_discord14.AttachmentBuilder) {
|
|
3598
3834
|
sendOptions.files.push(page);
|
|
3599
|
-
} else if (page instanceof
|
|
3835
|
+
} else if (page instanceof import_discord14.ContainerBuilder || page instanceof BetterContainer) {
|
|
3600
3836
|
sendOptions.components.push(page);
|
|
3601
3837
|
if (!sendOptions.flags.includes("IsComponentsV2")) {
|
|
3602
3838
|
sendOptions.flags.push("IsComponentsV2");
|
|
@@ -3619,20 +3855,20 @@ var Paginator = class {
|
|
|
3619
3855
|
}
|
|
3620
3856
|
return component;
|
|
3621
3857
|
});
|
|
3622
|
-
const disabledNavRow =
|
|
3858
|
+
const disabledNavRow = import_discord14.ActionRowBuilder.from(this.data.components.actionRows.navigation).setComponents(
|
|
3623
3859
|
disabledNavComponents
|
|
3624
3860
|
);
|
|
3625
3861
|
const newComponents = [];
|
|
3626
3862
|
const currentPage = this.data.page.current;
|
|
3627
|
-
if (currentPage instanceof
|
|
3863
|
+
if (currentPage instanceof import_discord14.ContainerBuilder || currentPage instanceof BetterContainer) {
|
|
3628
3864
|
newComponents.push(currentPage);
|
|
3629
3865
|
}
|
|
3630
3866
|
if (this.chapters.length > 1) {
|
|
3631
|
-
const disabledSelect =
|
|
3867
|
+
const disabledSelect = import_discord14.StringSelectMenuBuilder.from(this.data.components.chapterSelect).setDisabled(
|
|
3632
3868
|
true
|
|
3633
3869
|
);
|
|
3634
3870
|
newComponents.push(
|
|
3635
|
-
|
|
3871
|
+
import_discord14.ActionRowBuilder.from(this.data.components.actionRows.chapterSelect).setComponents(disabledSelect)
|
|
3636
3872
|
);
|
|
3637
3873
|
}
|
|
3638
3874
|
if (disabledNavRow.components.length > 0) {
|
|
@@ -3661,7 +3897,7 @@ var Paginator = class {
|
|
|
3661
3897
|
if (this.options.useReactions) {
|
|
3662
3898
|
await this.data.message.reactions.removeAll().catch(Boolean);
|
|
3663
3899
|
} else {
|
|
3664
|
-
const newComponents = this.data.message.components.filter((c) => c.type !==
|
|
3900
|
+
const newComponents = this.data.message.components.filter((c) => c.type !== import_discord14.ComponentType.Container);
|
|
3665
3901
|
await this.data.message.edit({ components: newComponents }).catch(Boolean);
|
|
3666
3902
|
}
|
|
3667
3903
|
}
|
|
@@ -3872,7 +4108,7 @@ var Paginator = class {
|
|
|
3872
4108
|
};
|
|
3873
4109
|
|
|
3874
4110
|
// src/tools/Prompt.ts
|
|
3875
|
-
var
|
|
4111
|
+
var import_discord15 = require("discord.js");
|
|
3876
4112
|
var PromptResolveType = /* @__PURE__ */ ((PromptResolveType2) => {
|
|
3877
4113
|
PromptResolveType2[PromptResolveType2["DisableComponents"] = 0] = "DisableComponents";
|
|
3878
4114
|
PromptResolveType2[PromptResolveType2["ClearComponents"] = 1] = "ClearComponents";
|
|
@@ -3915,13 +4151,13 @@ var Prompt = class {
|
|
|
3915
4151
|
buttonOptions?.confirm,
|
|
3916
4152
|
"btn_confirm",
|
|
3917
4153
|
this.config.prompt.confirmLabel,
|
|
3918
|
-
|
|
4154
|
+
import_discord15.ButtonStyle.Success
|
|
3919
4155
|
);
|
|
3920
4156
|
const reject = this.buildButton(
|
|
3921
4157
|
buttonOptions?.reject,
|
|
3922
4158
|
"btn_reject",
|
|
3923
4159
|
this.config.prompt.rejectLabel,
|
|
3924
|
-
|
|
4160
|
+
import_discord15.ButtonStyle.Danger
|
|
3925
4161
|
);
|
|
3926
4162
|
return { confirm, reject };
|
|
3927
4163
|
}
|
|
@@ -3929,19 +4165,19 @@ var Prompt = class {
|
|
|
3929
4165
|
const map = /* @__PURE__ */ new Map();
|
|
3930
4166
|
if (!customOptions) return map;
|
|
3931
4167
|
for (const [customId, { builder, handler, index = 2 }] of Object.entries(customOptions)) {
|
|
3932
|
-
const button = this.buildButton(builder, customId, customId,
|
|
4168
|
+
const button = this.buildButton(builder, customId, customId, import_discord15.ButtonStyle.Primary);
|
|
3933
4169
|
map.set(customId, { button, handler, index });
|
|
3934
4170
|
}
|
|
3935
4171
|
return map;
|
|
3936
4172
|
}
|
|
3937
4173
|
buildButton(option, customId, defaultLabel, defaultStyle) {
|
|
3938
4174
|
if (typeof option === "function") {
|
|
3939
|
-
return option(new
|
|
4175
|
+
return option(new import_discord15.ButtonBuilder());
|
|
3940
4176
|
}
|
|
3941
|
-
if (option instanceof
|
|
4177
|
+
if (option instanceof import_discord15.ButtonBuilder) {
|
|
3942
4178
|
return option;
|
|
3943
4179
|
}
|
|
3944
|
-
return new
|
|
4180
|
+
return new import_discord15.ButtonBuilder({
|
|
3945
4181
|
customId,
|
|
3946
4182
|
label: defaultLabel,
|
|
3947
4183
|
style: defaultStyle,
|
|
@@ -3949,12 +4185,12 @@ var Prompt = class {
|
|
|
3949
4185
|
});
|
|
3950
4186
|
}
|
|
3951
4187
|
buildActionRow(disable = {}) {
|
|
3952
|
-
const confirmBtn = disable.confirm ? new
|
|
3953
|
-
const rejectBtn = disable.reject ? new
|
|
4188
|
+
const confirmBtn = disable.confirm ? new import_discord15.ButtonBuilder(this.buttons.confirm.data).setDisabled(true) : this.buttons.confirm;
|
|
4189
|
+
const rejectBtn = disable.reject ? new import_discord15.ButtonBuilder(this.buttons.reject.data).setDisabled(true) : this.buttons.reject;
|
|
3954
4190
|
const buttons = [];
|
|
3955
4191
|
const customButtonsArray = Array.from(this.customButtons.entries()).map(([customId, data]) => ({
|
|
3956
4192
|
customId,
|
|
3957
|
-
button: disable[customId] ? new
|
|
4193
|
+
button: disable[customId] ? new import_discord15.ButtonBuilder(data.button.data).setDisabled(true) : data.button,
|
|
3958
4194
|
index: data.index
|
|
3959
4195
|
}));
|
|
3960
4196
|
customButtonsArray.sort((a, b) => a.index - b.index);
|
|
@@ -3975,7 +4211,7 @@ var Prompt = class {
|
|
|
3975
4211
|
buttons.push(custom.button);
|
|
3976
4212
|
}
|
|
3977
4213
|
}
|
|
3978
|
-
return new
|
|
4214
|
+
return new import_discord15.ActionRowBuilder({ components: buttons });
|
|
3979
4215
|
}
|
|
3980
4216
|
buildSendOptions(options) {
|
|
3981
4217
|
const sendData = { ...options };
|
|
@@ -4035,7 +4271,7 @@ var Prompt = class {
|
|
|
4035
4271
|
const validCustomIds = /* @__PURE__ */ new Set(["btn_confirm", "btn_reject", ...this.customButtons.keys()]);
|
|
4036
4272
|
try {
|
|
4037
4273
|
const interaction = await this.message.awaitMessageComponent({
|
|
4038
|
-
componentType:
|
|
4274
|
+
componentType: import_discord15.ComponentType.Button,
|
|
4039
4275
|
filter: (i) => validCustomIds.has(i.customId) && this.isParticipant(i.user.id),
|
|
4040
4276
|
time: this.timeout
|
|
4041
4277
|
});
|
|
@@ -4073,209 +4309,11 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4073
4309
|
await p.send(handler, sendOptions);
|
|
4074
4310
|
return await p.awaitResponse();
|
|
4075
4311
|
}
|
|
4076
|
-
|
|
4077
|
-
// src/utils/VimcordCLI.ts
|
|
4078
|
-
var import_node_readline = require("readline");
|
|
4079
|
-
var import_qznt5 = require("qznt");
|
|
4080
|
-
var VimcordCLI = class {
|
|
4081
|
-
rl;
|
|
4082
|
-
options;
|
|
4083
|
-
commands = /* @__PURE__ */ new Map();
|
|
4084
|
-
logger = new Logger({ prefixEmoji: "\u{1F680}", prefix: "CLI", showTimestamp: false });
|
|
4085
|
-
constructor(options) {
|
|
4086
|
-
this.options = options;
|
|
4087
|
-
this.rl = (0, import_node_readline.createInterface)({
|
|
4088
|
-
input: process.stdin,
|
|
4089
|
-
output: process.stdout,
|
|
4090
|
-
terminal: false
|
|
4091
|
-
});
|
|
4092
|
-
this.rl.on("line", (line) => {
|
|
4093
|
-
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
4094
|
-
if (!isCommand) return;
|
|
4095
|
-
const command = this.commands.get(commandName);
|
|
4096
|
-
if (!command) {
|
|
4097
|
-
const nearestMatches = Array.from(this.commands.keys()).filter(
|
|
4098
|
-
(cmd) => cmd.toLowerCase().includes(commandName.toLowerCase())
|
|
4099
|
-
);
|
|
4100
|
-
return this.logger.error(
|
|
4101
|
-
`Unknown command '${commandName}'${nearestMatches.length ? `. Did you mean ${nearestMatches.length > 1 ? `[${nearestMatches.map((m) => `'${this.options.prefix}${m}'`).join(", ")}]` : `'${this.options.prefix}${nearestMatches[0]}'`}?` : ""}`
|
|
4102
|
-
);
|
|
4103
|
-
}
|
|
4104
|
-
command.fn(args, content);
|
|
4105
|
-
});
|
|
4106
|
-
}
|
|
4107
|
-
parseLine(line) {
|
|
4108
|
-
if (line.startsWith(this.options.prefix)) {
|
|
4109
|
-
line = line.slice(this.options.prefix.length);
|
|
4110
|
-
} else {
|
|
4111
|
-
return { isCommand: false };
|
|
4112
|
-
}
|
|
4113
|
-
const args = line.split(" ").map((s) => s.trim());
|
|
4114
|
-
const commandName = args.shift();
|
|
4115
|
-
return { isCommand: true, commandName, content: args.join(" "), args };
|
|
4116
|
-
}
|
|
4117
|
-
getClientInstance(line) {
|
|
4118
|
-
const clientIndex = import_qznt5.$.str.getFlag(line, "--client", 1) || import_qznt5.$.str.getFlag(line, "-c", 1);
|
|
4119
|
-
if (clientIndex) {
|
|
4120
|
-
const idx = Number(clientIndex);
|
|
4121
|
-
if (isNaN(idx)) {
|
|
4122
|
-
CLI.logger.error(`'${clientIndex}' is not a valid number`);
|
|
4123
|
-
return void 0;
|
|
4124
|
-
}
|
|
4125
|
-
const client = clientInstances[idx];
|
|
4126
|
-
if (!client) {
|
|
4127
|
-
CLI.logger.error("Client instance not found");
|
|
4128
|
-
return void 0;
|
|
4129
|
-
}
|
|
4130
|
-
return client;
|
|
4131
|
-
} else {
|
|
4132
|
-
const client = clientInstances[0];
|
|
4133
|
-
if (!client) {
|
|
4134
|
-
CLI.logger.error("Client instance not found");
|
|
4135
|
-
return void 0;
|
|
4136
|
-
}
|
|
4137
|
-
return client;
|
|
4138
|
-
}
|
|
4139
|
-
}
|
|
4140
|
-
addCommand(commandName, description, fn) {
|
|
4141
|
-
this.commands.set(commandName, { description, fn });
|
|
4142
|
-
}
|
|
4143
|
-
removeCommand(commandName) {
|
|
4144
|
-
if (!this.commands.has(commandName)) return false;
|
|
4145
|
-
this.commands.delete(commandName);
|
|
4146
|
-
return true;
|
|
4147
|
-
}
|
|
4148
|
-
};
|
|
4149
|
-
var initCalled = false;
|
|
4150
|
-
var CLI = new VimcordCLI({ prefix: "/" });
|
|
4151
|
-
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
4152
|
-
const prefix = CLI.options.prefix;
|
|
4153
|
-
const helpList = {};
|
|
4154
|
-
for (const cmd of CLI.commands.entries()) {
|
|
4155
|
-
const commandName = cmd[0];
|
|
4156
|
-
const commandDescription = cmd[1].description;
|
|
4157
|
-
helpList[`${prefix}${commandName}`] = `~ ${commandDescription}`;
|
|
4158
|
-
}
|
|
4159
|
-
CLI.logger.table("(help)", helpList);
|
|
4160
|
-
});
|
|
4161
|
-
CLI.addCommand("register", "Register app commands (slash & context) globally, or per guild", async (args, content) => {
|
|
4162
|
-
const client = CLI.getClientInstance(content);
|
|
4163
|
-
if (!client) return;
|
|
4164
|
-
const mode = args[0]?.toLowerCase() || "";
|
|
4165
|
-
if (!["guild", "global"].includes(mode)) {
|
|
4166
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
4167
|
-
}
|
|
4168
|
-
let guildIds = (import_qznt5.$.str.getFlag(content, "--guilds", 1) || import_qznt5.$.str.getFlag(content, "-g", 1) || "").replaceAll(/["']/g, "").split(" ").filter(Boolean).map((s) => s.replaceAll(",", "").trim());
|
|
4169
|
-
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4170
|
-
switch (mode) {
|
|
4171
|
-
case "guild":
|
|
4172
|
-
CLI.logger.info("Registering guild commands...");
|
|
4173
|
-
await client.commands.registerGuild({ guilds: guildIds });
|
|
4174
|
-
break;
|
|
4175
|
-
case "global":
|
|
4176
|
-
CLI.logger.info("Registering global commands...");
|
|
4177
|
-
await client.commands.registerGlobal();
|
|
4178
|
-
break;
|
|
4179
|
-
}
|
|
4180
|
-
});
|
|
4181
|
-
CLI.addCommand("unregister", "Unregister app commands globally, or per guild", async (args, content) => {
|
|
4182
|
-
const client = CLI.getClientInstance(content);
|
|
4183
|
-
if (!client) return;
|
|
4184
|
-
const mode = args[0]?.toLowerCase() || "";
|
|
4185
|
-
if (!["guild", "global"].includes(mode)) {
|
|
4186
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
4187
|
-
}
|
|
4188
|
-
let guildIds = (import_qznt5.$.str.getFlag(content, "--guilds", 1) || import_qznt5.$.str.getFlag(content, "-g", 1) || "").replaceAll(/["']/g, "").split(" ").filter(Boolean).map((s) => s.replaceAll(",", "").trim());
|
|
4189
|
-
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4190
|
-
switch (mode) {
|
|
4191
|
-
case "guild":
|
|
4192
|
-
CLI.logger.info("Unregistering guild commands...");
|
|
4193
|
-
await client.commands.unregisterGuild({ guilds: guildIds });
|
|
4194
|
-
break;
|
|
4195
|
-
case "global":
|
|
4196
|
-
CLI.logger.info("Unregistering global commands...");
|
|
4197
|
-
await client.commands.unregisterGlobal();
|
|
4198
|
-
break;
|
|
4199
|
-
}
|
|
4200
|
-
});
|
|
4201
|
-
CLI.addCommand("stats", "View statistics about a client instance", (args, content) => {
|
|
4202
|
-
const client = CLI.getClientInstance(content);
|
|
4203
|
-
if (!client) return;
|
|
4204
|
-
CLI.logger.table(`(stats) ~ ${client.config.app.name}`, {
|
|
4205
|
-
"Guilds:": import_qznt5.$.format.number(client.guilds.cache.size),
|
|
4206
|
-
"Ping:": `${client.ws.ping || 0}ms`,
|
|
4207
|
-
"Uptime:": `${import_qznt5.$.math.secs(client.uptime || 0)}s`,
|
|
4208
|
-
"Process Uptime:": `${Math.floor(process.uptime())}s`,
|
|
4209
|
-
"Memory Usage:": `${(process.memoryUsage().rss / 1024 / 1024).toFixed(2)} MB`
|
|
4210
|
-
});
|
|
4211
|
-
});
|
|
4212
|
-
CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
4213
|
-
const client = CLI.getClientInstance(content);
|
|
4214
|
-
if (!client) return;
|
|
4215
|
-
const mode = (args[0] || "slash").toLowerCase();
|
|
4216
|
-
switch (mode) {
|
|
4217
|
-
case "slash": {
|
|
4218
|
-
const commands = Array.from(client.commands.slash.commands.values());
|
|
4219
|
-
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4220
|
-
const tableData = {};
|
|
4221
|
-
for (const cmd of commands) {
|
|
4222
|
-
tableData[`/${cmd.builder.name}`] = `~ ${cmd.builder.description || "No description"}`;
|
|
4223
|
-
}
|
|
4224
|
-
return CLI.logger.table(`(cmds) ~ slash (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4225
|
-
}
|
|
4226
|
-
case "prefix": {
|
|
4227
|
-
const commands = Array.from(client.commands.prefix.commands.values());
|
|
4228
|
-
commands.sort((a, b) => {
|
|
4229
|
-
const nameA = a.toConfig().name;
|
|
4230
|
-
const nameB = b.toConfig().name;
|
|
4231
|
-
return nameA.localeCompare(nameB);
|
|
4232
|
-
});
|
|
4233
|
-
const tableData = {};
|
|
4234
|
-
const defaultPrefix = client.config.prefixCommands.defaultPrefix;
|
|
4235
|
-
for (const cmd of commands) {
|
|
4236
|
-
const config = cmd.toConfig();
|
|
4237
|
-
const aliasIndicator = config.aliases?.length ? ` [${config.aliases.join(", ")}]` : "";
|
|
4238
|
-
tableData[`${defaultPrefix}${config.name}${aliasIndicator}`] = `~ ${config.description || "No description"}`;
|
|
4239
|
-
}
|
|
4240
|
-
return CLI.logger.table(`(cmds) ~ prefix (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4241
|
-
}
|
|
4242
|
-
case "ctx": {
|
|
4243
|
-
const commands = Array.from(client.commands.context.commands.values());
|
|
4244
|
-
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4245
|
-
const tableData = {};
|
|
4246
|
-
for (const cmd of commands) {
|
|
4247
|
-
const type = cmd.builder.type === 2 ? "User" : "Msg";
|
|
4248
|
-
tableData[`[${type}] ${cmd.builder.name}`] = "";
|
|
4249
|
-
}
|
|
4250
|
-
return CLI.logger.table(`(cmds) ~ ctx (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4251
|
-
}
|
|
4252
|
-
default:
|
|
4253
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
4254
|
-
}
|
|
4255
|
-
});
|
|
4256
|
-
function initCLI() {
|
|
4257
|
-
if (initCalled) return;
|
|
4258
|
-
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
4259
|
-
initCalled = true;
|
|
4260
|
-
}
|
|
4261
|
-
|
|
4262
|
-
// src/utils/clientUtils.ts
|
|
4263
|
-
function useClient(index = 0) {
|
|
4264
|
-
return clientInstances.at(index);
|
|
4265
|
-
}
|
|
4266
|
-
async function useReadyClient(index = 0) {
|
|
4267
|
-
return useClient(index)?.whenReady();
|
|
4268
|
-
}
|
|
4269
|
-
function createClient(options, features = {}, config = {}) {
|
|
4270
|
-
const client = new Vimcord(options, features, config);
|
|
4271
|
-
initCLI();
|
|
4272
|
-
return client;
|
|
4273
|
-
}
|
|
4274
|
-
function getClientInstances() {
|
|
4275
|
-
return clientInstances;
|
|
4276
|
-
}
|
|
4277
4312
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4278
4313
|
0 && (module.exports = {
|
|
4314
|
+
BUILTIN_ContextCommandHandler,
|
|
4315
|
+
BUILTIN_PrefixCommandHandler,
|
|
4316
|
+
BUILTIN_SlashCommandHandler,
|
|
4279
4317
|
BaseCommandBuilder,
|
|
4280
4318
|
BaseCommandManager,
|
|
4281
4319
|
BetterCollector,
|
|
@@ -4314,7 +4352,6 @@ function getClientInstances() {
|
|
|
4314
4352
|
VimcordCLI,
|
|
4315
4353
|
__zero,
|
|
4316
4354
|
cleanMention,
|
|
4317
|
-
clientInstances,
|
|
4318
4355
|
createClient,
|
|
4319
4356
|
createMongoPlugin,
|
|
4320
4357
|
createMongoSchema,
|
|
@@ -4333,9 +4370,7 @@ function getClientInstances() {
|
|
|
4333
4370
|
fetchMessage,
|
|
4334
4371
|
fetchRole,
|
|
4335
4372
|
fetchUser,
|
|
4336
|
-
formatThousands,
|
|
4337
4373
|
getCallerFileName,
|
|
4338
|
-
getClientInstances,
|
|
4339
4374
|
getFirstMentionId,
|
|
4340
4375
|
getMessageMention,
|
|
4341
4376
|
getProcessDir,
|
|
@@ -4345,7 +4380,6 @@ function getClientInstances() {
|
|
|
4345
4380
|
isMentionOrSnowflake,
|
|
4346
4381
|
logger,
|
|
4347
4382
|
prompt,
|
|
4348
|
-
retryExponentialBackoff,
|
|
4349
4383
|
sendCommandErrorEmbed,
|
|
4350
4384
|
useClient,
|
|
4351
4385
|
useReadyClient,
|