js-discord-modularcommand 1.1.0 → 2.0.0

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.
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @file Manages command cooldowns for users to prevent spam.
3
+ * @author vicentefelipechile
4
+ * @license MIT
5
+ */
6
+ /**
7
+ * @interface CooldownStatus
8
+ * @description Represents the cooldown status of a user for a specific command.
9
+ */
10
+ interface CooldownStatus {
11
+ /** Indicates if the user is currently on cooldown. */
12
+ inCooldown: boolean;
13
+ /** The remaining time in seconds until the cooldown expires. It will be 0 if the user is not in cooldown. */
14
+ waitTime: number;
15
+ }
16
+ /**
17
+ * Registers a new command and its cooldown duration in the internal maps.
18
+ * @param {string} name - The name of the command to register.
19
+ * @param {number} duration - The cooldown duration in seconds.
20
+ * @returns {void}
21
+ */
22
+ export declare function cooldownRegister(name: string, duration: number): void;
23
+ /**
24
+ * Gets the last execution timestamp for a user on a specific command.
25
+ * @param {string} name - The name of the command.
26
+ * @param {string} userId - The ID of the user.
27
+ * @returns {number | undefined} The timestamp (in milliseconds) of the last execution, or `undefined` if not found.
28
+ */
29
+ export declare function cooldownGetUser(name: string, userId: string): number | undefined;
30
+ /**
31
+ * Sets the current timestamp for a user on a specific command, effectively starting their cooldown.
32
+ * @param {string} name - The name of the command.
33
+ * @param {string} userId - The ID of the user.
34
+ * @returns {void}
35
+ */
36
+ export declare function cooldownSetUser(name: string, userId: string): void;
37
+ /**
38
+ * Checks if a user is currently on cooldown for a specific command.
39
+ * @param {string} name - The name of the command.
40
+ * @param {string} userId - The ID of the user.
41
+ * @returns {CooldownStatus} An object indicating if the user is in cooldown and the remaining time.
42
+ */
43
+ export default function isUserInCooldown(name: string, userId: string): CooldownStatus;
44
+ export {};
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ /**
3
+ * @file Manages command cooldowns for users to prevent spam.
4
+ * @author vicentefelipechile
5
+ * @license MIT
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.cooldownRegister = cooldownRegister;
9
+ exports.cooldownGetUser = cooldownGetUser;
10
+ exports.cooldownSetUser = cooldownSetUser;
11
+ exports.default = isUserInCooldown;
12
+ // =================================================================================================
13
+ // Module-level State
14
+ // =================================================================================================
15
+ /**
16
+ * @description Stores the cooldown duration configured for each command.
17
+ * @maps Command name (string) to its cooldown duration in seconds (number).
18
+ */
19
+ const COMMAND_CONFIG = new Map();
20
+ /**
21
+ * @description Stores the last execution timestamp for each user on a specific command.
22
+ * @maps Command name (string) to another Map, which in turn maps a user's ID (string) to the execution timestamp (number).
23
+ */
24
+ const COOLDOWNS_MAP = new Map();
25
+ // =================================================================================================
26
+ // Public Functions
27
+ // =================================================================================================
28
+ /**
29
+ * Registers a new command and its cooldown duration in the internal maps.
30
+ * @param {string} name - The name of the command to register.
31
+ * @param {number} duration - The cooldown duration in seconds.
32
+ * @returns {void}
33
+ */
34
+ function cooldownRegister(name, duration) {
35
+ COMMAND_CONFIG.set(name, duration);
36
+ COOLDOWNS_MAP.set(name, new Map());
37
+ }
38
+ ;
39
+ /**
40
+ * Gets the last execution timestamp for a user on a specific command.
41
+ * @param {string} name - The name of the command.
42
+ * @param {string} userId - The ID of the user.
43
+ * @returns {number | undefined} The timestamp (in milliseconds) of the last execution, or `undefined` if not found.
44
+ */
45
+ function cooldownGetUser(name, userId) {
46
+ return COOLDOWNS_MAP.get(name)?.get(userId);
47
+ }
48
+ /**
49
+ * Sets the current timestamp for a user on a specific command, effectively starting their cooldown.
50
+ * @param {string} name - The name of the command.
51
+ * @param {string} userId - The ID of the user.
52
+ * @returns {void}
53
+ */
54
+ function cooldownSetUser(name, userId) {
55
+ COOLDOWNS_MAP.get(name)?.set(userId, Date.now());
56
+ }
57
+ /**
58
+ * Checks if a user is currently on cooldown for a specific command.
59
+ * @param {string} name - The name of the command.
60
+ * @param {string} userId - The ID of the user.
61
+ * @returns {CooldownStatus} An object indicating if the user is in cooldown and the remaining time.
62
+ */
63
+ function isUserInCooldown(name, userId) {
64
+ const lastTime = cooldownGetUser(name, userId);
65
+ // If the user has never used the command, they are not on cooldown.
66
+ if (lastTime === undefined) {
67
+ return { inCooldown: false, waitTime: 0 };
68
+ }
69
+ const timePassed = (Date.now() - lastTime) / 1000; // Time passed in seconds
70
+ const cooldownCommand = COMMAND_CONFIG.get(name);
71
+ // This error indicates a developer mistake, as a command should be registered before being checked.
72
+ if (cooldownCommand === undefined) {
73
+ throw new Error(`Command '${name}' isn't registered in the cooldown system.`);
74
+ }
75
+ if (timePassed < cooldownCommand) {
76
+ // If the time passed is less than the required cooldown, the user is still on cooldown.
77
+ return { inCooldown: true, waitTime: cooldownCommand - timePassed };
78
+ }
79
+ // Otherwise, the cooldown has expired.
80
+ return { inCooldown: false, waitTime: 0 };
81
+ }
package/dist/index.d.ts CHANGED
@@ -1,13 +1,10 @@
1
- import { ModularCommand, ModularButton, RegisterCommand } from "./modularcommand";
1
+ import { LOCALE_DELAY, LOCALE_ERROR, LOCALE_FORBIDDEN, LOCALE_NSFW } from "./locales";
2
+ import ModularCommandHandler from "./interaction";
3
+ import { CommandData } from "./types";
2
4
  import ModularModal from "./modularmodal";
3
- import { LOCALE_DELAY, LOCALE_ERROR, LOCALE_FORBIDDEN, LOCALE_NSFW, FormatSecondsLocale } from "./locales";
5
+ import ModularCommand from "./modularcommand";
6
+ import ModularButton from "./modularbutton";
7
+ import RegisterCommand from "./registercommand";
8
+ import LoadCommand from "./loadcommands";
4
9
  export default ModularCommand;
5
- export { ModularCommand };
6
- export { ModularButton };
7
- export { ModularModal };
8
- export { RegisterCommand };
9
- export { FormatSecondsLocale };
10
- export { LOCALE_DELAY };
11
- export { LOCALE_ERROR };
12
- export { LOCALE_FORBIDDEN };
13
- export { LOCALE_NSFW };
10
+ export { ModularCommand, ModularButton, ModularModal, CommandData, RegisterCommand, LoadCommand, ModularCommandHandler, LOCALE_DELAY, LOCALE_ERROR, LOCALE_FORBIDDEN, LOCALE_NSFW };
package/dist/index.js CHANGED
@@ -3,17 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.LOCALE_NSFW = exports.LOCALE_FORBIDDEN = exports.LOCALE_ERROR = exports.LOCALE_DELAY = exports.FormatSecondsLocale = exports.RegisterCommand = exports.ModularModal = exports.ModularButton = exports.ModularCommand = void 0;
7
- const modularcommand_1 = require("./modularcommand");
8
- Object.defineProperty(exports, "ModularCommand", { enumerable: true, get: function () { return modularcommand_1.ModularCommand; } });
9
- Object.defineProperty(exports, "ModularButton", { enumerable: true, get: function () { return modularcommand_1.ModularButton; } });
10
- Object.defineProperty(exports, "RegisterCommand", { enumerable: true, get: function () { return modularcommand_1.RegisterCommand; } });
11
- const modularmodal_1 = __importDefault(require("./modularmodal"));
12
- exports.ModularModal = modularmodal_1.default;
6
+ exports.LOCALE_NSFW = exports.LOCALE_FORBIDDEN = exports.LOCALE_ERROR = exports.LOCALE_DELAY = exports.ModularCommandHandler = exports.LoadCommand = exports.RegisterCommand = exports.ModularModal = exports.ModularButton = exports.ModularCommand = void 0;
13
7
  const locales_1 = require("./locales");
14
8
  Object.defineProperty(exports, "LOCALE_DELAY", { enumerable: true, get: function () { return locales_1.LOCALE_DELAY; } });
15
9
  Object.defineProperty(exports, "LOCALE_ERROR", { enumerable: true, get: function () { return locales_1.LOCALE_ERROR; } });
16
10
  Object.defineProperty(exports, "LOCALE_FORBIDDEN", { enumerable: true, get: function () { return locales_1.LOCALE_FORBIDDEN; } });
17
11
  Object.defineProperty(exports, "LOCALE_NSFW", { enumerable: true, get: function () { return locales_1.LOCALE_NSFW; } });
18
- Object.defineProperty(exports, "FormatSecondsLocale", { enumerable: true, get: function () { return locales_1.FormatSecondsLocale; } });
19
- exports.default = modularcommand_1.ModularCommand;
12
+ const interaction_1 = __importDefault(require("./interaction"));
13
+ exports.ModularCommandHandler = interaction_1.default;
14
+ const modularmodal_1 = __importDefault(require("./modularmodal"));
15
+ exports.ModularModal = modularmodal_1.default;
16
+ const modularcommand_1 = __importDefault(require("./modularcommand"));
17
+ exports.ModularCommand = modularcommand_1.default;
18
+ const modularbutton_1 = __importDefault(require("./modularbutton"));
19
+ exports.ModularButton = modularbutton_1.default;
20
+ const registercommand_1 = __importDefault(require("./registercommand"));
21
+ exports.RegisterCommand = registercommand_1.default;
22
+ const loadcommands_1 = __importDefault(require("./loadcommands"));
23
+ exports.LoadCommand = loadcommands_1.default;
24
+ exports.default = modularcommand_1.default;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @file Contains the logic for handling Discord bot interactions.
3
+ * @author vicentefelipechile
4
+ * @license MIT
5
+ */
6
+ import { BaseInteraction, CommandInteraction, MessageComponentInteraction, ModalSubmitInteraction } from "discord.js";
7
+ import { ClientWithCommands } from "./types";
8
+ /**
9
+ * @interface InteractionHandlerArgs
10
+ * @description Defines the arguments for the custom interaction handler function.
11
+ */
12
+ interface InteractionHandlerArgs {
13
+ /** The interaction received from Discord. */
14
+ interaction: CommandInteraction | MessageComponentInteraction | ModalSubmitInteraction;
15
+ }
16
+ /**
17
+ * @type InteractionHandler
18
+ * @description A function signature for a custom interaction handler.
19
+ * @returns {Promise<boolean | undefined>} A promise that resolves to `false` to stop the default handler, or `true`/`undefined` to continue.
20
+ */
21
+ type InteractionHandler = (args: InteractionHandlerArgs) => Promise<boolean | undefined>;
22
+ /**
23
+ * @description Creates a modular command handler function for the Discord client.
24
+ * @param {ClientWithCommands} client The Discord client instance with a commands collection.
25
+ * @param {InteractionHandler} customHandler A custom function to handle interactions before the default logic.
26
+ * @returns {(interaction: BaseInteraction) = Promise<void>} The main interaction handler function.
27
+ */
28
+ export default function ModularCommandHandler(client: ClientWithCommands, customHandler: InteractionHandler): (interaction: BaseInteraction) => Promise<void>;
29
+ export {};
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * @file Contains the logic for handling Discord bot interactions.
4
+ * @author vicentefelipechile
5
+ * @license MIT
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.default = ModularCommandHandler;
9
+ const discord_js_1 = require("discord.js");
10
+ const locales_1 = require("./locales");
11
+ // =================================================================================================
12
+ // Main Handler Function
13
+ // =================================================================================================
14
+ /**
15
+ * @description Creates a modular command handler function for the Discord client.
16
+ * @param {ClientWithCommands} client The Discord client instance with a commands collection.
17
+ * @param {InteractionHandler} customHandler A custom function to handle interactions before the default logic.
18
+ * @returns {(interaction: BaseInteraction) = Promise<void>} The main interaction handler function.
19
+ */
20
+ function ModularCommandHandler(client, customHandler) {
21
+ if (!client.commands) {
22
+ throw new Error(`Client is missing the 'commands' collection.`);
23
+ }
24
+ if (!(client.commands instanceof discord_js_1.Collection)) {
25
+ throw new Error(`Client.commands is not an instance of Discord.js Collection.`);
26
+ }
27
+ const handler = async (interaction) => {
28
+ if (!interaction.isChatInputCommand() && !interaction.isMessageComponent() && !interaction.isModalSubmit()) {
29
+ return;
30
+ }
31
+ const response = await customHandler({ interaction });
32
+ if (response === false)
33
+ return;
34
+ let commandName;
35
+ if (interaction.isChatInputCommand()) {
36
+ commandName = interaction.commandName;
37
+ }
38
+ else if (interaction.customId) {
39
+ commandName = interaction.customId.split('_')[0];
40
+ }
41
+ else {
42
+ const errorMessage = locales_1.LOCALE_ERROR[interaction.locale];
43
+ if (interaction.replied || interaction.deferred) {
44
+ await interaction.followUp({ content: errorMessage, flags: discord_js_1.MessageFlags.Ephemeral });
45
+ }
46
+ else {
47
+ await interaction.reply({ content: errorMessage, flags: discord_js_1.MessageFlags.Ephemeral });
48
+ }
49
+ console.error(`Interaction does not have a commandName or customId: ${interaction.id}`);
50
+ return;
51
+ }
52
+ const command = client.commands.get(commandName);
53
+ if (command === undefined) {
54
+ console.error(`No command found for interaction: ${interaction.id} with command name: ${commandName}`);
55
+ return;
56
+ }
57
+ try {
58
+ if (interaction.isChatInputCommand()) {
59
+ await command.execute(interaction);
60
+ }
61
+ else if (interaction.isButton() && command.buttonExecute) {
62
+ await command.buttonExecute(interaction);
63
+ }
64
+ else if (interaction.isMessageComponent() && command.componentExecute) {
65
+ await command.componentExecute(interaction);
66
+ }
67
+ else if (interaction.isModalSubmit() && command.modalExecute) {
68
+ await command.modalExecute(interaction);
69
+ }
70
+ }
71
+ catch (error) {
72
+ const errorMessage = locales_1.LOCALE_ERROR[interaction.locale];
73
+ if (interaction.replied || interaction.deferred) {
74
+ await interaction.followUp({ content: errorMessage, flags: discord_js_1.MessageFlags.Ephemeral });
75
+ }
76
+ else {
77
+ await interaction.reply({ content: errorMessage, flags: discord_js_1.MessageFlags.Ephemeral });
78
+ }
79
+ console.error(`Error handling interaction: ${interaction.id}`, error);
80
+ }
81
+ };
82
+ return handler;
83
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file Contains the logic for loading modular commands into the Discord bot client.
3
+ * @author vicentefelipechile
4
+ * @license MIT
5
+ */
6
+ import { CommandData } from "./types";
7
+ /**
8
+ * @description Loads one or more commands into an array.
9
+ * @param {CommandData[]} commandsArray The array where the loaded commands will be stored.
10
+ * @param {CommandData | CommandData[]} command The command(s) to load. Can be a single `CommandData` object or an array of them.
11
+ * @throws {TypeError} If a command is missing the `execute` function.
12
+ * @example
13
+ * ```typescript
14
+ * import { Collection } from "discord.js";
15
+ * import LoadCommand from "./loadcommands";
16
+ * import exampleCommand from "./commands/example";
17
+ *
18
+ * const commandsList: CommandData[] = [];
19
+ * LoadCommand(commandsList, exampleCommand);
20
+ *
21
+ * const client = { commands: new Collection<string, CommandData>() };
22
+ * for (const cmd of commandsList) {
23
+ * client.commands.set(cmd.data.name, cmd);
24
+ * }
25
+ * ```
26
+ */
27
+ export default function LoadCommand(commandsArray: CommandData[], command: CommandData | CommandData[]): void;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ /**
3
+ * @file Contains the logic for loading modular commands into the Discord bot client.
4
+ * @author vicentefelipechile
5
+ * @license MIT
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.default = LoadCommand;
9
+ // =================================================================================================
10
+ // Main Loading Function
11
+ // =================================================================================================
12
+ /**
13
+ * @description Loads one or more commands into an array.
14
+ * @param {CommandData[]} commandsArray The array where the loaded commands will be stored.
15
+ * @param {CommandData | CommandData[]} command The command(s) to load. Can be a single `CommandData` object or an array of them.
16
+ * @throws {TypeError} If a command is missing the `execute` function.
17
+ * @example
18
+ * ```typescript
19
+ * import { Collection } from "discord.js";
20
+ * import LoadCommand from "./loadcommands";
21
+ * import exampleCommand from "./commands/example";
22
+ *
23
+ * const commandsList: CommandData[] = [];
24
+ * LoadCommand(commandsList, exampleCommand);
25
+ *
26
+ * const client = { commands: new Collection<string, CommandData>() };
27
+ * for (const cmd of commandsList) {
28
+ * client.commands.set(cmd.data.name, cmd);
29
+ * }
30
+ * ```
31
+ */
32
+ function LoadCommand(commandsArray, command) {
33
+ const commands = Array.isArray(command) ? command : [command];
34
+ for (const cmd of commands) {
35
+ if (typeof cmd.execute !== "function") {
36
+ throw new TypeError(`Command "${cmd.data.name}" is missing a required 'execute' function.`);
37
+ }
38
+ commandsArray.push(cmd);
39
+ }
40
+ }
package/dist/locales.d.ts CHANGED
@@ -1,51 +1,20 @@
1
1
  /**
2
- * @module ModularCommand Locales
3
- * @description Generic localization phrases used throughout the application.
2
+ * @file Contains the generic localization phrases used throughout the application.
3
+ * @author vicentefelipechile
4
4
  * @license MIT
5
5
  */
6
6
  import { Locale } from "discord.js";
7
+ import LOCALE_DELAY, { ModularLocale } from "./modularlocale";
7
8
  /**
8
- * @description Function to handle seconds format
9
- * @param phrase The phrase to format
10
- * @param time The time in seconds
11
- * @returns The formatted string
12
- * @example ```javascript
13
- * const phraseLocale = LOCALE_DELAY[Locale.EnglishUS];
14
- * const phrasePlural = FormatSecondsLocale(phraseLocale, 90);
15
- * console.log(phrasePlural); // 'You must wait 1 minute 30 seconds before using this command again.'
16
- *
17
- * const phraseSingular = FormatSecondsLocale(phraseLocale, 60);
18
- * console.log(phraseSingular); // 'You must wait 1 minute before using this command again.'
19
- * ```
20
- */
21
- declare function FormatSecondsLocale(phrase: string, time: number): string;
22
- /**
23
- * @description Localization phrases for delay commands.
24
- * @example
25
- * const example = LOCALE_DELAY[Locale.EnglishUS];
26
- *
27
- * console.log(FormatTimeLocale(example, 5)); // 'You must wait 5 seconds before using this command again.'
28
- * console.log(FormatTimeLocale(example, 63)); // 'You must wait 3 seconds and 1 minute before using this command again.'
29
- */
30
- declare const LOCALE_DELAY: Record<Locale, string>;
31
- /**
32
- * @description Localization phrases for various commands.
33
- * @example ```js
34
- * const example = LOCALE_FORBIDDEN[Locale.EnglishUS];
35
- * console.log(example); // 'You do not have permission to use this command.'
36
- * ```
9
+ * @description Localization phrases for various commands, specifically for permission errors.
37
10
  */
38
11
  declare const LOCALE_FORBIDDEN: Record<Locale, string>;
39
12
  /**
40
- * @description Localization phrases for NSFW commands.
41
- * @example ```js
42
- * const example = LOCALE_NSFW[Locale.EnglishUS];
43
- * console.log(example); // 'This command can only be used in NSFW channels.'
44
- * ```
13
+ * @description Localization phrases for NSFW command usage errors.
45
14
  */
46
15
  declare const LOCALE_NSFW: Record<Locale, string>;
47
16
  /**
48
- * Error messages for different locales.
49
- */
17
+ * @description Localization phrases for general application errors.
18
+ */
50
19
  declare const LOCALE_ERROR: Record<Locale, string>;
51
- export { FormatSecondsLocale, LOCALE_DELAY, LOCALE_ERROR, LOCALE_FORBIDDEN, LOCALE_NSFW };
20
+ export { LOCALE_DELAY, LOCALE_ERROR, LOCALE_FORBIDDEN, LOCALE_NSFW, ModularLocale };
package/dist/locales.js CHANGED
@@ -1,137 +1,53 @@
1
1
  "use strict";
2
2
  /**
3
- * @module ModularCommand Locales
4
- * @description Generic localization phrases used throughout the application.
3
+ * @file Contains the generic localization phrases used throughout the application.
4
+ * @author vicentefelipechile
5
5
  * @license MIT
6
6
  */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
7
40
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.LOCALE_NSFW = exports.LOCALE_FORBIDDEN = exports.LOCALE_ERROR = exports.LOCALE_DELAY = void 0;
9
- exports.FormatSecondsLocale = FormatSecondsLocale;
41
+ exports.ModularLocale = exports.LOCALE_NSFW = exports.LOCALE_FORBIDDEN = exports.LOCALE_ERROR = exports.LOCALE_DELAY = void 0;
10
42
  const discord_js_1 = require("discord.js");
43
+ const modularlocale_1 = __importStar(require("./modularlocale"));
44
+ exports.LOCALE_DELAY = modularlocale_1.default;
45
+ Object.defineProperty(exports, "ModularLocale", { enumerable: true, get: function () { return modularlocale_1.ModularLocale; } });
46
+ // =================================================================================================
47
+ // Localization Phrases
48
+ // =================================================================================================
11
49
  /**
12
- * Regular expressions for time formatting
13
- * Used to match and replace time-related placeholders in localization strings.
14
- */
15
- /**
16
- * @name SECONDS
17
- * @description Matches the `{seconds}` placeholder in localization strings to replace it with the amount of seconds of delay.
18
- */
19
- const SECONDS = new RegExp('\\{seconds(?:\\|([^}]+))?\\}', 'g');
20
- /**
21
- * @name SECONDS_PLURAL
22
- * @description Matches the `{seconds|plural|...}` placeholder in localization strings, unlike SECONDS RegEx, this one handles pluralization.
23
- */
24
- const SECONDS_PLURAL = new RegExp('\\{seconds\\|plural\\|([^}]+)\\}', 'g');
25
- /**
26
- * @name MINUTES
27
- * @description The same as `SECONDS`, but for minutes.
28
- */
29
- const MINUTES = new RegExp('\\{minutes(?:\\|([^}]+))?\\}', 'g');
30
- /**
31
- * @name MINUTES_PLURAL
32
- * @description Do we really need an explanation for this RegEx?
33
- */
34
- const MINUTES_PLURAL = new RegExp('\\{minutes\\|plural\\|([^}]+)\\}', 'g');
35
- /**
36
- * @description Function to handle seconds format
37
- * @param phrase The phrase to format
38
- * @param time The time in seconds
39
- * @returns The formatted string
40
- * @example ```javascript
41
- * const phraseLocale = LOCALE_DELAY[Locale.EnglishUS];
42
- * const phrasePlural = FormatSecondsLocale(phraseLocale, 90);
43
- * console.log(phrasePlural); // 'You must wait 1 minute 30 seconds before using this command again.'
44
- *
45
- * const phraseSingular = FormatSecondsLocale(phraseLocale, 60);
46
- * console.log(phraseSingular); // 'You must wait 1 minute before using this command again.'
47
- * ```
48
- */
49
- function FormatSecondsLocale(phrase, time) {
50
- const minutes = Math.floor(time / 60);
51
- const seconds = time % 60;
52
- let formattedPhrase = phrase;
53
- if (minutes > 0) {
54
- // Replace plural forms for minutes first
55
- formattedPhrase = formattedPhrase.replace(MINUTES_PLURAL, (match, p1) => {
56
- return minutes === 1 ? '' : p1;
57
- });
58
- // Replace minute values
59
- formattedPhrase = formattedPhrase.replace(MINUTES, (match, p1) => {
60
- if (p1) {
61
- // Handles patterns like {minutes|y $ minuto}
62
- return p1.replace('$', minutes.toString());
63
- }
64
- return minutes.toString();
65
- });
66
- }
67
- else {
68
- // If no minutes, remove all minute-related placeholders
69
- formattedPhrase = formattedPhrase.replace(MINUTES, '').replace(MINUTES_PLURAL, '');
70
- }
71
- if (seconds > 0 || minutes === 0) {
72
- // Replace plural forms for seconds
73
- formattedPhrase = formattedPhrase.replace(SECONDS_PLURAL, (match, p1) => {
74
- return seconds === 1 ? '' : p1;
75
- });
76
- // Replace second values
77
- formattedPhrase = formattedPhrase.replace(SECONDS, seconds.toString());
78
- }
79
- else {
80
- // If there are minutes but no seconds, remove second-related placeholders
81
- formattedPhrase = formattedPhrase.replace(SECONDS, '').replace(SECONDS_PLURAL, '');
82
- }
83
- // Clean up any remaining empty placeholders and extra spaces
84
- return formattedPhrase.replace(/\{[^}]+\}/g, '').replace(/\s+/g, ' ').trim();
85
- }
86
- /**
87
- * @description Localization phrases for delay commands.
88
- * @example
89
- * const example = LOCALE_DELAY[Locale.EnglishUS];
90
- *
91
- * console.log(FormatTimeLocale(example, 5)); // 'You must wait 5 seconds before using this command again.'
92
- * console.log(FormatTimeLocale(example, 63)); // 'You must wait 3 seconds and 1 minute before using this command again.'
93
- */
94
- const LOCALE_DELAY = {
95
- [discord_js_1.Locale.SpanishLATAM]: 'Debes esperar {seconds} segundo{seconds|plural|s} {minutes|y $ minuto}{minutes|plural|s} antes de utilizar este comando denuevo.',
96
- [discord_js_1.Locale.EnglishUS]: 'You must wait {seconds} second{seconds|plural|s} {minutes|and $ minute}{minutes|plural|s} before using this command again.',
97
- [discord_js_1.Locale.EnglishGB]: 'Good heavens! One must exhibit a spot of patience, you see. A brief pause of {seconds} second{seconds|plural|s} {minutes|and $ minute}{minutes|plural|s} is required before another attempt, what?',
98
- [discord_js_1.Locale.SpanishES]: '¡Joder, tío! ¡Que te esperes {seconds} segundo{seconds|plural|s} {minutes|y $ minuto}{minutes|plural|s}, coño! ¡No flipes y dale un respiro al bot, hostia ya!',
99
- [discord_js_1.Locale.PortugueseBR]: 'Você deve esperar {seconds} segundo{seconds|plural|s} {minutes|e $ minuto}{minutes|plural|s} antes de usar este comando novamente.',
100
- [discord_js_1.Locale.French]: 'Vous devez attendre {seconds} seconde{seconds|plural|s} {minutes|et $ minute}{minutes|plural|s} avant d\'utiliser cette commande à nouveau.',
101
- [discord_js_1.Locale.German]: 'Sie müssen {seconds} Sekunde{seconds|plural|n} {minutes|und $ Minute}{minutes|plural|n} warten, bevor Sie diesen Befehl erneut verwenden können.',
102
- [discord_js_1.Locale.Italian]: 'Devi aspettare {seconds} secondo{seconds|plural|i} {minutes|e $ minuto}{minutes|plural|i} prima di utilizzare di nuovo questo comando.',
103
- [discord_js_1.Locale.Russian]: 'Вы должны подождать {seconds} секунд{seconds|plural|у} {minutes|и $ минут}{minutes|plural|ы} перед повторным использованием этой команды.',
104
- [discord_js_1.Locale.ChineseCN]: '您必须等待 {seconds} 秒 {minutes|和 $ 分钟} 才能再次使用此命令。',
105
- [discord_js_1.Locale.ChineseTW]: '您必須等待 {seconds} 秒 {minutes|和 $ 分鐘} 才能再次使用此命令。',
106
- [discord_js_1.Locale.Japanese]: 'このコマンドを再度使用するには、{seconds} 秒 {minutes|と $ 分} 待つ必要があります。',
107
- [discord_js_1.Locale.Korean]: '이 명령어를 다시 사용하려면 {seconds} 초 {minutes|하고 $ 분} 기다려야 합니다.',
108
- [discord_js_1.Locale.Bulgarian]: 'Трябва да изчакате {seconds} секунд{seconds|plural|и} {minutes|и $ минут}{minutes|plural|и}, преди да използвате тази команда отново.',
109
- [discord_js_1.Locale.Czech]: 'Musíte počkat {seconds} sekund{seconds|plural|u} {minutes|a $ minut}{minutes|plural|y}, než znovu použijete tento příkaz.',
110
- [discord_js_1.Locale.Danish]: 'Du skal vente {seconds} sekund{seconds|plural|er} {minutes|og $ minut}{minutes|plural|ter} før du kan bruge denne kommando igen.',
111
- [discord_js_1.Locale.Dutch]: 'Je moet {seconds} seconde{seconds|plural|n} {minutes|en $ minuut}{minutes|plural|en} wachten voordat je dit commando opnieuw kunt gebruiken.',
112
- [discord_js_1.Locale.Finnish]: 'Sinun on odotettava {seconds} sekunti{seconds|plural|a} {minutes|ja $ minuutti}{minutes|plural|a} ennen kuin voit käyttää tätä komentoa uudelleen.',
113
- [discord_js_1.Locale.Hungarian]: 'Várnod kell {seconds} másodperc{seconds|plural|et} {minutes|és $ perc}{minutes|plural|et}, mielőtt újra használhatod ezt a parancsot.',
114
- [discord_js_1.Locale.Norwegian]: 'Du må vente {seconds} sekund{seconds|plural|er} {minutes|og $ minutt}{minutes|plural|er} før du kan bruke denne kommandoen igjen.',
115
- [discord_js_1.Locale.Polish]: 'Musisz poczekać {seconds} sekund{seconds|plural|y} {minutes|i $ minut}{minutes|plural|y}, zanim ponownie użyjesz tego polecenia.',
116
- [discord_js_1.Locale.Romanian]: 'Trebuie să aștepți {seconds} secund{seconds|plural|ă} {minutes|și $ minut}{minutes|plural|e} înainte de a folosi din nou acest comandă.',
117
- [discord_js_1.Locale.Swedish]: 'Du måste vänta {seconds} sekund{seconds|plural|er} {minutes|och $ minut}{minutes|plural|er} innan du kan använda det här kommandot igen.',
118
- [discord_js_1.Locale.Turkish]: 'Bu komutu tekrar kullanmadan önce {seconds} saniye {minutes|ve $ dakika} beklemelisiniz.',
119
- [discord_js_1.Locale.Ukrainian]: 'Вам потрібно почекати {seconds} секунд{seconds|plural|и} {minutes|і $ хвилин}{minutes|plural|и}, перш ніж знову використовувати цю команду.',
120
- [discord_js_1.Locale.Hindi]: 'आपको इस कमांड का उपयोग करने से पहले {seconds} सेकंड {minutes|और $ मिनट} इंतजार करना होगा।',
121
- [discord_js_1.Locale.Indonesian]: 'Anda harus menunggu {seconds} detik {minutes|dan $ menit} sebelum menggunakan perintah ini lagi.',
122
- [discord_js_1.Locale.Greek]: 'Πρέπει να περιμένετε {seconds} δευτερόλεπτ{seconds|plural|ο} {minutes|και $ λεπτό}{minutes|plural|ά} πριν χρησιμοποιήσετε ξανά αυτήν την εντολή.',
123
- [discord_js_1.Locale.Croatian]: 'Morate pričekati {seconds} sekund{seconds|plural|u} {minutes|i $ minut}{minutes|plural|e} prije nego što ponovno upotrijebite ovu naredbu.',
124
- [discord_js_1.Locale.Lithuanian]: 'Prieš vėl naudodamiesi šiuo komandu, turite palaukti {seconds} sekund{seconds|plural|ę} {minutes|ir $ minut}{minutes|plural|es}.',
125
- [discord_js_1.Locale.Thai]: 'คุณต้องรอ {seconds} วินาที {minutes|และ $ นาที} ก่อนที่จะใช้คำสั่งนี้อีกครั้ง',
126
- [discord_js_1.Locale.Vietnamese]: 'Bạn phải đợi {seconds} giây {minutes|và $ phút} trước khi sử dụng lại lệnh này.'
127
- };
128
- exports.LOCALE_DELAY = LOCALE_DELAY;
129
- /**
130
- * @description Localization phrases for various commands.
131
- * @example ```js
132
- * const example = LOCALE_FORBIDDEN[Locale.EnglishUS];
133
- * console.log(example); // 'You do not have permission to use this command.'
134
- * ```
50
+ * @description Localization phrases for various commands, specifically for permission errors.
135
51
  */
136
52
  const LOCALE_FORBIDDEN = {
137
53
  [discord_js_1.Locale.SpanishLATAM]: 'No tienes permiso para usar este comando.',
@@ -153,7 +69,7 @@ const LOCALE_FORBIDDEN = {
153
69
  [discord_js_1.Locale.Dutch]: 'Je hebt geen toestemming om deze opdracht te gebruiken.',
154
70
  [discord_js_1.Locale.Finnish]: 'Sinulla ei ole lupaa käyttää tätä komentoa.',
155
71
  [discord_js_1.Locale.Hungarian]: 'Nincs jogosultságod ehhez a parancshoz.',
156
- [discord_js_1.Locale.Norwegian]: 'Du har ikke tillatelse til å bruke denne kommandoen.',
72
+ [discord_js_1.Locale.Norwegian]: 'Du har ikke behörighet til å bruke denne kommandoen.',
157
73
  [discord_js_1.Locale.Polish]: 'Nie masz uprawnień do używania tej komendy.',
158
74
  [discord_js_1.Locale.Romanian]: 'Nu ai permisiunea de a folosi acest comandă.',
159
75
  [discord_js_1.Locale.Swedish]: 'Du har inte behörighet att använda det här kommandot.',
@@ -169,11 +85,7 @@ const LOCALE_FORBIDDEN = {
169
85
  };
170
86
  exports.LOCALE_FORBIDDEN = LOCALE_FORBIDDEN;
171
87
  /**
172
- * @description Localization phrases for NSFW commands.
173
- * @example ```js
174
- * const example = LOCALE_NSFW[Locale.EnglishUS];
175
- * console.log(example); // 'This command can only be used in NSFW channels.'
176
- * ```
88
+ * @description Localization phrases for NSFW command usage errors.
177
89
  */
178
90
  const LOCALE_NSFW = {
179
91
  [discord_js_1.Locale.SpanishLATAM]: 'Este comando solo puede ser usado en canales NSFW.',
@@ -211,8 +123,8 @@ const LOCALE_NSFW = {
211
123
  };
212
124
  exports.LOCALE_NSFW = LOCALE_NSFW;
213
125
  /**
214
- * Error messages for different locales.
215
- */
126
+ * @description Localization phrases for general application errors.
127
+ */
216
128
  const LOCALE_ERROR = {
217
129
  [discord_js_1.Locale.SpanishLATAM]: 'Ocurrió un error al procesar tu solicitud.',
218
130
  [discord_js_1.Locale.EnglishUS]: 'An error occurred while processing your request.',