/* * Copyright (C) 2026 Fluxer Contributors * * This file is part of Fluxer. * * Fluxer is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Fluxer is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Fluxer. If not, see . */ export const LIMIT_KEYS = [ 'avatar_max_size', 'emoji_max_size', 'feature_animated_avatar', 'feature_animated_banner', 'feature_custom_discriminator', 'feature_custom_notification_sounds', 'feature_early_access', 'feature_global_expressions', 'feature_higher_video_quality', 'feature_per_guild_profiles', 'feature_voice_entrance_sounds', 'max_attachments_per_message', 'max_bio_length', 'max_bookmarks', 'max_channels_per_category', 'max_created_packs', 'max_custom_backgrounds', 'max_embeds_per_message', 'max_favorite_meme_tags', 'max_favorite_memes', 'max_group_dm_recipients', 'max_group_dms_per_user', 'max_guild_channels', 'max_guild_emojis_animated_more', 'max_guild_emojis_animated', 'max_guild_emojis_static_more', 'max_guild_emojis_static', 'max_guild_invites', 'max_guild_members', 'max_guild_roles', 'max_guild_stickers_more', 'max_guild_stickers', 'max_guilds', 'max_installed_packs', 'max_attachment_file_size', 'max_message_length', 'max_pack_expressions', 'max_private_channels_per_user', 'max_reactions_per_message', 'max_relationships', 'max_users_per_message_reaction', 'max_voice_message_duration', 'max_webhooks_per_channel', 'max_webhooks_per_guild', 'sticker_max_size', ] as const; export type LimitKey = (typeof LIMIT_KEYS)[number]; export type LimitScope = 'user' | 'guild' | 'both'; export const LIMIT_KEY_SCOPES: Record = { avatar_max_size: 'user', emoji_max_size: 'guild', feature_animated_avatar: 'user', feature_animated_banner: 'user', feature_custom_discriminator: 'user', feature_custom_notification_sounds: 'user', feature_early_access: 'user', feature_global_expressions: 'user', feature_higher_video_quality: 'user', feature_per_guild_profiles: 'user', feature_voice_entrance_sounds: 'user', max_attachments_per_message: 'both', max_bio_length: 'user', max_bookmarks: 'user', max_channels_per_category: 'guild', max_created_packs: 'user', max_custom_backgrounds: 'user', max_embeds_per_message: 'both', max_favorite_meme_tags: 'user', max_favorite_memes: 'user', max_group_dm_recipients: 'user', max_group_dms_per_user: 'user', max_guild_channels: 'guild', max_guild_emojis_animated_more: 'guild', max_guild_emojis_animated: 'guild', max_guild_emojis_static_more: 'guild', max_guild_emojis_static: 'guild', max_guild_invites: 'guild', max_guild_members: 'guild', max_guild_roles: 'guild', max_guild_stickers_more: 'guild', max_guild_stickers: 'guild', max_guilds: 'user', max_installed_packs: 'user', max_attachment_file_size: 'both', max_message_length: 'both', max_pack_expressions: 'guild', max_private_channels_per_user: 'user', max_reactions_per_message: 'guild', max_relationships: 'user', max_users_per_message_reaction: 'guild', max_voice_message_duration: 'both', max_webhooks_per_channel: 'guild', max_webhooks_per_guild: 'guild', sticker_max_size: 'guild', }; export type LimitCategory = 'messages' | 'guilds' | 'channels' | 'expressions' | 'files' | 'social' | 'features'; export interface LimitKeyMetadata { key: LimitKey; label: string; description: string; category: LimitCategory; scope: LimitScope; isToggle: boolean; unit?: 'bytes' | 'count'; min?: number; max?: number; } export const LIMIT_CATEGORY_LABELS: Record = { messages: 'Messages', guilds: 'Guilds', channels: 'Channels', expressions: 'Expressions & Stickers', files: 'Files & Attachments', social: 'Social & Private', features: 'Premium Features', }; export const LIMIT_KEY_METADATA: Record = { max_message_length: { key: 'max_message_length', label: 'Max Message Length', description: 'Maximum number of characters per message', category: 'messages', scope: 'both', isToggle: false, unit: 'count', }, max_attachments_per_message: { key: 'max_attachments_per_message', label: 'Max Attachments per Message', description: 'Maximum number of file attachments per message', category: 'messages', scope: 'both', isToggle: false, unit: 'count', }, max_embeds_per_message: { key: 'max_embeds_per_message', label: 'Max Embeds per Message', description: 'Maximum number of embeds per message', category: 'messages', scope: 'both', isToggle: false, unit: 'count', }, max_reactions_per_message: { key: 'max_reactions_per_message', label: 'Max Reactions per Message', description: 'Maximum distinct reactions per message', category: 'messages', scope: 'guild', isToggle: false, unit: 'count', }, max_users_per_message_reaction: { key: 'max_users_per_message_reaction', label: 'Max Users per Reaction', description: 'Maximum users who can use the same reaction on a message', category: 'messages', scope: 'guild', isToggle: false, unit: 'count', }, max_voice_message_duration: { key: 'max_voice_message_duration', label: 'Max Voice Message Duration', description: 'Maximum duration in seconds for voice message recordings', category: 'messages', scope: 'both', isToggle: false, unit: 'count', }, max_guilds: { key: 'max_guilds', label: 'Max Guilds', description: 'Maximum number of guilds a user can join', category: 'guilds', scope: 'user', isToggle: false, unit: 'count', }, max_guild_members: { key: 'max_guild_members', label: 'Max Guild Members', description: 'Maximum members per guild', category: 'guilds', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_roles: { key: 'max_guild_roles', label: 'Max Guild Roles', description: 'Maximum roles per guild', category: 'guilds', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_invites: { key: 'max_guild_invites', label: 'Max Guild Invites', description: 'Maximum active invites per guild', category: 'guilds', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_channels: { key: 'max_guild_channels', label: 'Max Guild Channels', description: 'Maximum channels per guild', category: 'channels', scope: 'guild', isToggle: false, unit: 'count', }, max_channels_per_category: { key: 'max_channels_per_category', label: 'Max Channels per Category', description: 'Maximum channels per category', category: 'channels', scope: 'guild', isToggle: false, unit: 'count', }, max_webhooks_per_channel: { key: 'max_webhooks_per_channel', label: 'Max Webhooks per Channel', description: 'Maximum webhooks per channel', category: 'channels', scope: 'guild', isToggle: false, unit: 'count', }, max_webhooks_per_guild: { key: 'max_webhooks_per_guild', label: 'Max Webhooks per Guild', description: 'Maximum webhooks per guild', category: 'channels', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_emojis_static: { key: 'max_guild_emojis_static', label: 'Max Static Emojis', description: 'Maximum static emojis per guild', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_emojis_animated: { key: 'max_guild_emojis_animated', label: 'Max Animated Emojis', description: 'Maximum animated emojis per guild', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_emojis_static_more: { key: 'max_guild_emojis_static_more', label: 'Max Static Emojis (More Emoji)', description: 'Maximum static emojis with MORE_EMOJI feature', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_emojis_animated_more: { key: 'max_guild_emojis_animated_more', label: 'Max Animated Emojis (More Emoji)', description: 'Maximum animated emojis with MORE_EMOJI feature', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_stickers: { key: 'max_guild_stickers', label: 'Max Stickers', description: 'Maximum stickers per guild', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_guild_stickers_more: { key: 'max_guild_stickers_more', label: 'Max Stickers (More Stickers)', description: 'Maximum stickers with MORE_STICKERS feature', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, emoji_max_size: { key: 'emoji_max_size', label: 'Emoji Max Size', description: 'Maximum file size for emoji uploads', category: 'expressions', scope: 'guild', isToggle: false, unit: 'bytes', }, sticker_max_size: { key: 'sticker_max_size', label: 'Sticker Max Size', description: 'Maximum file size for sticker uploads', category: 'expressions', scope: 'guild', isToggle: false, unit: 'bytes', }, max_pack_expressions: { key: 'max_pack_expressions', label: 'Max Pack Expressions', description: 'Maximum expressions per pack', category: 'expressions', scope: 'guild', isToggle: false, unit: 'count', }, max_created_packs: { key: 'max_created_packs', label: 'Max Created Packs', description: 'Maximum expression packs a user can create', category: 'expressions', scope: 'user', isToggle: false, unit: 'count', }, max_installed_packs: { key: 'max_installed_packs', label: 'Max Installed Packs', description: 'Maximum expression packs a user can install', category: 'expressions', scope: 'user', isToggle: false, unit: 'count', }, max_attachment_file_size: { key: 'max_attachment_file_size', label: 'Max Attachment File Size', description: 'Maximum size of each attachment file', category: 'files', scope: 'both', isToggle: false, unit: 'bytes', }, avatar_max_size: { key: 'avatar_max_size', label: 'Avatar Max Size', description: 'Maximum file size for avatar uploads', category: 'files', scope: 'user', isToggle: false, unit: 'bytes', }, max_custom_backgrounds: { key: 'max_custom_backgrounds', label: 'Max Custom Backgrounds', description: 'Maximum custom profile backgrounds', category: 'files', scope: 'user', isToggle: false, unit: 'count', }, max_relationships: { key: 'max_relationships', label: 'Max Relationships', description: 'Maximum friends/blocked users', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_private_channels_per_user: { key: 'max_private_channels_per_user', label: 'Max Private Channels', description: 'Maximum DM channels per user', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_group_dms_per_user: { key: 'max_group_dms_per_user', label: 'Max Group DMs', description: 'Maximum group DMs a user can own', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_group_dm_recipients: { key: 'max_group_dm_recipients', label: 'Max Group DM Recipients', description: 'Maximum users per group DM', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_bio_length: { key: 'max_bio_length', label: 'Max Bio Length', description: 'Maximum characters in user bio', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_bookmarks: { key: 'max_bookmarks', label: 'Max Bookmarks', description: 'Maximum bookmarked messages', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_favorite_memes: { key: 'max_favorite_memes', label: 'Max Favorite Memes', description: 'Maximum favorited memes', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, max_favorite_meme_tags: { key: 'max_favorite_meme_tags', label: 'Max Favorite Meme Tags', description: 'Maximum meme tags to track', category: 'social', scope: 'user', isToggle: false, unit: 'count', }, feature_animated_avatar: { key: 'feature_animated_avatar', label: 'Animated Avatar', description: 'Allow animated avatar uploads', category: 'features', scope: 'user', isToggle: true, }, feature_animated_banner: { key: 'feature_animated_banner', label: 'Animated Banner', description: 'Allow animated banner uploads', category: 'features', scope: 'user', isToggle: true, }, feature_custom_discriminator: { key: 'feature_custom_discriminator', label: 'Custom Discriminator', description: 'Allow custom discriminator selection', category: 'features', scope: 'user', isToggle: true, }, feature_custom_notification_sounds: { key: 'feature_custom_notification_sounds', label: 'Custom Notification Sounds', description: 'Allow custom notification sounds', category: 'features', scope: 'user', isToggle: true, }, feature_early_access: { key: 'feature_early_access', label: 'Early Access', description: 'Access to beta features', category: 'features', scope: 'user', isToggle: true, }, feature_global_expressions: { key: 'feature_global_expressions', label: 'Global Expressions', description: 'Use expressions across all guilds', category: 'features', scope: 'user', isToggle: true, }, feature_higher_video_quality: { key: 'feature_higher_video_quality', label: 'Higher Video Quality', description: 'Access to higher video streaming quality', category: 'features', scope: 'user', isToggle: true, }, feature_per_guild_profiles: { key: 'feature_per_guild_profiles', label: 'Per-Guild Profiles', description: 'Different profile per guild', category: 'features', scope: 'user', isToggle: true, }, feature_voice_entrance_sounds: { key: 'feature_voice_entrance_sounds', label: 'Voice Entrance Sounds', description: 'Play sound when joining voice', category: 'features', scope: 'user', isToggle: true, }, };