vimcord 1.0.29 → 1.0.31
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 +1554 -1550
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +64 -44
- package/dist/index.d.ts +64 -44
- package/dist/index.js +1552 -1547
- 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
|
|
1426
|
+
setTitle(title) {
|
|
1427
|
+
this.data.title = title;
|
|
1428
|
+
this.build();
|
|
1429
|
+
return this;
|
|
1387
1430
|
}
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
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;
|
|
1431
|
+
setDescription(description) {
|
|
1432
|
+
this.data.description = description;
|
|
1433
|
+
this.build();
|
|
1434
|
+
return this;
|
|
1400
1435
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
1406
|
-
this.emitter.emit("changed", activity);
|
|
1436
|
+
setThumbnail(url) {
|
|
1437
|
+
this.data.thumbnailUrl = url;
|
|
1438
|
+
this.build();
|
|
1439
|
+
return this;
|
|
1407
1440
|
}
|
|
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);
|
|
1441
|
+
setImage(url) {
|
|
1442
|
+
this.data.imageUrl = url;
|
|
1443
|
+
this.build();
|
|
1444
|
+
return this;
|
|
1420
1445
|
}
|
|
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();
|
|
1446
|
+
setFooter(footer) {
|
|
1447
|
+
this.data.footer = footer;
|
|
1448
|
+
this.build();
|
|
1449
|
+
return this;
|
|
1427
1450
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1451
|
+
setColor(color) {
|
|
1452
|
+
this.data.color = color;
|
|
1453
|
+
this.build();
|
|
1454
|
+
return this;
|
|
1455
|
+
}
|
|
1456
|
+
setTimestamp(timestamp) {
|
|
1457
|
+
this.data.timestamp = timestamp;
|
|
1458
|
+
this.build();
|
|
1433
1459
|
return this;
|
|
1434
1460
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
this.emitter.emit("paused", this.task);
|
|
1439
|
-
}
|
|
1461
|
+
addFields(fields) {
|
|
1462
|
+
this.data.fields = [...this.data.fields, ...fields];
|
|
1463
|
+
this.build();
|
|
1440
1464
|
return this;
|
|
1441
1465
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
if (this.client.config.app.devMode) {
|
|
1446
|
-
clientStatus = statusConfig.development;
|
|
1447
|
-
} else {
|
|
1448
|
-
clientStatus = statusConfig.production;
|
|
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
|
-
}
|
|
1466
|
+
setFields(fields) {
|
|
1467
|
+
this.data.fields = fields;
|
|
1468
|
+
this.build();
|
|
1455
1469
|
return this;
|
|
1456
1470
|
}
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
this.task = null;
|
|
1461
|
-
this.emitter.emit("destroyed");
|
|
1462
|
-
await this.clear();
|
|
1463
|
-
}
|
|
1471
|
+
spliceFields(index, deleteCount, ...fields) {
|
|
1472
|
+
this.data.fields.splice(index, deleteCount, ...fields);
|
|
1473
|
+
this.build();
|
|
1464
1474
|
return this;
|
|
1465
1475
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
this.
|
|
1471
|
-
|
|
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
|
+
});
|
|
1472
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
|
-
console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
|
|
1649
|
-
return;
|
|
1650
|
-
}
|
|
1651
|
-
try {
|
|
1652
|
-
await client.rest.put(import_discord5.Routes.applicationCommands(client.user.id), { body: [] });
|
|
1653
|
-
console.log(`[CommandManager] \u2714 Removed app commands globally`);
|
|
1654
|
-
} catch (err) {
|
|
1655
|
-
console.error(`[CommandManager] \u2716 Failed to remove app commands globally`, err);
|
|
1656
|
-
}
|
|
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);
|
|
1657
1753
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
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));
|
|
1668
1785
|
}
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
)
|
|
1786
|
+
}
|
|
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")
|
|
1681
1818
|
);
|
|
1819
|
+
console.log(import_chalk.default.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
1682
1820
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
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;
|
|
1688
1880
|
}
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1881
|
+
}
|
|
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(
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
}
|
|
1733
|
-
clear() {
|
|
1734
|
-
this.events.forEach((e) => this.unregister(e.name));
|
|
1735
|
-
this.events.clear();
|
|
1736
|
-
}
|
|
1737
|
-
get(name) {
|
|
1738
|
-
return this.events.get(name);
|
|
1739
|
-
}
|
|
1740
|
-
getByTag(tag) {
|
|
1741
|
-
return Array.from(this.events.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
1742
|
-
}
|
|
1743
|
-
getByCategory(category) {
|
|
1744
|
-
return Array.from(this.events.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
1745
|
-
}
|
|
1746
|
-
getByEvent(eventType) {
|
|
1747
|
-
return Array.from(this.events.values()).filter((event) => event.event === eventType);
|
|
1748
|
-
}
|
|
1749
|
-
async executeEvents(eventType, ...args) {
|
|
1750
|
-
const events = this.getByEvent(eventType);
|
|
1751
|
-
if (!events.length) return;
|
|
1752
|
-
const sortedEvents = events.sort((a, b) => b.priority - a.priority);
|
|
1753
|
-
await Promise.all(
|
|
1754
|
-
sortedEvents.map(async (event) => {
|
|
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
|
-
);
|
|
1765
|
-
}
|
|
1766
|
-
/** Import event modules that end with `.event` */
|
|
1767
|
-
async importFrom(dir, replaceAll) {
|
|
1768
|
-
dir = Array.isArray(dir) ? dir : [dir];
|
|
1769
|
-
const eventModules = await Promise.all(
|
|
1770
|
-
dir.map((dir2) => importModulesFromDir(dir2, "event"))
|
|
1771
|
-
);
|
|
1772
|
-
if (replaceAll) {
|
|
1773
|
-
this.clear();
|
|
1774
|
-
}
|
|
1775
|
-
let importedEvents = 0;
|
|
1776
|
-
let ignoredEvents = 0;
|
|
1777
|
-
for (const event of eventModules.flat()) {
|
|
1778
|
-
if (!event.module.default.enabled) {
|
|
1779
|
-
ignoredEvents++;
|
|
1780
|
-
} else {
|
|
1781
|
-
importedEvents++;
|
|
1960
|
+
this.logger.debug("Status cleared");
|
|
1782
1961
|
}
|
|
1783
|
-
|
|
1784
|
-
}
|
|
1785
|
-
this.client.logger.moduleLoaded("Event Handlers", importedEvents, ignoredEvents);
|
|
1786
|
-
return this.events;
|
|
1962
|
+
});
|
|
1787
1963
|
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
var import_discord8 = require("discord.js");
|
|
1795
|
-
|
|
1796
|
-
// src/tools/dynaSend.ts
|
|
1797
|
-
var import_discord7 = require("discord.js");
|
|
1798
|
-
|
|
1799
|
-
// src/tools/types.ts
|
|
1800
|
-
var SendMethod = /* @__PURE__ */ ((SendMethod2) => {
|
|
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];
|
|
1964
|
+
clearData() {
|
|
1965
|
+
this.task?.stop();
|
|
1966
|
+
this.task = null;
|
|
1967
|
+
this.lastActivity = null;
|
|
1968
|
+
this.lastActivityIndex = 0;
|
|
1969
|
+
return this;
|
|
1815
1970
|
}
|
|
1816
|
-
|
|
1817
|
-
|
|
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;
|
|
1818
1975
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
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;
|
|
1823
1988
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
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);
|
|
1995
|
+
}
|
|
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];
|
|
1827
2005
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
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");
|
|
2006
|
+
await this.setActivity(activity);
|
|
2007
|
+
this.emitter.emit("rotation", activity);
|
|
1832
2008
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
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();
|
|
2015
|
+
}
|
|
2016
|
+
start() {
|
|
2017
|
+
if (this.task) {
|
|
2018
|
+
this.task.start();
|
|
2019
|
+
this.emitter.emit("started", this.task);
|
|
1837
2020
|
}
|
|
1838
|
-
|
|
1839
|
-
|
|
2021
|
+
return this;
|
|
2022
|
+
}
|
|
2023
|
+
pause() {
|
|
2024
|
+
if (this.task) {
|
|
2025
|
+
this.task.stop();
|
|
2026
|
+
this.emitter.emit("paused", this.task);
|
|
1840
2027
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
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;
|
|
1843
2037
|
}
|
|
1844
|
-
if (
|
|
1845
|
-
|
|
2038
|
+
if (!clientStatus.interval) {
|
|
2039
|
+
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2040
|
+
} else {
|
|
2041
|
+
await this.scheduleStatusRotation(clientStatus);
|
|
1846
2042
|
}
|
|
2043
|
+
return this;
|
|
1847
2044
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
allowedMentions: options.allowedMentions,
|
|
1855
|
-
tts: options.tts
|
|
1856
|
-
};
|
|
1857
|
-
switch (method) {
|
|
1858
|
-
case 0 /* Reply */:
|
|
1859
|
-
return {
|
|
1860
|
-
...baseData,
|
|
1861
|
-
flags: options.flags,
|
|
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
|
|
1906
|
-
};
|
|
1907
|
-
default:
|
|
1908
|
-
return baseData;
|
|
2045
|
+
async destroy() {
|
|
2046
|
+
if (this.task) {
|
|
2047
|
+
this.task.stop();
|
|
2048
|
+
this.task = null;
|
|
2049
|
+
this.emitter.emit("destroyed");
|
|
2050
|
+
await this.clear();
|
|
1909
2051
|
}
|
|
2052
|
+
return this;
|
|
1910
2053
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
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;
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
|
|
2063
|
+
// src/modules/command.manager.ts
|
|
2064
|
+
var import_discord9 = require("discord.js");
|
|
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;
|
|
2074
|
+
}
|
|
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
|
+
);
|
|
1933
2090
|
}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
2091
|
+
});
|
|
2092
|
+
} else {
|
|
2093
|
+
return this.commands.get(name);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
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);
|
|
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
|
+
});
|
|
2123
|
+
}
|
|
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: []
|
|
2138
|
+
};
|
|
2139
|
+
categories.set(metadata.category, entry);
|
|
1938
2140
|
}
|
|
1939
|
-
|
|
1940
|
-
console.error(`[DynaSend] Error with method '${SendMethod[method]}':`, error);
|
|
1941
|
-
return null;
|
|
2141
|
+
entry.commands.push(cmd);
|
|
1942
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
|
+
});
|
|
1943
2151
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
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));
|
|
1947
2164
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
await message.delete();
|
|
1952
|
-
}
|
|
1953
|
-
} catch (error) {
|
|
1954
|
-
console.error("[DynaSend] Error deleting message:", error);
|
|
1955
|
-
}
|
|
1956
|
-
}, delay);
|
|
1957
|
-
}
|
|
1958
|
-
static async send(handler, options) {
|
|
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);
|
|
2165
|
+
for (const module2 of modules) {
|
|
2166
|
+
const commandName = "builder" in module2 ? module2.builder.name : module2.options.name;
|
|
2167
|
+
this.commands.set(commandName, module2);
|
|
1965
2168
|
}
|
|
1966
|
-
|
|
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;
|
|
2180
|
+
}
|
|
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
|
-
|
|
2030
|
-
|
|
2194
|
+
};
|
|
2195
|
+
var PrefixCommandManager = class extends BaseCommandManager {
|
|
2196
|
+
constructor(client) {
|
|
2197
|
+
super(client, 1 /* Prefix */, client.config.app.moduleSuffixes.prefixCommand);
|
|
2198
|
+
}
|
|
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);
|
|
2210
|
+
}
|
|
2211
|
+
getAllAppCommands(options = {}) {
|
|
2212
|
+
return [...this.slash.getAll(options), ...this.context.getAll(options)];
|
|
2213
|
+
}
|
|
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;
|
|
2031
2219
|
}
|
|
2032
|
-
|
|
2033
|
-
|
|
2220
|
+
const commands = this.getAllAppCommands(options);
|
|
2221
|
+
if (!commands.length) {
|
|
2222
|
+
console.log("[CommandManager] No commands to register globally");
|
|
2223
|
+
return;
|
|
2034
2224
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
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);
|
|
2037
2231
|
}
|
|
2038
2232
|
}
|
|
2039
|
-
|
|
2040
|
-
const
|
|
2041
|
-
if (!
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
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;
|
|
2238
|
+
}
|
|
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);
|
|
2244
|
+
}
|
|
2048
2245
|
}
|
|
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);
|
|
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;
|
|
2061
2251
|
}
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
} else if (typeof this.data.author.icon === "string") {
|
|
2067
|
-
this.data.author.icon = formatString(this.data.author.icon);
|
|
2068
|
-
}
|
|
2252
|
+
const commands = this.getAllAppCommands(options);
|
|
2253
|
+
if (!commands.length) {
|
|
2254
|
+
console.log("[CommandManager] No commands to register by guild");
|
|
2255
|
+
return;
|
|
2069
2256
|
}
|
|
2070
|
-
|
|
2071
|
-
|
|
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;
|
|
2072
2276
|
}
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
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])
|
|
2076
2300
|
);
|
|
2077
2301
|
}
|
|
2078
|
-
if (this.data.footer && typeof this.data.footer === "object") {
|
|
2079
|
-
this.data.footer.text = formatString(this.data.footer.text);
|
|
2080
|
-
}
|
|
2081
|
-
if (this.data.thumbnailUrl) {
|
|
2082
|
-
this.data.thumbnailUrl = formatString(this.data.thumbnailUrl);
|
|
2083
|
-
}
|
|
2084
|
-
if (this.data.imageUrl) {
|
|
2085
|
-
this.data.imageUrl = formatString(this.data.imageUrl);
|
|
2086
|
-
}
|
|
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
2302
|
}
|
|
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);
|
|
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}'`);
|
|
2103
2308
|
}
|
|
2104
2309
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
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}'`);
|
|
2113
2318
|
}
|
|
2114
2319
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2320
|
+
}
|
|
2321
|
+
clear() {
|
|
2322
|
+
this.events.forEach((e) => this.unregister(e.name));
|
|
2323
|
+
this.events.clear();
|
|
2324
|
+
}
|
|
2325
|
+
get(name) {
|
|
2326
|
+
return this.events.get(name);
|
|
2327
|
+
}
|
|
2328
|
+
getByTag(tag) {
|
|
2329
|
+
return Array.from(this.events.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2330
|
+
}
|
|
2331
|
+
getByCategory(category) {
|
|
2332
|
+
return Array.from(this.events.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
2333
|
+
}
|
|
2334
|
+
getByEvent(eventType) {
|
|
2335
|
+
return Array.from(this.events.values()).filter((event) => event.event === eventType);
|
|
2336
|
+
}
|
|
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
|
+
);
|
|
2353
|
+
}
|
|
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();
|
|
2126
2362
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
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++;
|
|
2132
2370
|
}
|
|
2371
|
+
this.register(event.module.default);
|
|
2133
2372
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2373
|
+
this.client.logger.moduleLoaded("Event Handlers", importedEvents, ignoredEvents);
|
|
2374
|
+
return this.events;
|
|
2375
|
+
}
|
|
2376
|
+
};
|
|
2377
|
+
|
|
2378
|
+
// package.json
|
|
2379
|
+
var version = "1.0.31";
|
|
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
|
+
);
|
|
2142
2424
|
}
|
|
2425
|
+
command.fn(args, content);
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
parseLine(line) {
|
|
2429
|
+
if (line.startsWith(this.options.prefix)) {
|
|
2430
|
+
line = line.slice(this.options.prefix.length);
|
|
2431
|
+
} else {
|
|
2432
|
+
return { isCommand: false };
|
|
2143
2433
|
}
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2434
|
+
const args = line.split(" ").map((s) => s.trim());
|
|
2435
|
+
const commandName = args.shift();
|
|
2436
|
+
return { isCommand: true, commandName, content: args.join(" "), args };
|
|
2437
|
+
}
|
|
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;
|
|
2150
2445
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
} catch (error) {
|
|
2156
|
-
console.error("[BetterEmbed] Invalid timestamp:", error);
|
|
2446
|
+
const client = useClient(idx);
|
|
2447
|
+
if (!client) {
|
|
2448
|
+
CLI.logger.error("Client instance not found");
|
|
2449
|
+
return void 0;
|
|
2157
2450
|
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
const
|
|
2161
|
-
if (
|
|
2162
|
-
|
|
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;
|
|
2163
2457
|
}
|
|
2164
|
-
|
|
2458
|
+
return client;
|
|
2165
2459
|
}
|
|
2166
2460
|
}
|
|
2167
|
-
|
|
2168
|
-
this.
|
|
2169
|
-
this.build();
|
|
2170
|
-
return this;
|
|
2171
|
-
}
|
|
2172
|
-
setTitle(title) {
|
|
2173
|
-
this.data.title = title;
|
|
2174
|
-
this.build();
|
|
2175
|
-
return this;
|
|
2176
|
-
}
|
|
2177
|
-
setDescription(description) {
|
|
2178
|
-
this.data.description = description;
|
|
2179
|
-
this.build();
|
|
2180
|
-
return this;
|
|
2181
|
-
}
|
|
2182
|
-
setThumbnail(url) {
|
|
2183
|
-
this.data.thumbnailUrl = url;
|
|
2184
|
-
this.build();
|
|
2185
|
-
return this;
|
|
2186
|
-
}
|
|
2187
|
-
setImage(url) {
|
|
2188
|
-
this.data.imageUrl = url;
|
|
2189
|
-
this.build();
|
|
2190
|
-
return this;
|
|
2191
|
-
}
|
|
2192
|
-
setFooter(footer) {
|
|
2193
|
-
this.data.footer = footer;
|
|
2194
|
-
this.build();
|
|
2195
|
-
return this;
|
|
2196
|
-
}
|
|
2197
|
-
setColor(color) {
|
|
2198
|
-
this.data.color = color;
|
|
2199
|
-
this.build();
|
|
2200
|
-
return this;
|
|
2201
|
-
}
|
|
2202
|
-
setTimestamp(timestamp) {
|
|
2203
|
-
this.data.timestamp = timestamp;
|
|
2204
|
-
this.build();
|
|
2205
|
-
return this;
|
|
2461
|
+
addCommand(commandName, description, fn) {
|
|
2462
|
+
this.commands.set(commandName, { description, fn });
|
|
2206
2463
|
}
|
|
2207
|
-
|
|
2208
|
-
this.
|
|
2209
|
-
this.
|
|
2210
|
-
return
|
|
2464
|
+
removeCommand(commandName) {
|
|
2465
|
+
if (!this.commands.has(commandName)) return false;
|
|
2466
|
+
this.commands.delete(commandName);
|
|
2467
|
+
return true;
|
|
2211
2468
|
}
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
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}`;
|
|
2216
2479
|
}
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
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.29";
|
|
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 === true) {
|
|
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
|
}
|
|
@@ -2537,131 +2811,44 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2537
2811
|
await preHook?.(this);
|
|
2538
2812
|
}
|
|
2539
2813
|
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2540
|
-
const loginResult = await
|
|
2541
|
-
() => super.login(token),
|
|
2542
|
-
this.features.loginAttempts ?? 3,
|
|
2543
|
-
1e3
|
|
2544
|
-
);
|
|
2814
|
+
const loginResult = await import_qznt4.$.async.retry(() => super.login(token), this.features.loginAttempts ?? 3, 1e3);
|
|
2545
2815
|
stopLoader("Connected to Discord ");
|
|
2546
2816
|
this.config.app.verbose && this.logger.debug("\u23F3 Waiting for ready...");
|
|
2547
2817
|
return loginResult;
|
|
2548
2818
|
} catch (err) {
|
|
2549
|
-
this.logger.error(
|
|
2550
|
-
`Failed to log into Discord after ${this.features.loginAttempts} attempt(s))`,
|
|
2551
|
-
err
|
|
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" });
|
|
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;
|
|
2628
2826
|
}
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
return await command.run(client, client, interaction);
|
|
2633
|
-
} catch (err) {
|
|
2634
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2635
|
-
throw err;
|
|
2636
|
-
}
|
|
2827
|
+
};
|
|
2828
|
+
this.clientStartingPromise = main();
|
|
2829
|
+
return this.clientStartingPromise;
|
|
2637
2830
|
}
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
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" });
|
|
2649
|
-
}
|
|
2650
|
-
return interaction.reply({ content, flags: "Ephemeral" });
|
|
2651
|
-
}
|
|
2652
|
-
try {
|
|
2653
|
-
return await command.run(client, client, interaction);
|
|
2654
|
-
} catch (err) {
|
|
2655
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2656
|
-
throw err;
|
|
2657
|
-
}
|
|
2831
|
+
async kill() {
|
|
2832
|
+
await super.destroy();
|
|
2833
|
+
_Vimcord.instances.delete(this.clientId);
|
|
2834
|
+
this.logger.debug("\u{1F6AA} Logged out of Discord");
|
|
2658
2835
|
}
|
|
2659
|
-
}
|
|
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 {
|
|
@@ -2754,7 +2941,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2754
2941
|
this.isConnecting = true;
|
|
2755
2942
|
try {
|
|
2756
2943
|
const stopLoader = this.client.logger.loader("Connecting to MongoDB...");
|
|
2757
|
-
await
|
|
2944
|
+
await import_qznt5.$.async.retry(
|
|
2758
2945
|
() => this.mongoose.connect(connectionUri, { autoIndex: true, ...connectionOptions }),
|
|
2759
2946
|
maxRetries
|
|
2760
2947
|
);
|
|
@@ -2791,7 +2978,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2791
2978
|
// src/modules/db/mongo/mongoSchema.builder.ts
|
|
2792
2979
|
var import_mongoose2 = require("mongoose");
|
|
2793
2980
|
var import_node_crypto4 = require("crypto");
|
|
2794
|
-
var
|
|
2981
|
+
var import_qznt6 = require("qznt");
|
|
2795
2982
|
try {
|
|
2796
2983
|
import("mongoose");
|
|
2797
2984
|
} catch {
|
|
@@ -2877,7 +3064,7 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2877
3064
|
* @param maxRetries [default: 3]
|
|
2878
3065
|
*/
|
|
2879
3066
|
async execute(fn, maxRetries = 3) {
|
|
2880
|
-
return await
|
|
3067
|
+
return await import_qznt6.$.async.retry(async () => {
|
|
2881
3068
|
const model = await this.getModel();
|
|
2882
3069
|
return await fn(model);
|
|
2883
3070
|
}, maxRetries);
|
|
@@ -3166,9 +3353,9 @@ var BetterCollector = class _BetterCollector {
|
|
|
3166
3353
|
};
|
|
3167
3354
|
|
|
3168
3355
|
// src/tools/BetterContainer.ts
|
|
3169
|
-
var
|
|
3356
|
+
var import_discord12 = require("discord.js");
|
|
3170
3357
|
var BetterContainer = class {
|
|
3171
|
-
container = new
|
|
3358
|
+
container = new import_discord12.ContainerBuilder();
|
|
3172
3359
|
data;
|
|
3173
3360
|
config;
|
|
3174
3361
|
constructor(data = {}) {
|
|
@@ -3236,8 +3423,8 @@ var BetterContainer = class {
|
|
|
3236
3423
|
)
|
|
3237
3424
|
);
|
|
3238
3425
|
}
|
|
3239
|
-
if (data.thumbnail) sb.setThumbnailAccessory(new
|
|
3240
|
-
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));
|
|
3241
3428
|
return sb;
|
|
3242
3429
|
});
|
|
3243
3430
|
return this;
|
|
@@ -3261,11 +3448,8 @@ var BetterContainer = class {
|
|
|
3261
3448
|
};
|
|
3262
3449
|
|
|
3263
3450
|
// src/tools/BetterModal.ts
|
|
3264
|
-
var
|
|
3265
|
-
|
|
3266
|
-
const chars = "ABCDEFGHJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
3267
|
-
return Array.from({ length }, () => chars.charAt(Math.floor(Math.random() * chars.length))).join("");
|
|
3268
|
-
}
|
|
3451
|
+
var import_discord13 = require("discord.js");
|
|
3452
|
+
var import_qznt7 = require("qznt");
|
|
3269
3453
|
var BetterModal = class {
|
|
3270
3454
|
id;
|
|
3271
3455
|
options;
|
|
@@ -3275,7 +3459,7 @@ var BetterModal = class {
|
|
|
3275
3459
|
constructor(options = {}) {
|
|
3276
3460
|
this.id = options.id || this.createModalId();
|
|
3277
3461
|
this.options = options;
|
|
3278
|
-
this.modal = new
|
|
3462
|
+
this.modal = new import_discord13.ModalBuilder().setCustomId(this.id);
|
|
3279
3463
|
this.config = options.config || globalVimcordToolsConfig;
|
|
3280
3464
|
if (options.title) {
|
|
3281
3465
|
this.setTitle(options.title);
|
|
@@ -3285,10 +3469,10 @@ var BetterModal = class {
|
|
|
3285
3469
|
}
|
|
3286
3470
|
}
|
|
3287
3471
|
createModalId() {
|
|
3288
|
-
return `modal:${
|
|
3472
|
+
return `modal:${import_qznt7.$.rnd.str(10, "alpha", { casing: "mixed" })}-${Date.now()}`;
|
|
3289
3473
|
}
|
|
3290
3474
|
createComponentId() {
|
|
3291
|
-
return `modal-component:${
|
|
3475
|
+
return `modal-component:${this.id}-${import_qznt7.$.rnd.str(4, "alpha", { casing: "mixed" })}-${Date.now().toString().slice(-4)}`;
|
|
3292
3476
|
}
|
|
3293
3477
|
validateComponentLength() {
|
|
3294
3478
|
if (this.components.size >= 5) throw new Error("Modal can only have 5 components");
|
|
@@ -3333,9 +3517,9 @@ var BetterModal = class {
|
|
|
3333
3517
|
this.validateComponentLength();
|
|
3334
3518
|
let { label, description, custom_id, ...rest } = data;
|
|
3335
3519
|
custom_id ||= this.createComponentId();
|
|
3336
|
-
const textInputComponent = new
|
|
3337
|
-
if (!rest.style) textInputComponent.setStyle(
|
|
3338
|
-
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);
|
|
3339
3523
|
if (description) labelComponent.setDescription(description);
|
|
3340
3524
|
this.components.set(custom_id, labelComponent);
|
|
3341
3525
|
return this;
|
|
@@ -3344,8 +3528,8 @@ var BetterModal = class {
|
|
|
3344
3528
|
this.validateComponentLength();
|
|
3345
3529
|
let { label, description, custom_id, ...rest } = data;
|
|
3346
3530
|
custom_id ||= this.createComponentId();
|
|
3347
|
-
const stringSelectComponent = new
|
|
3348
|
-
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);
|
|
3349
3533
|
if (description) labelComponent.setDescription(description);
|
|
3350
3534
|
this.components.set(custom_id, labelComponent);
|
|
3351
3535
|
return this;
|
|
@@ -3354,8 +3538,8 @@ var BetterModal = class {
|
|
|
3354
3538
|
this.validateComponentLength();
|
|
3355
3539
|
let { label, description, custom_id, ...rest } = data;
|
|
3356
3540
|
custom_id ||= this.createComponentId();
|
|
3357
|
-
const channelSelectComponent = new
|
|
3358
|
-
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);
|
|
3359
3543
|
if (description) labelComponent.setDescription(description);
|
|
3360
3544
|
this.components.set(custom_id, labelComponent);
|
|
3361
3545
|
return this;
|
|
@@ -3364,8 +3548,8 @@ var BetterModal = class {
|
|
|
3364
3548
|
this.validateComponentLength();
|
|
3365
3549
|
let { label, description, custom_id, ...rest } = data;
|
|
3366
3550
|
custom_id ||= this.createComponentId();
|
|
3367
|
-
const userSelectComponent = new
|
|
3368
|
-
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);
|
|
3369
3553
|
if (description) labelComponent.setDescription(description);
|
|
3370
3554
|
this.components.set(custom_id, labelComponent);
|
|
3371
3555
|
return this;
|
|
@@ -3374,8 +3558,8 @@ var BetterModal = class {
|
|
|
3374
3558
|
this.validateComponentLength();
|
|
3375
3559
|
let { label, description, custom_id, ...rest } = data;
|
|
3376
3560
|
custom_id ||= this.createComponentId();
|
|
3377
|
-
const roleSelectComponent = new
|
|
3378
|
-
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);
|
|
3379
3563
|
if (description) labelComponent.setDescription(description);
|
|
3380
3564
|
this.components.set(custom_id, labelComponent);
|
|
3381
3565
|
return this;
|
|
@@ -3384,8 +3568,8 @@ var BetterModal = class {
|
|
|
3384
3568
|
this.validateComponentLength();
|
|
3385
3569
|
let { label, description, custom_id, ...rest } = data;
|
|
3386
3570
|
custom_id ||= this.createComponentId();
|
|
3387
|
-
const mentionableSelectComponent = new
|
|
3388
|
-
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);
|
|
3389
3573
|
if (description) labelComponent.setDescription(description);
|
|
3390
3574
|
this.components.set(custom_id, labelComponent);
|
|
3391
3575
|
return this;
|
|
@@ -3394,13 +3578,16 @@ var BetterModal = class {
|
|
|
3394
3578
|
this.validateComponentLength();
|
|
3395
3579
|
let { label, description, custom_id, ...rest } = data;
|
|
3396
3580
|
custom_id ||= this.createComponentId();
|
|
3397
|
-
const fileUploadComponent = new
|
|
3398
|
-
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);
|
|
3399
3583
|
if (description) labelComponent.setDescription(description);
|
|
3400
3584
|
this.components.set(custom_id, labelComponent);
|
|
3401
3585
|
return this;
|
|
3402
3586
|
}
|
|
3403
|
-
/**
|
|
3587
|
+
/**
|
|
3588
|
+
* Shows the modal via interaction.
|
|
3589
|
+
* @param interaction The interaction used to show the modal
|
|
3590
|
+
*/
|
|
3404
3591
|
async show(interaction) {
|
|
3405
3592
|
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3406
3593
|
if (!this.modal.data.title) throw new Error("Modal must have a title");
|
|
@@ -3409,18 +3596,22 @@ var BetterModal = class {
|
|
|
3409
3596
|
console.error("Modal failed to send", err);
|
|
3410
3597
|
});
|
|
3411
3598
|
}
|
|
3412
|
-
/**
|
|
3599
|
+
/**
|
|
3600
|
+
* Waits for the modal to be submitted and returns the component data.
|
|
3413
3601
|
* @param interaction The interaction used to show the modal
|
|
3414
3602
|
* @param options Options */
|
|
3415
3603
|
async awaitSubmit(interaction, options) {
|
|
3416
3604
|
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3417
3605
|
try {
|
|
3418
3606
|
const modalSubmit = await interaction.awaitModalSubmit({
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3607
|
+
filter: (i) => i.customId === this.id,
|
|
3608
|
+
time: options?.timeout ?? this.config.timeouts.modalSubmit,
|
|
3609
|
+
...options
|
|
3422
3610
|
});
|
|
3423
|
-
|
|
3611
|
+
if (options?.autoDefer) {
|
|
3612
|
+
await modalSubmit.deferUpdate();
|
|
3613
|
+
}
|
|
3614
|
+
const fields = /* @__PURE__ */ new Map();
|
|
3424
3615
|
const values = [];
|
|
3425
3616
|
for (const [customId] of this.components) {
|
|
3426
3617
|
let value = null;
|
|
@@ -3435,23 +3626,38 @@ var BetterModal = class {
|
|
|
3435
3626
|
} catch {
|
|
3436
3627
|
}
|
|
3437
3628
|
}
|
|
3438
|
-
fields
|
|
3629
|
+
fields.set(customId, value);
|
|
3439
3630
|
values.push(value);
|
|
3440
3631
|
}
|
|
3441
|
-
return {
|
|
3632
|
+
return {
|
|
3633
|
+
getField(customId, required) {
|
|
3634
|
+
const value = fields.get(customId);
|
|
3635
|
+
if (required && value === void 0) {
|
|
3636
|
+
throw new Error(`ModalSubmitResult: Field ${customId} is required but was not found`);
|
|
3637
|
+
}
|
|
3638
|
+
return value;
|
|
3639
|
+
},
|
|
3640
|
+
values,
|
|
3641
|
+
interaction: modalSubmit,
|
|
3642
|
+
reply: (options2) => dynaSend(modalSubmit, options2),
|
|
3643
|
+
deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2)
|
|
3644
|
+
};
|
|
3442
3645
|
} catch (error) {
|
|
3443
3646
|
return null;
|
|
3444
3647
|
}
|
|
3445
3648
|
}
|
|
3649
|
+
/**
|
|
3650
|
+
* Shows the modal and waits for the modal to be submitted, returning the component data.
|
|
3651
|
+
* @param interaction The interaction used to show the modal
|
|
3652
|
+
* @param options Options */
|
|
3446
3653
|
async showAndAwait(interaction, options) {
|
|
3447
|
-
if (!("showModal" in interaction)) throw new Error("Interaction does not support showing modals");
|
|
3448
3654
|
await this.show(interaction);
|
|
3449
3655
|
return this.awaitSubmit(interaction, options);
|
|
3450
3656
|
}
|
|
3451
3657
|
};
|
|
3452
3658
|
|
|
3453
3659
|
// src/tools/Paginator.ts
|
|
3454
|
-
var
|
|
3660
|
+
var import_discord14 = require("discord.js");
|
|
3455
3661
|
var import_node_events3 = __toESM(require("events"));
|
|
3456
3662
|
var PaginationType = /* @__PURE__ */ ((PaginationType2) => {
|
|
3457
3663
|
PaginationType2[PaginationType2["Short"] = 0] = "Short";
|
|
@@ -3472,7 +3678,7 @@ function wrapPositive(num, max) {
|
|
|
3472
3678
|
}
|
|
3473
3679
|
function createNavButton(id, config) {
|
|
3474
3680
|
const data = config.paginator.buttons[id];
|
|
3475
|
-
const btn = new
|
|
3681
|
+
const btn = new import_discord14.ButtonBuilder({ customId: `btn_${id}`, style: import_discord14.ButtonStyle.Secondary });
|
|
3476
3682
|
if (data.label) {
|
|
3477
3683
|
btn.setLabel(data.label);
|
|
3478
3684
|
} else {
|
|
@@ -3481,7 +3687,7 @@ function createNavButton(id, config) {
|
|
|
3481
3687
|
return btn;
|
|
3482
3688
|
}
|
|
3483
3689
|
function isEmbed(item) {
|
|
3484
|
-
return item instanceof
|
|
3690
|
+
return item instanceof import_discord14.EmbedBuilder || item instanceof BetterEmbed;
|
|
3485
3691
|
}
|
|
3486
3692
|
function resolvePages(pages) {
|
|
3487
3693
|
if (Array.isArray(pages)) {
|
|
@@ -3518,7 +3724,7 @@ var Paginator = class {
|
|
|
3518
3724
|
navigation: { reactions: [], isRequired: false, isLong: false, canJump: false },
|
|
3519
3725
|
collectors: { component: null, reaction: null },
|
|
3520
3726
|
components: {
|
|
3521
|
-
chapterSelect: new
|
|
3727
|
+
chapterSelect: new import_discord14.StringSelectMenuBuilder({ customId: "ssm_chapterSelect" }),
|
|
3522
3728
|
navigation: {
|
|
3523
3729
|
first: createNavButton("first", this.config),
|
|
3524
3730
|
back: createNavButton("back", this.config),
|
|
@@ -3527,8 +3733,8 @@ var Paginator = class {
|
|
|
3527
3733
|
last: createNavButton("last", this.config)
|
|
3528
3734
|
},
|
|
3529
3735
|
actionRows: {
|
|
3530
|
-
chapterSelect: new
|
|
3531
|
-
navigation: new
|
|
3736
|
+
chapterSelect: new import_discord14.ActionRowBuilder(),
|
|
3737
|
+
navigation: new import_discord14.ActionRowBuilder()
|
|
3532
3738
|
}
|
|
3533
3739
|
}
|
|
3534
3740
|
};
|
|
@@ -3628,9 +3834,9 @@ var Paginator = class {
|
|
|
3628
3834
|
sendOptions.content = page;
|
|
3629
3835
|
} else if (isEmbed(page)) {
|
|
3630
3836
|
sendOptions.embeds.push(page);
|
|
3631
|
-
} else if (page instanceof
|
|
3837
|
+
} else if (page instanceof import_discord14.AttachmentBuilder) {
|
|
3632
3838
|
sendOptions.files.push(page);
|
|
3633
|
-
} else if (page instanceof
|
|
3839
|
+
} else if (page instanceof import_discord14.ContainerBuilder || page instanceof BetterContainer) {
|
|
3634
3840
|
sendOptions.components.push(page);
|
|
3635
3841
|
if (!sendOptions.flags.includes("IsComponentsV2")) {
|
|
3636
3842
|
sendOptions.flags.push("IsComponentsV2");
|
|
@@ -3653,20 +3859,20 @@ var Paginator = class {
|
|
|
3653
3859
|
}
|
|
3654
3860
|
return component;
|
|
3655
3861
|
});
|
|
3656
|
-
const disabledNavRow =
|
|
3862
|
+
const disabledNavRow = import_discord14.ActionRowBuilder.from(this.data.components.actionRows.navigation).setComponents(
|
|
3657
3863
|
disabledNavComponents
|
|
3658
3864
|
);
|
|
3659
3865
|
const newComponents = [];
|
|
3660
3866
|
const currentPage = this.data.page.current;
|
|
3661
|
-
if (currentPage instanceof
|
|
3867
|
+
if (currentPage instanceof import_discord14.ContainerBuilder || currentPage instanceof BetterContainer) {
|
|
3662
3868
|
newComponents.push(currentPage);
|
|
3663
3869
|
}
|
|
3664
3870
|
if (this.chapters.length > 1) {
|
|
3665
|
-
const disabledSelect =
|
|
3871
|
+
const disabledSelect = import_discord14.StringSelectMenuBuilder.from(this.data.components.chapterSelect).setDisabled(
|
|
3666
3872
|
true
|
|
3667
3873
|
);
|
|
3668
3874
|
newComponents.push(
|
|
3669
|
-
|
|
3875
|
+
import_discord14.ActionRowBuilder.from(this.data.components.actionRows.chapterSelect).setComponents(disabledSelect)
|
|
3670
3876
|
);
|
|
3671
3877
|
}
|
|
3672
3878
|
if (disabledNavRow.components.length > 0) {
|
|
@@ -3695,7 +3901,7 @@ var Paginator = class {
|
|
|
3695
3901
|
if (this.options.useReactions) {
|
|
3696
3902
|
await this.data.message.reactions.removeAll().catch(Boolean);
|
|
3697
3903
|
} else {
|
|
3698
|
-
const newComponents = this.data.message.components.filter((c) => c.type !==
|
|
3904
|
+
const newComponents = this.data.message.components.filter((c) => c.type !== import_discord14.ComponentType.Container);
|
|
3699
3905
|
await this.data.message.edit({ components: newComponents }).catch(Boolean);
|
|
3700
3906
|
}
|
|
3701
3907
|
}
|
|
@@ -3906,7 +4112,7 @@ var Paginator = class {
|
|
|
3906
4112
|
};
|
|
3907
4113
|
|
|
3908
4114
|
// src/tools/Prompt.ts
|
|
3909
|
-
var
|
|
4115
|
+
var import_discord15 = require("discord.js");
|
|
3910
4116
|
var PromptResolveType = /* @__PURE__ */ ((PromptResolveType2) => {
|
|
3911
4117
|
PromptResolveType2[PromptResolveType2["DisableComponents"] = 0] = "DisableComponents";
|
|
3912
4118
|
PromptResolveType2[PromptResolveType2["ClearComponents"] = 1] = "ClearComponents";
|
|
@@ -3949,13 +4155,13 @@ var Prompt = class {
|
|
|
3949
4155
|
buttonOptions?.confirm,
|
|
3950
4156
|
"btn_confirm",
|
|
3951
4157
|
this.config.prompt.confirmLabel,
|
|
3952
|
-
|
|
4158
|
+
import_discord15.ButtonStyle.Success
|
|
3953
4159
|
);
|
|
3954
4160
|
const reject = this.buildButton(
|
|
3955
4161
|
buttonOptions?.reject,
|
|
3956
4162
|
"btn_reject",
|
|
3957
4163
|
this.config.prompt.rejectLabel,
|
|
3958
|
-
|
|
4164
|
+
import_discord15.ButtonStyle.Danger
|
|
3959
4165
|
);
|
|
3960
4166
|
return { confirm, reject };
|
|
3961
4167
|
}
|
|
@@ -3963,19 +4169,19 @@ var Prompt = class {
|
|
|
3963
4169
|
const map = /* @__PURE__ */ new Map();
|
|
3964
4170
|
if (!customOptions) return map;
|
|
3965
4171
|
for (const [customId, { builder, handler, index = 2 }] of Object.entries(customOptions)) {
|
|
3966
|
-
const button = this.buildButton(builder, customId, customId,
|
|
4172
|
+
const button = this.buildButton(builder, customId, customId, import_discord15.ButtonStyle.Primary);
|
|
3967
4173
|
map.set(customId, { button, handler, index });
|
|
3968
4174
|
}
|
|
3969
4175
|
return map;
|
|
3970
4176
|
}
|
|
3971
4177
|
buildButton(option, customId, defaultLabel, defaultStyle) {
|
|
3972
4178
|
if (typeof option === "function") {
|
|
3973
|
-
return option(new
|
|
4179
|
+
return option(new import_discord15.ButtonBuilder());
|
|
3974
4180
|
}
|
|
3975
|
-
if (option instanceof
|
|
4181
|
+
if (option instanceof import_discord15.ButtonBuilder) {
|
|
3976
4182
|
return option;
|
|
3977
4183
|
}
|
|
3978
|
-
return new
|
|
4184
|
+
return new import_discord15.ButtonBuilder({
|
|
3979
4185
|
customId,
|
|
3980
4186
|
label: defaultLabel,
|
|
3981
4187
|
style: defaultStyle,
|
|
@@ -3983,12 +4189,12 @@ var Prompt = class {
|
|
|
3983
4189
|
});
|
|
3984
4190
|
}
|
|
3985
4191
|
buildActionRow(disable = {}) {
|
|
3986
|
-
const confirmBtn = disable.confirm ? new
|
|
3987
|
-
const rejectBtn = disable.reject ? new
|
|
4192
|
+
const confirmBtn = disable.confirm ? new import_discord15.ButtonBuilder(this.buttons.confirm.data).setDisabled(true) : this.buttons.confirm;
|
|
4193
|
+
const rejectBtn = disable.reject ? new import_discord15.ButtonBuilder(this.buttons.reject.data).setDisabled(true) : this.buttons.reject;
|
|
3988
4194
|
const buttons = [];
|
|
3989
4195
|
const customButtonsArray = Array.from(this.customButtons.entries()).map(([customId, data]) => ({
|
|
3990
4196
|
customId,
|
|
3991
|
-
button: disable[customId] ? new
|
|
4197
|
+
button: disable[customId] ? new import_discord15.ButtonBuilder(data.button.data).setDisabled(true) : data.button,
|
|
3992
4198
|
index: data.index
|
|
3993
4199
|
}));
|
|
3994
4200
|
customButtonsArray.sort((a, b) => a.index - b.index);
|
|
@@ -4009,7 +4215,7 @@ var Prompt = class {
|
|
|
4009
4215
|
buttons.push(custom.button);
|
|
4010
4216
|
}
|
|
4011
4217
|
}
|
|
4012
|
-
return new
|
|
4218
|
+
return new import_discord15.ActionRowBuilder({ components: buttons });
|
|
4013
4219
|
}
|
|
4014
4220
|
buildSendOptions(options) {
|
|
4015
4221
|
const sendData = { ...options };
|
|
@@ -4069,7 +4275,7 @@ var Prompt = class {
|
|
|
4069
4275
|
const validCustomIds = /* @__PURE__ */ new Set(["btn_confirm", "btn_reject", ...this.customButtons.keys()]);
|
|
4070
4276
|
try {
|
|
4071
4277
|
const interaction = await this.message.awaitMessageComponent({
|
|
4072
|
-
componentType:
|
|
4278
|
+
componentType: import_discord15.ComponentType.Button,
|
|
4073
4279
|
filter: (i) => validCustomIds.has(i.customId) && this.isParticipant(i.user.id),
|
|
4074
4280
|
time: this.timeout
|
|
4075
4281
|
});
|
|
@@ -4107,209 +4313,11 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4107
4313
|
await p.send(handler, sendOptions);
|
|
4108
4314
|
return await p.awaitResponse();
|
|
4109
4315
|
}
|
|
4110
|
-
|
|
4111
|
-
// src/utils/VimcordCLI.ts
|
|
4112
|
-
var import_node_readline = require("readline");
|
|
4113
|
-
var import_qznt5 = require("qznt");
|
|
4114
|
-
var VimcordCLI = class {
|
|
4115
|
-
rl;
|
|
4116
|
-
options;
|
|
4117
|
-
commands = /* @__PURE__ */ new Map();
|
|
4118
|
-
logger = new Logger({ prefixEmoji: "\u{1F680}", prefix: "CLI", showTimestamp: false });
|
|
4119
|
-
constructor(options) {
|
|
4120
|
-
this.options = options;
|
|
4121
|
-
this.rl = (0, import_node_readline.createInterface)({
|
|
4122
|
-
input: process.stdin,
|
|
4123
|
-
output: process.stdout,
|
|
4124
|
-
terminal: false
|
|
4125
|
-
});
|
|
4126
|
-
this.rl.on("line", (line) => {
|
|
4127
|
-
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
4128
|
-
if (!isCommand) return;
|
|
4129
|
-
const command = this.commands.get(commandName);
|
|
4130
|
-
if (!command) {
|
|
4131
|
-
const nearestMatches = Array.from(this.commands.keys()).filter(
|
|
4132
|
-
(cmd) => cmd.toLowerCase().includes(commandName.toLowerCase())
|
|
4133
|
-
);
|
|
4134
|
-
return this.logger.error(
|
|
4135
|
-
`Unknown command '${commandName}'${nearestMatches.length ? `. Did you mean ${nearestMatches.length > 1 ? `[${nearestMatches.map((m) => `'${this.options.prefix}${m}'`).join(", ")}]` : `'${this.options.prefix}${nearestMatches[0]}'`}?` : ""}`
|
|
4136
|
-
);
|
|
4137
|
-
}
|
|
4138
|
-
command.fn(args, content);
|
|
4139
|
-
});
|
|
4140
|
-
}
|
|
4141
|
-
parseLine(line) {
|
|
4142
|
-
if (line.startsWith(this.options.prefix)) {
|
|
4143
|
-
line = line.slice(this.options.prefix.length);
|
|
4144
|
-
} else {
|
|
4145
|
-
return { isCommand: false };
|
|
4146
|
-
}
|
|
4147
|
-
const args = line.split(" ").map((s) => s.trim());
|
|
4148
|
-
const commandName = args.shift();
|
|
4149
|
-
return { isCommand: true, commandName, content: args.join(" "), args };
|
|
4150
|
-
}
|
|
4151
|
-
getClientInstance(line) {
|
|
4152
|
-
const clientIndex = import_qznt5.$.str.getFlag(line, "--client", 1) || import_qznt5.$.str.getFlag(line, "-c", 1);
|
|
4153
|
-
if (clientIndex) {
|
|
4154
|
-
const idx = Number(clientIndex);
|
|
4155
|
-
if (isNaN(idx)) {
|
|
4156
|
-
CLI.logger.error(`'${clientIndex}' is not a valid number`);
|
|
4157
|
-
return void 0;
|
|
4158
|
-
}
|
|
4159
|
-
const client = clientInstances[idx];
|
|
4160
|
-
if (!client) {
|
|
4161
|
-
CLI.logger.error("Client instance not found");
|
|
4162
|
-
return void 0;
|
|
4163
|
-
}
|
|
4164
|
-
return client;
|
|
4165
|
-
} else {
|
|
4166
|
-
const client = clientInstances[0];
|
|
4167
|
-
if (!client) {
|
|
4168
|
-
CLI.logger.error("Client instance not found");
|
|
4169
|
-
return void 0;
|
|
4170
|
-
}
|
|
4171
|
-
return client;
|
|
4172
|
-
}
|
|
4173
|
-
}
|
|
4174
|
-
addCommand(commandName, description, fn) {
|
|
4175
|
-
this.commands.set(commandName, { description, fn });
|
|
4176
|
-
}
|
|
4177
|
-
removeCommand(commandName) {
|
|
4178
|
-
if (!this.commands.has(commandName)) return false;
|
|
4179
|
-
this.commands.delete(commandName);
|
|
4180
|
-
return true;
|
|
4181
|
-
}
|
|
4182
|
-
};
|
|
4183
|
-
var initCalled = false;
|
|
4184
|
-
var CLI = new VimcordCLI({ prefix: "/" });
|
|
4185
|
-
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
4186
|
-
const prefix = CLI.options.prefix;
|
|
4187
|
-
const helpList = {};
|
|
4188
|
-
for (const cmd of CLI.commands.entries()) {
|
|
4189
|
-
const commandName = cmd[0];
|
|
4190
|
-
const commandDescription = cmd[1].description;
|
|
4191
|
-
helpList[`${prefix}${commandName}`] = `~ ${commandDescription}`;
|
|
4192
|
-
}
|
|
4193
|
-
CLI.logger.table("(help)", helpList);
|
|
4194
|
-
});
|
|
4195
|
-
CLI.addCommand("register", "Register app commands (slash & context) globally, or per guild", async (args, content) => {
|
|
4196
|
-
const client = CLI.getClientInstance(content);
|
|
4197
|
-
if (!client) return;
|
|
4198
|
-
const mode = args[0]?.toLowerCase() || "";
|
|
4199
|
-
if (!["guild", "global"].includes(mode)) {
|
|
4200
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
4201
|
-
}
|
|
4202
|
-
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());
|
|
4203
|
-
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4204
|
-
switch (mode) {
|
|
4205
|
-
case "guild":
|
|
4206
|
-
CLI.logger.info("Registering guild commands...");
|
|
4207
|
-
await client.commands.registerGuild({ guilds: guildIds });
|
|
4208
|
-
break;
|
|
4209
|
-
case "global":
|
|
4210
|
-
CLI.logger.info("Registering global commands...");
|
|
4211
|
-
await client.commands.registerGlobal();
|
|
4212
|
-
break;
|
|
4213
|
-
}
|
|
4214
|
-
});
|
|
4215
|
-
CLI.addCommand("unregister", "Unregister app commands globally, or per guild", async (args, content) => {
|
|
4216
|
-
const client = CLI.getClientInstance(content);
|
|
4217
|
-
if (!client) return;
|
|
4218
|
-
const mode = args[0]?.toLowerCase() || "";
|
|
4219
|
-
if (!["guild", "global"].includes(mode)) {
|
|
4220
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Your options are [guild|global]`);
|
|
4221
|
-
}
|
|
4222
|
-
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());
|
|
4223
|
-
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4224
|
-
switch (mode) {
|
|
4225
|
-
case "guild":
|
|
4226
|
-
CLI.logger.info("Unregistering guild commands...");
|
|
4227
|
-
await client.commands.unregisterGuild({ guilds: guildIds });
|
|
4228
|
-
break;
|
|
4229
|
-
case "global":
|
|
4230
|
-
CLI.logger.info("Unregistering global commands...");
|
|
4231
|
-
await client.commands.unregisterGlobal();
|
|
4232
|
-
break;
|
|
4233
|
-
}
|
|
4234
|
-
});
|
|
4235
|
-
CLI.addCommand("stats", "View statistics about a client instance", (args, content) => {
|
|
4236
|
-
const client = CLI.getClientInstance(content);
|
|
4237
|
-
if (!client) return;
|
|
4238
|
-
CLI.logger.table(`(stats) ~ ${client.config.app.name}`, {
|
|
4239
|
-
"Guilds:": import_qznt5.$.format.number(client.guilds.cache.size),
|
|
4240
|
-
"Ping:": `${client.ws.ping || 0}ms`,
|
|
4241
|
-
"Uptime:": `${import_qznt5.$.math.secs(client.uptime || 0)}s`,
|
|
4242
|
-
"Process Uptime:": `${Math.floor(process.uptime())}s`,
|
|
4243
|
-
"Memory Usage:": `${(process.memoryUsage().rss / 1024 / 1024).toFixed(2)} MB`
|
|
4244
|
-
});
|
|
4245
|
-
});
|
|
4246
|
-
CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
4247
|
-
const client = CLI.getClientInstance(content);
|
|
4248
|
-
if (!client) return;
|
|
4249
|
-
const mode = (args[0] || "slash").toLowerCase();
|
|
4250
|
-
switch (mode) {
|
|
4251
|
-
case "slash": {
|
|
4252
|
-
const commands = Array.from(client.commands.slash.commands.values());
|
|
4253
|
-
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4254
|
-
const tableData = {};
|
|
4255
|
-
for (const cmd of commands) {
|
|
4256
|
-
tableData[`/${cmd.builder.name}`] = `~ ${cmd.builder.description || "No description"}`;
|
|
4257
|
-
}
|
|
4258
|
-
return CLI.logger.table(`(cmds) ~ slash (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4259
|
-
}
|
|
4260
|
-
case "prefix": {
|
|
4261
|
-
const commands = Array.from(client.commands.prefix.commands.values());
|
|
4262
|
-
commands.sort((a, b) => {
|
|
4263
|
-
const nameA = a.toConfig().name;
|
|
4264
|
-
const nameB = b.toConfig().name;
|
|
4265
|
-
return nameA.localeCompare(nameB);
|
|
4266
|
-
});
|
|
4267
|
-
const tableData = {};
|
|
4268
|
-
const defaultPrefix = client.config.prefixCommands.defaultPrefix;
|
|
4269
|
-
for (const cmd of commands) {
|
|
4270
|
-
const config = cmd.toConfig();
|
|
4271
|
-
const aliasIndicator = config.aliases?.length ? ` [${config.aliases.join(", ")}]` : "";
|
|
4272
|
-
tableData[`${defaultPrefix}${config.name}${aliasIndicator}`] = `~ ${config.description || "No description"}`;
|
|
4273
|
-
}
|
|
4274
|
-
return CLI.logger.table(`(cmds) ~ prefix (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4275
|
-
}
|
|
4276
|
-
case "ctx": {
|
|
4277
|
-
const commands = Array.from(client.commands.context.commands.values());
|
|
4278
|
-
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4279
|
-
const tableData = {};
|
|
4280
|
-
for (const cmd of commands) {
|
|
4281
|
-
const type = cmd.builder.type === 2 ? "User" : "Msg";
|
|
4282
|
-
tableData[`[${type}] ${cmd.builder.name}`] = "";
|
|
4283
|
-
}
|
|
4284
|
-
return CLI.logger.table(`(cmds) ~ ctx (${import_qznt5.$.format.number(commands.length)})`, tableData);
|
|
4285
|
-
}
|
|
4286
|
-
default:
|
|
4287
|
-
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
4288
|
-
}
|
|
4289
|
-
});
|
|
4290
|
-
function initCLI() {
|
|
4291
|
-
if (initCalled) return;
|
|
4292
|
-
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
4293
|
-
initCalled = true;
|
|
4294
|
-
}
|
|
4295
|
-
|
|
4296
|
-
// src/utils/clientUtils.ts
|
|
4297
|
-
function useClient(index = 0) {
|
|
4298
|
-
return clientInstances.at(index);
|
|
4299
|
-
}
|
|
4300
|
-
async function useReadyClient(index = 0) {
|
|
4301
|
-
return useClient(index)?.whenReady();
|
|
4302
|
-
}
|
|
4303
|
-
function createClient(options, features = {}, config = {}) {
|
|
4304
|
-
const client = new Vimcord(options, features, config);
|
|
4305
|
-
initCLI();
|
|
4306
|
-
return client;
|
|
4307
|
-
}
|
|
4308
|
-
function getClientInstances() {
|
|
4309
|
-
return clientInstances;
|
|
4310
|
-
}
|
|
4311
4316
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4312
4317
|
0 && (module.exports = {
|
|
4318
|
+
BUILTIN_ContextCommandHandler,
|
|
4319
|
+
BUILTIN_PrefixCommandHandler,
|
|
4320
|
+
BUILTIN_SlashCommandHandler,
|
|
4313
4321
|
BaseCommandBuilder,
|
|
4314
4322
|
BaseCommandManager,
|
|
4315
4323
|
BetterCollector,
|
|
@@ -4348,7 +4356,6 @@ function getClientInstances() {
|
|
|
4348
4356
|
VimcordCLI,
|
|
4349
4357
|
__zero,
|
|
4350
4358
|
cleanMention,
|
|
4351
|
-
clientInstances,
|
|
4352
4359
|
createClient,
|
|
4353
4360
|
createMongoPlugin,
|
|
4354
4361
|
createMongoSchema,
|
|
@@ -4367,9 +4374,7 @@ function getClientInstances() {
|
|
|
4367
4374
|
fetchMessage,
|
|
4368
4375
|
fetchRole,
|
|
4369
4376
|
fetchUser,
|
|
4370
|
-
formatThousands,
|
|
4371
4377
|
getCallerFileName,
|
|
4372
|
-
getClientInstances,
|
|
4373
4378
|
getFirstMentionId,
|
|
4374
4379
|
getMessageMention,
|
|
4375
4380
|
getProcessDir,
|
|
@@ -4379,7 +4384,6 @@ function getClientInstances() {
|
|
|
4379
4384
|
isMentionOrSnowflake,
|
|
4380
4385
|
logger,
|
|
4381
4386
|
prompt,
|
|
4382
|
-
retryExponentialBackoff,
|
|
4383
4387
|
sendCommandErrorEmbed,
|
|
4384
4388
|
useClient,
|
|
4385
4389
|
useReadyClient,
|