commandkit 0.1.6 → 0.1.7-dev.20231212150647
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/README.md +12 -9
- package/bin/build.mjs +86 -0
- package/bin/common.mjs +102 -0
- package/bin/development.mjs +163 -0
- package/bin/index.mjs +39 -0
- package/bin/parse-env.mjs +61 -0
- package/bin/production.mjs +83 -0
- package/dist/index.d.mts +288 -67
- package/dist/index.d.ts +288 -67
- package/dist/index.js +290 -128
- package/dist/index.mjs +289 -126
- package/package.json +56 -47
package/dist/index.mjs
CHANGED
|
@@ -6,48 +6,52 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
// src/utils/
|
|
9
|
+
// src/utils/resolve-file-url.ts
|
|
10
10
|
import path from "path";
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
function toFileURL(filePath) {
|
|
12
|
+
const resolvedPath = path.resolve(filePath);
|
|
13
|
+
return "file://" + resolvedPath.replace(/\\\\|\\/g, "/");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/utils/get-paths.ts
|
|
17
|
+
import path2 from "path";
|
|
18
|
+
import fs from "fs/promises";
|
|
19
|
+
async function getFilePaths(directory, nesting) {
|
|
13
20
|
let filePaths = [];
|
|
14
21
|
if (!directory)
|
|
15
22
|
return filePaths;
|
|
16
|
-
const files = fs.
|
|
23
|
+
const files = await fs.readdir(directory, { withFileTypes: true });
|
|
17
24
|
for (const file of files) {
|
|
18
|
-
const filePath =
|
|
25
|
+
const filePath = path2.join(directory, file.name);
|
|
19
26
|
if (file.isFile()) {
|
|
20
27
|
filePaths.push(filePath);
|
|
21
28
|
}
|
|
22
29
|
if (nesting && file.isDirectory()) {
|
|
23
|
-
filePaths = [...filePaths, ...getFilePaths(filePath, true)];
|
|
30
|
+
filePaths = [...filePaths, ...await getFilePaths(filePath, true)];
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
33
|
return filePaths;
|
|
27
34
|
}
|
|
28
|
-
function getFolderPaths(directory, nesting) {
|
|
35
|
+
async function getFolderPaths(directory, nesting) {
|
|
29
36
|
let folderPaths = [];
|
|
30
37
|
if (!directory)
|
|
31
38
|
return folderPaths;
|
|
32
|
-
const folders = fs.
|
|
39
|
+
const folders = await fs.readdir(directory, { withFileTypes: true });
|
|
33
40
|
for (const folder of folders) {
|
|
34
|
-
const folderPath =
|
|
41
|
+
const folderPath = path2.join(directory, folder.name);
|
|
35
42
|
if (folder.isDirectory()) {
|
|
36
43
|
folderPaths.push(folderPath);
|
|
37
44
|
if (nesting) {
|
|
38
|
-
folderPaths = [...folderPaths, ...getFolderPaths(folderPath, true)];
|
|
45
|
+
folderPaths = [...folderPaths, ...await getFolderPaths(folderPath, true)];
|
|
39
46
|
}
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
return folderPaths;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
// src/utils/
|
|
46
|
-
import
|
|
47
|
-
|
|
48
|
-
const resolvedPath = path2.resolve(filePath);
|
|
49
|
-
return "file://" + resolvedPath.replace(/\\\\|\\/g, "/");
|
|
50
|
-
}
|
|
52
|
+
// src/utils/clone.ts
|
|
53
|
+
import rfdc from "rfdc";
|
|
54
|
+
var clone = rfdc();
|
|
51
55
|
|
|
52
56
|
// src/utils/colors.ts
|
|
53
57
|
var resetColor = "\x1B[0m";
|
|
@@ -331,35 +335,10 @@ async function registerDevCommands(client, commands, guildIds) {
|
|
|
331
335
|
}
|
|
332
336
|
}
|
|
333
337
|
|
|
334
|
-
// src/handlers/command-handler/validations/botPermissions.ts
|
|
335
|
-
function botPermissions_default({ interaction, targetCommand }) {
|
|
336
|
-
const botMember = interaction.guild?.members.me;
|
|
337
|
-
let commandPermissions = targetCommand.options?.botPermissions;
|
|
338
|
-
if (!botMember || !commandPermissions)
|
|
339
|
-
return;
|
|
340
|
-
if (!Array.isArray(commandPermissions)) {
|
|
341
|
-
commandPermissions = [commandPermissions];
|
|
342
|
-
}
|
|
343
|
-
const missingPermissions = [];
|
|
344
|
-
for (const permission of commandPermissions) {
|
|
345
|
-
const hasPermission = botMember.permissions.has(permission);
|
|
346
|
-
if (!hasPermission) {
|
|
347
|
-
missingPermissions.push(`\`${permission.toString()}\``);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
if (missingPermissions.length) {
|
|
351
|
-
interaction.reply({
|
|
352
|
-
content: `\u274C I do not have enough permissions to execute this command. Missing: ${missingPermissions.join(
|
|
353
|
-
", "
|
|
354
|
-
)}`,
|
|
355
|
-
ephemeral: true
|
|
356
|
-
});
|
|
357
|
-
return true;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
338
|
// src/handlers/command-handler/validations/devOnly.ts
|
|
362
339
|
function devOnly_default({ interaction, targetCommand, handlerData }) {
|
|
340
|
+
if (interaction.isAutocomplete())
|
|
341
|
+
return;
|
|
363
342
|
if (targetCommand.options?.devOnly) {
|
|
364
343
|
if (interaction.inGuild() && !handlerData.devGuildIds.includes(interaction.guildId)) {
|
|
365
344
|
interaction.reply({
|
|
@@ -387,50 +366,76 @@ function devOnly_default({ interaction, targetCommand, handlerData }) {
|
|
|
387
366
|
}
|
|
388
367
|
}
|
|
389
368
|
|
|
390
|
-
// src/handlers/command-handler/validations/
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
369
|
+
// src/handlers/command-handler/validations/permissions.ts
|
|
370
|
+
import { EmbedBuilder } from "discord.js";
|
|
371
|
+
function permissions_default({ interaction, targetCommand }) {
|
|
372
|
+
if (interaction.isAutocomplete())
|
|
373
|
+
return;
|
|
374
|
+
const userPermissions = interaction.memberPermissions;
|
|
375
|
+
let userPermissionsRequired = targetCommand.options?.userPermissions;
|
|
376
|
+
let missingUserPermissions = [];
|
|
377
|
+
if (typeof userPermissionsRequired === "string") {
|
|
378
|
+
userPermissionsRequired = [userPermissionsRequired];
|
|
398
379
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
if (!
|
|
380
|
+
const botPermissions = interaction.guild?.members.me?.permissions;
|
|
381
|
+
let botPermissionsRequired = targetCommand.options?.botPermissions;
|
|
382
|
+
let missingBotPermissions = [];
|
|
383
|
+
if (typeof botPermissionsRequired === "string") {
|
|
384
|
+
botPermissionsRequired = [botPermissionsRequired];
|
|
385
|
+
}
|
|
386
|
+
if (!userPermissionsRequired?.length && !botPermissionsRequired?.length) {
|
|
406
387
|
return;
|
|
407
|
-
if (!Array.isArray(commandPermissions)) {
|
|
408
|
-
commandPermissions = [commandPermissions];
|
|
409
|
-
}
|
|
410
|
-
const missingPermissions = [];
|
|
411
|
-
for (const permission of commandPermissions) {
|
|
412
|
-
const hasPermission = memberPermissions.has(permission);
|
|
413
|
-
if (!hasPermission) {
|
|
414
|
-
missingPermissions.push(`\`${permission.toString()}\``);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
if (missingPermissions.length) {
|
|
418
|
-
interaction.reply({
|
|
419
|
-
content: `\u274C You do not have enough permissions to run this command. Missing: ${missingPermissions.join(
|
|
420
|
-
", "
|
|
421
|
-
)}`,
|
|
422
|
-
ephemeral: true
|
|
423
|
-
});
|
|
424
|
-
return true;
|
|
425
388
|
}
|
|
389
|
+
if (userPermissions && userPermissionsRequired) {
|
|
390
|
+
for (const permission of userPermissionsRequired) {
|
|
391
|
+
const hasPermission = userPermissions.has(permission);
|
|
392
|
+
if (!hasPermission) {
|
|
393
|
+
missingUserPermissions.push(permission);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
if (botPermissions && botPermissionsRequired) {
|
|
398
|
+
for (const permission of botPermissionsRequired) {
|
|
399
|
+
const hasPermission = botPermissions.has(permission);
|
|
400
|
+
if (!hasPermission) {
|
|
401
|
+
missingBotPermissions.push(permission);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
if (!missingUserPermissions.length && !missingBotPermissions.length) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const pattern = /([a-z])([A-Z])|([A-Z]+)([A-Z][a-z])/g;
|
|
409
|
+
missingUserPermissions = missingUserPermissions.map((str) => str.replace(pattern, "$1$3 $2$4"));
|
|
410
|
+
missingBotPermissions = missingBotPermissions.map((str) => str.replace(pattern, "$1$3 $2$4"));
|
|
411
|
+
let embedDescription = "";
|
|
412
|
+
const formatter = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
|
|
413
|
+
const getPermissionWord = (permissions) => permissions.length === 1 ? "permission" : "permissions";
|
|
414
|
+
if (missingUserPermissions.length) {
|
|
415
|
+
const formattedPermissions = missingUserPermissions.map((p) => `\`${p}\``);
|
|
416
|
+
const permissionsString = formatter.format(formattedPermissions);
|
|
417
|
+
embedDescription += `- You must have the ${permissionsString} ${getPermissionWord(
|
|
418
|
+
missingUserPermissions
|
|
419
|
+
)} to be able to run this command.
|
|
420
|
+
`;
|
|
421
|
+
}
|
|
422
|
+
if (missingBotPermissions.length) {
|
|
423
|
+
const formattedPermissions = missingBotPermissions.map((p) => `\`${p}\``);
|
|
424
|
+
const permissionsString = formatter.format(formattedPermissions);
|
|
425
|
+
embedDescription += `- I must have the ${permissionsString} ${getPermissionWord(
|
|
426
|
+
missingBotPermissions
|
|
427
|
+
)} to be able to execute this command.
|
|
428
|
+
`;
|
|
429
|
+
}
|
|
430
|
+
const embed = new EmbedBuilder().setTitle(`:x: Missing permissions!`).setDescription(embedDescription).setColor("Red");
|
|
431
|
+
interaction.reply({ embeds: [embed], ephemeral: true });
|
|
432
|
+
return true;
|
|
426
433
|
}
|
|
427
434
|
|
|
428
435
|
// src/handlers/command-handler/validations/index.ts
|
|
429
|
-
var validations_default = [
|
|
436
|
+
var validations_default = [devOnly_default, permissions_default];
|
|
430
437
|
|
|
431
438
|
// src/handlers/command-handler/CommandHandler.ts
|
|
432
|
-
import rdfc from "rfdc";
|
|
433
|
-
var clone = rdfc();
|
|
434
439
|
var CommandHandler = class {
|
|
435
440
|
#data;
|
|
436
441
|
constructor({ ...options }) {
|
|
@@ -442,19 +447,19 @@ var CommandHandler = class {
|
|
|
442
447
|
}
|
|
443
448
|
async init() {
|
|
444
449
|
await this.#buildCommands();
|
|
445
|
-
this.#
|
|
450
|
+
this.#buildBuiltInValidations();
|
|
446
451
|
const devOnlyCommands = this.#data.commands.filter((cmd) => cmd.options?.devOnly);
|
|
447
452
|
if (devOnlyCommands.length && !this.#data.devGuildIds.length) {
|
|
448
453
|
console.log(
|
|
449
454
|
colors_default.yellow(
|
|
450
|
-
'\u2139\uFE0F Warning: You have commands marked as "devOnly" but "devGuildIds"
|
|
455
|
+
'\u2139\uFE0F Warning: You have commands marked as "devOnly", but "devGuildIds" have not been set.'
|
|
451
456
|
)
|
|
452
457
|
);
|
|
453
458
|
}
|
|
454
459
|
if (devOnlyCommands.length && !this.#data.devUserIds.length && !this.#data.devRoleIds.length) {
|
|
455
460
|
console.log(
|
|
456
461
|
colors_default.yellow(
|
|
457
|
-
'\u2139\uFE0F Warning: You have commands marked as "devOnly" but
|
|
462
|
+
'\u2139\uFE0F Warning: You have commands marked as "devOnly", but "devUserIds" or "devRoleIds" have not been set.'
|
|
458
463
|
)
|
|
459
464
|
);
|
|
460
465
|
}
|
|
@@ -475,12 +480,11 @@ var CommandHandler = class {
|
|
|
475
480
|
}
|
|
476
481
|
async #buildCommands() {
|
|
477
482
|
const allowedExtensions = /\.(js|mjs|cjs|ts)$/i;
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
);
|
|
483
|
+
const paths = await getFilePaths(this.#data.commandsPath, true);
|
|
484
|
+
const commandFilePaths = paths.filter((path3) => allowedExtensions.test(path3));
|
|
481
485
|
for (const commandFilePath of commandFilePaths) {
|
|
482
486
|
const modulePath = toFileURL(commandFilePath);
|
|
483
|
-
|
|
487
|
+
const importedObj = await import(`${modulePath}?t=${Date.now()}`);
|
|
484
488
|
let commandObj = clone(importedObj);
|
|
485
489
|
if (typeof module !== "undefined" && typeof __require !== "undefined") {
|
|
486
490
|
delete __require.cache[__require.resolve(commandFilePath)];
|
|
@@ -532,24 +536,34 @@ var CommandHandler = class {
|
|
|
532
536
|
} else {
|
|
533
537
|
commandObj.category = commandCategory;
|
|
534
538
|
}
|
|
539
|
+
if (commandObj.options?.guildOnly) {
|
|
540
|
+
console.log(
|
|
541
|
+
colors_default.yellow(
|
|
542
|
+
`\u2139\uFE0F Deprecation warning: The command "${commandObj.data.name}" uses "options.guildOnly", which will be deprecated soon. Use "data.dm_permission" instead.`
|
|
543
|
+
)
|
|
544
|
+
);
|
|
545
|
+
}
|
|
535
546
|
this.#data.commands.push(commandObj);
|
|
536
547
|
}
|
|
537
548
|
}
|
|
538
|
-
#
|
|
539
|
-
for (const
|
|
540
|
-
this.#data.builtInValidations.push(
|
|
549
|
+
#buildBuiltInValidations() {
|
|
550
|
+
for (const builtInValidationFunction of validations_default) {
|
|
551
|
+
this.#data.builtInValidations.push(builtInValidationFunction);
|
|
541
552
|
}
|
|
542
553
|
}
|
|
543
554
|
handleCommands() {
|
|
544
555
|
this.#data.client.on("interactionCreate", async (interaction) => {
|
|
545
|
-
if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand())
|
|
556
|
+
if (!interaction.isChatInputCommand() && !interaction.isContextMenuCommand() && !interaction.isAutocomplete())
|
|
546
557
|
return;
|
|
558
|
+
const isAutocomplete = interaction.isAutocomplete();
|
|
547
559
|
const targetCommand = this.#data.commands.find(
|
|
548
560
|
(cmd) => cmd.data.name === interaction.commandName
|
|
549
561
|
);
|
|
550
562
|
if (!targetCommand)
|
|
551
563
|
return;
|
|
552
|
-
const { data, options, run, ...rest } = targetCommand;
|
|
564
|
+
const { data, options, run, autocompleteRun, ...rest } = targetCommand;
|
|
565
|
+
if (isAutocomplete && !autocompleteRun)
|
|
566
|
+
return;
|
|
553
567
|
const commandObj = {
|
|
554
568
|
data: targetCommand.data,
|
|
555
569
|
options: targetCommand.options,
|
|
@@ -588,17 +602,23 @@ var CommandHandler = class {
|
|
|
588
602
|
}
|
|
589
603
|
if (!canRun)
|
|
590
604
|
return;
|
|
591
|
-
|
|
605
|
+
const context2 = {
|
|
592
606
|
interaction,
|
|
593
607
|
client: this.#data.client,
|
|
594
608
|
handler: this.#data.commandkitInstance
|
|
595
|
-
}
|
|
609
|
+
};
|
|
610
|
+
await targetCommand[isAutocomplete ? "autocompleteRun" : "run"](context2);
|
|
596
611
|
});
|
|
597
612
|
}
|
|
598
613
|
get commands() {
|
|
599
614
|
return this.#data.commands;
|
|
600
615
|
}
|
|
601
616
|
async reloadCommands(type) {
|
|
617
|
+
if (!this.#data.commandsPath) {
|
|
618
|
+
throw new Error(
|
|
619
|
+
'Cannot reload commands as "commandsPath" was not provided when instantiating CommandKit.'
|
|
620
|
+
);
|
|
621
|
+
}
|
|
602
622
|
this.#data.commands = [];
|
|
603
623
|
await this.#buildCommands();
|
|
604
624
|
if (this.#data.bulkRegister) {
|
|
@@ -619,13 +639,9 @@ var CommandHandler = class {
|
|
|
619
639
|
});
|
|
620
640
|
}
|
|
621
641
|
}
|
|
622
|
-
async useUpdatedValidations() {
|
|
623
|
-
}
|
|
624
642
|
};
|
|
625
643
|
|
|
626
644
|
// src/handlers/event-handler/EventHandler.ts
|
|
627
|
-
import rdfc2 from "rfdc";
|
|
628
|
-
var clone2 = rdfc2();
|
|
629
645
|
var EventHandler = class {
|
|
630
646
|
#data;
|
|
631
647
|
constructor({ ...options }) {
|
|
@@ -639,13 +655,12 @@ var EventHandler = class {
|
|
|
639
655
|
this.#registerEvents();
|
|
640
656
|
}
|
|
641
657
|
async #buildEvents() {
|
|
642
|
-
const eventFolderPaths = getFolderPaths(this.#data.eventsPath);
|
|
658
|
+
const eventFolderPaths = await getFolderPaths(this.#data.eventsPath);
|
|
643
659
|
for (const eventFolderPath of eventFolderPaths) {
|
|
644
660
|
const eventName = eventFolderPath.replace(/\\\\|\\/g, "/").split("/").pop();
|
|
645
661
|
const allowedExtensions = /\.(js|mjs|cjs|ts)$/i;
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
);
|
|
662
|
+
const eventPaths = await getFilePaths(eventFolderPath, true);
|
|
663
|
+
const eventFilePaths = eventPaths.filter((path3) => allowedExtensions.test(path3));
|
|
649
664
|
const eventObj = {
|
|
650
665
|
name: eventName,
|
|
651
666
|
functions: []
|
|
@@ -654,7 +669,7 @@ var EventHandler = class {
|
|
|
654
669
|
for (const eventFilePath of eventFilePaths) {
|
|
655
670
|
const modulePath = toFileURL(eventFilePath);
|
|
656
671
|
let importedFunction = (await import(`${modulePath}?t=${Date.now()}`)).default;
|
|
657
|
-
let eventFunction =
|
|
672
|
+
let eventFunction = clone(importedFunction);
|
|
658
673
|
if (typeof module !== "undefined" && typeof __require !== "undefined") {
|
|
659
674
|
delete __require.cache[__require.resolve(eventFilePath)];
|
|
660
675
|
}
|
|
@@ -692,6 +707,11 @@ var EventHandler = class {
|
|
|
692
707
|
return this.#data.events;
|
|
693
708
|
}
|
|
694
709
|
async reloadEvents(commandHandler) {
|
|
710
|
+
if (!this.#data.eventsPath) {
|
|
711
|
+
throw new Error(
|
|
712
|
+
'Cannot reload events as "eventsPath" was not provided when instantiating CommandKit.'
|
|
713
|
+
);
|
|
714
|
+
}
|
|
695
715
|
this.#data.events = [];
|
|
696
716
|
await this.#buildEvents();
|
|
697
717
|
this.#data.client.removeAllListeners();
|
|
@@ -701,8 +721,6 @@ var EventHandler = class {
|
|
|
701
721
|
};
|
|
702
722
|
|
|
703
723
|
// src/handlers/validation-handler/ValidationHandler.ts
|
|
704
|
-
import rdfc3 from "rfdc";
|
|
705
|
-
var clone3 = rdfc3();
|
|
706
724
|
var ValidationHandler = class {
|
|
707
725
|
#data;
|
|
708
726
|
constructor({ ...options }) {
|
|
@@ -712,17 +730,17 @@ var ValidationHandler = class {
|
|
|
712
730
|
};
|
|
713
731
|
}
|
|
714
732
|
async init() {
|
|
715
|
-
await this.#buildValidations();
|
|
733
|
+
this.#data.validations = await this.#buildValidations();
|
|
716
734
|
}
|
|
717
735
|
async #buildValidations() {
|
|
718
736
|
const allowedExtensions = /\.(js|mjs|cjs|ts)$/i;
|
|
719
|
-
const
|
|
720
|
-
|
|
721
|
-
|
|
737
|
+
const validationPaths = await getFilePaths(this.#data.validationsPath, true);
|
|
738
|
+
const validationFilePaths = validationPaths.filter((path3) => allowedExtensions.test(path3));
|
|
739
|
+
const validationFunctions = [];
|
|
722
740
|
for (const validationFilePath of validationFilePaths) {
|
|
723
741
|
const modulePath = toFileURL(validationFilePath);
|
|
724
742
|
let importedFunction = (await import(`${modulePath}?t=${Date.now()}`)).default;
|
|
725
|
-
let validationFunction =
|
|
743
|
+
let validationFunction = clone(importedFunction);
|
|
726
744
|
if (typeof module !== "undefined" && typeof __require !== "undefined") {
|
|
727
745
|
delete __require.cache[__require.resolve(validationFilePath)];
|
|
728
746
|
}
|
|
@@ -738,21 +756,33 @@ var ValidationHandler = class {
|
|
|
738
756
|
);
|
|
739
757
|
continue;
|
|
740
758
|
}
|
|
741
|
-
|
|
759
|
+
validationFunctions.push(validationFunction);
|
|
742
760
|
}
|
|
761
|
+
return validationFunctions;
|
|
743
762
|
}
|
|
744
763
|
get validations() {
|
|
745
764
|
return this.#data.validations;
|
|
746
765
|
}
|
|
747
766
|
async reloadValidations() {
|
|
748
|
-
this.#data.
|
|
749
|
-
|
|
767
|
+
if (!this.#data.validationsPath) {
|
|
768
|
+
throw new Error(
|
|
769
|
+
'Cannot reload validations as "validationsPath" was not provided when instantiating CommandKit.'
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
const newValidations = await this.#buildValidations();
|
|
773
|
+
this.#data.validations = newValidations;
|
|
750
774
|
}
|
|
751
775
|
};
|
|
752
776
|
|
|
753
777
|
// src/CommandKit.ts
|
|
754
778
|
var CommandKit = class {
|
|
755
779
|
#data;
|
|
780
|
+
/**
|
|
781
|
+
* Create a new command and event handler with CommandKit.
|
|
782
|
+
*
|
|
783
|
+
* @param options - The default CommandKit configuration.
|
|
784
|
+
* @see {@link https://commandkit.js.org/docs/commandkit-setup}
|
|
785
|
+
*/
|
|
756
786
|
constructor(options) {
|
|
757
787
|
if (!options.client) {
|
|
758
788
|
throw new Error(colors_default.red('"client" is required when instantiating CommandKit.'));
|
|
@@ -765,6 +795,9 @@ var CommandKit = class {
|
|
|
765
795
|
this.#data = options;
|
|
766
796
|
this.#init();
|
|
767
797
|
}
|
|
798
|
+
/**
|
|
799
|
+
* (Private) Initialize CommandKit.
|
|
800
|
+
*/
|
|
768
801
|
async #init() {
|
|
769
802
|
if (this.#data.eventsPath) {
|
|
770
803
|
const eventHandler = new EventHandler({
|
|
@@ -873,20 +906,150 @@ var CommandKit = class {
|
|
|
873
906
|
}
|
|
874
907
|
};
|
|
875
908
|
|
|
876
|
-
// src/
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
909
|
+
// src/components/ButtonKit.ts
|
|
910
|
+
import {
|
|
911
|
+
ButtonStyle,
|
|
912
|
+
ButtonBuilder,
|
|
913
|
+
ComponentType
|
|
914
|
+
} from "discord.js";
|
|
915
|
+
var ButtonKit = class extends ButtonBuilder {
|
|
916
|
+
#onClickHandler = null;
|
|
917
|
+
#contextData = null;
|
|
918
|
+
#collector = null;
|
|
919
|
+
onClick(handler, data) {
|
|
920
|
+
if (this.data.style === ButtonStyle.Link) {
|
|
921
|
+
throw new TypeError('Cannot setup "onClick" handler on link buttons.');
|
|
922
|
+
}
|
|
923
|
+
this.#destroyCollector();
|
|
924
|
+
this.#onClickHandler = handler;
|
|
925
|
+
if (handler && data)
|
|
926
|
+
this.#contextData = data;
|
|
927
|
+
this.#setupInteractionCollector();
|
|
928
|
+
return this;
|
|
929
|
+
}
|
|
930
|
+
#setupInteractionCollector() {
|
|
931
|
+
if (!this.#contextData || !this.#onClickHandler)
|
|
932
|
+
return;
|
|
933
|
+
const message = this.#contextData.message;
|
|
934
|
+
if (!message) {
|
|
935
|
+
throw new TypeError(
|
|
936
|
+
'Cannot setup "onClick" handler without a message in the context data.'
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
if ("customId" in this.data && !this.data.customId) {
|
|
940
|
+
throw new TypeError('Cannot setup "onClick" handler on a button without a custom id.');
|
|
941
|
+
}
|
|
942
|
+
const data = {
|
|
943
|
+
time: 864e5,
|
|
944
|
+
autoReset: true,
|
|
945
|
+
...this.#contextData
|
|
946
|
+
};
|
|
947
|
+
const collector = this.#collector = message.createMessageComponentCollector({
|
|
948
|
+
filter: (interaction) => interaction.customId === this.data.custom_id && interaction.message.id === message.id,
|
|
949
|
+
componentType: ComponentType.Button,
|
|
950
|
+
...data
|
|
951
|
+
});
|
|
952
|
+
this.#collector.on("collect", (interaction) => {
|
|
953
|
+
const handler = this.#onClickHandler;
|
|
954
|
+
if (!handler)
|
|
955
|
+
return this.#destroyCollector();
|
|
956
|
+
if (!this.#collector) {
|
|
957
|
+
return collector.stop("destroyed");
|
|
958
|
+
}
|
|
959
|
+
if (data.autoReset) {
|
|
960
|
+
this.#collector.resetTimer();
|
|
961
|
+
}
|
|
962
|
+
return handler(interaction);
|
|
963
|
+
});
|
|
964
|
+
this.#collector.on("end", () => {
|
|
965
|
+
this.#destroyCollector();
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
#destroyCollector() {
|
|
969
|
+
this.#onClickHandler?.(null);
|
|
970
|
+
this.#collector?.stop("end");
|
|
971
|
+
this.#collector?.removeAllListeners();
|
|
972
|
+
this.#collector = null;
|
|
973
|
+
this.#contextData = null;
|
|
974
|
+
this.#onClickHandler = null;
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
// src/config.ts
|
|
979
|
+
var globalConfig = {
|
|
980
|
+
envExtra: true,
|
|
981
|
+
outDir: "dist",
|
|
982
|
+
watch: true,
|
|
983
|
+
clearRestartLogs: true,
|
|
984
|
+
minify: false,
|
|
985
|
+
sourcemap: false,
|
|
986
|
+
nodeOptions: [],
|
|
987
|
+
antiCrash: true
|
|
988
|
+
};
|
|
989
|
+
function getConfig() {
|
|
990
|
+
return globalConfig;
|
|
991
|
+
}
|
|
992
|
+
var requiredProps = ["src", "main"];
|
|
993
|
+
function defineConfig(config) {
|
|
994
|
+
for (const prop of requiredProps) {
|
|
995
|
+
if (!config[prop]) {
|
|
996
|
+
throw new Error(`[CommandKit Config] Missing required config property: ${prop}`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
globalConfig = {
|
|
1000
|
+
...globalConfig,
|
|
1001
|
+
...config
|
|
1002
|
+
};
|
|
1003
|
+
return globalConfig;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// src/utils/signal.ts
|
|
1007
|
+
var context = [];
|
|
1008
|
+
function createSignal(value) {
|
|
1009
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
1010
|
+
let disposed = false;
|
|
1011
|
+
let val = value instanceof Function ? value() : value;
|
|
1012
|
+
const getter = () => {
|
|
1013
|
+
if (!disposed) {
|
|
1014
|
+
const running = getCurrentObserver();
|
|
1015
|
+
if (running)
|
|
1016
|
+
subscribers.add(running);
|
|
1017
|
+
}
|
|
1018
|
+
return val;
|
|
1019
|
+
};
|
|
1020
|
+
const setter = (newValue) => {
|
|
1021
|
+
if (disposed)
|
|
1022
|
+
return;
|
|
1023
|
+
val = newValue instanceof Function ? newValue(val) : newValue;
|
|
1024
|
+
for (const subscriber of subscribers) {
|
|
1025
|
+
subscriber();
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
const dispose = () => {
|
|
1029
|
+
subscribers.clear();
|
|
1030
|
+
disposed = true;
|
|
1031
|
+
};
|
|
1032
|
+
return [getter, setter, dispose];
|
|
1033
|
+
}
|
|
1034
|
+
function createEffect(callback) {
|
|
1035
|
+
const execute = () => {
|
|
1036
|
+
context.push(execute);
|
|
1037
|
+
try {
|
|
1038
|
+
callback();
|
|
1039
|
+
} finally {
|
|
1040
|
+
context.pop();
|
|
1041
|
+
}
|
|
1042
|
+
};
|
|
1043
|
+
execute();
|
|
1044
|
+
}
|
|
1045
|
+
function getCurrentObserver() {
|
|
1046
|
+
return context[context.length - 1];
|
|
1047
|
+
}
|
|
888
1048
|
export {
|
|
1049
|
+
ButtonKit,
|
|
889
1050
|
CommandKit,
|
|
890
|
-
|
|
891
|
-
|
|
1051
|
+
createEffect,
|
|
1052
|
+
createSignal,
|
|
1053
|
+
defineConfig,
|
|
1054
|
+
getConfig
|
|
892
1055
|
};
|