/** * Shared utility functions for XP commands. * Provides permission checking, embed creation, formatting, and validation helpers. */ import { EmbedBuilder, type ChatInputCommandInteraction, type Interaction, type InteractionReplyOptions, type RepliableInteraction } from 'discord.js'; import type { CommandResult } from 'robo.js'; import type { GuildConfig } from '../types.js'; /** * Gets the required permission bit for admin commands. * Reads process.env.XP_ADMIN_PERMISSION to allow environment-driven permission override. * Falls back to PermissionFlagsBits.ManageGuild on invalid or missing values. * * @example * ```typescript * // In environment: XP_ADMIN_PERMISSION=Administrator * const permBit = getRequiredPermissionBit() // Returns PermissionFlagsBits.Administrator * ``` */ export declare function getRequiredPermissionBit(): bigint; /** * Checks if user has permission to run admin commands. * Supports env override via XP_ADMIN_PERMISSION for custom permission name. * * @example * ```typescript * if (!hasAdminPermission(interaction)) { * return createPermissionError() * } * ``` */ export declare function hasAdminPermission(interaction: ChatInputCommandInteraction): boolean; /** * Validates guild context and returns guildId or error message. * Uses discriminated union for type safety. * * @example * ```typescript * const guildCheck = requireGuild(interaction) * if (typeof guildCheck === 'string') { * return { embeds: [createErrorEmbed('Error', guildCheck)] } * } * const { guildId } = guildCheck * ``` */ export declare function requireGuild(interaction: Interaction): { guildId: string; } | string; /** * Returns the embed color from guild config theme or default Blurple. * * @param config - Guild configuration * @returns Embed color (number) * * @example * ```typescript * const color = getEmbedColor(config) // Returns 0x5865F2 if theme is set, otherwise Colors.Blurple * ``` */ export declare function getEmbedColor(config: GuildConfig): number; /** * Creates a Unicode progress bar from current/total values. * * @param current - Current progress value * @param total - Total/maximum value * @param length - Bar length in characters (default: 10, min: 5, max: 30) * @returns Progress bar string using ▰ (filled) and ▱ (empty) * * @example * ```typescript * createProgressBar(50, 100, 10) // Returns "▰▰▰▰▰▱▱▱▱▱" * createProgressBar(75, 100, 10) // Returns "▰▰▰▰▰▰▱▱▱▱" * createProgressBar(100, 100, 10) // Returns "▰▰▰▰▰▰▰▰▰▰" * createProgressBar(0, 100, 10) // Returns "▱▱▱▱▱▱▱▱" * ``` */ export declare function createProgressBar(current: number, total: number, length?: number): string; /** * Formats rank with ordinal suffix (e.g., '1st', '2nd', '3rd', '4th'). * * @param rank - Rank number (1-indexed) * @returns Formatted rank string with ordinal suffix * * @example * ```typescript * formatRank(1) // Returns "1st" * formatRank(2) // Returns "2nd" * formatRank(3) // Returns "3rd" * formatRank(4) // Returns "4th" * formatRank(11) // Returns "11th" * formatRank(21) // Returns "21st" * ``` */ export declare function formatRank(rank: number): string; /** * Formats multiplier as percentage or "None". * * @param multiplier - Multiplier value (e.g., 1.0, 1.5, 0.75) * @returns Formatted string (e.g., "None", "+50%", "-25%") * * @example * ```typescript * formatMultiplier(1.0) // Returns "None" * formatMultiplier(1.5) // Returns "+50%" * formatMultiplier(2.0) // Returns "+100%" * formatMultiplier(0.75) // Returns "-25%" * formatMultiplier(0.5) // Returns "-50%" * ``` */ export declare function formatMultiplier(multiplier: number): string; export declare function safeReply(interaction: RepliableInteraction, options: InteractionReplyOptions): Promise; /** * Creates a green success embed with optional fields. * * @param title - Embed title * @param description - Embed description * @param fields - Optional array of embed fields * @param color - Optional custom color (defaults to Colors.Green) * @returns EmbedBuilder with green color and timestamp */ export declare function createSuccessEmbed(title: string, description: string, fields?: Array<{ name: string; value: string; inline?: boolean; }>, color?: number): EmbedBuilder; /** * Creates a red error embed. * * @param title - Embed title * @param description - Error description * @returns EmbedBuilder with red color and timestamp */ export declare function createErrorEmbed(title: string, description: string): EmbedBuilder; /** * Creates a blue info embed with optional fields. * * @param title - Embed title * @param description - Embed description * @param fields - Optional array of embed fields * @param color - Optional custom color (defaults to Colors.Blue) * @returns EmbedBuilder with blue color and timestamp */ export declare function createInfoEmbed(title: string, description: string, fields?: Array<{ name: string; value: string; inline?: boolean; }>, color?: number): EmbedBuilder; /** * Formats XP with commas and custom label. * * @param xp - XP amount to format * @param label - Custom label for XP (defaults to 'XP') * @returns Formatted string with thousands separators * * @example * formatXP(1500) // Returns '1,500 XP' * formatXP(1500, 'Reputation') // Returns '1,500 Reputation' * formatXP(1500, 'Points') // Returns '1,500 Points' */ export declare function formatXP(xp: number, label?: string): string; /** * Extracts custom XP label from guild config with fallback to 'XP'. * * @param config - Guild configuration * @returns Custom XP display name or 'XP' if not configured * * @example * const label = getXpLabel(config) * // Returns 'Reputation' if config.labels.xpDisplayName is set * // Returns 'XP' if labels is undefined or xpDisplayName is undefined */ export declare function getXpLabel(config: GuildConfig): string; /** * Formats level (e.g., 'Level 5'). */ export declare function formatLevel(level: number): string; /** * Formats user mention (e.g., '<@123456789>'). */ export declare function formatUser(userId: string): string; /** * Formats role mention (e.g., '<@&123456789>'). */ export declare function formatRole(roleId: string): string; /** * Formats channel mention (e.g., '<#123456789>'). */ export declare function formatChannel(channelId: string): string; /** * Formats percentage (e.g., '75.5%'). */ export declare function formatPercentage(value: number): string; /** * Validates numeric amounts. * * @param amount - Number to validate * @param min - Minimum allowed value (default: 0) * @param max - Maximum allowed value (optional) * @returns Validation result with error message if invalid */ export declare function validateAmount(amount: number, min?: number, max?: number): { valid: boolean; error?: string; }; /** * Validates Discord snowflake (18-19 digits). */ export declare function validateSnowflake(id: string): boolean; /** * Returns standard permission denied error (ephemeral). */ export declare function createPermissionError(): CommandResult; /** * Returns standard guild-only error (ephemeral). */ export declare function createGuildOnlyError(): CommandResult; /** * Returns user not found error. */ export declare function createUserNotFoundError(userId: string): CommandResult;