vimcord 1.0.0 → 1.0.1
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 +834 -649
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +287 -182
- package/dist/index.d.ts +287 -182
- package/dist/index.js +830 -649
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +54 -54
package/dist/index.cjs
CHANGED
|
@@ -31,14 +31,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
BaseCommandBuilder: () => BaseCommandBuilder,
|
|
34
|
+
BetterCollector: () => BetterCollector,
|
|
34
35
|
BetterContainer: () => BetterContainer,
|
|
35
36
|
BetterEmbed: () => BetterEmbed,
|
|
36
37
|
BetterModal: () => BetterModal,
|
|
37
38
|
CLI: () => CLI,
|
|
39
|
+
CollectorTimeoutType: () => CollectorTimeoutType,
|
|
38
40
|
CommandType: () => CommandType,
|
|
39
41
|
ContextCommandBuilder: () => ContextCommandBuilder,
|
|
40
42
|
DynaSend: () => DynaSend,
|
|
41
43
|
EventBuilder: () => EventBuilder,
|
|
44
|
+
LOGGER_COLORS: () => LOGGER_COLORS,
|
|
42
45
|
LogLevel: () => LogLevel,
|
|
43
46
|
Logger: () => Logger,
|
|
44
47
|
MissingPermissionReason: () => MissingPermissionReason,
|
|
@@ -67,6 +70,7 @@ __export(index_exports, {
|
|
|
67
70
|
clientInstances: () => clientInstances,
|
|
68
71
|
createClient: () => createClient,
|
|
69
72
|
createMongoSchema: () => createMongoSchema,
|
|
73
|
+
createMongoSession: () => createMongoSession,
|
|
70
74
|
createToolsConfig: () => createToolsConfig,
|
|
71
75
|
createVimcordAppConfig: () => createVimcordAppConfig,
|
|
72
76
|
createVimcordContextCommandConfig: () => createVimcordContextCommandConfig,
|
|
@@ -100,16 +104,17 @@ __export(index_exports, {
|
|
|
100
104
|
useClient: () => useClient,
|
|
101
105
|
useMongoDatabase: () => useMongoDatabase,
|
|
102
106
|
useReadyClient: () => useReadyClient,
|
|
107
|
+
useReadyMongoDatabase: () => useReadyMongoDatabase,
|
|
103
108
|
validateCommandPermissions: () => validateCommandPermissions
|
|
104
109
|
});
|
|
105
110
|
module.exports = __toCommonJS(index_exports);
|
|
106
111
|
|
|
107
112
|
// src/types/command.base.ts
|
|
108
|
-
var CommandType = /* @__PURE__ */ ((
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return
|
|
113
|
+
var CommandType = /* @__PURE__ */ ((CommandType2) => {
|
|
114
|
+
CommandType2[CommandType2["Slash"] = 0] = "Slash";
|
|
115
|
+
CommandType2[CommandType2["Prefix"] = 1] = "Prefix";
|
|
116
|
+
CommandType2[CommandType2["Context"] = 2] = "Context";
|
|
117
|
+
return CommandType2;
|
|
113
118
|
})(CommandType || {});
|
|
114
119
|
var MissingPermissionReason = /* @__PURE__ */ ((MissingPermissionReason2) => {
|
|
115
120
|
MissingPermissionReason2[MissingPermissionReason2["User"] = 0] = "User";
|
|
@@ -233,270 +238,239 @@ var import_lodash = __toESM(require("lodash"));
|
|
|
233
238
|
var BaseCommandBuilder = class {
|
|
234
239
|
uuid = (0, import_node_crypto.randomUUID)();
|
|
235
240
|
commandType;
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
channelRateLimitData = /* @__PURE__ */ new Map();
|
|
254
|
-
constructor(type, config) {
|
|
241
|
+
/** Local command configuration and hooks */
|
|
242
|
+
options;
|
|
243
|
+
/** Internal state for rate limiting across different scopes */
|
|
244
|
+
rlStores = {
|
|
245
|
+
[3 /* Global */]: { executions: 0, timestamp: 0 },
|
|
246
|
+
[0 /* User */]: /* @__PURE__ */ new Map(),
|
|
247
|
+
[1 /* Guild */]: /* @__PURE__ */ new Map(),
|
|
248
|
+
[2 /* Channel */]: /* @__PURE__ */ new Map()
|
|
249
|
+
};
|
|
250
|
+
/** * Mapping of CommandTypes to their respective config keys in the Vimcord client
|
|
251
|
+
*/
|
|
252
|
+
typeConfigMapping = {
|
|
253
|
+
[0 /* Slash */]: "slashCommands",
|
|
254
|
+
[1 /* Prefix */]: "prefixCommands",
|
|
255
|
+
[2 /* Context */]: "contextCommands"
|
|
256
|
+
};
|
|
257
|
+
constructor(type, options = {}) {
|
|
255
258
|
this.commandType = type;
|
|
256
|
-
this.
|
|
257
|
-
this.conditions = config?.conditions;
|
|
258
|
-
this.permissions = config?.permissions;
|
|
259
|
-
this.metadata = config?.metadata;
|
|
260
|
-
this.rateLimit = config?.rateLimit;
|
|
261
|
-
this.beforeExecute = config?.beforeExecute;
|
|
262
|
-
this.execute = config?.execute;
|
|
263
|
-
this.afterExecute = config?.afterExecute;
|
|
264
|
-
this.onRateLimit = config?.onRateLimit;
|
|
265
|
-
this.onMissingPermissions = config?.onMissingPermissions;
|
|
266
|
-
this.onConditionsNotMet = config?.onConditionsNotMet;
|
|
267
|
-
this.onUsedWhenDisabled = config?.onUsedWhenDisabled;
|
|
268
|
-
this.onError = config?.onError;
|
|
269
|
-
this.validateBaseConfig();
|
|
259
|
+
this.options = { enabled: true, ...options };
|
|
270
260
|
}
|
|
271
261
|
validateBaseConfig() {
|
|
272
|
-
if (this.rateLimit) {
|
|
273
|
-
|
|
274
|
-
|
|
262
|
+
if (this.options.rateLimit) {
|
|
263
|
+
const { max, interval } = this.options.rateLimit;
|
|
264
|
+
if (max <= 0 || interval <= 0) {
|
|
265
|
+
throw new Error(`[Vimcord:${this.constructor.name}] Rate limit values must be positive.`);
|
|
275
266
|
}
|
|
276
|
-
|
|
277
|
-
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Resolves the final configuration by merging layers:
|
|
271
|
+
* Client Defaults < Client Type-Specific < Local Command Options
|
|
272
|
+
*/
|
|
273
|
+
resolveConfig(client) {
|
|
274
|
+
const typeKey = this.typeConfigMapping[this.commandType];
|
|
275
|
+
const typeSpecificGlobals = client.config?.[typeKey] || {};
|
|
276
|
+
return import_lodash.default.merge({}, typeSpecificGlobals, this.options);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Executes the command lifecycle.
|
|
280
|
+
* Merges global client config with local command options at runtime.
|
|
281
|
+
*/
|
|
282
|
+
async run(client, ...args) {
|
|
283
|
+
const config = this.resolveConfig(client);
|
|
284
|
+
const ctx = this.extractContext(args);
|
|
285
|
+
try {
|
|
286
|
+
if (!config.enabled) {
|
|
287
|
+
return await config.onUsedWhenDisabled?.(...args);
|
|
288
|
+
}
|
|
289
|
+
if (this.isRateLimited(config, ctx)) {
|
|
290
|
+
return await config.onRateLimit?.(...args);
|
|
291
|
+
}
|
|
292
|
+
const perms = this.checkPermissions(client, ctx.member || ctx.user, args[1]);
|
|
293
|
+
if (!perms.validated) {
|
|
294
|
+
return await config.onMissingPermissions?.(perms, ...args);
|
|
278
295
|
}
|
|
296
|
+
if (!await this.checkConditions(config, ...args)) {
|
|
297
|
+
return await config.onConditionsNotMet?.(...args);
|
|
298
|
+
}
|
|
299
|
+
await config.beforeExecute?.(...args);
|
|
300
|
+
if (config.logExecution !== false) {
|
|
301
|
+
const cmdName = this.options.name || this.builder?.name || "Unknown";
|
|
302
|
+
const location = ctx.guild ? `${ctx.guild.name} (${ctx.guild.id})` : "Direct Messages";
|
|
303
|
+
client.logger.commandExecuted(cmdName, ctx.user.username, location);
|
|
304
|
+
}
|
|
305
|
+
const result = await config.execute?.(...args);
|
|
306
|
+
await config.afterExecute?.(result, ...args);
|
|
307
|
+
} catch (error) {
|
|
308
|
+
await this.handleError(error, config, ...args);
|
|
279
309
|
}
|
|
280
310
|
}
|
|
281
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Internal logic to determine if a command execution should be throttled.
|
|
313
|
+
* @param config The merged configuration to use for limits.
|
|
314
|
+
* @param ctx Extracted Discord context (User, Guild, Channel).
|
|
315
|
+
*/
|
|
316
|
+
isRateLimited(config, ctx) {
|
|
317
|
+
if (!config.rateLimit) return false;
|
|
318
|
+
const { scope, interval, max } = config.rateLimit;
|
|
319
|
+
const now = Date.now();
|
|
320
|
+
const key = this.getScopeKey(scope, ctx);
|
|
321
|
+
if (scope !== 3 /* Global */ && !key) return false;
|
|
322
|
+
let data;
|
|
323
|
+
if (scope === 3 /* Global */) {
|
|
324
|
+
data = this.rlStores[3 /* Global */];
|
|
325
|
+
} else {
|
|
326
|
+
const store = this.rlStores[scope];
|
|
327
|
+
data = store.get(key) ?? { executions: 0, timestamp: now };
|
|
328
|
+
store.set(key, data);
|
|
329
|
+
}
|
|
330
|
+
if (now - data.timestamp > interval) {
|
|
331
|
+
data.executions = 0;
|
|
332
|
+
data.timestamp = now;
|
|
333
|
+
}
|
|
334
|
+
if (data.executions >= max) return true;
|
|
335
|
+
data.executions++;
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Validates if the user has required permissions.
|
|
340
|
+
*/
|
|
341
|
+
checkPermissions(client, user, target) {
|
|
342
|
+
if (!this.options.permissions) return { validated: true };
|
|
343
|
+
return validateCommandPermissions(this.options.permissions, client, user, target);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Evaluates all custom conditions defined for the command.
|
|
347
|
+
*/
|
|
348
|
+
async checkConditions(config, ...args) {
|
|
349
|
+
if (!config.conditions?.length) return true;
|
|
350
|
+
const results = await Promise.all(config.conditions.map((c) => c(...args)));
|
|
351
|
+
return results.every(Boolean);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Normalizes the trigger arguments into a standard context object.
|
|
355
|
+
*/
|
|
356
|
+
extractContext(args) {
|
|
357
|
+
const event = args[1];
|
|
282
358
|
return {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
rateLimit: this.rateLimit,
|
|
288
|
-
beforeExecute: this.beforeExecute,
|
|
289
|
-
execute: this.execute,
|
|
290
|
-
afterExecute: this.afterExecute,
|
|
291
|
-
onMissingPermissions: this.onMissingPermissions,
|
|
292
|
-
onConditionsNotMet: this.onConditionsNotMet,
|
|
293
|
-
onUsedWhenDisabled: this.onUsedWhenDisabled,
|
|
294
|
-
onRateLimit: this.onRateLimit,
|
|
295
|
-
onError: this.onError
|
|
359
|
+
user: event.user || event.author,
|
|
360
|
+
member: event.member,
|
|
361
|
+
guild: event.guild,
|
|
362
|
+
channel: event.channel
|
|
296
363
|
};
|
|
297
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* Resolves the storage key based on the RateLimit scope.
|
|
367
|
+
*/
|
|
368
|
+
getScopeKey(scope, ctx) {
|
|
369
|
+
switch (scope) {
|
|
370
|
+
case 0 /* User */:
|
|
371
|
+
return ctx.user.id;
|
|
372
|
+
case 1 /* Guild */:
|
|
373
|
+
return ctx.guild?.id ?? null;
|
|
374
|
+
case 2 /* Channel */:
|
|
375
|
+
return ctx.channel?.id ?? null;
|
|
376
|
+
default:
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Handles command errors by checking local handlers before falling back to global handlers.
|
|
382
|
+
*/
|
|
383
|
+
async handleError(err, config, ...args) {
|
|
384
|
+
if (config.onError) return config.onError(err, ...args);
|
|
385
|
+
throw err;
|
|
386
|
+
}
|
|
387
|
+
/** Toggle command availability */
|
|
298
388
|
setEnabled(enabled) {
|
|
299
|
-
this.enabled = enabled;
|
|
389
|
+
this.options.enabled = enabled;
|
|
300
390
|
return this;
|
|
301
391
|
}
|
|
392
|
+
/** Merge new permission requirements into the existing ones */
|
|
393
|
+
setPermissions(perms) {
|
|
394
|
+
this.options.permissions = import_lodash.default.merge(this.options.permissions || {}, perms);
|
|
395
|
+
return this;
|
|
396
|
+
}
|
|
397
|
+
/** Add custom logic checks that run before execution */
|
|
302
398
|
addConditions(...conditions) {
|
|
303
|
-
|
|
304
|
-
this.conditions.push(...conditions);
|
|
399
|
+
this.options.conditions = [...this.options.conditions || [], ...conditions];
|
|
305
400
|
return this;
|
|
306
401
|
}
|
|
307
|
-
|
|
308
|
-
|
|
402
|
+
/** Set the primary command execution logic */
|
|
403
|
+
setExecute(fn) {
|
|
404
|
+
this.options.execute = fn;
|
|
309
405
|
return this;
|
|
310
406
|
}
|
|
311
|
-
|
|
312
|
-
|
|
407
|
+
/** * Set the custom conditions that must be met for this command to execute
|
|
408
|
+
*/
|
|
409
|
+
setConditions(conditions) {
|
|
410
|
+
this.options.conditions = conditions;
|
|
313
411
|
return this;
|
|
314
412
|
}
|
|
413
|
+
/** * Set the command metadata configuration
|
|
414
|
+
*/
|
|
315
415
|
setMetadata(metadata) {
|
|
316
|
-
this.metadata = import_lodash.default.merge(this.metadata, metadata);
|
|
416
|
+
this.options.metadata = import_lodash.default.merge(this.options.metadata || {}, metadata);
|
|
317
417
|
return this;
|
|
318
418
|
}
|
|
419
|
+
/** * Set the rate limiting options for this command
|
|
420
|
+
*/
|
|
319
421
|
setRateLimit(options) {
|
|
320
|
-
this.rateLimit = options;
|
|
422
|
+
this.options.rateLimit = options;
|
|
423
|
+
this.validateBaseConfig();
|
|
321
424
|
return this;
|
|
322
425
|
}
|
|
323
|
-
|
|
324
|
-
|
|
426
|
+
/** * Set whether to log whenever this command is executed
|
|
427
|
+
* @default true
|
|
428
|
+
*/
|
|
429
|
+
setLogExecution(log) {
|
|
430
|
+
this.options.logExecution = log;
|
|
325
431
|
return this;
|
|
326
432
|
}
|
|
327
|
-
|
|
328
|
-
|
|
433
|
+
/** * Set the function to execute before the main command logic
|
|
434
|
+
*/
|
|
435
|
+
setBeforeExecute(callback) {
|
|
436
|
+
this.options.beforeExecute = callback;
|
|
329
437
|
return this;
|
|
330
438
|
}
|
|
439
|
+
/** * Set the function to execute after successful command execution
|
|
440
|
+
*/
|
|
331
441
|
setAfterExecute(callback) {
|
|
332
|
-
this.afterExecute = callback;
|
|
333
|
-
return this;
|
|
334
|
-
}
|
|
335
|
-
setOnRateLimit(callback) {
|
|
336
|
-
this.onRateLimit = callback;
|
|
442
|
+
this.options.afterExecute = callback;
|
|
337
443
|
return this;
|
|
338
444
|
}
|
|
445
|
+
/** * Set the function to execute when the required permissions are not met
|
|
446
|
+
*/
|
|
339
447
|
setOnMissingPermissions(callback) {
|
|
340
|
-
this.onMissingPermissions = callback;
|
|
448
|
+
this.options.onMissingPermissions = callback;
|
|
341
449
|
return this;
|
|
342
450
|
}
|
|
451
|
+
/** * Set the function to execute when the required conditions are not met
|
|
452
|
+
*/
|
|
343
453
|
setOnConditionsNotMet(callback) {
|
|
344
|
-
this.onConditionsNotMet = callback;
|
|
454
|
+
this.options.onConditionsNotMet = callback;
|
|
345
455
|
return this;
|
|
346
456
|
}
|
|
457
|
+
/** * Set the function to execute when this command is used when its disabled
|
|
458
|
+
*/
|
|
347
459
|
setOnUsedWhenDisabled(callback) {
|
|
348
|
-
this.onUsedWhenDisabled = callback;
|
|
460
|
+
this.options.onUsedWhenDisabled = callback;
|
|
349
461
|
return this;
|
|
350
462
|
}
|
|
351
|
-
|
|
352
|
-
|
|
463
|
+
/** * Set the function to execute when the rate limit is hit
|
|
464
|
+
*/
|
|
465
|
+
setOnRateLimit(callback) {
|
|
466
|
+
this.options.onRateLimit = callback;
|
|
353
467
|
return this;
|
|
354
468
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (!user) return null;
|
|
361
|
-
rateLimitData = this.userRateLimitData.get(user.id) ?? { executions: 0, timestamp: 0 };
|
|
362
|
-
break;
|
|
363
|
-
case 1 /* Guild */:
|
|
364
|
-
if (!guild) return null;
|
|
365
|
-
rateLimitData = this.guildRateLimitData.get(guild.id) ?? { executions: 0, timestamp: 0 };
|
|
366
|
-
break;
|
|
367
|
-
case 2 /* Channel */:
|
|
368
|
-
if (!channel) return null;
|
|
369
|
-
rateLimitData = this.channelRateLimitData.get(channel.id) ?? { executions: 0, timestamp: 0 };
|
|
370
|
-
break;
|
|
371
|
-
case 3 /* Global */:
|
|
372
|
-
rateLimitData = this.globalRateLimitData;
|
|
373
|
-
break;
|
|
374
|
-
default:
|
|
375
|
-
return null;
|
|
376
|
-
}
|
|
377
|
-
return { ...rateLimitData, isLimited: this.isRateLimited(user, guild, channel, false) };
|
|
378
|
-
}
|
|
379
|
-
isRateLimited(user, guild, channel, updateExecutions = true) {
|
|
380
|
-
if (!this.rateLimit) return false;
|
|
381
|
-
const now = Date.now();
|
|
382
|
-
let rateLimitData;
|
|
383
|
-
switch (this.rateLimit.scope) {
|
|
384
|
-
case 0 /* User */:
|
|
385
|
-
if (!user) return false;
|
|
386
|
-
rateLimitData = this.userRateLimitData.get(user.id) ?? { executions: 0, timestamp: 0 };
|
|
387
|
-
if (now - rateLimitData.timestamp >= this.rateLimit.interval) {
|
|
388
|
-
rateLimitData.executions = 0;
|
|
389
|
-
rateLimitData.timestamp = now;
|
|
390
|
-
}
|
|
391
|
-
if (updateExecutions) rateLimitData.executions++;
|
|
392
|
-
this.userRateLimitData.set(user.id, rateLimitData);
|
|
393
|
-
break;
|
|
394
|
-
case 1 /* Guild */:
|
|
395
|
-
if (!guild) return false;
|
|
396
|
-
rateLimitData = this.guildRateLimitData.get(guild.id) ?? { executions: 0, timestamp: 0 };
|
|
397
|
-
if (now - rateLimitData.timestamp >= this.rateLimit.interval) {
|
|
398
|
-
rateLimitData.executions = 0;
|
|
399
|
-
rateLimitData.timestamp = now;
|
|
400
|
-
}
|
|
401
|
-
if (updateExecutions) rateLimitData.executions++;
|
|
402
|
-
this.guildRateLimitData.set(guild.id, rateLimitData);
|
|
403
|
-
break;
|
|
404
|
-
case 2 /* Channel */:
|
|
405
|
-
if (!channel) return false;
|
|
406
|
-
rateLimitData = this.guildRateLimitData.get(channel.id) ?? { executions: 0, timestamp: 0 };
|
|
407
|
-
if (now - rateLimitData.timestamp >= this.rateLimit.interval) {
|
|
408
|
-
rateLimitData.executions = 0;
|
|
409
|
-
rateLimitData.timestamp = now;
|
|
410
|
-
}
|
|
411
|
-
if (updateExecutions) rateLimitData.executions++;
|
|
412
|
-
this.channelRateLimitData.set(channel.id, rateLimitData);
|
|
413
|
-
break;
|
|
414
|
-
case 3 /* Global */:
|
|
415
|
-
rateLimitData = this.globalRateLimitData;
|
|
416
|
-
if (now - rateLimitData.timestamp >= this.rateLimit.interval) {
|
|
417
|
-
rateLimitData.executions = 0;
|
|
418
|
-
rateLimitData.timestamp = now;
|
|
419
|
-
}
|
|
420
|
-
if (updateExecutions) rateLimitData.executions++;
|
|
421
|
-
this.globalRateLimitData = rateLimitData;
|
|
422
|
-
break;
|
|
423
|
-
}
|
|
424
|
-
return rateLimitData.executions >= this.rateLimit.max;
|
|
425
|
-
}
|
|
426
|
-
checkPermissions(client, user, command) {
|
|
427
|
-
if (!this.permissions) return { validated: true };
|
|
428
|
-
return validateCommandPermissions(this.permissions, client, user, command);
|
|
429
|
-
}
|
|
430
|
-
async checkConditions(...args) {
|
|
431
|
-
if (!this.conditions?.length) return true;
|
|
432
|
-
const results = await Promise.all(this.conditions.map((condition) => condition(...args)));
|
|
433
|
-
return results.every(Boolean);
|
|
434
|
-
}
|
|
435
|
-
async _runPreflight(clientConfig, command, ...args) {
|
|
436
|
-
try {
|
|
437
|
-
if (!this.enabled) {
|
|
438
|
-
await clientConfig.onUsedWhenDisabled?.(...args);
|
|
439
|
-
await this.onUsedWhenDisabled?.(...args);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
if (this.isRateLimited(args[1]?.member || args[1]?.author, args[1].guild, args[1].channel)) {
|
|
443
|
-
await clientConfig.onRateLimit?.(...args);
|
|
444
|
-
await this.rateLimit?.onRateLimit?.(...args);
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
const permissionResults = this.checkPermissions(
|
|
448
|
-
args[0],
|
|
449
|
-
args[1]?.member || args[1]?.author || args[1]?.user,
|
|
450
|
-
command
|
|
451
|
-
);
|
|
452
|
-
if (!permissionResults.validated) {
|
|
453
|
-
await clientConfig.onMissingPermissions?.(permissionResults, ...args);
|
|
454
|
-
await this.onMissingPermissions?.(permissionResults, ...args);
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
if (!await this.checkConditions(...args)) {
|
|
458
|
-
await clientConfig.onConditionsNotMet?.(...args);
|
|
459
|
-
await this.onConditionsNotMet?.(...args);
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
} catch (err) {
|
|
463
|
-
if (this.onError) {
|
|
464
|
-
return this.onError(err, ...args);
|
|
465
|
-
} else if (clientConfig.onError) {
|
|
466
|
-
return clientConfig.onError(err, ...args);
|
|
467
|
-
} else {
|
|
468
|
-
throw err;
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
async _runCabinCheck(clientConfig, ...args) {
|
|
473
|
-
try {
|
|
474
|
-
await clientConfig.beforeExecute?.(...args);
|
|
475
|
-
await this.beforeExecute?.(...args);
|
|
476
|
-
} catch (err) {
|
|
477
|
-
if (this.onError) {
|
|
478
|
-
return this.onError(err, ...args);
|
|
479
|
-
} else if (clientConfig.onError) {
|
|
480
|
-
return clientConfig.onError(err, ...args);
|
|
481
|
-
} else {
|
|
482
|
-
throw err;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
async _runFlyAndLand(clientConfig, ...args) {
|
|
487
|
-
try {
|
|
488
|
-
const result = await this.execute?.(...args);
|
|
489
|
-
await clientConfig?.afterExecute?.(result, ...args);
|
|
490
|
-
await this.afterExecute?.(result, ...args);
|
|
491
|
-
} catch (err) {
|
|
492
|
-
if (this.onError) {
|
|
493
|
-
return this.onError(err, ...args);
|
|
494
|
-
} else if (clientConfig.onError) {
|
|
495
|
-
return clientConfig.onError(err, ...args);
|
|
496
|
-
} else {
|
|
497
|
-
throw err;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
469
|
+
/** * Set a custom error handler for this command
|
|
470
|
+
*/
|
|
471
|
+
setOnError(callback) {
|
|
472
|
+
this.options.onError = callback;
|
|
473
|
+
return this;
|
|
500
474
|
}
|
|
501
475
|
};
|
|
502
476
|
|
|
@@ -505,73 +479,48 @@ var import_discord2 = require("discord.js");
|
|
|
505
479
|
var import_lodash2 = __toESM(require("lodash"));
|
|
506
480
|
var ContextCommandBuilder = class extends BaseCommandBuilder {
|
|
507
481
|
builder;
|
|
508
|
-
deferReply;
|
|
509
|
-
deployment;
|
|
510
482
|
constructor(config) {
|
|
511
483
|
super(2 /* Context */, config);
|
|
512
484
|
this.setBuilder(config.builder);
|
|
513
|
-
|
|
514
|
-
this.
|
|
515
|
-
|
|
485
|
+
const originalExecute = this.options.execute;
|
|
486
|
+
this.options.execute = async (client, interaction) => {
|
|
487
|
+
return await this.handleExecution(client, interaction, originalExecute);
|
|
488
|
+
};
|
|
516
489
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
try {
|
|
522
|
-
this.builder.toJSON();
|
|
523
|
-
} catch (err) {
|
|
524
|
-
throw new Error("VContextCommandBuilder: Invalid command builder", { cause: err });
|
|
490
|
+
async handleExecution(client, interaction, originalExecute) {
|
|
491
|
+
const config = this.resolveConfig(client);
|
|
492
|
+
if (config.deferReply && !interaction.replied && !interaction.deferred) {
|
|
493
|
+
await interaction.deferReply(typeof config.deferReply === "object" ? config.deferReply : void 0);
|
|
525
494
|
}
|
|
495
|
+
return await originalExecute?.(client, interaction);
|
|
526
496
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
return {
|
|
531
|
-
...super.toConfig(),
|
|
532
|
-
builder: this.builder,
|
|
533
|
-
deferReply: this.deferReply,
|
|
534
|
-
deployment: this.deployment
|
|
535
|
-
};
|
|
497
|
+
validateBuilder() {
|
|
498
|
+
if (!this.builder.name) throw new Error(`[Vimcord] ContextCommandBuilder: Command name is required.`);
|
|
499
|
+
this.builder.toJSON();
|
|
536
500
|
}
|
|
501
|
+
// --- Specialized Fluent API ---
|
|
537
502
|
setBuilder(builder) {
|
|
538
|
-
|
|
539
|
-
this.builder = builder(new import_discord2.ContextMenuCommandBuilder());
|
|
540
|
-
} else {
|
|
541
|
-
this.builder = builder;
|
|
542
|
-
}
|
|
503
|
+
this.builder = typeof builder === "function" ? builder(new import_discord2.ContextMenuCommandBuilder()) : builder;
|
|
543
504
|
this.validateBuilder();
|
|
544
505
|
return this;
|
|
545
506
|
}
|
|
546
507
|
setDeferReply(defer) {
|
|
547
|
-
this.deferReply = defer;
|
|
508
|
+
this.options.deferReply = defer;
|
|
548
509
|
return this;
|
|
549
510
|
}
|
|
550
511
|
setDeployment(deployment) {
|
|
551
|
-
this.deployment = import_lodash2.default.merge(this.deployment, deployment);
|
|
512
|
+
this.options.deployment = import_lodash2.default.merge(this.options.deployment || {}, deployment);
|
|
552
513
|
return this;
|
|
553
514
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
await this.
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
if (this.onError) {
|
|
564
|
-
return this.onError(err, client, interaction);
|
|
565
|
-
} else if (client.config.contextCommands.onError) {
|
|
566
|
-
return client.config.contextCommands.onError(err, client, interaction);
|
|
567
|
-
} else {
|
|
568
|
-
throw err;
|
|
569
|
-
}
|
|
570
|
-
} finally {
|
|
571
|
-
if (client.config.contextCommands.logExecution) {
|
|
572
|
-
client.logger.commandExecuted(this.builder.name, interaction.user.username, interaction.guild?.name);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
515
|
+
setExecute(fn) {
|
|
516
|
+
const originalExecute = fn;
|
|
517
|
+
this.options.execute = async (client, interaction) => {
|
|
518
|
+
return await this.handleExecution(client, interaction, originalExecute);
|
|
519
|
+
};
|
|
520
|
+
return this;
|
|
521
|
+
}
|
|
522
|
+
toConfig() {
|
|
523
|
+
return { ...this.options, builder: this.builder };
|
|
575
524
|
}
|
|
576
525
|
};
|
|
577
526
|
|
|
@@ -818,39 +767,74 @@ var EventBuilder = class _EventBuilder {
|
|
|
818
767
|
|
|
819
768
|
// src/builders/prefixCommand.builder.ts
|
|
820
769
|
var PrefixCommandBuilder = class extends BaseCommandBuilder {
|
|
821
|
-
name;
|
|
822
|
-
aliases;
|
|
823
|
-
description;
|
|
824
770
|
constructor(config) {
|
|
825
771
|
super(1 /* Prefix */, config);
|
|
826
|
-
|
|
827
|
-
this.
|
|
828
|
-
|
|
772
|
+
const originalExecute = this.options.execute;
|
|
773
|
+
this.options.execute = async (client, message) => {
|
|
774
|
+
return await this.handleExecution(client, message, originalExecute);
|
|
775
|
+
};
|
|
776
|
+
this.validatePrefixConfig();
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Specialized execution logic for Prefix Commands.
|
|
780
|
+
*/
|
|
781
|
+
async handleExecution(client, message, originalExecute) {
|
|
782
|
+
return await originalExecute?.(client, message);
|
|
783
|
+
}
|
|
784
|
+
validatePrefixConfig() {
|
|
785
|
+
if (!this.options.name) {
|
|
786
|
+
throw new Error(`[Vimcord] PrefixCommandBuilder: Command name is required.`);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
// --- Fluent API (Prefix Specific Only) ---
|
|
790
|
+
/**
|
|
791
|
+
* Set the primary name of the command.
|
|
792
|
+
*/
|
|
793
|
+
setName(name) {
|
|
794
|
+
this.options.name = name;
|
|
795
|
+
return this;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Set or replace the command aliases.
|
|
799
|
+
*/
|
|
800
|
+
setAliases(aliases) {
|
|
801
|
+
this.options.aliases = aliases;
|
|
802
|
+
return this;
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Add additional aliases without clearing existing ones.
|
|
806
|
+
*/
|
|
807
|
+
addAliases(...aliases) {
|
|
808
|
+
this.options.aliases = [...this.options.aliases || [], ...aliases];
|
|
809
|
+
return this;
|
|
829
810
|
}
|
|
830
|
-
|
|
811
|
+
/**
|
|
812
|
+
* Set the command description.
|
|
813
|
+
*/
|
|
814
|
+
setDescription(description) {
|
|
815
|
+
this.options.description = description;
|
|
816
|
+
return this;
|
|
831
817
|
}
|
|
818
|
+
// --- Overrides ---
|
|
819
|
+
/**
|
|
820
|
+
* Override setExecute to ensure handleExecution remains the entry point.
|
|
821
|
+
* This is the only base method we need to redefine.
|
|
822
|
+
*/
|
|
823
|
+
setExecute(fn) {
|
|
824
|
+
const originalExecute = fn;
|
|
825
|
+
this.options.execute = async (client, message) => {
|
|
826
|
+
return await this.handleExecution(client, message, originalExecute);
|
|
827
|
+
};
|
|
828
|
+
return this;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Converts the current builder state back into a config object.
|
|
832
|
+
*/
|
|
832
833
|
toConfig() {
|
|
833
834
|
return {
|
|
834
|
-
...
|
|
835
|
-
name: this.name,
|
|
836
|
-
description: this.description
|
|
835
|
+
...this.options
|
|
837
836
|
};
|
|
838
837
|
}
|
|
839
|
-
async executeCommand(client, message) {
|
|
840
|
-
try {
|
|
841
|
-
await this._runPreflight(client.config.prefixCommands, this.name, client, message);
|
|
842
|
-
await this._runCabinCheck(client.config.prefixCommands, client, message);
|
|
843
|
-
return this._runFlyAndLand(client.config.prefixCommands, client, message);
|
|
844
|
-
} catch (err) {
|
|
845
|
-
this.onError?.(err, client, message);
|
|
846
|
-
client.config.prefixCommands.onError?.(err, client, message);
|
|
847
|
-
throw err;
|
|
848
|
-
} finally {
|
|
849
|
-
if (client.config.prefixCommands.logExecution) {
|
|
850
|
-
client.logger.commandExecuted(this.name, message.author.username, message.guild?.name);
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
}
|
|
854
838
|
};
|
|
855
839
|
|
|
856
840
|
// src/builders/slashCommand.builder.ts
|
|
@@ -858,110 +842,81 @@ var import_discord3 = require("discord.js");
|
|
|
858
842
|
var import_lodash4 = __toESM(require("lodash"));
|
|
859
843
|
var SlashCommandBuilder = class extends BaseCommandBuilder {
|
|
860
844
|
builder;
|
|
861
|
-
deferReply;
|
|
862
|
-
deployment;
|
|
863
845
|
routes = /* @__PURE__ */ new Map();
|
|
864
|
-
onUnknownRouteHandler;
|
|
865
846
|
constructor(config) {
|
|
866
847
|
super(0 /* Slash */, config);
|
|
867
848
|
this.setBuilder(config.builder);
|
|
868
|
-
this.
|
|
869
|
-
|
|
870
|
-
this.
|
|
871
|
-
|
|
849
|
+
if (config.routes) this.addRoutes(...config.routes);
|
|
850
|
+
const originalExecute = this.options.execute;
|
|
851
|
+
this.options.execute = async (client, interaction) => {
|
|
852
|
+
return await this.handleExecution(client, interaction, originalExecute);
|
|
853
|
+
};
|
|
872
854
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
855
|
+
async handleExecution(client, interaction, originalExecute) {
|
|
856
|
+
const config = this.resolveConfig(client);
|
|
857
|
+
if (config.deferReply && !interaction.replied && !interaction.deferred) {
|
|
858
|
+
await interaction.deferReply(typeof config.deferReply === "object" ? config.deferReply : void 0);
|
|
876
859
|
}
|
|
877
|
-
|
|
878
|
-
|
|
860
|
+
const subCommand = interaction.options.getSubcommand(false);
|
|
861
|
+
if (subCommand) {
|
|
862
|
+
const handler = this.routes.get(subCommand.toLowerCase());
|
|
863
|
+
if (handler) return await handler(client, interaction);
|
|
864
|
+
if (config.onUnknownRouteHandler) return await config.onUnknownRouteHandler(client, interaction);
|
|
879
865
|
}
|
|
880
|
-
|
|
881
|
-
this.builder.toJSON();
|
|
882
|
-
} catch (err) {
|
|
883
|
-
throw new Error("VSlashCommandBuilder: Invalid command builder", { cause: err });
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
validateConfig() {
|
|
866
|
+
return await originalExecute?.(client, interaction);
|
|
887
867
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
deferReply: this.deferReply,
|
|
893
|
-
deployment: this.deployment,
|
|
894
|
-
routes: this.routes.size ? Array.from(this.routes.entries()).map(([k, v]) => ({ name: k, handler: v })) : void 0,
|
|
895
|
-
onUnknownRouteHandler: this.onUnknownRouteHandler
|
|
896
|
-
};
|
|
868
|
+
validateBuilder() {
|
|
869
|
+
if (!this.builder.name) throw new Error(`[Vimcord] SlashCommandBuilder: Command name is required.`);
|
|
870
|
+
if (!this.builder.description) throw new Error(`[Vimcord] SlashCommandBuilder: Command description is required.`);
|
|
871
|
+
this.builder.toJSON();
|
|
897
872
|
}
|
|
873
|
+
// --- Specialized Fluent API ---
|
|
898
874
|
setBuilder(builder) {
|
|
899
|
-
|
|
900
|
-
this.builder = builder(new import_discord3.SlashCommandBuilder());
|
|
901
|
-
} else {
|
|
902
|
-
this.builder = builder;
|
|
903
|
-
}
|
|
875
|
+
this.builder = typeof builder === "function" ? builder(new import_discord3.SlashCommandBuilder()) : builder;
|
|
904
876
|
this.validateBuilder();
|
|
905
877
|
return this;
|
|
906
878
|
}
|
|
907
879
|
setDeferReply(defer) {
|
|
908
|
-
this.deferReply = defer;
|
|
880
|
+
this.options.deferReply = defer;
|
|
909
881
|
return this;
|
|
910
882
|
}
|
|
911
883
|
setDeployment(deployment) {
|
|
912
|
-
this.deployment = import_lodash4.default.merge(this.deployment, deployment);
|
|
884
|
+
this.options.deployment = import_lodash4.default.merge(this.options.deployment || {}, deployment);
|
|
913
885
|
return this;
|
|
914
886
|
}
|
|
915
887
|
setRoutes(...routes) {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
this.routes.set(route.name.toLowerCase(), route.handler);
|
|
919
|
-
}
|
|
920
|
-
} else {
|
|
921
|
-
this.routes = /* @__PURE__ */ new Map();
|
|
922
|
-
}
|
|
888
|
+
this.routes.clear();
|
|
889
|
+
this.addRoutes(...routes);
|
|
923
890
|
return this;
|
|
924
891
|
}
|
|
925
892
|
addRoutes(...routes) {
|
|
893
|
+
if (!this.options.routes) this.options.routes = [];
|
|
926
894
|
for (const route of routes) {
|
|
927
|
-
|
|
895
|
+
const name = route.name.toLowerCase();
|
|
896
|
+
this.routes.set(name, route.handler);
|
|
897
|
+
const existingIndex = this.options.routes.findIndex((r) => r.name.toLowerCase() === name);
|
|
898
|
+
if (existingIndex > -1) this.options.routes[existingIndex] = route;
|
|
899
|
+
else this.options.routes.push(route);
|
|
928
900
|
}
|
|
929
901
|
return this;
|
|
930
902
|
}
|
|
931
903
|
setUnknownRouteHandler(handler) {
|
|
932
|
-
this.onUnknownRouteHandler = handler;
|
|
904
|
+
this.options.onUnknownRouteHandler = handler;
|
|
933
905
|
return this;
|
|
934
906
|
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
await this.
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
return result;
|
|
949
|
-
} else if (this.onUnknownRouteHandler) {
|
|
950
|
-
const result = await this.onUnknownRouteHandler?.(client, interaction);
|
|
951
|
-
await this.afterExecute?.(result, client, interaction);
|
|
952
|
-
return result;
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
return this._runFlyAndLand(client.config.slashCommands, client, interaction);
|
|
956
|
-
} catch (err) {
|
|
957
|
-
this.onError?.(err, client, interaction);
|
|
958
|
-
client.config.slashCommands.onError?.(err, client, interaction);
|
|
959
|
-
throw err;
|
|
960
|
-
} finally {
|
|
961
|
-
if (client.config.slashCommands.logExecution) {
|
|
962
|
-
client.logger.commandExecuted(this.builder.name, interaction.user.username, interaction.guild?.name);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
907
|
+
setExecute(fn) {
|
|
908
|
+
const originalExecute = fn;
|
|
909
|
+
this.options.execute = async (client, interaction) => {
|
|
910
|
+
return await this.handleExecution(client, interaction, originalExecute);
|
|
911
|
+
};
|
|
912
|
+
return this;
|
|
913
|
+
}
|
|
914
|
+
toConfig() {
|
|
915
|
+
return {
|
|
916
|
+
...this.options,
|
|
917
|
+
builder: this.builder,
|
|
918
|
+
routes: Array.from(this.routes.entries()).map(([name, handler]) => ({ name, handler }))
|
|
919
|
+
};
|
|
965
920
|
}
|
|
966
921
|
};
|
|
967
922
|
|
|
@@ -976,12 +931,19 @@ var globalVimcordToolsConfig = {
|
|
|
976
931
|
embedColor: [],
|
|
977
932
|
embedColorDev: [],
|
|
978
933
|
timeouts: {
|
|
934
|
+
collectorTimeout: 6e4,
|
|
935
|
+
collectorIdle: 6e4,
|
|
979
936
|
pagination: 6e4,
|
|
980
937
|
prompt: 3e4,
|
|
981
938
|
modalSubmit: 6e4
|
|
982
939
|
},
|
|
940
|
+
collector: {
|
|
941
|
+
notAParticipantMessage: "You are not allowed to use this.",
|
|
942
|
+
userLockMessage: "Please wait until your current action is finished.",
|
|
943
|
+
notAParticipantWarningCooldown: 5e3
|
|
944
|
+
},
|
|
983
945
|
paginator: {
|
|
984
|
-
notAParticipantMessage: "You are not allowed to use this
|
|
946
|
+
notAParticipantMessage: "You are not allowed to use this.",
|
|
985
947
|
jumpableThreshold: 5,
|
|
986
948
|
longThreshold: 4,
|
|
987
949
|
buttons: {
|
|
@@ -994,7 +956,7 @@ var globalVimcordToolsConfig = {
|
|
|
994
956
|
},
|
|
995
957
|
prompt: {
|
|
996
958
|
defaultTitle: "Are you sure?",
|
|
997
|
-
defaultDescription: "Make sure you know what you're doing
|
|
959
|
+
defaultDescription: "Make sure you know what you're doing.",
|
|
998
960
|
confirmLabel: "Confirm",
|
|
999
961
|
rejectLabel: "Cancel"
|
|
1000
962
|
}
|
|
@@ -1084,7 +1046,7 @@ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
|
1084
1046
|
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
1085
1047
|
return LogLevel2;
|
|
1086
1048
|
})(LogLevel || {});
|
|
1087
|
-
var
|
|
1049
|
+
var LOGGER_COLORS = {
|
|
1088
1050
|
primary: "#5865F2",
|
|
1089
1051
|
success: "#57F287",
|
|
1090
1052
|
warn: "#FEE75C",
|
|
@@ -1105,7 +1067,7 @@ var Logger = class {
|
|
|
1105
1067
|
this.minLevel = minLevel;
|
|
1106
1068
|
this.showTimestamp = showTimestamp;
|
|
1107
1069
|
this.colorScheme = {
|
|
1108
|
-
...
|
|
1070
|
+
...LOGGER_COLORS,
|
|
1109
1071
|
...options?.colors
|
|
1110
1072
|
};
|
|
1111
1073
|
}
|
|
@@ -1166,7 +1128,7 @@ var Logger = class {
|
|
|
1166
1128
|
}
|
|
1167
1129
|
setColors(colors) {
|
|
1168
1130
|
this.colorScheme = {
|
|
1169
|
-
...
|
|
1131
|
+
...LOGGER_COLORS,
|
|
1170
1132
|
...colors
|
|
1171
1133
|
};
|
|
1172
1134
|
return this;
|
|
@@ -1561,236 +1523,187 @@ var VimcordStatusManager = class {
|
|
|
1561
1523
|
|
|
1562
1524
|
// src/modules/command.manager.ts
|
|
1563
1525
|
var import_discord5 = require("discord.js");
|
|
1564
|
-
var
|
|
1565
|
-
|
|
1566
|
-
prefix;
|
|
1567
|
-
context;
|
|
1568
|
-
constructor(client) {
|
|
1569
|
-
this.slash = new VimcordSlashCommandManager(client);
|
|
1570
|
-
this.prefix = new VimcordPrefixCommandManager(client);
|
|
1571
|
-
this.context = new VimcordContextCommandManager(client);
|
|
1572
|
-
}
|
|
1573
|
-
};
|
|
1574
|
-
var VimcordSlashCommandManager = class {
|
|
1575
|
-
constructor(client) {
|
|
1526
|
+
var VimcordAppCommandManager = class {
|
|
1527
|
+
constructor(client, typeName) {
|
|
1576
1528
|
this.client = client;
|
|
1577
|
-
|
|
1529
|
+
this.typeName = typeName;
|
|
1530
|
+
this.client.whenReady().then((c) => this.rest = new import_discord5.REST().setToken(c.token));
|
|
1578
1531
|
}
|
|
1579
1532
|
commands = /* @__PURE__ */ new Map();
|
|
1580
1533
|
rest;
|
|
1581
1534
|
get(name) {
|
|
1582
1535
|
return this.commands.get(name);
|
|
1583
1536
|
}
|
|
1537
|
+
/**
|
|
1538
|
+
* Filters and returns commands based on deployment options
|
|
1539
|
+
*/
|
|
1584
1540
|
getAll(options) {
|
|
1585
1541
|
const matchedCommands = /* @__PURE__ */ new Map();
|
|
1542
|
+
const isDev = this.client.config.app.devMode;
|
|
1586
1543
|
for (const cmd of this.commands.values()) {
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
options.fuzzyNames?.some((fuzzyCommand) => cmd.builder.name.includes(fuzzyCommand))
|
|
1593
|
-
);
|
|
1594
|
-
if ((options.names || options.fuzzyNames) && !nameMatched) continue;
|
|
1595
|
-
const guildMatched = cmd.deployment?.guilds?.some((guildId) => options.guilds?.includes(guildId));
|
|
1596
|
-
if (options.guilds && !guildMatched) continue;
|
|
1597
|
-
matched = cmd;
|
|
1598
|
-
} else {
|
|
1599
|
-
matched = cmd;
|
|
1544
|
+
const config = cmd.toConfig();
|
|
1545
|
+
const name = cmd.builder.name;
|
|
1546
|
+
if (options?.names || options?.fuzzyNames) {
|
|
1547
|
+
const nameMatched = options.names?.includes(name) || options.fuzzyNames?.some((fuzzy) => name.includes(fuzzy));
|
|
1548
|
+
if (!nameMatched) continue;
|
|
1600
1549
|
}
|
|
1601
|
-
if (!matched) continue;
|
|
1602
1550
|
if (options?.ignoreDeploymentOptions) {
|
|
1603
|
-
|
|
1604
|
-
matchedCommands.set(matched.builder.name, matched);
|
|
1551
|
+
matchedCommands.set(name, cmd);
|
|
1605
1552
|
continue;
|
|
1606
1553
|
}
|
|
1607
|
-
const
|
|
1608
|
-
|
|
1609
|
-
);
|
|
1610
|
-
if (
|
|
1611
|
-
|
|
1612
|
-
}
|
|
1554
|
+
const deployment = config.deployment || {};
|
|
1555
|
+
const isProperEnv = !deployment.environments || deployment.environments.includes(isDev ? "development" : "production");
|
|
1556
|
+
if (!isProperEnv) continue;
|
|
1557
|
+
if (options?.globalOnly && deployment.global === false) continue;
|
|
1558
|
+
matchedCommands.set(name, cmd);
|
|
1613
1559
|
}
|
|
1614
1560
|
return matchedCommands;
|
|
1615
1561
|
}
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
this.
|
|
1562
|
+
async registerGlobal(options) {
|
|
1563
|
+
const client = await this.client.whenReady();
|
|
1564
|
+
const commands = Array.from(
|
|
1565
|
+
this.getAll({
|
|
1566
|
+
names: options?.commands,
|
|
1567
|
+
fuzzyNames: options?.fuzzyCommands,
|
|
1568
|
+
globalOnly: true
|
|
1569
|
+
}).values()
|
|
1570
|
+
).map((cmd) => cmd.builder.toJSON());
|
|
1571
|
+
if (!commands.length) {
|
|
1572
|
+
console.log(`[${this.typeName}] No commands to register`);
|
|
1573
|
+
return;
|
|
1620
1574
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
const isProperEnvironment = command.module.default.deployment?.environments?.includes(
|
|
1628
|
-
this.client.config.app.devMode ? "development" : "production"
|
|
1629
|
-
);
|
|
1630
|
-
if (isProperEnvironment ?? true) {
|
|
1631
|
-
this.commands.set(command.module.default.builder.name, command.module.default);
|
|
1632
|
-
importedCommands++;
|
|
1633
|
-
}
|
|
1575
|
+
console.log(`[${this.typeName}] Registering ${commands.length} commands globally...`);
|
|
1576
|
+
try {
|
|
1577
|
+
await this.rest.put(import_discord5.Routes.applicationCommands(client.user.id), { body: commands });
|
|
1578
|
+
console.log(`[${this.typeName}] \u2714 Registered app commands globally`);
|
|
1579
|
+
} catch (err) {
|
|
1580
|
+
console.log(`[${this.typeName}] \u2716 Failed to register app commands globally`, err);
|
|
1634
1581
|
}
|
|
1635
|
-
this.client.logger.moduleLoaded("Slash Commands", importedCommands);
|
|
1636
|
-
return this.commands;
|
|
1637
1582
|
}
|
|
1638
1583
|
async registerGuild(options) {
|
|
1639
1584
|
const client = await this.client.whenReady();
|
|
1640
|
-
const
|
|
1585
|
+
const commands = Array.from(
|
|
1641
1586
|
this.getAll({
|
|
1642
1587
|
names: options?.commands,
|
|
1643
1588
|
fuzzyNames: options?.fuzzyCommands
|
|
1644
1589
|
}).values()
|
|
1645
1590
|
).map((cmd) => cmd.builder.toJSON());
|
|
1646
|
-
if (!
|
|
1647
|
-
console.log(
|
|
1591
|
+
if (!commands.length) {
|
|
1592
|
+
console.log(`[${this.typeName}] No commands to register`);
|
|
1648
1593
|
return;
|
|
1649
1594
|
}
|
|
1650
|
-
const guildIds = options?.guilds || client.guilds.cache.map((
|
|
1651
|
-
console.log(
|
|
1652
|
-
`[SlashCommandManager] Registering ${commandsToRegister.length} app (/) ${commandsToRegister.length === 1 ? "command" : "commands"} for ${guildIds.length} ${guildIds.length === 1 ? "guild" : "guilds"}...`
|
|
1653
|
-
);
|
|
1595
|
+
const guildIds = options?.guilds || client.guilds.cache.map((g) => g.id);
|
|
1596
|
+
console.log(`[${this.typeName}] Registering ${commands.length} commands for ${guildIds.length} guilds...`);
|
|
1654
1597
|
await Promise.all(
|
|
1655
1598
|
guildIds.map(
|
|
1656
|
-
(guildId) => this.rest.put(import_discord5.Routes.applicationGuildCommands(client.user.id, guildId), {
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
)
|
|
1662
|
-
)
|
|
1663
|
-
(err) => console.log(
|
|
1664
|
-
`[SlashCommandManager] \u2716 Failed to set app (/) commands in guild: ${guildId} (${client.guilds.cache.find((g) => g.id === guildId)?.name || "n/a"})`,
|
|
1665
|
-
err
|
|
1666
|
-
)
|
|
1667
|
-
)
|
|
1599
|
+
(guildId) => this.rest.put(import_discord5.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
|
|
1600
|
+
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
1601
|
+
console.log(`[${this.typeName}] \u2714 Set app commands in guild: ${guildId} (${gName})`);
|
|
1602
|
+
}).catch((err) => {
|
|
1603
|
+
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
1604
|
+
console.log(`[${this.typeName}] \u2716 Failed to set app commands in guild: ${guildId} (${gName})`, err);
|
|
1605
|
+
})
|
|
1668
1606
|
)
|
|
1669
1607
|
);
|
|
1670
|
-
console.log(
|
|
1671
|
-
`[SlashCommandManager] \u2714 Finished registering app (/) commands for ${guildIds.length} ${guildIds.length === 1 ? "guild" : "guilds"}`
|
|
1672
|
-
);
|
|
1673
1608
|
}
|
|
1674
1609
|
async unregisterGuild(options) {
|
|
1675
1610
|
const client = await this.client.whenReady();
|
|
1676
|
-
const guildIds = options?.guilds || client.guilds.cache.map((
|
|
1677
|
-
console.log(
|
|
1678
|
-
`[SlashCommandManager] Unregistering app (/) commands from ${guildIds.length} ${guildIds.length === 1 ? "guild" : "guilds"}...`
|
|
1679
|
-
);
|
|
1611
|
+
const guildIds = options?.guilds || client.guilds.cache.map((g) => g.id);
|
|
1612
|
+
console.log(`[${this.typeName}] Unregistering commands from ${guildIds.length} guilds...`);
|
|
1680
1613
|
await Promise.all(
|
|
1681
1614
|
guildIds.map(
|
|
1682
|
-
(guildId) => this.rest.put(import_discord5.Routes.applicationGuildCommands(client.user.id, guildId), {
|
|
1683
|
-
|
|
1684
|
-
}).then(
|
|
1685
|
-
() => console.log(
|
|
1686
|
-
`[SlashCommandManager] \u2714 Removed app (/) commands in guild: ${guildId} (${client.guilds.cache.find((g) => g.id === guildId)?.name || "n/a"})`
|
|
1687
|
-
)
|
|
1688
|
-
).catch(
|
|
1689
|
-
(err) => console.log(
|
|
1690
|
-
`[SlashCommandManager] \u2716 Failed to remove app (/) commands in guild: ${guildId} (${client.guilds.cache.find((g) => g.id === guildId)?.name || "n/a"})`,
|
|
1691
|
-
err
|
|
1692
|
-
)
|
|
1615
|
+
(guildId) => this.rest.put(import_discord5.Routes.applicationGuildCommands(client.user.id, guildId), { body: [] }).then(() => console.log(`[${this.typeName}] \u2714 Removed app commands in guild: ${guildId}`)).catch(
|
|
1616
|
+
(err) => console.log(`[${this.typeName}] \u2716 Failed to remove app commands in guild: ${guildId}`, err)
|
|
1693
1617
|
)
|
|
1694
1618
|
)
|
|
1695
1619
|
);
|
|
1696
|
-
console.log(
|
|
1697
|
-
`[SlashCommandManager] \u2714 Finished unregistering app (/) commands for ${guildIds.length} ${guildIds.length === 1 ? "guild" : "guilds"}`
|
|
1698
|
-
);
|
|
1699
|
-
}
|
|
1700
|
-
async registerGlobal(options) {
|
|
1701
|
-
const client = await this.client.whenReady();
|
|
1702
|
-
const commandsToRegister = Array.from(
|
|
1703
|
-
this.getAll({
|
|
1704
|
-
names: options?.commands,
|
|
1705
|
-
fuzzyNames: options?.fuzzyCommands,
|
|
1706
|
-
globalOnly: true
|
|
1707
|
-
}).values()
|
|
1708
|
-
).map((cmd) => cmd.builder.toJSON());
|
|
1709
|
-
if (!commandsToRegister.length) {
|
|
1710
|
-
console.log("[SlashCommandManager] No commands to register");
|
|
1711
|
-
return;
|
|
1712
|
-
}
|
|
1713
|
-
console.log(
|
|
1714
|
-
`[SlashCommandManager] Registering ${commandsToRegister.length} app (/) ${commandsToRegister.length === 1 ? "command" : "commands"} globally...`
|
|
1715
|
-
);
|
|
1716
|
-
try {
|
|
1717
|
-
await this.rest.put(import_discord5.Routes.applicationCommands(client.user.id), { body: commandsToRegister });
|
|
1718
|
-
console.log("[SlashCommandManager] \u2714 Registered app (/) commands globally");
|
|
1719
|
-
} catch (err) {
|
|
1720
|
-
console.log("[SlashCommandManager] \u2716 Failed to register app (/) commands globally", err);
|
|
1721
|
-
}
|
|
1722
1620
|
}
|
|
1723
1621
|
async unregisterGlobal() {
|
|
1724
1622
|
const client = await this.client.whenReady();
|
|
1725
|
-
console.log("[SlashCommandManager] Unregistering app (/) commands globally...");
|
|
1726
1623
|
try {
|
|
1727
1624
|
await this.rest.put(import_discord5.Routes.applicationCommands(client.user.id), { body: [] });
|
|
1728
|
-
console.log(
|
|
1625
|
+
console.log(`[${this.typeName}] \u2714 Removed app commands globally`);
|
|
1729
1626
|
} catch (err) {
|
|
1730
|
-
console.log(
|
|
1627
|
+
console.log(`[${this.typeName}] \u2716 Failed to remove app commands globally`, err);
|
|
1731
1628
|
}
|
|
1732
1629
|
}
|
|
1733
1630
|
};
|
|
1734
|
-
var
|
|
1631
|
+
var VimcordSlashCommandManager = class extends VimcordAppCommandManager {
|
|
1735
1632
|
constructor(client) {
|
|
1736
|
-
|
|
1737
|
-
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
return Array.from(this.commands.values()).find((cmd) => cmd.aliases?.includes(alias));
|
|
1750
|
-
}
|
|
1751
|
-
return Array.from(this.commands.values()).find((cmd) => cmd.aliases?.includes(alias));
|
|
1633
|
+
super(client, "SlashCommandManager");
|
|
1634
|
+
}
|
|
1635
|
+
async importFrom(dir, replaceAll = false) {
|
|
1636
|
+
if (replaceAll) this.commands.clear();
|
|
1637
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1638
|
+
const modules = (await Promise.all(
|
|
1639
|
+
dirs.map((d) => importModulesFromDir(d, "slash"))
|
|
1640
|
+
)).flat();
|
|
1641
|
+
for (const { module: module2 } of modules) {
|
|
1642
|
+
this.commands.set(module2.default.builder.name, module2.default);
|
|
1643
|
+
}
|
|
1644
|
+
this.client.logger.moduleLoaded("Slash Commands", modules.length);
|
|
1645
|
+
return this.commands;
|
|
1752
1646
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
}
|
|
1767
|
-
this.client.logger.moduleLoaded("
|
|
1647
|
+
};
|
|
1648
|
+
var VimcordContextCommandManager = class extends VimcordAppCommandManager {
|
|
1649
|
+
constructor(client) {
|
|
1650
|
+
super(client, "ContextCommandManager");
|
|
1651
|
+
}
|
|
1652
|
+
async importFrom(dir, replaceAll = false) {
|
|
1653
|
+
if (replaceAll) this.commands.clear();
|
|
1654
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1655
|
+
const modules = (await Promise.all(
|
|
1656
|
+
dirs.map((d) => importModulesFromDir(d, "ctx"))
|
|
1657
|
+
)).flat();
|
|
1658
|
+
for (const { module: module2 } of modules) {
|
|
1659
|
+
this.commands.set(module2.default.builder.name, module2.default);
|
|
1660
|
+
}
|
|
1661
|
+
this.client.logger.moduleLoaded("Context Commands", modules.length);
|
|
1768
1662
|
return this.commands;
|
|
1769
1663
|
}
|
|
1770
1664
|
};
|
|
1771
|
-
var
|
|
1665
|
+
var VimcordPrefixCommandManager = class {
|
|
1772
1666
|
constructor(client) {
|
|
1773
1667
|
this.client = client;
|
|
1774
1668
|
}
|
|
1775
1669
|
commands = /* @__PURE__ */ new Map();
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1670
|
+
resolve(trigger) {
|
|
1671
|
+
const config = this.client.config.prefixCommands;
|
|
1672
|
+
const search = config.allowCaseInsensitiveCommandNames ? trigger.toLowerCase() : trigger;
|
|
1673
|
+
return Array.from(this.commands.values()).find((cmd) => {
|
|
1674
|
+
const opts = cmd.toConfig();
|
|
1675
|
+
const name = config.allowCaseInsensitiveCommandNames ? opts.name.toLowerCase() : opts.name;
|
|
1676
|
+
if (name === search) return true;
|
|
1677
|
+
return opts.aliases?.some(
|
|
1678
|
+
(a) => config.allowCaseInsensitiveCommandNames ? a.toLowerCase() === search : a === search
|
|
1679
|
+
);
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
async importFrom(dir, replaceAll = false) {
|
|
1683
|
+
if (replaceAll) this.commands.clear();
|
|
1684
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1685
|
+
const modules = (await Promise.all(
|
|
1686
|
+
dirs.map(
|
|
1687
|
+
(d) => importModulesFromDir(d, "prefix")
|
|
1688
|
+
)
|
|
1689
|
+
)).flat();
|
|
1690
|
+
for (const { module: module2 } of modules) {
|
|
1691
|
+
this.commands.set(module2.default.toConfig().name, module2.default);
|
|
1789
1692
|
}
|
|
1790
|
-
this.client.logger.moduleLoaded("
|
|
1693
|
+
this.client.logger.moduleLoaded("Prefix Commands", modules.length);
|
|
1791
1694
|
return this.commands;
|
|
1792
1695
|
}
|
|
1793
1696
|
};
|
|
1697
|
+
var VimcordCommandManager = class {
|
|
1698
|
+
slash;
|
|
1699
|
+
prefix;
|
|
1700
|
+
context;
|
|
1701
|
+
constructor(client) {
|
|
1702
|
+
this.slash = new VimcordSlashCommandManager(client);
|
|
1703
|
+
this.prefix = new VimcordPrefixCommandManager(client);
|
|
1704
|
+
this.context = new VimcordContextCommandManager(client);
|
|
1705
|
+
}
|
|
1706
|
+
};
|
|
1794
1707
|
|
|
1795
1708
|
// src/modules/event.manager.ts
|
|
1796
1709
|
var import_discord6 = require("discord.js");
|
|
@@ -2168,7 +2081,7 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
2168
2081
|
}
|
|
2169
2082
|
if (this.data.description) {
|
|
2170
2083
|
this.data.description = formatString(
|
|
2171
|
-
Array.isArray(this.data.description) ? this.data.description.join("\n") : this.data.description
|
|
2084
|
+
Array.isArray(this.data.description) ? this.data.description.filter((s) => s !== null && s !== void 0).join("\n") : this.data.description
|
|
2172
2085
|
);
|
|
2173
2086
|
}
|
|
2174
2087
|
if (this.data.footer && typeof this.data.footer === "object") {
|
|
@@ -2180,7 +2093,7 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
2180
2093
|
if (this.data.imageUrl) {
|
|
2181
2094
|
this.data.imageUrl = formatString(this.data.imageUrl);
|
|
2182
2095
|
}
|
|
2183
|
-
this.data.fields = this.data.fields.map((field) => ({
|
|
2096
|
+
this.data.fields = this.data.fields.filter(Boolean).map((field) => ({
|
|
2184
2097
|
...field,
|
|
2185
2098
|
name: formatString(field.name),
|
|
2186
2099
|
value: formatString(field.value)
|
|
@@ -2405,7 +2318,7 @@ async function retryExponentialBackoff(fn, maxRetries = 3, retryDelay = 1e3) {
|
|
|
2405
2318
|
}
|
|
2406
2319
|
|
|
2407
2320
|
// package.json
|
|
2408
|
-
var version = "1.0.
|
|
2321
|
+
var version = "1.0.1";
|
|
2409
2322
|
|
|
2410
2323
|
// src/client.ts
|
|
2411
2324
|
var import_node_crypto3 = require("crypto");
|
|
@@ -2671,62 +2584,63 @@ var Vimcord = class _Vimcord extends import_discord10.Client {
|
|
|
2671
2584
|
return fetchGuild(client, id);
|
|
2672
2585
|
}
|
|
2673
2586
|
};
|
|
2674
|
-
var defaultSlashCommandHandler = new EventBuilder({
|
|
2675
|
-
event: "interactionCreate",
|
|
2676
|
-
name: "SlashCommandHandler",
|
|
2677
|
-
async execute(client, interaction) {
|
|
2678
|
-
if (!interaction.isChatInputCommand()) return;
|
|
2679
|
-
const command = client.commands.slash.get(interaction.commandName);
|
|
2680
|
-
if (!command) {
|
|
2681
|
-
return interaction.reply({
|
|
2682
|
-
content: `**/\`${interaction.commandName}\`** is not a command`,
|
|
2683
|
-
flags: "Ephemeral"
|
|
2684
|
-
});
|
|
2685
|
-
}
|
|
2686
|
-
if (command.deferReply && !interaction.replied && !interaction.deferred) {
|
|
2687
|
-
await interaction.deferReply(typeof command.deferReply === "object" ? command.deferReply : void 0);
|
|
2688
|
-
}
|
|
2689
|
-
try {
|
|
2690
|
-
return command.executeCommand(client, interaction);
|
|
2691
|
-
} catch (err) {
|
|
2692
|
-
sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2693
|
-
throw err;
|
|
2694
|
-
}
|
|
2695
|
-
}
|
|
2696
|
-
});
|
|
2697
2587
|
var defaultPrefixCommandHandler = new EventBuilder({
|
|
2698
2588
|
event: "messageCreate",
|
|
2699
2589
|
name: "PrefixCommandHandler",
|
|
2700
2590
|
async execute(client, message) {
|
|
2701
|
-
if (message.author.bot) return;
|
|
2591
|
+
if (message.author.bot || !message.guild) return;
|
|
2592
|
+
const config = client.config.prefixCommands;
|
|
2593
|
+
let activePrefix = config.defaultPrefix;
|
|
2594
|
+
if (config.guildPrefixResolver) {
|
|
2595
|
+
try {
|
|
2596
|
+
const customPrefix = await config.guildPrefixResolver(client, message.guild.id);
|
|
2597
|
+
if (customPrefix) activePrefix = customPrefix;
|
|
2598
|
+
} catch (err) {
|
|
2599
|
+
client.logger.error(`Error in guildPrefixResolver for guild ${message.guild.id}:`, err);
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2702
2602
|
let prefixUsed;
|
|
2703
|
-
if (
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
}
|
|
2710
|
-
} else {
|
|
2711
|
-
return;
|
|
2603
|
+
if (message.content.startsWith(activePrefix)) {
|
|
2604
|
+
prefixUsed = activePrefix;
|
|
2605
|
+
} else if (config.allowMentionAsPrefix) {
|
|
2606
|
+
const mention = (0, import_discord10.userMention)(client.user.id);
|
|
2607
|
+
if (message.content.startsWith(mention)) {
|
|
2608
|
+
prefixUsed = message.content.startsWith(`${mention} `) ? `${mention} ` : mention;
|
|
2712
2609
|
}
|
|
2713
|
-
} else {
|
|
2714
|
-
prefixUsed = client.config.prefixCommands.defaultPrefix;
|
|
2715
2610
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2611
|
+
if (!prefixUsed) return;
|
|
2612
|
+
const contentWithoutPrefix = message.content.slice(prefixUsed.length).trim();
|
|
2613
|
+
const args = contentWithoutPrefix.split(/\s+/);
|
|
2614
|
+
const trigger = args.shift();
|
|
2615
|
+
if (!trigger) return;
|
|
2616
|
+
const command = client.commands.prefix.resolve(trigger);
|
|
2617
|
+
if (!command) return;
|
|
2618
|
+
message.content = args.join(" ");
|
|
2619
|
+
try {
|
|
2620
|
+
return await command.run(client, client, message);
|
|
2621
|
+
} catch (err) {
|
|
2622
|
+
await sendCommandErrorEmbed(client, err, message.guild, message);
|
|
2623
|
+
throw err;
|
|
2720
2624
|
}
|
|
2721
|
-
|
|
2625
|
+
}
|
|
2626
|
+
});
|
|
2627
|
+
var defaultSlashCommandHandler = new EventBuilder({
|
|
2628
|
+
event: "interactionCreate",
|
|
2629
|
+
name: "SlashCommandHandler",
|
|
2630
|
+
async execute(client, interaction) {
|
|
2631
|
+
if (!interaction.isChatInputCommand()) return;
|
|
2632
|
+
const command = client.commands.slash.get(interaction.commandName);
|
|
2722
2633
|
if (!command) {
|
|
2723
|
-
|
|
2634
|
+
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
2635
|
+
if (interaction.replied || interaction.deferred) {
|
|
2636
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
2637
|
+
}
|
|
2638
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
2724
2639
|
}
|
|
2725
|
-
message.content = message.content.slice(commandName.length + 1);
|
|
2726
2640
|
try {
|
|
2727
|
-
return command.
|
|
2641
|
+
return await command.run(client, client, interaction);
|
|
2728
2642
|
} catch (err) {
|
|
2729
|
-
sendCommandErrorEmbed(client, err,
|
|
2643
|
+
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2730
2644
|
throw err;
|
|
2731
2645
|
}
|
|
2732
2646
|
}
|
|
@@ -2734,9 +2648,22 @@ var defaultPrefixCommandHandler = new EventBuilder({
|
|
|
2734
2648
|
var defaultContextCommandHandler = new EventBuilder({
|
|
2735
2649
|
event: "interactionCreate",
|
|
2736
2650
|
name: "ContextCommandHandler",
|
|
2737
|
-
execute(client, interaction) {
|
|
2651
|
+
async execute(client, interaction) {
|
|
2738
2652
|
if (!interaction.isContextMenuCommand()) return;
|
|
2739
|
-
|
|
2653
|
+
const command = client.commands.context.get(interaction.commandName);
|
|
2654
|
+
if (!command) {
|
|
2655
|
+
const content = `**${interaction.commandName}** is not a registered context command.`;
|
|
2656
|
+
if (interaction.replied || interaction.deferred) {
|
|
2657
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
2658
|
+
}
|
|
2659
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
2660
|
+
}
|
|
2661
|
+
try {
|
|
2662
|
+
return await command.run(client, client, interaction);
|
|
2663
|
+
} catch (err) {
|
|
2664
|
+
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
2665
|
+
throw err;
|
|
2666
|
+
}
|
|
2740
2667
|
}
|
|
2741
2668
|
});
|
|
2742
2669
|
|
|
@@ -2751,8 +2678,8 @@ try {
|
|
|
2751
2678
|
}
|
|
2752
2679
|
var globalInstanceEmitter = new import_node_events2.default();
|
|
2753
2680
|
var instances = [];
|
|
2754
|
-
async function useMongoDatabase(
|
|
2755
|
-
const instance = instances.at(
|
|
2681
|
+
async function useMongoDatabase(instanceIndex) {
|
|
2682
|
+
const instance = instances.at(instanceIndex ?? 0);
|
|
2756
2683
|
if (!instance) {
|
|
2757
2684
|
return new Promise((resolve, reject) => {
|
|
2758
2685
|
const timeout = setTimeout(() => reject("useMongoDatabase timed out"), 45e3);
|
|
@@ -2764,6 +2691,15 @@ async function useMongoDatabase(index) {
|
|
|
2764
2691
|
}
|
|
2765
2692
|
return instance;
|
|
2766
2693
|
}
|
|
2694
|
+
async function useReadyMongoDatabase(instanceIndex) {
|
|
2695
|
+
const instance = await useMongoDatabase(instanceIndex);
|
|
2696
|
+
await instance.waitForReady();
|
|
2697
|
+
return instance;
|
|
2698
|
+
}
|
|
2699
|
+
async function createMongoSession(instanceIndex, options) {
|
|
2700
|
+
const instance = await useReadyMongoDatabase(instanceIndex);
|
|
2701
|
+
return instance.mongoose.startSession(options);
|
|
2702
|
+
}
|
|
2767
2703
|
var MongoDatabase = class {
|
|
2768
2704
|
constructor(client, options) {
|
|
2769
2705
|
this.client = client;
|
|
@@ -2918,6 +2854,7 @@ var MongoSchemaBuilder = class {
|
|
|
2918
2854
|
this.eventEmitter.off(event, listener);
|
|
2919
2855
|
return this;
|
|
2920
2856
|
}
|
|
2857
|
+
/** Execute a function while ensuring the connection is ready. On error it will retry using an exponential backoff. */
|
|
2921
2858
|
async execute(fn) {
|
|
2922
2859
|
try {
|
|
2923
2860
|
if (!this.isReady) {
|
|
@@ -2954,9 +2891,9 @@ var MongoSchemaBuilder = class {
|
|
|
2954
2891
|
return id;
|
|
2955
2892
|
});
|
|
2956
2893
|
}
|
|
2957
|
-
async count(filter) {
|
|
2894
|
+
async count(filter, options) {
|
|
2958
2895
|
return await this.execute(async () => {
|
|
2959
|
-
return this.model.countDocuments(filter);
|
|
2896
|
+
return this.model.countDocuments(filter, options);
|
|
2960
2897
|
});
|
|
2961
2898
|
}
|
|
2962
2899
|
async exists(filter) {
|
|
@@ -2964,29 +2901,29 @@ var MongoSchemaBuilder = class {
|
|
|
2964
2901
|
return await this.model.exists(filter) ? true : false;
|
|
2965
2902
|
});
|
|
2966
2903
|
}
|
|
2967
|
-
async create(query) {
|
|
2904
|
+
async create(query, options) {
|
|
2968
2905
|
return await this.execute(async () => {
|
|
2969
|
-
return this.model.create(query);
|
|
2970
|
-
});
|
|
2906
|
+
return this.model.create(query, options);
|
|
2907
|
+
}) ?? [];
|
|
2971
2908
|
}
|
|
2972
2909
|
async upsert(filter, query, options) {
|
|
2973
2910
|
return await this.execute(async () => {
|
|
2974
2911
|
return this.model.findOneAndUpdate(filter, query, { ...options, upsert: true, new: true });
|
|
2975
2912
|
});
|
|
2976
2913
|
}
|
|
2977
|
-
async delete(filter) {
|
|
2914
|
+
async delete(filter, options) {
|
|
2978
2915
|
return await this.execute(async () => {
|
|
2979
|
-
return this.model.deleteOne(filter);
|
|
2916
|
+
return this.model.deleteOne(filter, options);
|
|
2980
2917
|
});
|
|
2981
2918
|
}
|
|
2982
|
-
async deleteAll(filter) {
|
|
2919
|
+
async deleteAll(filter, options) {
|
|
2983
2920
|
return await this.execute(async () => {
|
|
2984
|
-
return this.model.deleteMany(filter);
|
|
2921
|
+
return this.model.deleteMany(filter, options);
|
|
2985
2922
|
});
|
|
2986
2923
|
}
|
|
2987
|
-
async distinct(key, filter) {
|
|
2924
|
+
async distinct(key, filter, options) {
|
|
2988
2925
|
return await this.execute(async () => {
|
|
2989
|
-
return this.model.distinct(key, filter);
|
|
2926
|
+
return this.model.distinct(key, filter, options);
|
|
2990
2927
|
});
|
|
2991
2928
|
}
|
|
2992
2929
|
async fetch(filter, projection, options) {
|
|
@@ -3017,6 +2954,215 @@ var MongoSchemaBuilder = class {
|
|
|
3017
2954
|
}
|
|
3018
2955
|
};
|
|
3019
2956
|
|
|
2957
|
+
// src/tools/BetterCollector.ts
|
|
2958
|
+
var CollectorTimeoutType = /* @__PURE__ */ ((CollectorTimeoutType2) => {
|
|
2959
|
+
CollectorTimeoutType2[CollectorTimeoutType2["DisableComponents"] = 0] = "DisableComponents";
|
|
2960
|
+
CollectorTimeoutType2[CollectorTimeoutType2["DeleteMessage"] = 1] = "DeleteMessage";
|
|
2961
|
+
CollectorTimeoutType2[CollectorTimeoutType2["DoNothing"] = 2] = "DoNothing";
|
|
2962
|
+
return CollectorTimeoutType2;
|
|
2963
|
+
})(CollectorTimeoutType || {});
|
|
2964
|
+
var BetterCollector = class _BetterCollector {
|
|
2965
|
+
message;
|
|
2966
|
+
collector;
|
|
2967
|
+
options;
|
|
2968
|
+
activeUsers = /* @__PURE__ */ new Set();
|
|
2969
|
+
participantWarningCooldowns = /* @__PURE__ */ new Map();
|
|
2970
|
+
config;
|
|
2971
|
+
events = {
|
|
2972
|
+
collectId: /* @__PURE__ */ new Map(),
|
|
2973
|
+
collect: [],
|
|
2974
|
+
end: [],
|
|
2975
|
+
timeout: []
|
|
2976
|
+
};
|
|
2977
|
+
static create(message, options) {
|
|
2978
|
+
return new _BetterCollector(message, options);
|
|
2979
|
+
}
|
|
2980
|
+
async validateParticipant(interaction, participants) {
|
|
2981
|
+
const allowedParticipants = participants || this.options?.participants || [];
|
|
2982
|
+
if (!allowedParticipants.length) return true;
|
|
2983
|
+
const isAllowed = allowedParticipants.some((user) => {
|
|
2984
|
+
if (typeof user === "string") return user === interaction.user.id;
|
|
2985
|
+
if (typeof user === "object" && "id" in user) return user.id === interaction.user.id;
|
|
2986
|
+
return false;
|
|
2987
|
+
});
|
|
2988
|
+
if (!isAllowed) {
|
|
2989
|
+
const now = Date.now();
|
|
2990
|
+
const lastWarned = this.participantWarningCooldowns.get(interaction.user.id) || 0;
|
|
2991
|
+
if (now - lastWarned > this.config.collector.notAParticipantWarningCooldown) {
|
|
2992
|
+
this.participantWarningCooldowns.set(interaction.user.id, now);
|
|
2993
|
+
if (this.config.collector.notAParticipantMessage) {
|
|
2994
|
+
await interaction.reply({
|
|
2995
|
+
content: this.config.collector.notAParticipantMessage,
|
|
2996
|
+
flags: "Ephemeral"
|
|
2997
|
+
}).catch(() => {
|
|
2998
|
+
});
|
|
2999
|
+
} else {
|
|
3000
|
+
await interaction.deferUpdate().catch(() => {
|
|
3001
|
+
});
|
|
3002
|
+
}
|
|
3003
|
+
} else {
|
|
3004
|
+
await interaction.deferUpdate().catch(() => {
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
return isAllowed;
|
|
3009
|
+
}
|
|
3010
|
+
build() {
|
|
3011
|
+
if (!this.message) return;
|
|
3012
|
+
if (this.collector) return;
|
|
3013
|
+
this.collector = this.message.createMessageComponentCollector({
|
|
3014
|
+
idle: this.options?.idle ?? this.config.timeouts.collectorIdle,
|
|
3015
|
+
time: this.options?.timeout ?? this.config.timeouts.collectorTimeout,
|
|
3016
|
+
componentType: this.options?.type,
|
|
3017
|
+
max: this.options?.max,
|
|
3018
|
+
maxComponents: this.options?.maxComponents,
|
|
3019
|
+
maxUsers: this.options?.maxUsers
|
|
3020
|
+
});
|
|
3021
|
+
this.setupListeners();
|
|
3022
|
+
}
|
|
3023
|
+
setupListeners() {
|
|
3024
|
+
if (!this.collector) return;
|
|
3025
|
+
this.collector.on("collect", async (interaction) => {
|
|
3026
|
+
if (this.options?.userLock && this.activeUsers.has(interaction.user.id)) {
|
|
3027
|
+
return interaction.reply({ content: this.config.collector.userLockMessage, flags: "Ephemeral" }).catch(() => {
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3030
|
+
if (this.options?.userLock) {
|
|
3031
|
+
this.activeUsers.add(interaction.user.id);
|
|
3032
|
+
}
|
|
3033
|
+
const globalListeners = this.events.collect;
|
|
3034
|
+
const idListeners = this.events.collectId.get(interaction.customId) || [];
|
|
3035
|
+
const allListeners = [...globalListeners, ...idListeners];
|
|
3036
|
+
const shouldBeDeferred = allListeners.find((l) => l.options?.defer)?.options?.defer;
|
|
3037
|
+
const validListeners = [];
|
|
3038
|
+
for (const listener of allListeners) {
|
|
3039
|
+
const isAllowed = await this.validateParticipant(interaction, listener.options?.participants);
|
|
3040
|
+
if (isAllowed) validListeners.push(listener);
|
|
3041
|
+
}
|
|
3042
|
+
if (validListeners.length === 0) return;
|
|
3043
|
+
try {
|
|
3044
|
+
if (shouldBeDeferred) {
|
|
3045
|
+
if (typeof shouldBeDeferred === "object") {
|
|
3046
|
+
if (shouldBeDeferred.update) {
|
|
3047
|
+
await interaction.deferUpdate().catch(Boolean);
|
|
3048
|
+
} else {
|
|
3049
|
+
await interaction.deferReply({ ephemeral: shouldBeDeferred.ephemeral }).catch(Boolean);
|
|
3050
|
+
}
|
|
3051
|
+
} else {
|
|
3052
|
+
await interaction.deferReply().catch(Boolean);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
if (this.options?.sequential) {
|
|
3056
|
+
for (const listener of allListeners) {
|
|
3057
|
+
try {
|
|
3058
|
+
const isAllowed = await this.validateParticipant(interaction, listener.options?.participants);
|
|
3059
|
+
if (!isAllowed) return;
|
|
3060
|
+
await listener.fn(interaction);
|
|
3061
|
+
} catch (err) {
|
|
3062
|
+
this.handleListenerError(err);
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
} else {
|
|
3066
|
+
Promise.all(
|
|
3067
|
+
allListeners.map((l) => {
|
|
3068
|
+
const isAllowed = this.validateParticipant(interaction, l.options?.participants);
|
|
3069
|
+
if (!isAllowed) return;
|
|
3070
|
+
return l.fn(interaction).catch(this.handleListenerError);
|
|
3071
|
+
})
|
|
3072
|
+
);
|
|
3073
|
+
}
|
|
3074
|
+
} finally {
|
|
3075
|
+
if (this.options?.userLock) {
|
|
3076
|
+
this.activeUsers.delete(interaction.user.id);
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
});
|
|
3080
|
+
this.collector.on("end", async (collected, reason) => {
|
|
3081
|
+
if (this.options?.sequential) {
|
|
3082
|
+
for (const listener of this.events.end) {
|
|
3083
|
+
try {
|
|
3084
|
+
await listener.fn(collected, reason);
|
|
3085
|
+
} catch (err) {
|
|
3086
|
+
this.handleListenerError(err);
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
} else {
|
|
3090
|
+
Promise.all(this.events.end.map((l) => l.fn(collected, reason).catch(this.handleListenerError)));
|
|
3091
|
+
}
|
|
3092
|
+
switch (this.options?.onTimeout) {
|
|
3093
|
+
case 0 /* DisableComponents */:
|
|
3094
|
+
if (!this.message?.editable) break;
|
|
3095
|
+
try {
|
|
3096
|
+
const disabledRows = this.message.components.map((row) => {
|
|
3097
|
+
const updatedRow = row.toJSON();
|
|
3098
|
+
if ("components" in updatedRow) {
|
|
3099
|
+
updatedRow.components = updatedRow.components.map((component) => ({
|
|
3100
|
+
...component,
|
|
3101
|
+
disabled: true
|
|
3102
|
+
}));
|
|
3103
|
+
}
|
|
3104
|
+
return updatedRow;
|
|
3105
|
+
});
|
|
3106
|
+
await this.message.edit({ components: disabledRows });
|
|
3107
|
+
} catch (err) {
|
|
3108
|
+
if (!(err instanceof Error && err.message.includes("Unknown Message"))) {
|
|
3109
|
+
this.handleListenerError(err);
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
break;
|
|
3113
|
+
case 1 /* DeleteMessage */:
|
|
3114
|
+
if (!this.message?.deletable) break;
|
|
3115
|
+
await this.message.delete().catch(Boolean);
|
|
3116
|
+
break;
|
|
3117
|
+
case 2 /* DoNothing */:
|
|
3118
|
+
default:
|
|
3119
|
+
break;
|
|
3120
|
+
}
|
|
3121
|
+
});
|
|
3122
|
+
}
|
|
3123
|
+
handleListenerError(err) {
|
|
3124
|
+
console.error("[BetterCollector] Listener Error:", err);
|
|
3125
|
+
}
|
|
3126
|
+
constructor(message, options) {
|
|
3127
|
+
this.config = options?.config || globalVimcordToolsConfig;
|
|
3128
|
+
this.message = message || void 0;
|
|
3129
|
+
this.options = options;
|
|
3130
|
+
this.build();
|
|
3131
|
+
}
|
|
3132
|
+
on(idOrFunc, fnOrOptions, options) {
|
|
3133
|
+
let finalFn;
|
|
3134
|
+
let finalOptions;
|
|
3135
|
+
let customId;
|
|
3136
|
+
if (typeof idOrFunc === "function") {
|
|
3137
|
+
finalFn = idOrFunc;
|
|
3138
|
+
finalOptions = fnOrOptions;
|
|
3139
|
+
} else {
|
|
3140
|
+
if (typeof fnOrOptions !== "function") {
|
|
3141
|
+
throw new Error("[BetterCollector] Second argument must be a function when a customId is provided.");
|
|
3142
|
+
}
|
|
3143
|
+
customId = idOrFunc;
|
|
3144
|
+
finalFn = fnOrOptions;
|
|
3145
|
+
finalOptions = options;
|
|
3146
|
+
}
|
|
3147
|
+
if (customId) {
|
|
3148
|
+
const listeners = this.events.collectId.get(customId) || [];
|
|
3149
|
+
listeners.push({ fn: finalFn, options: finalOptions });
|
|
3150
|
+
this.events.collectId.set(customId, listeners);
|
|
3151
|
+
} else {
|
|
3152
|
+
this.events.collect.push({ fn: finalFn, options: finalOptions });
|
|
3153
|
+
}
|
|
3154
|
+
return this;
|
|
3155
|
+
}
|
|
3156
|
+
onEnd(fn, options) {
|
|
3157
|
+
this.events.end.push({ fn, options });
|
|
3158
|
+
return this;
|
|
3159
|
+
}
|
|
3160
|
+
/** Manually stop the collector and trigger cleanup */
|
|
3161
|
+
stop(reason = "manual") {
|
|
3162
|
+
this.collector?.stop(reason);
|
|
3163
|
+
}
|
|
3164
|
+
};
|
|
3165
|
+
|
|
3020
3166
|
// src/tools/BetterContainer.ts
|
|
3021
3167
|
var import_discord11 = require("discord.js");
|
|
3022
3168
|
var BetterContainer = class {
|
|
@@ -3057,7 +3203,9 @@ var BetterContainer = class {
|
|
|
3057
3203
|
return this;
|
|
3058
3204
|
}
|
|
3059
3205
|
addText(text) {
|
|
3060
|
-
this.container.addTextDisplayComponents(
|
|
3206
|
+
this.container.addTextDisplayComponents(
|
|
3207
|
+
(tdb) => tdb.setContent(Array.isArray(text) ? text.filter((t) => t !== null && t !== void 0).join("\n") : text)
|
|
3208
|
+
);
|
|
3061
3209
|
return this;
|
|
3062
3210
|
}
|
|
3063
3211
|
addMedia(...media) {
|
|
@@ -3081,7 +3229,9 @@ var BetterContainer = class {
|
|
|
3081
3229
|
this.container.addSectionComponents((sb) => {
|
|
3082
3230
|
if (data.text) {
|
|
3083
3231
|
sb.addTextDisplayComponents(
|
|
3084
|
-
(tdb) => tdb.setContent(
|
|
3232
|
+
(tdb) => tdb.setContent(
|
|
3233
|
+
Array.isArray(data.text) ? data.text.filter((t) => t !== null && t !== void 0).join("\n") : data.text
|
|
3234
|
+
)
|
|
3085
3235
|
);
|
|
3086
3236
|
}
|
|
3087
3237
|
if (data.thumbnail) sb.setThumbnailAccessory(new import_discord11.ThumbnailBuilder(data.thumbnail));
|
|
@@ -3312,6 +3462,7 @@ var PaginationTimeoutType = /* @__PURE__ */ ((PaginationTimeoutType2) => {
|
|
|
3312
3462
|
PaginationTimeoutType2[PaginationTimeoutType2["DisableComponents"] = 0] = "DisableComponents";
|
|
3313
3463
|
PaginationTimeoutType2[PaginationTimeoutType2["ClearComponents"] = 1] = "ClearComponents";
|
|
3314
3464
|
PaginationTimeoutType2[PaginationTimeoutType2["DeleteMessage"] = 2] = "DeleteMessage";
|
|
3465
|
+
PaginationTimeoutType2[PaginationTimeoutType2["DoNothing"] = 3] = "DoNothing";
|
|
3315
3466
|
return PaginationTimeoutType2;
|
|
3316
3467
|
})(PaginationTimeoutType || {});
|
|
3317
3468
|
function wrapPositive(num, max) {
|
|
@@ -3392,7 +3543,8 @@ var Paginator = class {
|
|
|
3392
3543
|
last: [],
|
|
3393
3544
|
collect: [],
|
|
3394
3545
|
react: [],
|
|
3395
|
-
|
|
3546
|
+
preTimeout: [],
|
|
3547
|
+
postTimeout: []
|
|
3396
3548
|
};
|
|
3397
3549
|
if (this.options.pages.length) {
|
|
3398
3550
|
this.addChapter(this.options.pages, { label: "Default" });
|
|
@@ -3459,16 +3611,23 @@ var Paginator = class {
|
|
|
3459
3611
|
embeds: [],
|
|
3460
3612
|
components: [],
|
|
3461
3613
|
flags: [],
|
|
3614
|
+
files: [],
|
|
3615
|
+
// Explicitly empty to clear previous files on page switch
|
|
3462
3616
|
...options,
|
|
3463
3617
|
withResponse: true
|
|
3464
3618
|
};
|
|
3465
3619
|
const page = this.data.page.current;
|
|
3620
|
+
const currentChapter = this.chapters[this.data.page.index.chapter];
|
|
3621
|
+
const chapterFile = currentChapter?.files?.[this.data.page.index.nested];
|
|
3622
|
+
if (chapterFile) sendOptions.files.push(chapterFile);
|
|
3466
3623
|
if (Array.isArray(page)) {
|
|
3467
3624
|
sendOptions.embeds.push(...page);
|
|
3468
3625
|
} else if (typeof page === "string") {
|
|
3469
3626
|
sendOptions.content = page;
|
|
3470
3627
|
} else if (isEmbed(page)) {
|
|
3471
3628
|
sendOptions.embeds.push(page);
|
|
3629
|
+
} else if (page instanceof import_discord13.AttachmentBuilder) {
|
|
3630
|
+
sendOptions.files.push(page);
|
|
3472
3631
|
} else if (page instanceof import_discord13.ContainerBuilder || page instanceof BetterContainer) {
|
|
3473
3632
|
sendOptions.components.push(page);
|
|
3474
3633
|
if (!sendOptions.flags.includes("IsComponentsV2")) {
|
|
@@ -3480,7 +3639,7 @@ var Paginator = class {
|
|
|
3480
3639
|
}
|
|
3481
3640
|
async handlePostTimeout() {
|
|
3482
3641
|
if (!this.data.message) return;
|
|
3483
|
-
this.callEventStack("
|
|
3642
|
+
this.callEventStack("preTimeout", this.data.message);
|
|
3484
3643
|
this.data.collectors.component?.stop();
|
|
3485
3644
|
this.data.collectors.reaction?.stop();
|
|
3486
3645
|
switch (this.options.onTimeout) {
|
|
@@ -3524,7 +3683,10 @@ var Paginator = class {
|
|
|
3524
3683
|
case 2 /* DeleteMessage */:
|
|
3525
3684
|
await this.data.message.delete().catch(Boolean);
|
|
3526
3685
|
break;
|
|
3686
|
+
case 3 /* DoNothing */:
|
|
3687
|
+
break;
|
|
3527
3688
|
}
|
|
3689
|
+
this.callEventStack("postTimeout", this.data.message);
|
|
3528
3690
|
}
|
|
3529
3691
|
async nav_removeFromMessage() {
|
|
3530
3692
|
if (!this.data.message?.editable) return;
|
|
@@ -3571,35 +3733,43 @@ var Paginator = class {
|
|
|
3571
3733
|
await i.reply({ content: "Jump not implemented yet.", flags: "Ephemeral" });
|
|
3572
3734
|
return;
|
|
3573
3735
|
}
|
|
3574
|
-
await i.deferUpdate().catch(Boolean);
|
|
3575
3736
|
switch (i.customId) {
|
|
3576
3737
|
case "ssm_chapterSelect":
|
|
3738
|
+
await i.deferUpdate().catch(Boolean);
|
|
3577
3739
|
const chapterIndex = this.chapters.findIndex(
|
|
3578
3740
|
(c) => c.id === i.values[0]
|
|
3579
3741
|
);
|
|
3580
3742
|
await this.setPage(chapterIndex, 0);
|
|
3743
|
+
await this.refresh();
|
|
3581
3744
|
break;
|
|
3582
3745
|
case "btn_first":
|
|
3746
|
+
await i.deferUpdate().catch(Boolean);
|
|
3583
3747
|
this.callEventStack("first", this.data.page.current, this.data.page.index);
|
|
3584
3748
|
await this.setPage(this.data.page.index.chapter, 0);
|
|
3749
|
+
await this.refresh();
|
|
3585
3750
|
break;
|
|
3586
3751
|
case "btn_back":
|
|
3752
|
+
await i.deferUpdate().catch(Boolean);
|
|
3587
3753
|
this.callEventStack("back", this.data.page.current, this.data.page.index);
|
|
3588
3754
|
await this.setPage(this.data.page.index.chapter, this.data.page.index.nested - 1);
|
|
3755
|
+
await this.refresh();
|
|
3589
3756
|
break;
|
|
3590
3757
|
case "btn_next":
|
|
3758
|
+
await i.deferUpdate().catch(Boolean);
|
|
3591
3759
|
this.callEventStack("next", this.data.page.current, this.data.page.index);
|
|
3592
3760
|
await this.setPage(this.data.page.index.chapter, this.data.page.index.nested + 1);
|
|
3761
|
+
await this.refresh();
|
|
3593
3762
|
break;
|
|
3594
3763
|
case "btn_last":
|
|
3764
|
+
await i.deferUpdate().catch(Boolean);
|
|
3595
3765
|
this.callEventStack("last", this.data.page.current, this.data.page.index);
|
|
3596
3766
|
await this.setPage(
|
|
3597
3767
|
this.data.page.index.chapter,
|
|
3598
3768
|
this.chapters[this.data.page.index.chapter].pages.length - 1
|
|
3599
3769
|
);
|
|
3770
|
+
await this.refresh();
|
|
3600
3771
|
break;
|
|
3601
3772
|
}
|
|
3602
|
-
await this.refresh();
|
|
3603
3773
|
} catch (err) {
|
|
3604
3774
|
console.error("[Paginator] Component navigation error", err);
|
|
3605
3775
|
}
|
|
@@ -3639,7 +3809,7 @@ var Paginator = class {
|
|
|
3639
3809
|
data.value = `ssm_c:${this.chapters.length}`;
|
|
3640
3810
|
}
|
|
3641
3811
|
const normalizedPages = resolvePages(pages);
|
|
3642
|
-
this.chapters.push({ id: data.value, pages: normalizedPages });
|
|
3812
|
+
this.chapters.push({ id: data.value, pages: normalizedPages, files: data.files });
|
|
3643
3813
|
this.data.components.chapterSelect.addOptions(data);
|
|
3644
3814
|
return this;
|
|
3645
3815
|
}
|
|
@@ -4016,7 +4186,7 @@ CLI.addCommand("help", "View information about a command, or the available CLI o
|
|
|
4016
4186
|
}
|
|
4017
4187
|
CLI.logger.table("(help)", helpList);
|
|
4018
4188
|
});
|
|
4019
|
-
CLI.addCommand("register", "Register app commands globally, or per guild", async (args, content) => {
|
|
4189
|
+
CLI.addCommand("register", "Register app commands (slash & context) globally, or per guild", async (args, content) => {
|
|
4020
4190
|
const client = CLI.getClientInstance(content);
|
|
4021
4191
|
if (!client) return;
|
|
4022
4192
|
const mode = args[0]?.toLowerCase() || "";
|
|
@@ -4027,10 +4197,14 @@ CLI.addCommand("register", "Register app commands globally, or per guild", async
|
|
|
4027
4197
|
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4028
4198
|
switch (mode) {
|
|
4029
4199
|
case "guild":
|
|
4200
|
+
CLI.logger.info("Registering guild commands...");
|
|
4030
4201
|
await client.commands.slash.registerGuild({ guilds: guildIds });
|
|
4202
|
+
await client.commands.context.registerGuild({ guilds: guildIds });
|
|
4031
4203
|
break;
|
|
4032
4204
|
case "global":
|
|
4205
|
+
CLI.logger.info("Registering global commands...");
|
|
4033
4206
|
await client.commands.slash.registerGlobal();
|
|
4207
|
+
await client.commands.context.registerGlobal();
|
|
4034
4208
|
break;
|
|
4035
4209
|
}
|
|
4036
4210
|
});
|
|
@@ -4045,10 +4219,14 @@ CLI.addCommand("unregister", "Unregister app commands globally, or per guild", a
|
|
|
4045
4219
|
if (!guildIds.length) guildIds = client.guilds.cache.map((g) => g.id);
|
|
4046
4220
|
switch (mode) {
|
|
4047
4221
|
case "guild":
|
|
4222
|
+
CLI.logger.info("Unregistering guild commands...");
|
|
4048
4223
|
await client.commands.slash.unregisterGuild({ guilds: guildIds });
|
|
4224
|
+
await client.commands.context.unregisterGuild({ guilds: guildIds });
|
|
4049
4225
|
break;
|
|
4050
4226
|
case "global":
|
|
4227
|
+
CLI.logger.info("Unregistering global commands...");
|
|
4051
4228
|
await client.commands.slash.unregisterGlobal();
|
|
4229
|
+
await client.commands.context.unregisterGlobal();
|
|
4052
4230
|
break;
|
|
4053
4231
|
}
|
|
4054
4232
|
});
|
|
@@ -4063,46 +4241,48 @@ CLI.addCommand("stats", "View statistics about a client instance", (args, conten
|
|
|
4063
4241
|
"Memory Usage:": `${(process.memoryUsage().rss / 1024 / 1024).toFixed(2)} MB`
|
|
4064
4242
|
});
|
|
4065
4243
|
});
|
|
4066
|
-
CLI.addCommand("cmds", "List the loaded commands", (args, content) => {
|
|
4244
|
+
CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
4067
4245
|
const client = CLI.getClientInstance(content);
|
|
4068
4246
|
if (!client) return;
|
|
4069
|
-
const mode = args[0] || "slash";
|
|
4247
|
+
const mode = (args[0] || "slash").toLowerCase();
|
|
4070
4248
|
switch (mode) {
|
|
4071
|
-
case "slash":
|
|
4072
|
-
const
|
|
4073
|
-
|
|
4074
|
-
const
|
|
4075
|
-
for (const cmd of
|
|
4076
|
-
|
|
4249
|
+
case "slash": {
|
|
4250
|
+
const commands = Array.from(client.commands.slash.commands.values());
|
|
4251
|
+
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4252
|
+
const tableData = {};
|
|
4253
|
+
for (const cmd of commands) {
|
|
4254
|
+
tableData[`/${cmd.builder.name}`] = `~ ${cmd.builder.description || "No description"}`;
|
|
4077
4255
|
}
|
|
4078
|
-
return CLI.logger.table(
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
);
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4256
|
+
return CLI.logger.table(`(cmds) ~ slash (${import_jstools2.default.formatThousands(commands.length)})`, tableData);
|
|
4257
|
+
}
|
|
4258
|
+
case "prefix": {
|
|
4259
|
+
const commands = Array.from(client.commands.prefix.commands.values());
|
|
4260
|
+
commands.sort((a, b) => {
|
|
4261
|
+
const nameA = a.toConfig().name;
|
|
4262
|
+
const nameB = b.toConfig().name;
|
|
4263
|
+
return nameA.localeCompare(nameB);
|
|
4264
|
+
});
|
|
4265
|
+
const tableData = {};
|
|
4266
|
+
const defaultPrefix = client.config.prefixCommands.defaultPrefix;
|
|
4267
|
+
for (const cmd of commands) {
|
|
4268
|
+
const config = cmd.toConfig();
|
|
4269
|
+
const aliasIndicator = config.aliases?.length ? ` [${config.aliases.join(", ")}]` : "";
|
|
4270
|
+
tableData[`${defaultPrefix}${config.name}${aliasIndicator}`] = `~ ${config.description || "No description"}`;
|
|
4088
4271
|
}
|
|
4089
|
-
return CLI.logger.table(
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
);
|
|
4093
|
-
|
|
4094
|
-
const
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
contextCommands_f[`${cmd.builder.name}`] = "";
|
|
4272
|
+
return CLI.logger.table(`(cmds) ~ prefix (${import_jstools2.default.formatThousands(commands.length)})`, tableData);
|
|
4273
|
+
}
|
|
4274
|
+
case "ctx": {
|
|
4275
|
+
const commands = Array.from(client.commands.context.commands.values());
|
|
4276
|
+
commands.sort((a, b) => a.builder.name.localeCompare(b.builder.name));
|
|
4277
|
+
const tableData = {};
|
|
4278
|
+
for (const cmd of commands) {
|
|
4279
|
+
const type = cmd.builder.type === 2 ? "User" : "Msg";
|
|
4280
|
+
tableData[`[${type}] ${cmd.builder.name}`] = "";
|
|
4099
4281
|
}
|
|
4100
|
-
return CLI.logger.table(
|
|
4101
|
-
|
|
4102
|
-
contextCommands_f
|
|
4103
|
-
);
|
|
4282
|
+
return CLI.logger.table(`(cmds) ~ ctx (${import_jstools2.default.formatThousands(commands.length)})`, tableData);
|
|
4283
|
+
}
|
|
4104
4284
|
default:
|
|
4105
|
-
return CLI.logger.error(`'${mode}' is not a valid option.
|
|
4285
|
+
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
4106
4286
|
}
|
|
4107
4287
|
});
|
|
4108
4288
|
function initCLI() {
|
|
@@ -4129,14 +4309,17 @@ function getClientInstances() {
|
|
|
4129
4309
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4130
4310
|
0 && (module.exports = {
|
|
4131
4311
|
BaseCommandBuilder,
|
|
4312
|
+
BetterCollector,
|
|
4132
4313
|
BetterContainer,
|
|
4133
4314
|
BetterEmbed,
|
|
4134
4315
|
BetterModal,
|
|
4135
4316
|
CLI,
|
|
4317
|
+
CollectorTimeoutType,
|
|
4136
4318
|
CommandType,
|
|
4137
4319
|
ContextCommandBuilder,
|
|
4138
4320
|
DynaSend,
|
|
4139
4321
|
EventBuilder,
|
|
4322
|
+
LOGGER_COLORS,
|
|
4140
4323
|
LogLevel,
|
|
4141
4324
|
Logger,
|
|
4142
4325
|
MissingPermissionReason,
|
|
@@ -4165,6 +4348,7 @@ function getClientInstances() {
|
|
|
4165
4348
|
clientInstances,
|
|
4166
4349
|
createClient,
|
|
4167
4350
|
createMongoSchema,
|
|
4351
|
+
createMongoSession,
|
|
4168
4352
|
createToolsConfig,
|
|
4169
4353
|
createVimcordAppConfig,
|
|
4170
4354
|
createVimcordContextCommandConfig,
|
|
@@ -4198,6 +4382,7 @@ function getClientInstances() {
|
|
|
4198
4382
|
useClient,
|
|
4199
4383
|
useMongoDatabase,
|
|
4200
4384
|
useReadyClient,
|
|
4385
|
+
useReadyMongoDatabase,
|
|
4201
4386
|
validateCommandPermissions
|
|
4202
4387
|
});
|
|
4203
4388
|
//# sourceMappingURL=index.cjs.map
|