This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251// SPDX-License-Identifier: AGPL-3.0-or-later
import type { GuildEmojiResponse, GuildEmojiWithUserResponse, GuildStickerResponse, GuildStickerWithUserResponse,} from '@fluxer/schema/src/domains/guild/GuildEmojiSchemas';import type {GuildBanResponse, GuildMemberResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';import type {GuildPartialResponse, GuildResponse} from '@fluxer/schema/src/domains/guild/GuildResponseSchemas';import type {GuildRoleResponse} from '@fluxer/schema/src/domains/guild/GuildRoleSchemas';import type {UserPartialResponse} from '@fluxer/schema/src/domains/user/UserResponseSchemas';import type {z} from 'zod';import { stripGuildBannerForFeatures, stripGuildIconForFeatures, stripGuildSplashForFeatures,} from '../infrastructure/AssetEntitlementUtils';import type {UserCacheService} from '../infrastructure/UserCacheService';import type {RequestCache} from '../middleware/RequestCacheMiddleware';import type {Guild} from '../models/Guild';import type {GuildBan} from '../models/GuildBan';import type {GuildEmoji} from '../models/GuildEmoji';import type {GuildMember} from '../models/GuildMember';import type {GuildRole} from '../models/GuildRole';import type {GuildSticker} from '../models/GuildSticker';import {getCachedUserPartialResponse, getCachedUserPartialResponses} from '../user/UserCacheHelpers';import {mapGuildFeatures} from './GuildFeatureUtils';
export function mapGuildToPartialResponse(guild: Guild): z.infer<typeof GuildPartialResponse> { const guildId = guild.id.toString(); const iconHash = stripGuildIconForFeatures(guild.iconHash, guild.features); const bannerHash = stripGuildBannerForFeatures(guild.bannerHash, guild.features); const splashHash = stripGuildSplashForFeatures(guild.splashHash, guild.features); const embedSplashHash = stripGuildSplashForFeatures(guild.embedSplashHash, guild.features); return { id: guildId, name: guild.name, icon: iconHash, banner: bannerHash, banner_width: bannerHash ? guild.bannerWidth : null, banner_height: bannerHash ? guild.bannerHeight : null, splash: splashHash, splash_width: splashHash ? guild.splashWidth : null, splash_height: splashHash ? guild.splashHeight : null, embed_splash: embedSplashHash, embed_splash_width: embedSplashHash ? guild.embedSplashWidth : null, embed_splash_height: embedSplashHash ? guild.embedSplashHeight : null, splash_card_alignment: guild.splashCardAlignment, features: mapGuildFeatures(guild.features), };}
export function mapGuildToGuildResponse( guild: Guild, options?: { permissions?: bigint | null; },): z.infer<typeof GuildResponse> { const iconHash = stripGuildIconForFeatures(guild.iconHash, guild.features); const bannerHash = stripGuildBannerForFeatures(guild.bannerHash, guild.features); const splashHash = stripGuildSplashForFeatures(guild.splashHash, guild.features); const embedSplashHash = stripGuildSplashForFeatures(guild.embedSplashHash, guild.features); return { id: guild.id.toString(), name: guild.name, icon: iconHash, banner: bannerHash, banner_width: bannerHash ? guild.bannerWidth : null, banner_height: bannerHash ? guild.bannerHeight : null, splash: splashHash, splash_width: splashHash ? guild.splashWidth : null, splash_height: splashHash ? guild.splashHeight : null, embed_splash: embedSplashHash, embed_splash_width: embedSplashHash ? guild.embedSplashWidth : null, embed_splash_height: embedSplashHash ? guild.embedSplashHeight : null, splash_card_alignment: guild.splashCardAlignment, vanity_url_code: guild.vanityUrlCode, owner_id: guild.ownerId.toString(), system_channel_id: guild.systemChannelId ? guild.systemChannelId.toString() : null, system_channel_flags: guild.systemChannelFlags, rules_channel_id: guild.rulesChannelId ? guild.rulesChannelId.toString() : null, afk_channel_id: guild.afkChannelId ? guild.afkChannelId.toString() : null, afk_timeout: guild.afkTimeout, features: mapGuildFeatures(guild.features), verification_level: guild.verificationLevel, mfa_level: guild.mfaLevel, nsfw_level: guild.nsfwLevel, nsfw: guild.nsfw, content_warning_level: guild.contentWarningLevel as 0 | 1, content_warning_text: guild.contentWarningText, explicit_content_filter: guild.explicitContentFilter, default_message_notifications: guild.defaultMessageNotifications, disabled_operations: guild.disabledOperations, message_history_cutoff: guild.messageHistoryCutoff ? guild.messageHistoryCutoff.toISOString() : null, permissions: options?.permissions != null ? options.permissions.toString() : undefined, };}
export function mapGuildRoleToResponse(role: GuildRole): z.infer<typeof GuildRoleResponse> { return { id: role.id.toString(), name: role.name, color: role.color, position: role.position, hoist_position: role.hoistPosition, permissions: role.permissions.toString(), hoist: role.isHoisted, mentionable: role.isMentionable, };}
export function mapGuildEmojiToResponse(emoji: GuildEmoji): z.infer<typeof GuildEmojiResponse> { const id = emoji.id.toString(); return { id, name: emoji.name, animated: emoji.isAnimated, nsfw: emoji.isNsfw, };}
export function mapGuildStickerToResponse(sticker: GuildSticker): z.infer<typeof GuildStickerResponse> { const id = sticker.id.toString(); return { id, name: sticker.name, description: sticker.description ?? '', tags: sticker.tags, animated: sticker.animated, nsfw: sticker.isNsfw, };}
function mapMemberWithUser( member: GuildMember, userPartial: z.infer<typeof UserPartialResponse>,): z.infer<typeof GuildMemberResponse> { const now = Date.now(); const isTimedOut = member.communicationDisabledUntil != null && member.communicationDisabledUntil.getTime() > now; return { user: userPartial, nick: member.nickname, avatar: member.isPremiumSanitized ? null : member.avatarHash, banner: member.isPremiumSanitized ? null : member.bannerHash, accent_color: member.accentColor, roles: Array.from(member.roleIds).map((id) => id.toString()), joined_at: member.joinedAt.toISOString(), mute: isTimedOut ? true : member.isMute, deaf: member.isDeaf, communication_disabled_until: member.communicationDisabledUntil?.toISOString() ?? null, profile_flags: member.profileFlags || undefined, mention_flags: member.mentionFlags || undefined, };}
export function isGuildMemberTimedOut(member?: z.infer<typeof GuildMemberResponse> | null): boolean { if (!member?.communication_disabled_until) { return false; } const timestamp = Date.parse(member.communication_disabled_until); return !Number.isNaN(timestamp) && timestamp > Date.now();}
export async function mapGuildMemberToResponse( member: GuildMember, userCacheService: Pick<UserCacheService, 'getUserPartialResponse'>, requestCache: RequestCache,): Promise<z.infer<typeof GuildMemberResponse>> { const userPartial = await getCachedUserPartialResponse({userId: member.userId, userCacheService, requestCache}); return mapMemberWithUser(member, userPartial);}
function mapEmojiWithUser( emoji: GuildEmoji, userPartial: z.infer<typeof UserPartialResponse>,): z.infer<typeof GuildEmojiWithUserResponse> { const id = emoji.id.toString(); return { id, name: emoji.name, animated: emoji.isAnimated, nsfw: emoji.isNsfw, user: userPartial, };}
export async function mapGuildEmojisWithUsersToResponse( emojis: Array<GuildEmoji>, userCacheService: Pick<UserCacheService, 'getUserPartialResponses'>, requestCache: RequestCache,): Promise<Array<z.infer<typeof GuildEmojiWithUserResponse>>> { const userIds = [...new Set(emojis.map((emoji) => emoji.creatorId))]; const userPartials = await getCachedUserPartialResponses({userIds, userCacheService, requestCache}); return emojis .filter((emoji) => userPartials.has(emoji.creatorId)) .map((emoji) => mapEmojiWithUser(emoji, userPartials.get(emoji.creatorId)!));}
function mapStickerWithUser( sticker: GuildSticker, userPartial: z.infer<typeof UserPartialResponse>,): z.infer<typeof GuildStickerWithUserResponse> { return { id: sticker.id.toString(), name: sticker.name, description: sticker.description ?? '', tags: sticker.tags, animated: sticker.animated, nsfw: sticker.isNsfw, user: userPartial, };}
export async function mapGuildStickersWithUsersToResponse( stickers: Array<GuildSticker>, userCacheService: Pick<UserCacheService, 'getUserPartialResponses'>, requestCache: RequestCache,): Promise<Array<z.infer<typeof GuildStickerWithUserResponse>>> { const userIds = [...new Set(stickers.map((sticker) => sticker.creatorId))]; const userPartials = await getCachedUserPartialResponses({userIds, userCacheService, requestCache}); return stickers .filter((sticker) => userPartials.has(sticker.creatorId)) .map((sticker) => mapStickerWithUser(sticker, userPartials.get(sticker.creatorId)!));}
function mapBanWithUser( ban: GuildBan, userPartial: z.infer<typeof UserPartialResponse>,): z.infer<typeof GuildBanResponse> { return { user: userPartial, reason: ban.reason, moderator_id: ban.moderatorId.toString(), banned_at: ban.bannedAt.toISOString(), expires_at: ban.expiresAt ? ban.expiresAt.toISOString() : null, };}
export async function mapGuildBansToResponse( bans: Array<GuildBan>, userCacheService: Pick<UserCacheService, 'getUserPartialResponses'>, requestCache: RequestCache,): Promise<Array<z.infer<typeof GuildBanResponse>>> { const userIds = [...new Set(bans.map((ban) => ban.userId))]; const userPartials = await getCachedUserPartialResponses({userIds, userCacheService, requestCache}); return bans .filter((ban) => userPartials.has(ban.userId)) .map((ban) => mapBanWithUser(ban, userPartials.get(ban.userId)!));}