diff --git a/src/api/routes/channels/#channel_id/index.ts b/src/api/routes/channels/#channel_id/index.ts index 15d0e0175..3318eca2e 100644 --- a/src/api/routes/channels/#channel_id/index.ts +++ b/src/api/routes/channels/#channel_id/index.ts @@ -77,7 +77,7 @@ router.delete( recipient.save(), emitEvent({ event: "CHANNEL_DELETE", - data: channel, + data: channel.toJSON(), user_id: req.user_id, } satisfies ChannelDeleteEvent), ]); @@ -120,7 +120,7 @@ router.delete( Channel.deleteChannel(channel), emitEvent({ event: "CHANNEL_DELETE", - data: channel, + data: channel.toJSON(), channel_id, } satisfies ChannelDeleteEvent), ]); diff --git a/src/api/routes/channels/#channel_id/messages/index.ts b/src/api/routes/channels/#channel_id/messages/index.ts index bd0f32ec9..eada48759 100644 --- a/src/api/routes/channels/#channel_id/messages/index.ts +++ b/src/api/routes/channels/#channel_id/messages/index.ts @@ -338,17 +338,17 @@ router.post( data: { guild_id: channel.guild_id!, id: channel.id, - member_count: channel.member_count, + member_count: channel.member_count ?? 0, // TODO: is this the right fix? added_members: [{ user_id: req.user_id, ...threadMember.toJSON() }], }, channel_id: channel.id, - } as ThreadMembersUpdateEvent); + } satisfies ThreadMembersUpdateEvent); await emitEvent({ event: "THREAD_CREATE", data: { ...channel.toJSON(), newly_created: false }, user_id: req.user_id, - } as ThreadCreateEvent); + } satisfies ThreadCreateEvent); } } } else { diff --git a/src/api/routes/channels/#channel_id/thread-members.ts b/src/api/routes/channels/#channel_id/thread-members.ts index 83b1b2930..9006fa144 100644 --- a/src/api/routes/channels/#channel_id/thread-members.ts +++ b/src/api/routes/channels/#channel_id/thread-members.ts @@ -102,17 +102,17 @@ router.post( data: { guild_id: thread.guild_id!, id: thread.id, - member_count: thread.member_count, + member_count: thread.member_count ?? 0, //TODO: is this the right fix? added_members: [{ user_id: user_id, ...threadMember.toJSON() }], }, channel_id: thread.id, - } as ThreadMembersUpdateEvent); + } satisfies ThreadMembersUpdateEvent); await emitEvent({ event: "THREAD_CREATE", data: { ...thread.toJSON(), newly_created: false }, user_id: user_id, - } as ThreadCreateEvent); + } satisfies ThreadCreateEvent); return res.status(204).send(); }, @@ -151,11 +151,11 @@ router.delete( data: { guild_id: thread.guild_id!, id: thread.id, - member_count: thread.member_count, + member_count: thread.member_count ?? 0, // TODO: is this the right fix? removed_member_ids: [user_id], }, channel_id: thread.id, - } as ThreadMembersUpdateEvent); + } satisfies ThreadMembersUpdateEvent); if (thread.type === ChannelType.GUILD_PRIVATE_THREAD) await emitEvent({ event: "THREAD_DELETE", @@ -166,7 +166,7 @@ router.delete( type: thread.type, }, user_id: user_id, - } as ThreadDeleteEvent); + } satisfies ThreadDeleteEvent); return res.status(204).send(); }, @@ -193,7 +193,7 @@ router.patch( // event: "THREAD_MEMBER_UPDATE", // data: , // user_id: user_id, - // } as ThreadMemberUpdateEvent); + // } satisfies ThreadMemberUpdateEvent); return res.status(500).send("not implemented"); }, diff --git a/src/api/routes/guilds/#guild_id/channels.ts b/src/api/routes/guilds/#guild_id/channels.ts index f20463d14..5c87a1dc0 100644 --- a/src/api/routes/guilds/#guild_id/channels.ts +++ b/src/api/routes/guilds/#guild_id/channels.ts @@ -155,7 +155,7 @@ router.patch( await emitEvent({ event: "CHANNEL_UPDATE", - data: channel.toJSON(), + data: channel?.toJSON(), channel_id: channel.id, guild_id, } satisfies ChannelUpdateEvent); diff --git a/src/schemas/api/channels/Channel.ts b/src/schemas/api/channels/Channel.ts index e5d99074d..b9fb8c37b 100644 --- a/src/schemas/api/channels/Channel.ts +++ b/src/schemas/api/channels/Channel.ts @@ -1,5 +1,8 @@ -import { Channel, Recipient } from "@spacebar/util"; +import { Channel, Guild, Invite, Message, ReadState, Recipient, Tag, ThreadMember, User, VoiceState, Webhook } from "@spacebar/util"; import { HTTPError } from "lambert-server"; +import { Column, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm"; +import { Snowflake } from "../../Identifiers"; +import { PartialUser, PublicMember } from "../users"; export enum ChannelType { GUILD_TEXT = 0, // a text channel within a guild @@ -72,3 +75,60 @@ export function isTextChannel(type: ChannelType): boolean { throw new HTTPError("unimplemented", 400); } } + +// TODO: split up by channel type? +export interface PublicChannel { + id: Snowflake; + type: ChannelType; + guild_id?: Snowflake; + position?: number; + permission_overwrites?: ChannelPermissionOverwrite[]; + name?: string | null; + topic?: string | null; + nsfw?: boolean; + last_message_id?: Snowflake | null; + last_pin_timestamp?: string | null; + bitrate?: number; + user_limit?: number; + rate_limit_per_user?: number; + recipients?: PartialUser[]; + recipient_flags?: number; + icon?: string | null; + // nicks?: ChannelNick[]; // TODO + managed?: boolean; + blocked_user_warning_dismissed?: boolean; + // safety_warnings?: SafetyWarning[]; // TODO + application_id?: Snowflake; + owner_id?: Snowflake; + owner?: PublicMember | null; + parent_id?: Snowflake | null; + rtc_region?: string | null; + video_quality_mode?: number; + total_message_sent?: number; + message_count?: number; + member_count?: number; + member_ids_preview?: Snowflake[]; + thread_metadata?: ThreadMetadata; + member?: ThreadMember; + default_auto_archive_duration?: number | null; + default_thread_rate_limit_per_user?: number; + permissions?: string; + flags?: number; + available_tags?: Tag[]; + applied_tags?: Snowflake[]; + default_reaction_emoji?: string | null; // DefaultReaction type..? this is supposed to be an object apparently + default_forum_layout?: number; + default_sort_order?: number | null; + default_tag_setting?: string; + // icon_emoji?: IconEmoji | null; // TODO + is_message_request?: boolean; + is_message_request_timestamp?: string | null; + is_spam?: boolean; + theme_color?: number | null; + status?: string | null; + hd_streaming_until?: string | null; + hd_streaming_buyer_id?: Snowflake | null; + // linked_lobby?: LinkedLobby | null; // TODO + is_linkable?: boolean; + is_viewable_and_writeable_by_all_members?: boolean; +} diff --git a/src/util/entities/Channel.ts b/src/util/entities/Channel.ts index 4e7123f0a..1fa552b24 100644 --- a/src/util/entities/Channel.ts +++ b/src/util/entities/Channel.ts @@ -32,7 +32,7 @@ import { User } from "./User"; import { VoiceState } from "./VoiceState"; import { Webhook } from "./Webhook"; import { Member } from "./Member"; -import { ChannelPermissionOverwrite, ChannelType, PublicUserProjection, ThreadMetadata } from "@spacebar/schemas"; +import { ChannelPermissionOverwrite, ChannelType, PublicChannel, PublicUserProjection, ThreadMetadata } from "@spacebar/schemas"; import { OrmUtils } from "../imports"; import { ThreadMember } from "./ThreadMember"; @@ -409,18 +409,18 @@ export class Channel extends BaseClass { newly_created: true, }, guild_id: channel.guild_id, - } as ThreadCreateEvent), + } satisfies ThreadCreateEvent), emitEvent({ event: "THREAD_MEMBERS_UPDATE", data: { - guild_id: channel.guild_id, + guild_id: channel.guild_id!, // TODO: is this the right fix? id: thread.id, - member_count: channel.member_count, + member_count: channel.member_count ?? 0, //TODO: is this the right fix? added_members: [threadMember], removed_member_ids: [], }, guild_id: channel.guild_id, - } as ThreadMembersUpdateEvent), + } satisfies ThreadMembersUpdateEvent), ]); } @@ -703,9 +703,12 @@ export class Channel extends BaseClass { } } - toJSON() { + toJSON(): PublicChannel { return { ...this, + last_pin_timestamp: this.last_pin_timestamp?.toISOString(), + recipients: undefined, //this.recipients?.map(x=>x.user.toPublicUser()), // TODO: fix me + owner: undefined, // TODO: fix me - this is thread owner // these fields are not returned depending on the type of channel bitrate: this.bitrate || undefined, diff --git a/src/util/entities/ThreadMember.ts b/src/util/entities/ThreadMember.ts index 22741bd61..a24ba3e99 100644 --- a/src/util/entities/ThreadMember.ts +++ b/src/util/entities/ThreadMember.ts @@ -106,13 +106,13 @@ export class ThreadMember extends BaseClassWithoutId { emitEvent({ event: "THREAD_MEMBERS_UPDATE", data: { - guild_id: channel.guild_id, + guild_id: channel.guild_id!, // TODO: is this the right fix? id: channel.id, - member_count: channel.member_count, + member_count: channel.member_count ?? 0, removed_member_ids: [member_id], }, channel_id: thread_id, - } as ThreadMembersUpdateEvent), + } satisfies ThreadMembersUpdateEvent), ]); } diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts index 87c8c812b..0072bb25a 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts @@ -44,6 +44,7 @@ import { GuildCreateResponse, InteractionFailureReason, PartialEmoji, + PublicChannel, PublicMember, PublicUser, PublicVoiceState, @@ -161,17 +162,17 @@ export interface ReadyEvent extends Event { export interface ChannelCreateEvent extends Event { event: "CHANNEL_CREATE"; - data: Channel; + data: PublicChannel; } export interface ChannelUpdateEvent extends Event { event: "CHANNEL_UPDATE"; - data: Channel; + data: PublicChannel; } export interface ChannelDeleteEvent extends Event { event: "CHANNEL_DELETE"; - data: Channel; + data: PublicChannel; } export interface ChannelPinsUpdateEvent extends Event { @@ -630,17 +631,17 @@ export interface GuildMemberListUpdate extends Event { export interface ThreadCreateEvent extends Event { event: "THREAD_CREATE"; - data: Channel & { newly_created: boolean }; + data: PublicChannel & { newly_created: boolean }; } export interface ThreadUpdatEvent extends Event { event: "THREAD_UPDATE"; - data: Channel; + data: PublicChannel; } export interface ThreadDeleteEvent extends Event { event: "THREAD_DELETE"; - data: Pick; + data: Pick; } export interface ThreadListSyncEvent extends Event {