djs-next 1.0.0-dev.2 → 1.0.0-dev.3
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.
Potentially problematic release.
This version of djs-next might be problematic. Click here for more details.
- package/README.md +51 -29
- package/bin/create-djs-next.js +78 -0
- package/dist/index.d.mts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +578 -290
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +578 -280
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +213 -106
- package/src/index.ts +4 -1
- package/src/plugins/dnxt.ts +215 -176
- package/src/templates/cjs.ts +11 -6
- package/src/templates/esm.ts +11 -4
- package/src/templates/ts.ts +11 -5
- package/src/types.ts +21 -1
- package/src/utils/PaginationBuilder.ts +94 -0
- package/src/utils/paginate.ts +32 -13
- package/src/utils/prompts.ts +76 -0
- package/test_payload.js +3 -0
- package/test_reply.js +4 -0
- package/tsup.config.ts +1 -1
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -344
- package/dist/cli.js.map +0 -1
- package/dist/cli.mjs +0 -321
- package/dist/cli.mjs.map +0 -1
- package/src/cli.ts +0 -203
package/dist/index.js
CHANGED
|
@@ -32,6 +32,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
34
|
DJSNextClient: () => DJSNextClient,
|
|
35
|
+
PaginationBuilder: () => PaginationBuilder,
|
|
36
|
+
confirmPrompt: () => confirmPrompt,
|
|
35
37
|
defineConfig: () => defineConfig,
|
|
36
38
|
getLocalesCache: () => getLocalesCache,
|
|
37
39
|
loadConfig: () => loadConfig,
|
|
@@ -40,9 +42,10 @@ __export(index_exports, {
|
|
|
40
42
|
translate: () => translate
|
|
41
43
|
});
|
|
42
44
|
module.exports = __toCommonJS(index_exports);
|
|
45
|
+
var import_config = require("dotenv/config");
|
|
43
46
|
|
|
44
47
|
// src/client.ts
|
|
45
|
-
var
|
|
48
|
+
var import_discord4 = require("discord.js");
|
|
46
49
|
|
|
47
50
|
// src/handlers/commandHandler.ts
|
|
48
51
|
var import_discord = require("discord.js");
|
|
@@ -288,9 +291,9 @@ function loadLocales(localesDir, defaultLocale) {
|
|
|
288
291
|
for (const file of files) {
|
|
289
292
|
if (file.endsWith(".json")) {
|
|
290
293
|
const lang = file.replace(".json", "");
|
|
291
|
-
const
|
|
294
|
+
const content2 = import_fs7.default.readFileSync(import_path5.default.join(localesDir, file), "utf8");
|
|
292
295
|
try {
|
|
293
|
-
localesCache[lang] = JSON.parse(
|
|
296
|
+
localesCache[lang] = JSON.parse(content2);
|
|
294
297
|
} catch (e) {
|
|
295
298
|
console.error(`[djs-next] Failed to parse locale file: ${file}`, e);
|
|
296
299
|
}
|
|
@@ -324,26 +327,92 @@ function getLocalesCache() {
|
|
|
324
327
|
}
|
|
325
328
|
|
|
326
329
|
// src/plugins/dnxt.ts
|
|
330
|
+
var import_discord3 = require("discord.js");
|
|
327
331
|
var import_child_process = require("child_process");
|
|
328
332
|
var import_util = __toESM(require("util"));
|
|
329
333
|
var import_os = __toESM(require("os"));
|
|
330
334
|
var execAsync = import_util.default.promisify(import_child_process.exec);
|
|
331
|
-
|
|
335
|
+
function buildDisplayMessage(content2, color = 5397233) {
|
|
336
|
+
const djs = require("discord.js");
|
|
337
|
+
const container = new djs.ContainerBuilder().setAccentColor(color).addTextDisplayComponents(
|
|
338
|
+
new djs.TextDisplayBuilder().setContent(content2)
|
|
339
|
+
);
|
|
340
|
+
return { components: [container], flags: 32768 };
|
|
341
|
+
}
|
|
342
|
+
async function handleDNXT(message, client, devPrefix) {
|
|
332
343
|
if (message.author.bot) return;
|
|
333
|
-
if (!client
|
|
334
|
-
if (
|
|
335
|
-
const
|
|
344
|
+
if (!client._developers.includes(message.author.id)) return;
|
|
345
|
+
if (client.config?.devGuildId && message.guildId !== client.config.devGuildId) return;
|
|
346
|
+
const originalReply = message.reply.bind(message);
|
|
347
|
+
message.reply = (async (content2) => {
|
|
348
|
+
if (typeof content2 === "string") {
|
|
349
|
+
return await originalReply({ ...buildDisplayMessage(content2), allowedMentions: { repliedUser: false } });
|
|
350
|
+
}
|
|
351
|
+
if (!content2.allowedMentions) content2.allowedMentions = { repliedUser: false };
|
|
352
|
+
return await originalReply(content2);
|
|
353
|
+
});
|
|
354
|
+
const content = message.content.trim();
|
|
355
|
+
const validTriggers = [devPrefix];
|
|
356
|
+
const clientPrefixes = client._prefixes || [];
|
|
357
|
+
for (const p of clientPrefixes) {
|
|
358
|
+
if (p !== "") validTriggers.push(`${p}${devPrefix}`);
|
|
359
|
+
}
|
|
360
|
+
let matchedTrigger = validTriggers.find((t) => content === t || content.startsWith(`${t} `));
|
|
361
|
+
if (!matchedTrigger) return;
|
|
362
|
+
const args = content.slice(matchedTrigger.length).trim().split(/ +/g);
|
|
336
363
|
const command = args.shift()?.toLowerCase();
|
|
364
|
+
if (command === "help") {
|
|
365
|
+
const djs = require("discord.js");
|
|
366
|
+
const container = new djs.ContainerBuilder().setAccentColor(5397233).addTextDisplayComponents(
|
|
367
|
+
new djs.TextDisplayBuilder().setContent(`# \u{1F4D6} DNXT Toolkit Reference
|
|
368
|
+
> Current prefix trigger: \`${matchedTrigger}\``)
|
|
369
|
+
).addSeparatorComponents(new djs.SeparatorBuilder()).addTextDisplayComponents(
|
|
370
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F4CA} Core Framework
|
|
371
|
+
- \`${matchedTrigger}\` \u2014 Developer system dashboard
|
|
372
|
+
- \`${matchedTrigger} help\` \u2014 Shows this reference menu`),
|
|
373
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F4BB} Execution & Diagnostics
|
|
374
|
+
- \`${matchedTrigger} js <code>\` \u2014 Evaluates raw JS code
|
|
375
|
+
- \`${matchedTrigger} sh <cmd>\` \u2014 Runs terminal shell script
|
|
376
|
+
- \`${matchedTrigger} debug <code>\` \u2014 Evaluates JS with precise memory deltas`),
|
|
377
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F4C2} File System & Network
|
|
378
|
+
- \`${matchedTrigger} cat <file>\` \u2014 Reads file contents
|
|
379
|
+
- \`${matchedTrigger} curl <url>\` \u2014 Fetches remote URL data
|
|
380
|
+
- \`${matchedTrigger} git <cmd>\` \u2014 Executes git repository commands`),
|
|
381
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F9F0} Utilities
|
|
382
|
+
- \`${matchedTrigger} <load|unload|reload> <target>\` \u2014 Manages system modules
|
|
383
|
+
- \`${matchedTrigger} sync\` \u2014 Forces global slash command sync
|
|
384
|
+
- \`${matchedTrigger} in <channel> <cmd>\` \u2014 Executes command in target channel
|
|
385
|
+
- \`${matchedTrigger} restart\` \u2014 Restarts the bot completely
|
|
386
|
+
- \`${matchedTrigger} shutdown\` \u2014 Stops the bot completely`)
|
|
387
|
+
);
|
|
388
|
+
await message.reply({ components: [container], flags: 32768, allowedMentions: { repliedUser: false } });
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
337
391
|
if (!command) {
|
|
338
392
|
const mem = process.memoryUsage();
|
|
339
|
-
const discordJsVersion = require("discord.js/package.json").version;
|
|
340
393
|
const botPing = client.ws.ping;
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
394
|
+
const djs = require("discord.js");
|
|
395
|
+
const container = new djs.ContainerBuilder().setAccentColor(5397233).addTextDisplayComponents(
|
|
396
|
+
new djs.TextDisplayBuilder().setContent(`# \u{1F6E0}\uFE0F Developer System Dashboard
|
|
397
|
+
> **DNXT Framework Engine**`)
|
|
398
|
+
).addSeparatorComponents(new djs.SeparatorBuilder()).addTextDisplayComponents(
|
|
399
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F4E1} Network Status
|
|
400
|
+
- **System Uptime:** <t:${Math.floor((Date.now() - client.uptime) / 1e3)}:R>
|
|
401
|
+
- **WebSocket Latency:** \`${botPing}ms\``),
|
|
402
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F4E6} Host Environment
|
|
403
|
+
- **Discord.js Library:** \`v${import_discord3.version}\`
|
|
404
|
+
- **Node.js Runtime:** \`${process.version}\`
|
|
405
|
+
- **Operating System:** \`${import_os.default.type()}\` (\`${import_os.default.cpus().length}\` thread cores, \`${(import_os.default.uptime() / 60 / 60).toFixed(2)}\` hrs uptime)`),
|
|
406
|
+
new djs.TextDisplayBuilder().setContent(`### \u{1F9E0} Resource Utilization
|
|
407
|
+
- **Physical Memory:** \`${(mem.rss / 1024 / 1024).toFixed(2)} MB\`
|
|
408
|
+
- **Heap Allocated:** \`${(mem.heapUsed / 1024 / 1024).toFixed(2)} MB\``)
|
|
409
|
+
);
|
|
410
|
+
await message.reply({
|
|
411
|
+
components: [container],
|
|
412
|
+
flags: 32768,
|
|
413
|
+
// MessageFlags.IsComponentsV2
|
|
414
|
+
allowedMentions: { repliedUser: false }
|
|
415
|
+
});
|
|
347
416
|
return;
|
|
348
417
|
}
|
|
349
418
|
if (command === "js" || command === "eval" || command === "py") {
|
|
@@ -357,12 +426,12 @@ System: \`${import_os.default.cpus().length}\` thread(s), \`${(import_os.default
|
|
|
357
426
|
let evaled = await eval(`(async () => { ${code} })()`);
|
|
358
427
|
const end = process.hrtime.bigint();
|
|
359
428
|
const timeMs = Number(end - start) / 1e6;
|
|
360
|
-
if (typeof evaled !== "string") evaled = import_util.default.inspect(evaled, { depth: 1 });
|
|
429
|
+
if (typeof evaled !== "string") evaled = import_util.default.inspect(evaled, { depth: 1, colors: true });
|
|
361
430
|
await sendPaginatedText(message, `\u2705 **Evaluated in ${timeMs.toFixed(3)}ms**
|
|
362
|
-
`, evaled, "
|
|
431
|
+
`, evaled, "ansi");
|
|
363
432
|
} catch (err) {
|
|
364
433
|
await sendPaginatedText(message, `\u274C **Evaluation Error**
|
|
365
|
-
`, err.message, "
|
|
434
|
+
`, err.message, "ansi");
|
|
366
435
|
}
|
|
367
436
|
return;
|
|
368
437
|
}
|
|
@@ -371,52 +440,74 @@ System: \`${import_os.default.cpus().length}\` thread(s), \`${(import_os.default
|
|
|
371
440
|
if (!cmd) return void await message.reply("\u274C Please provide a command to execute.");
|
|
372
441
|
try {
|
|
373
442
|
const start2 = process.hrtime.bigint();
|
|
374
|
-
|
|
443
|
+
let stdout = "", stderr = "", code2 = 0;
|
|
444
|
+
try {
|
|
445
|
+
const result = await execAsync(cmd);
|
|
446
|
+
stdout = result.stdout;
|
|
447
|
+
stderr = result.stderr;
|
|
448
|
+
} catch (err) {
|
|
449
|
+
stdout = err.stdout || "";
|
|
450
|
+
stderr = err.stderr || err.message || "";
|
|
451
|
+
code2 = err.code || 1;
|
|
452
|
+
}
|
|
375
453
|
const end2 = process.hrtime.bigint();
|
|
376
454
|
const timeMs2 = Number(end2 - start2) / 1e6;
|
|
377
|
-
|
|
455
|
+
let resultText = `$ ${cmd}
|
|
456
|
+
`;
|
|
457
|
+
if (stdout) resultText += `${stdout}
|
|
458
|
+
`;
|
|
459
|
+
if (stderr) resultText += `${stderr}
|
|
460
|
+
`;
|
|
461
|
+
resultText += `
|
|
462
|
+
[status] Return code ${code2}`;
|
|
378
463
|
await sendPaginatedText(message, `\u2705 **Executed in ${timeMs2.toFixed(3)}ms**
|
|
379
|
-
`,
|
|
464
|
+
`, resultText, "ansi");
|
|
380
465
|
} catch (err) {
|
|
381
466
|
await sendPaginatedText(message, `\u274C **Shell Error**
|
|
382
|
-
`, err.message, "
|
|
467
|
+
`, err.message, "ansi");
|
|
383
468
|
}
|
|
384
469
|
return;
|
|
385
470
|
}
|
|
386
|
-
if (command === "
|
|
471
|
+
if (command === "load" || command === "unload" || command === "reload") {
|
|
387
472
|
const target = args[0]?.toLowerCase();
|
|
388
473
|
try {
|
|
389
474
|
if (target === "commands" && client["_commandsDir"]) {
|
|
390
|
-
client.commands.clear();
|
|
391
|
-
client.commands = await loadAndDeployCommands(client["_commandsDir"], client.token, client["_clientId"], client["_guildId"]);
|
|
392
|
-
await message.reply(
|
|
475
|
+
if (command === "unload" || command === "reload") client.commands.clear();
|
|
476
|
+
if (command === "load" || command === "reload") client.commands = await loadAndDeployCommands(client["_commandsDir"], client.token, client["_clientId"], client["_guildId"]);
|
|
477
|
+
await message.reply(`\u2705 Successfully ${command}ed commands.`);
|
|
393
478
|
} else if (target === "events" && client["_eventsDir"]) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
479
|
+
if (command === "unload" || command === "reload") {
|
|
480
|
+
client.removeAllListeners();
|
|
481
|
+
client["attachCoreListeners"]();
|
|
482
|
+
}
|
|
483
|
+
if (command === "load" || command === "reload") await loadEvents(client, client["_eventsDir"]);
|
|
484
|
+
await message.reply(`\u2705 Successfully ${command}ed events.`);
|
|
398
485
|
} else if (target === "components" && client["_componentsDir"]) {
|
|
399
|
-
client.components.clear();
|
|
400
|
-
client.components = await loadComponents(client["_componentsDir"]);
|
|
401
|
-
await message.reply(
|
|
486
|
+
if (command === "unload" || command === "reload") client.components.clear();
|
|
487
|
+
if (command === "load" || command === "reload") client.components = await loadComponents(client["_componentsDir"]);
|
|
488
|
+
await message.reply(`\u2705 Successfully ${command}ed components.`);
|
|
402
489
|
} else if (target === "locales" && client["_localesDir"]) {
|
|
403
|
-
loadLocales(client["_localesDir"], client.config.defaultLocale);
|
|
404
|
-
await message.reply(
|
|
490
|
+
if (command === "load" || command === "reload") loadLocales(client["_localesDir"], client.config.defaultLocale);
|
|
491
|
+
await message.reply(`\u2705 Successfully ${command}ed locales.`);
|
|
405
492
|
} else if (target === "all" || !target) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
if (
|
|
413
|
-
|
|
414
|
-
|
|
493
|
+
if (command === "unload" || command === "reload") {
|
|
494
|
+
client.removeAllListeners();
|
|
495
|
+
client["attachCoreListeners"]();
|
|
496
|
+
client.commands.clear();
|
|
497
|
+
client.components.clear();
|
|
498
|
+
}
|
|
499
|
+
if (command === "load" || command === "reload") {
|
|
500
|
+
if (client["_eventsDir"]) await loadEvents(client, client["_eventsDir"]);
|
|
501
|
+
if (client["_componentsDir"]) client.components = await loadComponents(client["_componentsDir"]);
|
|
502
|
+
if (client["_localesDir"]) loadLocales(client["_localesDir"], client.config.defaultLocale);
|
|
503
|
+
if (client["_commandsDir"]) client.commands = await loadAndDeployCommands(client["_commandsDir"], client.token, client["_clientId"], client["_guildId"]);
|
|
504
|
+
}
|
|
505
|
+
await message.reply(`\u2705 Successfully ${command}ed all framework modules.`);
|
|
415
506
|
} else {
|
|
416
507
|
await message.reply("\u274C Unknown target. Valid targets: `commands, events, components, locales, all`");
|
|
417
508
|
}
|
|
418
509
|
} catch (err) {
|
|
419
|
-
await message.reply(`\u274C
|
|
510
|
+
await message.reply(`\u274C **${command.toUpperCase()} Error:** ${err.message}`);
|
|
420
511
|
}
|
|
421
512
|
return;
|
|
422
513
|
}
|
|
@@ -426,49 +517,14 @@ System: \`${import_os.default.cpus().length}\` thread(s), \`${(import_os.default
|
|
|
426
517
|
const file = args.join(" ");
|
|
427
518
|
if (!file) return void await message.reply("\u274C Please provide a file to read.");
|
|
428
519
|
try {
|
|
429
|
-
const
|
|
520
|
+
const content2 = fs9.readFileSync(path7.resolve(process.cwd(), file), "utf8");
|
|
430
521
|
await sendPaginatedText(message, `\u{1F4C4} **${file}**
|
|
431
|
-
`,
|
|
522
|
+
`, content2, file.split(".").pop() || "");
|
|
432
523
|
} catch (e) {
|
|
433
524
|
await message.reply(`\u274C **Error reading file:** ${e.message}`);
|
|
434
525
|
}
|
|
435
526
|
return;
|
|
436
527
|
}
|
|
437
|
-
if (command === "su" || command === "sudo") {
|
|
438
|
-
const targetUserId = args.shift();
|
|
439
|
-
const cmd = args.join(" ");
|
|
440
|
-
if (!targetUserId || !cmd) return void await message.reply(`\u274C Usage: ${prefix} su <user_id> <command>`);
|
|
441
|
-
try {
|
|
442
|
-
const targetUser = await client.users.fetch(targetUserId.replace(/<@!?|>/g, ""));
|
|
443
|
-
if (!targetUser) throw new Error("User not found.");
|
|
444
|
-
const mockMessage = Object.assign(Object.create(Object.getPrototypeOf(message)), message);
|
|
445
|
-
mockMessage.author = targetUser;
|
|
446
|
-
if (message.guild) {
|
|
447
|
-
mockMessage.member = await message.guild.members.fetch(targetUser.id).catch(() => null);
|
|
448
|
-
}
|
|
449
|
-
mockMessage.content = cmd;
|
|
450
|
-
client.emit("messageCreate", mockMessage);
|
|
451
|
-
await message.reply(`\u2705 Invoked \`${cmd}\` as **${targetUser.tag}**.`);
|
|
452
|
-
} catch (e) {
|
|
453
|
-
await message.reply(`\u274C **Sudo Error:** ${e.message}`);
|
|
454
|
-
}
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
if (command === "source" || command === "src") {
|
|
458
|
-
const target = args.join(" ");
|
|
459
|
-
if (!target) return void await message.reply("\u274C Please provide a command name.");
|
|
460
|
-
const cmdData = client.commands.get(target);
|
|
461
|
-
if (!cmdData || !cmdData.filepath) return void await message.reply("\u274C Command not found or has no associated filepath.");
|
|
462
|
-
try {
|
|
463
|
-
const fs9 = await import("fs");
|
|
464
|
-
const content = fs9.readFileSync(cmdData.filepath, "utf8");
|
|
465
|
-
await sendPaginatedText(message, `\u{1F4C4} **Source of \`${target}\`**
|
|
466
|
-
`, content, cmdData.filepath.split(".").pop() || "");
|
|
467
|
-
} catch (e) {
|
|
468
|
-
await message.reply(`\u274C **Error reading source:** ${e.message}`);
|
|
469
|
-
}
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
528
|
if (command === "curl") {
|
|
473
529
|
const url = args[0];
|
|
474
530
|
if (!url) return void await message.reply("\u274C Please provide a URL.");
|
|
@@ -496,64 +552,38 @@ System: \`${import_os.default.cpus().length}\` thread(s), \`${(import_os.default
|
|
|
496
552
|
const endMem = process.memoryUsage().heapUsed;
|
|
497
553
|
const timeMs = Number(end - start) / 1e6;
|
|
498
554
|
const memDiff = (endMem - startMem) / 1024 / 1024;
|
|
499
|
-
if (typeof evaled !== "string") evaled = import_util.default.inspect(evaled, { depth: 1 });
|
|
555
|
+
if (typeof evaled !== "string") evaled = import_util.default.inspect(evaled, { depth: 1, colors: true });
|
|
500
556
|
await sendPaginatedText(message, `\u23F1\uFE0F **Debug Execution**
|
|
501
557
|
Time: \`${timeMs.toFixed(3)}ms\` | Heap Delta: \`${memDiff.toFixed(3)}MB\`
|
|
502
|
-
`, evaled, "
|
|
558
|
+
`, evaled, "ansi");
|
|
503
559
|
} catch (err) {
|
|
504
560
|
await sendPaginatedText(message, `\u274C **Debug Error**
|
|
505
|
-
`, err.message, "
|
|
561
|
+
`, err.message, "ansi");
|
|
506
562
|
}
|
|
507
563
|
return;
|
|
508
564
|
}
|
|
509
565
|
if (command === "in") {
|
|
510
566
|
const channelId = args.shift()?.replace(/<#|>/g, "");
|
|
511
567
|
const cmd = args.join(" ");
|
|
512
|
-
if (!channelId || !cmd) return void await message.reply(`\u274C Usage: ${
|
|
568
|
+
if (!channelId || !cmd) return void await message.reply(`\u274C Usage: ${matchedTrigger} in <#channel|id> <command>`);
|
|
513
569
|
try {
|
|
514
570
|
const targetChannel = await client.channels.fetch(channelId);
|
|
515
571
|
if (!targetChannel || !targetChannel.isTextBased()) throw new Error("Invalid Text Channel.");
|
|
516
572
|
const mockMessage = Object.assign(Object.create(Object.getPrototypeOf(message)), message);
|
|
517
|
-
mockMessage
|
|
518
|
-
|
|
519
|
-
|
|
573
|
+
Object.defineProperty(mockMessage, "client", { value: client, configurable: true });
|
|
574
|
+
if (message.guild) {
|
|
575
|
+
Object.defineProperty(mockMessage, "guild", { value: message.guild, configurable: true });
|
|
576
|
+
Object.defineProperty(mockMessage, "guildId", { value: message.guildId, configurable: true });
|
|
577
|
+
}
|
|
578
|
+
Object.defineProperty(mockMessage, "channel", { value: targetChannel, configurable: true });
|
|
579
|
+
Object.defineProperty(mockMessage, "channelId", { value: targetChannel.id, configurable: true });
|
|
580
|
+
Object.defineProperty(mockMessage, "content", { value: cmd, configurable: true });
|
|
520
581
|
client.emit("messageCreate", mockMessage);
|
|
521
|
-
await message.reply(`\u2705 Redirected execution to <#${targetChannel.id}>.`);
|
|
522
582
|
} catch (e) {
|
|
523
583
|
await message.reply(`\u274C **In Error:** ${e.message}`);
|
|
524
584
|
}
|
|
525
585
|
return;
|
|
526
586
|
}
|
|
527
|
-
if (command === "tasks") {
|
|
528
|
-
const tasks = client._activeTasks;
|
|
529
|
-
if (!tasks || tasks.size === 0) return void await message.reply("No active background tasks running.");
|
|
530
|
-
let text = `\u2699\uFE0F **Active Background Tasks (${tasks.size})**
|
|
531
|
-
`;
|
|
532
|
-
for (const [name] of tasks.entries()) {
|
|
533
|
-
text += `- \`${name.split("/").pop()}\`
|
|
534
|
-
`;
|
|
535
|
-
}
|
|
536
|
-
await sendPaginatedText(message, "", text, "");
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
if (command === "cancel") {
|
|
540
|
-
const target = args.join(" ");
|
|
541
|
-
if (!target) return void await message.reply(`\u274C Usage: ${prefix} cancel <task_name>`);
|
|
542
|
-
const tasks = client._activeTasks;
|
|
543
|
-
if (!tasks) return void await message.reply("No active tasks to cancel.");
|
|
544
|
-
let found = false;
|
|
545
|
-
for (const [name, intervalId] of tasks.entries()) {
|
|
546
|
-
if (name.includes(target)) {
|
|
547
|
-
clearInterval(intervalId);
|
|
548
|
-
tasks.delete(name);
|
|
549
|
-
found = true;
|
|
550
|
-
await message.reply(`\u2705 Cancelled background task: \`${name.split("/").pop()}\``);
|
|
551
|
-
break;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
if (!found) await message.reply("\u274C Task not found.");
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
587
|
if (command === "sync") {
|
|
558
588
|
try {
|
|
559
589
|
await message.reply("\u{1F504} Force syncing slash commands...");
|
|
@@ -564,85 +594,107 @@ Time: \`${timeMs.toFixed(3)}ms\` | Heap Delta: \`${memDiff.toFixed(3)}MB\`
|
|
|
564
594
|
}
|
|
565
595
|
return;
|
|
566
596
|
}
|
|
567
|
-
if (command === "
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
const inspect = import_util.default.inspect(res, { depth: 2 });
|
|
580
|
-
await sendPaginatedText(message, `\u{1F5C4}\uFE0F **SQL Query**
|
|
581
|
-
`, inspect, "js");
|
|
582
|
-
} catch (e) {
|
|
583
|
-
await message.reply(`\u274C **SQL Error:** ${e.message}`);
|
|
584
|
-
}
|
|
597
|
+
if (command === "restart") {
|
|
598
|
+
await message.reply("\u{1F504} Restarting framework...");
|
|
599
|
+
client.destroy();
|
|
600
|
+
const { spawn } = require("child_process");
|
|
601
|
+
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
602
|
+
detached: true,
|
|
603
|
+
stdio: "ignore",
|
|
604
|
+
cwd: process.cwd()
|
|
605
|
+
});
|
|
606
|
+
child.unref();
|
|
607
|
+
process.exit(0);
|
|
585
608
|
return;
|
|
586
609
|
}
|
|
587
|
-
if (command === "
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
const text = `\u{1F399}\uFE0F **Voice Debugger**
|
|
592
|
-
Channel: <#${me.voice.channel.id}> (\`${me.voice.channel.id}\`)
|
|
593
|
-
Muted: ${me.voice.mute} | Deafened: ${me.voice.deaf}
|
|
594
|
-
Session ID: \`${me.voice.sessionId || "None"}\``;
|
|
595
|
-
await message.reply(text);
|
|
610
|
+
if (command === "shutdown" || command === "stop") {
|
|
611
|
+
await message.reply("\u{1F6D1} Shutting down framework...");
|
|
612
|
+
client.destroy();
|
|
613
|
+
process.exit(0);
|
|
596
614
|
return;
|
|
597
615
|
}
|
|
598
|
-
await message.reply(`\u2753 Unknown ${
|
|
616
|
+
await message.reply(`\u2753 Unknown ${matchedTrigger} command. Available: \`js, sh, git, cat, curl, in, debug, reload, sync, restart, shutdown\``);
|
|
599
617
|
}
|
|
600
|
-
async function sendPaginatedText(message2, header,
|
|
601
|
-
const maxLength =
|
|
602
|
-
if (
|
|
603
|
-
await message2.reply(
|
|
604
|
-
|
|
605
|
-
|
|
618
|
+
async function sendPaginatedText(message2, header, content2, language = "") {
|
|
619
|
+
const maxLength = 800;
|
|
620
|
+
if (content2.length <= maxLength) {
|
|
621
|
+
await message2.reply(buildDisplayMessage(`### ${header.replace(/\\*\\*/g, "")}
|
|
622
|
+
\`\`\`${language}
|
|
623
|
+
${content2}
|
|
624
|
+
\`\`\``));
|
|
606
625
|
return;
|
|
607
626
|
}
|
|
608
627
|
const chunks = [];
|
|
609
|
-
for (let i = 0; i <
|
|
610
|
-
chunks.push(
|
|
628
|
+
for (let i = 0; i < content2.length; i += maxLength) {
|
|
629
|
+
chunks.push(content2.substring(i, i + maxLength));
|
|
611
630
|
}
|
|
612
631
|
let index = 0;
|
|
613
|
-
const
|
|
614
|
-
|
|
632
|
+
const djs = require("discord.js");
|
|
633
|
+
function buildPage(idx) {
|
|
634
|
+
const text = `### ${header.replace(/\\*\\*/g, "")}
|
|
635
|
+
\`\`\`${language}
|
|
636
|
+
${chunks[idx]}
|
|
615
637
|
\`\`\`
|
|
616
|
-
*Page 1 of ${chunks.length}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
638
|
+
> *Page ${idx + 1} of ${chunks.length}*`;
|
|
639
|
+
const container = new djs.ContainerBuilder().setAccentColor(5397233).addTextDisplayComponents(
|
|
640
|
+
new djs.TextDisplayBuilder().setContent(text)
|
|
641
|
+
);
|
|
642
|
+
const row1 = new djs.ActionRowBuilder().addComponents(
|
|
643
|
+
new djs.ButtonBuilder().setCustomId("first").setLabel("\u226A").setStyle(2),
|
|
644
|
+
new djs.ButtonBuilder().setCustomId("prev").setLabel("\uFF1C").setStyle(2),
|
|
645
|
+
new djs.ButtonBuilder().setCustomId("goto").setLabel("\u2398").setStyle(1),
|
|
646
|
+
new djs.ButtonBuilder().setCustomId("next").setLabel("\uFF1E").setStyle(2),
|
|
647
|
+
new djs.ButtonBuilder().setCustomId("last").setLabel("\u226B").setStyle(2)
|
|
648
|
+
);
|
|
649
|
+
const row2 = new djs.ActionRowBuilder().addComponents(
|
|
650
|
+
new djs.ButtonBuilder().setCustomId("stop").setLabel("\u2716 Close").setStyle(4)
|
|
651
|
+
);
|
|
652
|
+
container.addActionRowComponents(row1, row2);
|
|
653
|
+
return { components: [container], flags: 32768 };
|
|
654
|
+
}
|
|
655
|
+
const reply = await message2.reply(buildPage(index));
|
|
656
|
+
const collector = reply.createMessageComponentCollector({
|
|
657
|
+
filter: (i) => ["first", "prev", "goto", "stop", "next", "last"].includes(i.customId) && i.user.id === message2.author.id,
|
|
622
658
|
time: 12e4
|
|
623
659
|
});
|
|
624
|
-
collector.on("collect", async (
|
|
625
|
-
|
|
626
|
-
|
|
660
|
+
collector.on("collect", async (i) => {
|
|
661
|
+
if (i.customId === "first") {
|
|
662
|
+
index = 0;
|
|
663
|
+
} else if (i.customId === "prev") {
|
|
627
664
|
index = index > 0 ? index - 1 : index;
|
|
628
|
-
} else if (
|
|
665
|
+
} else if (i.customId === "next") {
|
|
629
666
|
index = index < chunks.length - 1 ? index + 1 : index;
|
|
630
|
-
} else if (
|
|
667
|
+
} else if (i.customId === "last") {
|
|
668
|
+
index = chunks.length - 1;
|
|
669
|
+
} else if (i.customId === "goto") {
|
|
670
|
+
const modal = new djs.ModalBuilder().setCustomId("goto_modal").setTitle("Go to Page");
|
|
671
|
+
const input = new djs.TextInputBuilder().setCustomId("page_num").setLabel(`Page Number (1-${chunks.length})`).setStyle(1).setRequired(true);
|
|
672
|
+
modal.addComponents(new djs.ActionRowBuilder().addComponents(input));
|
|
673
|
+
await i.showModal(modal);
|
|
674
|
+
try {
|
|
675
|
+
const modalSubmit = await i.awaitModalSubmit({ filter: (mi) => mi.user.id === message2.author.id && mi.customId === "goto_modal", time: 6e4 });
|
|
676
|
+
const targetPage = parseInt(modalSubmit.fields.getTextInputValue("page_num"), 10);
|
|
677
|
+
if (!isNaN(targetPage) && targetPage >= 1 && targetPage <= chunks.length) {
|
|
678
|
+
index = targetPage - 1;
|
|
679
|
+
}
|
|
680
|
+
await modalSubmit.update(buildPage(index));
|
|
681
|
+
} catch {
|
|
682
|
+
}
|
|
683
|
+
return;
|
|
684
|
+
} else if (i.customId === "stop") {
|
|
685
|
+
await reply.delete().catch(() => null);
|
|
631
686
|
collector.stop();
|
|
632
687
|
return;
|
|
633
688
|
}
|
|
634
|
-
await
|
|
635
|
-
${chunks[index]}
|
|
636
|
-
\`\`\`
|
|
637
|
-
*Page ${index + 1} of ${chunks.length}*`);
|
|
689
|
+
await i.update(buildPage(index));
|
|
638
690
|
});
|
|
639
691
|
collector.on("end", () => {
|
|
640
|
-
reply.
|
|
692
|
+
reply.edit({ components: [] }).catch(() => null);
|
|
641
693
|
});
|
|
642
694
|
}
|
|
643
695
|
|
|
644
696
|
// src/client.ts
|
|
645
|
-
var DJSNextClient = class extends
|
|
697
|
+
var DJSNextClient = class extends import_discord4.Client {
|
|
646
698
|
commands;
|
|
647
699
|
components;
|
|
648
700
|
cooldowns;
|
|
@@ -659,12 +711,15 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
659
711
|
_developers;
|
|
660
712
|
_middleware;
|
|
661
713
|
_prefixes;
|
|
714
|
+
_enableSlashCommands;
|
|
715
|
+
_enableTextCommands;
|
|
662
716
|
_enableMentionPrefix;
|
|
717
|
+
_enableNoPrefix;
|
|
663
718
|
constructor(options) {
|
|
664
719
|
super(options);
|
|
665
|
-
this.commands = new
|
|
666
|
-
this.components = new
|
|
667
|
-
this.cooldowns = new
|
|
720
|
+
this.commands = new import_discord4.Collection();
|
|
721
|
+
this.components = new import_discord4.Collection();
|
|
722
|
+
this.cooldowns = new import_discord4.Collection();
|
|
668
723
|
this._commandsDir = options.commandsDir ? import_path6.default.resolve(process.cwd(), options.commandsDir) : void 0;
|
|
669
724
|
this._eventsDir = options.eventsDir ? import_path6.default.resolve(process.cwd(), options.eventsDir) : void 0;
|
|
670
725
|
this._componentsDir = options.componentsDir ? import_path6.default.resolve(process.cwd(), options.componentsDir) : void 0;
|
|
@@ -675,7 +730,12 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
675
730
|
this._middleware = options.middleware;
|
|
676
731
|
const prefs = options.prefixes || [];
|
|
677
732
|
this._prefixes = Array.isArray(prefs) ? prefs : [prefs];
|
|
733
|
+
this._prefixes = this._prefixes.filter((p) => p !== "");
|
|
734
|
+
this._enableSlashCommands = options.enableSlashCommands ?? true;
|
|
735
|
+
this._enableTextCommands = options.enableTextCommands ?? true;
|
|
678
736
|
this._enableMentionPrefix = options.enableMentionPrefix ?? true;
|
|
737
|
+
this._enableNoPrefix = options.enableNoPrefix ?? false;
|
|
738
|
+
if (options.db) this.db = options.db;
|
|
679
739
|
this.attachCoreListeners();
|
|
680
740
|
}
|
|
681
741
|
attachCoreListeners() {
|
|
@@ -690,6 +750,7 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
690
750
|
}
|
|
691
751
|
}
|
|
692
752
|
if (interaction.isChatInputCommand()) {
|
|
753
|
+
if (!this._enableSlashCommands) return;
|
|
693
754
|
let commandKey = interaction.commandName;
|
|
694
755
|
const group = interaction.options.getSubcommandGroup(false);
|
|
695
756
|
const sub = interaction.options.getSubcommand(false);
|
|
@@ -697,48 +758,11 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
697
758
|
if (sub) commandKey += ` ${sub}`;
|
|
698
759
|
const command2 = this.commands.get(commandKey);
|
|
699
760
|
if (!command2 || !command2.execute) return;
|
|
700
|
-
if (
|
|
701
|
-
return interaction.reply({ content: "Only developers can use this command.", ephemeral: true });
|
|
702
|
-
}
|
|
703
|
-
if (command2.guildOnly && !interaction.inGuild()) {
|
|
704
|
-
return interaction.reply({ content: "This command can only be used in a server.", ephemeral: true });
|
|
705
|
-
}
|
|
706
|
-
if (command2.userPermissions && interaction.memberPermissions) {
|
|
707
|
-
const missing = interaction.memberPermissions.missing(command2.userPermissions);
|
|
708
|
-
if (missing.length > 0) {
|
|
709
|
-
return interaction.reply({ content: `You are missing permissions: \`${missing.join(", ")}\``, ephemeral: true });
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
if (command2.botPermissions && interaction.guild?.members.me?.permissions) {
|
|
713
|
-
const missing = interaction.guild.members.me.permissions.missing(command2.botPermissions);
|
|
714
|
-
if (missing.length > 0) {
|
|
715
|
-
return interaction.reply({ content: `I am missing permissions to run this: \`${missing.join(", ")}\``, ephemeral: true });
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
if (command2.cooldown) {
|
|
719
|
-
if (!this.cooldowns.has(commandKey)) this.cooldowns.set(commandKey, new import_discord3.Collection());
|
|
720
|
-
const now = Date.now();
|
|
721
|
-
const timestamps = this.cooldowns.get(commandKey);
|
|
722
|
-
const cooldownAmount = command2.cooldown * 1e3;
|
|
723
|
-
if (timestamps.has(interaction.user.id)) {
|
|
724
|
-
const expirationTime = timestamps.get(interaction.user.id) + cooldownAmount;
|
|
725
|
-
if (now < expirationTime) {
|
|
726
|
-
return interaction.reply({
|
|
727
|
-
content: `Please wait, you are on a cooldown. You can use it again <t:${Math.round(expirationTime / 1e3)}:R>.`,
|
|
728
|
-
ephemeral: true
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
timestamps.set(interaction.user.id, now);
|
|
733
|
-
setTimeout(() => timestamps.delete(interaction.user.id), cooldownAmount);
|
|
734
|
-
}
|
|
761
|
+
if (!await this.handlePreconditions(command2, interaction, commandKey)) return;
|
|
735
762
|
try {
|
|
736
763
|
await command2.execute(interaction, this);
|
|
737
764
|
} catch (error) {
|
|
738
|
-
|
|
739
|
-
const msg = { content: "We ran into an internal error executing this command. The developers have been notified.", ephemeral: true };
|
|
740
|
-
if (interaction.replied || interaction.deferred) await interaction.followUp(msg).catch(() => null);
|
|
741
|
-
else await interaction.reply(msg).catch(() => null);
|
|
765
|
+
await this.handleCommandError(error, commandKey, interaction);
|
|
742
766
|
}
|
|
743
767
|
}
|
|
744
768
|
if (interaction.isAutocomplete()) {
|
|
@@ -774,19 +798,18 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
774
798
|
}
|
|
775
799
|
}
|
|
776
800
|
if (component) {
|
|
801
|
+
if (!await this.handlePreconditions(component, interaction, interaction.customId)) return;
|
|
777
802
|
try {
|
|
778
803
|
await component.execute(interaction, this, params);
|
|
779
804
|
} catch (error) {
|
|
780
|
-
|
|
781
|
-
const msg = { content: "We ran into an internal error executing this component.", ephemeral: true };
|
|
782
|
-
if (interaction.replied || interaction.deferred) await interaction.followUp(msg).catch(() => null);
|
|
783
|
-
else await interaction.reply(msg).catch(() => null);
|
|
805
|
+
await this.handleCommandError(error, interaction.customId, interaction);
|
|
784
806
|
}
|
|
785
807
|
}
|
|
786
808
|
}
|
|
787
809
|
});
|
|
788
810
|
this.on("messageCreate", async (message2) => {
|
|
789
811
|
if (message2.author.bot) return;
|
|
812
|
+
if (!this._enableTextCommands) return;
|
|
790
813
|
if (this._middleware) {
|
|
791
814
|
try {
|
|
792
815
|
const shouldContinue = await this._middleware(message2, this);
|
|
@@ -796,28 +819,31 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
796
819
|
return;
|
|
797
820
|
}
|
|
798
821
|
}
|
|
799
|
-
let
|
|
822
|
+
let content2 = message2.content.trim();
|
|
800
823
|
let matchedPrefix = "";
|
|
801
824
|
let isCommand = false;
|
|
802
825
|
const mentionRegex = new RegExp(`^<@!?${this.user?.id}>\\s*`);
|
|
803
|
-
|
|
804
|
-
|
|
826
|
+
const canUseMention = this._enableMentionPrefix === true || Array.isArray(this._enableMentionPrefix) && this._enableMentionPrefix.includes(message2.author.id);
|
|
827
|
+
if (canUseMention && mentionRegex.test(content2)) {
|
|
828
|
+
matchedPrefix = content2.match(mentionRegex)[0];
|
|
805
829
|
isCommand = true;
|
|
806
830
|
} else {
|
|
807
831
|
const sortedPrefs = [...this._prefixes].sort((a, b) => b.length - a.length);
|
|
808
|
-
if (sortedPrefs.includes("")) {
|
|
809
|
-
isCommand = true;
|
|
810
|
-
}
|
|
811
832
|
for (const p of sortedPrefs) {
|
|
812
|
-
if (
|
|
833
|
+
if (content2.startsWith(p)) {
|
|
813
834
|
matchedPrefix = p;
|
|
814
835
|
isCommand = true;
|
|
815
836
|
break;
|
|
816
837
|
}
|
|
817
838
|
}
|
|
839
|
+
const canUseNoPrefix = this._enableNoPrefix === true || Array.isArray(this._enableNoPrefix) && this._enableNoPrefix.includes(message2.author.id);
|
|
840
|
+
if (!isCommand && canUseNoPrefix) {
|
|
841
|
+
isCommand = true;
|
|
842
|
+
matchedPrefix = "";
|
|
843
|
+
}
|
|
818
844
|
}
|
|
819
845
|
if (!isCommand) return;
|
|
820
|
-
const args2 =
|
|
846
|
+
const args2 = content2.slice(matchedPrefix.length).trim().split(/ +/g);
|
|
821
847
|
const commandName = args2.shift()?.toLowerCase();
|
|
822
848
|
if (!commandName) return;
|
|
823
849
|
let command2 = this.commands.get(commandName);
|
|
@@ -825,35 +851,11 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
825
851
|
command2 = this.commands.find((c) => c.aliases?.includes(commandName) || false);
|
|
826
852
|
}
|
|
827
853
|
if (!command2 || !command2.executeText) return;
|
|
828
|
-
if (
|
|
829
|
-
if (command2.guildOnly && !message2.guild) return;
|
|
830
|
-
if (command2.userPermissions && message2.member?.permissions) {
|
|
831
|
-
const missing = message2.member.permissions.missing(command2.userPermissions);
|
|
832
|
-
if (missing.length > 0) return;
|
|
833
|
-
}
|
|
834
|
-
if (command2.botPermissions && message2.guild?.members.me?.permissions) {
|
|
835
|
-
const missing = message2.guild.members.me.permissions.missing(command2.botPermissions);
|
|
836
|
-
if (missing.length > 0) return;
|
|
837
|
-
}
|
|
838
|
-
if (command2.cooldown) {
|
|
839
|
-
if (!this.cooldowns.has(commandName)) this.cooldowns.set(commandName, new import_discord3.Collection());
|
|
840
|
-
const now = Date.now();
|
|
841
|
-
const timestamps = this.cooldowns.get(commandName);
|
|
842
|
-
const cooldownAmount = command2.cooldown * 1e3;
|
|
843
|
-
if (timestamps.has(message2.author.id)) {
|
|
844
|
-
const expirationTime = timestamps.get(message2.author.id) + cooldownAmount;
|
|
845
|
-
if (now < expirationTime) {
|
|
846
|
-
return void await message2.reply(`Please wait, you are on a cooldown. You can use it again <t:${Math.round(expirationTime / 1e3)}:R>.`);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
timestamps.set(message2.author.id, now);
|
|
850
|
-
setTimeout(() => timestamps.delete(message2.author.id), cooldownAmount);
|
|
851
|
-
}
|
|
854
|
+
if (!await this.handlePreconditions(command2, message2, commandName)) return;
|
|
852
855
|
try {
|
|
853
856
|
await command2.executeText(message2, args2, this);
|
|
854
857
|
} catch (error) {
|
|
855
|
-
|
|
856
|
-
await message2.reply("We ran into an internal error executing this command.").catch(() => null);
|
|
858
|
+
await this.handleCommandError(error, commandName, message2);
|
|
857
859
|
}
|
|
858
860
|
});
|
|
859
861
|
}
|
|
@@ -861,12 +863,12 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
861
863
|
if (!token) throw new Error("[djs-next] A token must be provided to start the bot.");
|
|
862
864
|
this.config = await loadConfig();
|
|
863
865
|
this._guildId = this._guildId || this.config.devGuildId;
|
|
864
|
-
if (!this._commandsDir
|
|
865
|
-
if (!this._eventsDir
|
|
866
|
-
if (!this._componentsDir
|
|
867
|
-
if (!this._tasksDir
|
|
868
|
-
if (!this._localesDir
|
|
869
|
-
if (this._localesDir) loadLocales(this._localesDir, this.config.defaultLocale);
|
|
866
|
+
if (!this._commandsDir) this._commandsDir = import_path6.default.resolve(process.cwd(), this.config.directories?.commands || "src/commands");
|
|
867
|
+
if (!this._eventsDir) this._eventsDir = import_path6.default.resolve(process.cwd(), this.config.directories?.events || "src/events");
|
|
868
|
+
if (!this._componentsDir) this._componentsDir = import_path6.default.resolve(process.cwd(), this.config.directories?.components || "src/components");
|
|
869
|
+
if (!this._tasksDir) this._tasksDir = import_path6.default.resolve(process.cwd(), this.config.directories?.tasks || "src/tasks");
|
|
870
|
+
if (!this._localesDir) this._localesDir = import_path6.default.resolve(process.cwd(), this.config.directories?.locales || "src/locales");
|
|
871
|
+
if (import_fs8.default.existsSync(this._localesDir)) loadLocales(this._localesDir, this.config.defaultLocale);
|
|
870
872
|
if (!this._middleware) {
|
|
871
873
|
const exts = [".js", ".mjs", ".cjs", ".ts", ".mts", ".cts"];
|
|
872
874
|
const cwd = process.cwd();
|
|
@@ -886,24 +888,24 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
886
888
|
}
|
|
887
889
|
}
|
|
888
890
|
}
|
|
889
|
-
if (this._eventsDir) await loadEvents(this, this._eventsDir);
|
|
890
|
-
if (this._componentsDir) this.components = await loadComponents(this._componentsDir);
|
|
891
|
-
if (this._tasksDir) await loadTasks(this, this._tasksDir);
|
|
892
|
-
if (this._commandsDir) {
|
|
893
|
-
if (!this._clientId) throw new Error("[djs-next] You must provide a clientId to deploy commands.");
|
|
894
|
-
this.commands = await loadAndDeployCommands(this._commandsDir, token, this._clientId, this._guildId);
|
|
895
|
-
}
|
|
891
|
+
if (import_fs8.default.existsSync(this._eventsDir)) await loadEvents(this, this._eventsDir);
|
|
892
|
+
if (import_fs8.default.existsSync(this._componentsDir)) this.components = await loadComponents(this._componentsDir);
|
|
893
|
+
if (import_fs8.default.existsSync(this._tasksDir)) await loadTasks(this, this._tasksDir);
|
|
896
894
|
await this.login(token);
|
|
897
895
|
console.log(`[djs-next] Bot is ready and logged in as ${this.user?.tag}!`);
|
|
896
|
+
if (import_fs8.default.existsSync(this._commandsDir)) {
|
|
897
|
+
this._clientId = this._clientId || this.user.id;
|
|
898
|
+
this.commands = await loadAndDeployCommands(this._commandsDir, token, this._clientId, this._guildId);
|
|
899
|
+
}
|
|
898
900
|
}
|
|
899
|
-
enableDevTools(
|
|
900
|
-
if (
|
|
901
|
-
throw new Error(`[djs-next] Developer Tools prefix must be either 'dnxt' or 'nxt'. Received: ${
|
|
901
|
+
enableDevTools(prefix = "dnxt") {
|
|
902
|
+
if (prefix !== "dnxt" && prefix !== "nxt") {
|
|
903
|
+
throw new Error(`[djs-next] Developer Tools prefix must be either 'dnxt' or 'nxt'. Received: ${prefix}`);
|
|
902
904
|
}
|
|
903
905
|
this.on("messageCreate", async (message2) => {
|
|
904
|
-
await handleDNXT(message2, this,
|
|
906
|
+
await handleDNXT(message2, this, prefix);
|
|
905
907
|
});
|
|
906
|
-
console.log(`[djs-next] \u{1F6E0}\uFE0F Developer Tools enabled. Use "${
|
|
908
|
+
console.log(`[djs-next] \u{1F6E0}\uFE0F Developer Tools enabled. Use "${prefix}" in chat. Ensure MessageContent intent is enabled!`);
|
|
907
909
|
}
|
|
908
910
|
async enableHMR() {
|
|
909
911
|
try {
|
|
@@ -933,27 +935,193 @@ var DJSNextClient = class extends import_discord3.Client {
|
|
|
933
935
|
console.warn(`[djs-next] chokidar not installed. HMR is disabled. Please run "npm install chokidar" to use this feature.`);
|
|
934
936
|
}
|
|
935
937
|
}
|
|
938
|
+
async handleCommandError(error, commandKey, context) {
|
|
939
|
+
console.error(`[djs-next] Error executing command/component: "${commandKey}"`, error);
|
|
940
|
+
const djs = require("discord.js");
|
|
941
|
+
if (this.config.responses?.errorBoundary === null) {
|
|
942
|
+
} else {
|
|
943
|
+
try {
|
|
944
|
+
const errorContent = this.config.responses?.errorBoundary || `### \u26A0\uFE0F Execution Error
|
|
945
|
+
> The framework encountered a fatal error while executing \`${commandKey}\`.`;
|
|
946
|
+
const codeBlock = `\`\`\`js
|
|
947
|
+
${String(error.stack || error.message).substring(0, 1500)}
|
|
948
|
+
\`\`\``;
|
|
949
|
+
if ("commandName" in context || "customId" in context) {
|
|
950
|
+
const container = new djs.ContainerBuilder().setAccentColor(15548997).addTextDisplayComponents(new djs.TextDisplayBuilder().setContent(errorContent)).addSeparatorComponents(new djs.SeparatorBuilder()).addTextDisplayComponents(new djs.TextDisplayBuilder().setContent(codeBlock));
|
|
951
|
+
const payload = { components: [container], flags: 32768, ephemeral: true };
|
|
952
|
+
const i = context;
|
|
953
|
+
if (i.isRepliable()) {
|
|
954
|
+
if (i.replied || i.deferred) await i.followUp(payload);
|
|
955
|
+
else await i.reply(payload);
|
|
956
|
+
}
|
|
957
|
+
} else {
|
|
958
|
+
const embed = new djs.EmbedBuilder().setColor(15548997).setDescription(`${errorContent}
|
|
959
|
+
|
|
960
|
+
${codeBlock}`);
|
|
961
|
+
const m = context;
|
|
962
|
+
await m.reply({ embeds: [embed] });
|
|
963
|
+
}
|
|
964
|
+
} catch (e) {
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
if (this.config.errorLogChannelId) {
|
|
968
|
+
try {
|
|
969
|
+
const channel = await this.channels.fetch(this.config.errorLogChannelId);
|
|
970
|
+
if (channel && channel.isTextBased()) {
|
|
971
|
+
const userId = "user" in context ? context.user.id : context.author.id;
|
|
972
|
+
await channel.send(`\u{1F6A8} **Global Error Boundary Caught Exception**
|
|
973
|
+
**Context:** \`${commandKey}\`
|
|
974
|
+
**User:** <@${userId}>
|
|
975
|
+
\`\`\`js
|
|
976
|
+
${String(error.stack || error.message).substring(0, 1900)}
|
|
977
|
+
\`\`\``);
|
|
978
|
+
}
|
|
979
|
+
} catch (e) {
|
|
980
|
+
console.error(`[djs-next] Failed to send error to log channel:`, e);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
async handlePreconditions(command2, context, commandKey) {
|
|
985
|
+
const userId = "user" in context ? context.user.id : context.author.id;
|
|
986
|
+
const isGuild = "guild" in context && context.guild !== null;
|
|
987
|
+
const member = context.member;
|
|
988
|
+
const sendErr = async (msg) => {
|
|
989
|
+
if (msg === null) return;
|
|
990
|
+
if ("reply" in context && typeof context.reply === "function") {
|
|
991
|
+
try {
|
|
992
|
+
if ("replied" in context && context.isRepliable() && (context.replied || context.deferred)) {
|
|
993
|
+
await context.followUp({ content: msg, ephemeral: true });
|
|
994
|
+
} else {
|
|
995
|
+
await context.reply({ content: msg, ephemeral: true, allowedMentions: { repliedUser: false } });
|
|
996
|
+
}
|
|
997
|
+
} catch (e) {
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
if ("developerOnly" in command2 && command2.developerOnly && !this._developers.includes(userId)) {
|
|
1002
|
+
await sendErr(this.config.responses?.developerOnly !== void 0 ? this.config.responses.developerOnly : "Only developers can use this command.");
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
if ("guildOnly" in command2 && command2.guildOnly && !isGuild) {
|
|
1006
|
+
await sendErr(this.config.responses?.guildOnly !== void 0 ? this.config.responses.guildOnly : "This command can only be used in a server.");
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
if ("userPermissions" in command2 && command2.userPermissions && member?.permissions) {
|
|
1010
|
+
const missing = member.permissions.missing(command2.userPermissions);
|
|
1011
|
+
if (missing.length > 0) {
|
|
1012
|
+
await sendErr(this.config.responses?.missingPerms !== void 0 ? this.config.responses.missingPerms === null ? null : this.config.responses.missingPerms.replace("{perms}", missing.join(", ")) : `You are missing permissions: \`${missing.join(", ")}\``);
|
|
1013
|
+
return false;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
if ("botPermissions" in command2 && command2.botPermissions && context.guild?.members.me?.permissions) {
|
|
1017
|
+
const missing = context.guild.members.me.permissions.missing(command2.botPermissions);
|
|
1018
|
+
if (missing.length > 0) {
|
|
1019
|
+
await sendErr(this.config.responses?.missingPerms !== void 0 ? this.config.responses.missingPerms === null ? null : this.config.responses.missingPerms.replace("{perms}", missing.join(", ")) : `I am missing permissions to run this: \`${missing.join(", ")}\``);
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
let totalCooldown = "cooldown" in command2 && command2.cooldown ? command2.cooldown * 1e3 : 0;
|
|
1024
|
+
if (command2.preconditions) {
|
|
1025
|
+
for (const pre of command2.preconditions) {
|
|
1026
|
+
const parts = pre.split(":");
|
|
1027
|
+
const type = parts[0].toLowerCase();
|
|
1028
|
+
const val = parts.slice(1).join(":");
|
|
1029
|
+
if (type === "owneronly" || type === "developeronly") {
|
|
1030
|
+
if (!this._developers.includes(userId)) {
|
|
1031
|
+
await sendErr(this.config.responses?.developerOnly !== void 0 ? this.config.responses.developerOnly : "Only developers can use this command.");
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
} else if (type === "guildonly") {
|
|
1035
|
+
if (!isGuild) {
|
|
1036
|
+
await sendErr(this.config.responses?.guildOnly !== void 0 ? this.config.responses.guildOnly : "This command can only be used in a server.");
|
|
1037
|
+
return false;
|
|
1038
|
+
}
|
|
1039
|
+
} else if (type === "requireperms") {
|
|
1040
|
+
const perms = val.split(",").map((p) => p.trim());
|
|
1041
|
+
if (member?.permissions) {
|
|
1042
|
+
const missing = member.permissions.missing(perms);
|
|
1043
|
+
if (missing.length > 0) {
|
|
1044
|
+
await sendErr(this.config.responses?.missingPerms !== void 0 ? this.config.responses.missingPerms === null ? null : this.config.responses.missingPerms.replace("{perms}", missing.join(", ")) : `You are missing permissions: \`${missing.join(", ")}\``);
|
|
1045
|
+
return false;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
} else if (type === "cooldown") {
|
|
1049
|
+
const match = val.match(/(\d+)(s|m|h)/);
|
|
1050
|
+
if (match) {
|
|
1051
|
+
let amount = parseInt(match[1]) * 1e3;
|
|
1052
|
+
if (match[2] === "m") amount *= 60;
|
|
1053
|
+
if (match[2] === "h") amount *= 3600;
|
|
1054
|
+
totalCooldown = Math.max(totalCooldown, amount);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
if (totalCooldown > 0) {
|
|
1060
|
+
const now = Date.now();
|
|
1061
|
+
if (this.config.cooldownAdapter) {
|
|
1062
|
+
const lastUsed = await this.config.cooldownAdapter.get(commandKey, userId);
|
|
1063
|
+
if (lastUsed) {
|
|
1064
|
+
const expirationTime = lastUsed + totalCooldown;
|
|
1065
|
+
if (now < expirationTime) {
|
|
1066
|
+
const timeStr = `<t:${Math.round(expirationTime / 1e3)}:R>`;
|
|
1067
|
+
await sendErr(this.config.responses?.cooldown !== void 0 ? this.config.responses.cooldown === null ? null : this.config.responses.cooldown.replace("{time}", timeStr) : `Please wait, you are on a cooldown. You can use it again ${timeStr}.`);
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
await this.config.cooldownAdapter.set(commandKey, userId, now);
|
|
1072
|
+
} else {
|
|
1073
|
+
if (!this.cooldowns.has(commandKey)) this.cooldowns.set(commandKey, new import_discord4.Collection());
|
|
1074
|
+
const timestamps = this.cooldowns.get(commandKey);
|
|
1075
|
+
if (timestamps.has(userId)) {
|
|
1076
|
+
const expirationTime = timestamps.get(userId) + totalCooldown;
|
|
1077
|
+
if (now < expirationTime) {
|
|
1078
|
+
const timeStr = `<t:${Math.round(expirationTime / 1e3)}:R>`;
|
|
1079
|
+
await sendErr(this.config.responses?.cooldown !== void 0 ? this.config.responses.cooldown === null ? null : this.config.responses.cooldown.replace("{time}", timeStr) : `Please wait, you are on a cooldown. You can use it again ${timeStr}.`);
|
|
1080
|
+
return false;
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
timestamps.set(userId, now);
|
|
1084
|
+
setTimeout(() => timestamps.delete(userId), totalCooldown);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return true;
|
|
1088
|
+
}
|
|
936
1089
|
};
|
|
937
1090
|
|
|
938
1091
|
// src/utils/paginate.ts
|
|
939
|
-
var
|
|
940
|
-
async function paginate(
|
|
941
|
-
|
|
942
|
-
|
|
1092
|
+
var import_discord5 = require("discord.js");
|
|
1093
|
+
async function paginate(context, pages, time = 6e4) {
|
|
1094
|
+
const isMessage = "author" in context;
|
|
1095
|
+
if (!isMessage) {
|
|
1096
|
+
if (!context.deferred && !context.replied) {
|
|
1097
|
+
await context.deferReply();
|
|
1098
|
+
}
|
|
943
1099
|
}
|
|
944
1100
|
if (pages.length === 1) {
|
|
945
|
-
|
|
1101
|
+
if (isMessage) {
|
|
1102
|
+
return context.reply({ embeds: [pages[0]], components: [] });
|
|
1103
|
+
} else {
|
|
1104
|
+
return context.editReply({ embeds: [pages[0]], components: [] });
|
|
1105
|
+
}
|
|
946
1106
|
}
|
|
947
1107
|
let index = 0;
|
|
948
|
-
const prevButton = new
|
|
949
|
-
const nextButton = new
|
|
950
|
-
const row = new
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1108
|
+
const prevButton = new import_discord5.ButtonBuilder().setCustomId("djs_prev").setLabel("Previous").setStyle(import_discord5.ButtonStyle.Primary).setDisabled(true);
|
|
1109
|
+
const nextButton = new import_discord5.ButtonBuilder().setCustomId("djs_next").setLabel("Next").setStyle(import_discord5.ButtonStyle.Primary);
|
|
1110
|
+
const row = new import_discord5.ActionRowBuilder().addComponents(prevButton, nextButton);
|
|
1111
|
+
let message2;
|
|
1112
|
+
if (isMessage) {
|
|
1113
|
+
message2 = await context.reply({
|
|
1114
|
+
embeds: [pages[index]],
|
|
1115
|
+
components: [row]
|
|
1116
|
+
});
|
|
1117
|
+
} else {
|
|
1118
|
+
message2 = await context.editReply({
|
|
1119
|
+
embeds: [pages[index]],
|
|
1120
|
+
components: [row]
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
955
1123
|
const collector = message2.createMessageComponentCollector({
|
|
956
|
-
filter: (i) => i.user.id ===
|
|
1124
|
+
filter: (i) => i.user.id === (isMessage ? context.author.id : context.user.id),
|
|
957
1125
|
time
|
|
958
1126
|
});
|
|
959
1127
|
collector.on("collect", async (i) => {
|
|
@@ -966,24 +1134,144 @@ async function paginate(interaction, pages, time = 6e4) {
|
|
|
966
1134
|
nextButton.setDisabled(index === pages.length - 1);
|
|
967
1135
|
await i.update({
|
|
968
1136
|
embeds: [pages[index]],
|
|
969
|
-
components: [new
|
|
1137
|
+
components: [new import_discord5.ActionRowBuilder().addComponents(prevButton, nextButton)]
|
|
970
1138
|
});
|
|
971
1139
|
});
|
|
972
1140
|
collector.on("end", async () => {
|
|
973
1141
|
prevButton.setDisabled(true);
|
|
974
1142
|
nextButton.setDisabled(true);
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1143
|
+
if (message2.editable) {
|
|
1144
|
+
await message2.edit({
|
|
1145
|
+
components: [new import_discord5.ActionRowBuilder().addComponents(prevButton, nextButton)]
|
|
1146
|
+
}).catch(() => {
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
979
1149
|
});
|
|
980
1150
|
}
|
|
981
1151
|
|
|
1152
|
+
// src/utils/prompts.ts
|
|
1153
|
+
var import_discord6 = require("discord.js");
|
|
1154
|
+
async function confirmPrompt(context, content2, time = 3e4) {
|
|
1155
|
+
const isMessage = "author" in context;
|
|
1156
|
+
if (!isMessage) {
|
|
1157
|
+
if (!context.deferred && !context.replied) {
|
|
1158
|
+
await context.deferReply();
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
const yesButton = new import_discord6.ButtonBuilder().setCustomId("djs_prompt_yes").setLabel("Yes").setStyle(import_discord6.ButtonStyle.Success);
|
|
1162
|
+
const noButton = new import_discord6.ButtonBuilder().setCustomId("djs_prompt_no").setLabel("No").setStyle(import_discord6.ButtonStyle.Danger);
|
|
1163
|
+
const row = new import_discord6.ActionRowBuilder().addComponents(yesButton, noButton);
|
|
1164
|
+
const payload = { components: [row] };
|
|
1165
|
+
if (typeof content2 === "string") {
|
|
1166
|
+
payload.content = content2;
|
|
1167
|
+
} else {
|
|
1168
|
+
payload.embeds = [content2];
|
|
1169
|
+
}
|
|
1170
|
+
let message2;
|
|
1171
|
+
if (isMessage) {
|
|
1172
|
+
message2 = await context.reply(payload);
|
|
1173
|
+
} else {
|
|
1174
|
+
message2 = await context.editReply(payload);
|
|
1175
|
+
}
|
|
1176
|
+
try {
|
|
1177
|
+
const interaction = await message2.awaitMessageComponent({
|
|
1178
|
+
filter: (i) => i.user.id === (isMessage ? context.author.id : context.user.id),
|
|
1179
|
+
time
|
|
1180
|
+
});
|
|
1181
|
+
if (interaction.customId === "djs_prompt_yes") {
|
|
1182
|
+
await interaction.update({ components: [] });
|
|
1183
|
+
return true;
|
|
1184
|
+
} else {
|
|
1185
|
+
await interaction.update({ components: [] });
|
|
1186
|
+
return false;
|
|
1187
|
+
}
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
if (message2.editable) {
|
|
1190
|
+
await message2.edit({ components: [] }).catch(() => {
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
return null;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// src/utils/PaginationBuilder.ts
|
|
1198
|
+
var import_discord7 = require("discord.js");
|
|
1199
|
+
var PaginationBuilder = class {
|
|
1200
|
+
pages = [];
|
|
1201
|
+
timeout = 6e4;
|
|
1202
|
+
constructor(pages) {
|
|
1203
|
+
if (pages) this.pages = pages;
|
|
1204
|
+
}
|
|
1205
|
+
addPage(embed) {
|
|
1206
|
+
this.pages.push(embed);
|
|
1207
|
+
return this;
|
|
1208
|
+
}
|
|
1209
|
+
setPages(pages) {
|
|
1210
|
+
this.pages = pages;
|
|
1211
|
+
return this;
|
|
1212
|
+
}
|
|
1213
|
+
setTimeout(ms) {
|
|
1214
|
+
this.timeout = ms;
|
|
1215
|
+
return this;
|
|
1216
|
+
}
|
|
1217
|
+
async build(target) {
|
|
1218
|
+
if (this.pages.length === 0) throw new Error("[djs-next] PaginationBuilder requires at least one page.");
|
|
1219
|
+
if (this.pages.length === 1) {
|
|
1220
|
+
if (target instanceof import_discord7.CommandInteraction) {
|
|
1221
|
+
if (target.deferred || target.replied) {
|
|
1222
|
+
return await target.editReply({ embeds: [this.pages[0]] });
|
|
1223
|
+
}
|
|
1224
|
+
return await target.reply({ embeds: [this.pages[0]], fetchReply: true });
|
|
1225
|
+
} else {
|
|
1226
|
+
return await target.reply({ embeds: [this.pages[0]] });
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
let currentPage = 0;
|
|
1230
|
+
const row = new import_discord7.ActionRowBuilder().addComponents(
|
|
1231
|
+
new import_discord7.ButtonBuilder().setCustomId("prev").setLabel("\u25C0").setStyle(import_discord7.ButtonStyle.Primary).setDisabled(true),
|
|
1232
|
+
new import_discord7.ButtonBuilder().setCustomId("page").setLabel(`1 / ${this.pages.length}`).setStyle(import_discord7.ButtonStyle.Secondary).setDisabled(true),
|
|
1233
|
+
new import_discord7.ButtonBuilder().setCustomId("next").setLabel("\u25B6").setStyle(import_discord7.ButtonStyle.Primary)
|
|
1234
|
+
);
|
|
1235
|
+
let replyMsg;
|
|
1236
|
+
if (target instanceof import_discord7.CommandInteraction) {
|
|
1237
|
+
if (target.deferred || target.replied) {
|
|
1238
|
+
replyMsg = await target.editReply({ embeds: [this.pages[0]], components: [row] });
|
|
1239
|
+
} else {
|
|
1240
|
+
replyMsg = await target.reply({ embeds: [this.pages[0]], components: [row], fetchReply: true });
|
|
1241
|
+
}
|
|
1242
|
+
} else {
|
|
1243
|
+
replyMsg = await target.reply({ embeds: [this.pages[0]], components: [row] });
|
|
1244
|
+
}
|
|
1245
|
+
const userId = target instanceof import_discord7.CommandInteraction ? target.user.id : target.author.id;
|
|
1246
|
+
const collector = replyMsg.createMessageComponentCollector({
|
|
1247
|
+
componentType: import_discord7.ComponentType.Button,
|
|
1248
|
+
time: this.timeout,
|
|
1249
|
+
filter: (i) => i.user.id === userId
|
|
1250
|
+
});
|
|
1251
|
+
collector.on("collect", async (i) => {
|
|
1252
|
+
if (i.customId === "prev") currentPage--;
|
|
1253
|
+
else if (i.customId === "next") currentPage++;
|
|
1254
|
+
const newRow = new import_discord7.ActionRowBuilder().addComponents(
|
|
1255
|
+
new import_discord7.ButtonBuilder().setCustomId("prev").setLabel("\u25C0").setStyle(import_discord7.ButtonStyle.Primary).setDisabled(currentPage === 0),
|
|
1256
|
+
new import_discord7.ButtonBuilder().setCustomId("page").setLabel(`${currentPage + 1} / ${this.pages.length}`).setStyle(import_discord7.ButtonStyle.Secondary).setDisabled(true),
|
|
1257
|
+
new import_discord7.ButtonBuilder().setCustomId("next").setLabel("\u25B6").setStyle(import_discord7.ButtonStyle.Primary).setDisabled(currentPage === this.pages.length - 1)
|
|
1258
|
+
);
|
|
1259
|
+
await i.update({ embeds: [this.pages[currentPage]], components: [newRow] });
|
|
1260
|
+
});
|
|
1261
|
+
collector.on("end", () => {
|
|
1262
|
+
replyMsg.edit({ components: [] }).catch(() => null);
|
|
1263
|
+
});
|
|
1264
|
+
return replyMsg;
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
|
|
982
1268
|
// src/index.ts
|
|
983
1269
|
__reExport(index_exports, require("discord.js"), module.exports);
|
|
984
1270
|
// Annotate the CommonJS export names for ESM import in node:
|
|
985
1271
|
0 && (module.exports = {
|
|
986
1272
|
DJSNextClient,
|
|
1273
|
+
PaginationBuilder,
|
|
1274
|
+
confirmPrompt,
|
|
987
1275
|
defineConfig,
|
|
988
1276
|
getLocalesCache,
|
|
989
1277
|
loadConfig,
|