Refacor electron app and add migrations
This commit is contained in:
20
electron/cqrs/commands/handlers/clearAllData.ts
Normal file
20
electron/cqrs/commands/handlers/clearAllData.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import {
|
||||
MessageEntity,
|
||||
UserEntity,
|
||||
RoomEntity,
|
||||
ReactionEntity,
|
||||
BanEntity,
|
||||
AttachmentEntity,
|
||||
MetaEntity
|
||||
} from '../../../entities';
|
||||
|
||||
export async function handleClearAllData(dataSource: DataSource): Promise<void> {
|
||||
await dataSource.getRepository(MessageEntity).clear();
|
||||
await dataSource.getRepository(UserEntity).clear();
|
||||
await dataSource.getRepository(RoomEntity).clear();
|
||||
await dataSource.getRepository(ReactionEntity).clear();
|
||||
await dataSource.getRepository(BanEntity).clear();
|
||||
await dataSource.getRepository(AttachmentEntity).clear();
|
||||
await dataSource.getRepository(MetaEntity).clear();
|
||||
}
|
||||
9
electron/cqrs/commands/handlers/clearRoomMessages.ts
Normal file
9
electron/cqrs/commands/handlers/clearRoomMessages.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { ClearRoomMessagesCommand } from '../../types';
|
||||
|
||||
export async function handleClearRoomMessages(command: ClearRoomMessagesCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
|
||||
await repo.delete({ roomId: command.payload.roomId });
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AttachmentEntity } from '../../../entities';
|
||||
import { DeleteAttachmentsForMessageCommand } from '../../types';
|
||||
|
||||
export async function handleDeleteAttachmentsForMessage(command: DeleteAttachmentsForMessageCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(AttachmentEntity);
|
||||
|
||||
await repo.delete({ messageId: command.payload.messageId });
|
||||
}
|
||||
9
electron/cqrs/commands/handlers/deleteMessage.ts
Normal file
9
electron/cqrs/commands/handlers/deleteMessage.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { DeleteMessageCommand } from '../../types';
|
||||
|
||||
export async function handleDeleteMessage(command: DeleteMessageCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
|
||||
await repo.delete({ id: command.payload.messageId });
|
||||
}
|
||||
9
electron/cqrs/commands/handlers/deleteRoom.ts
Normal file
9
electron/cqrs/commands/handlers/deleteRoom.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { RoomEntity, MessageEntity } from '../../../entities';
|
||||
import { DeleteRoomCommand } from '../../types';
|
||||
|
||||
export async function handleDeleteRoom(command: DeleteRoomCommand, dataSource: DataSource): Promise<void> {
|
||||
const { roomId } = command.payload;
|
||||
await dataSource.getRepository(RoomEntity).delete({ id: roomId });
|
||||
await dataSource.getRepository(MessageEntity).delete({ roomId });
|
||||
}
|
||||
9
electron/cqrs/commands/handlers/removeBan.ts
Normal file
9
electron/cqrs/commands/handlers/removeBan.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { BanEntity } from '../../../entities';
|
||||
import { RemoveBanCommand } from '../../types';
|
||||
|
||||
export async function handleRemoveBan(command: RemoveBanCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(BanEntity);
|
||||
|
||||
await repo.delete({ oderId: command.payload.oderId });
|
||||
}
|
||||
10
electron/cqrs/commands/handlers/removeReaction.ts
Normal file
10
electron/cqrs/commands/handlers/removeReaction.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { ReactionEntity } from '../../../entities';
|
||||
import { RemoveReactionCommand } from '../../types';
|
||||
|
||||
export async function handleRemoveReaction(command: RemoveReactionCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(ReactionEntity);
|
||||
const { messageId, userId, emoji } = command.payload;
|
||||
|
||||
await repo.delete({ messageId, userId, emoji });
|
||||
}
|
||||
21
electron/cqrs/commands/handlers/saveAttachment.ts
Normal file
21
electron/cqrs/commands/handlers/saveAttachment.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AttachmentEntity } from '../../../entities';
|
||||
import { SaveAttachmentCommand } from '../../types';
|
||||
|
||||
export async function handleSaveAttachment(command: SaveAttachmentCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(AttachmentEntity);
|
||||
const { attachment } = command.payload;
|
||||
const entity = repo.create({
|
||||
id: attachment.id,
|
||||
messageId: attachment.messageId,
|
||||
filename: attachment.filename,
|
||||
size: attachment.size,
|
||||
mime: attachment.mime,
|
||||
isImage: attachment.isImage ? 1 : 0,
|
||||
uploaderPeerId: attachment.uploaderPeerId ?? null,
|
||||
filePath: attachment.filePath ?? null,
|
||||
savedPath: attachment.savedPath ?? null
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
20
electron/cqrs/commands/handlers/saveBan.ts
Normal file
20
electron/cqrs/commands/handlers/saveBan.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { BanEntity } from '../../../entities';
|
||||
import { SaveBanCommand } from '../../types';
|
||||
|
||||
export async function handleSaveBan(command: SaveBanCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(BanEntity);
|
||||
const { ban } = command.payload;
|
||||
const entity = repo.create({
|
||||
oderId: ban.oderId,
|
||||
roomId: ban.roomId,
|
||||
userId: ban.userId ?? null,
|
||||
bannedBy: ban.bannedBy,
|
||||
displayName: ban.displayName ?? null,
|
||||
reason: ban.reason ?? null,
|
||||
expiresAt: ban.expiresAt ?? null,
|
||||
timestamp: ban.timestamp
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
24
electron/cqrs/commands/handlers/saveMessage.ts
Normal file
24
electron/cqrs/commands/handlers/saveMessage.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { SaveMessageCommand } from '../../types';
|
||||
|
||||
export async function handleSaveMessage(command: SaveMessageCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
const { message } = command.payload;
|
||||
|
||||
const entity = repo.create({
|
||||
id: message.id,
|
||||
roomId: message.roomId,
|
||||
channelId: message.channelId ?? null,
|
||||
senderId: message.senderId,
|
||||
senderName: message.senderName,
|
||||
content: message.content,
|
||||
timestamp: message.timestamp,
|
||||
editedAt: message.editedAt ?? null,
|
||||
reactions: JSON.stringify(message.reactions ?? []),
|
||||
isDeleted: message.isDeleted ? 1 : 0,
|
||||
replyToId: message.replyToId ?? null,
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
26
electron/cqrs/commands/handlers/saveReaction.ts
Normal file
26
electron/cqrs/commands/handlers/saveReaction.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { ReactionEntity } from '../../../entities';
|
||||
import { SaveReactionCommand } from '../../types';
|
||||
|
||||
export async function handleSaveReaction(command: SaveReactionCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(ReactionEntity);
|
||||
const { reaction } = command.payload;
|
||||
// Deduplicate: skip if same messageId + userId + emoji already exists
|
||||
const existing = await repo.findOne({
|
||||
where: { messageId: reaction.messageId, userId: reaction.userId, emoji: reaction.emoji }
|
||||
});
|
||||
|
||||
if (existing)
|
||||
return;
|
||||
|
||||
const entity = repo.create({
|
||||
id: reaction.id,
|
||||
messageId: reaction.messageId,
|
||||
oderId: reaction.oderId ?? null,
|
||||
userId: reaction.userId ?? null,
|
||||
emoji: reaction.emoji,
|
||||
timestamp: reaction.timestamp
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
26
electron/cqrs/commands/handlers/saveRoom.ts
Normal file
26
electron/cqrs/commands/handlers/saveRoom.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { RoomEntity } from '../../../entities';
|
||||
import { SaveRoomCommand } from '../../types';
|
||||
|
||||
export async function handleSaveRoom(command: SaveRoomCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(RoomEntity);
|
||||
const { room } = command.payload;
|
||||
const entity = repo.create({
|
||||
id: room.id,
|
||||
name: room.name,
|
||||
description: room.description ?? null,
|
||||
topic: room.topic ?? null,
|
||||
hostId: room.hostId,
|
||||
password: room.password ?? null,
|
||||
isPrivate: room.isPrivate ? 1 : 0,
|
||||
createdAt: room.createdAt,
|
||||
userCount: room.userCount ?? 0,
|
||||
maxUsers: room.maxUsers ?? null,
|
||||
icon: room.icon ?? null,
|
||||
iconUpdatedAt: room.iconUpdatedAt ?? null,
|
||||
permissions: room.permissions != null ? JSON.stringify(room.permissions) : null,
|
||||
channels: room.channels != null ? JSON.stringify(room.channels) : null
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
26
electron/cqrs/commands/handlers/saveUser.ts
Normal file
26
electron/cqrs/commands/handlers/saveUser.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { UserEntity } from '../../../entities';
|
||||
import { SaveUserCommand } from '../../types';
|
||||
|
||||
export async function handleSaveUser(command: SaveUserCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(UserEntity);
|
||||
const { user } = command.payload;
|
||||
const entity = repo.create({
|
||||
id: user.id,
|
||||
oderId: user.oderId ?? null,
|
||||
username: user.username ?? null,
|
||||
displayName: user.displayName ?? null,
|
||||
avatarUrl: user.avatarUrl ?? null,
|
||||
status: user.status ?? null,
|
||||
role: user.role ?? null,
|
||||
joinedAt: user.joinedAt ?? null,
|
||||
peerId: user.peerId ?? null,
|
||||
isOnline: user.isOnline ? 1 : 0,
|
||||
isAdmin: user.isAdmin ? 1 : 0,
|
||||
isRoomOwner: user.isRoomOwner ? 1 : 0,
|
||||
voiceState: user.voiceState != null ? JSON.stringify(user.voiceState) : null,
|
||||
screenShareState: user.screenShareState != null ? JSON.stringify(user.screenShareState) : null
|
||||
});
|
||||
|
||||
await repo.save(entity);
|
||||
}
|
||||
9
electron/cqrs/commands/handlers/setCurrentUserId.ts
Normal file
9
electron/cqrs/commands/handlers/setCurrentUserId.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MetaEntity } from '../../../entities';
|
||||
import { SetCurrentUserIdCommand } from '../../types';
|
||||
|
||||
export async function handleSetCurrentUserId(command: SetCurrentUserIdCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(MetaEntity);
|
||||
|
||||
await repo.save({ key: 'currentUserId', value: command.payload.userId });
|
||||
}
|
||||
41
electron/cqrs/commands/handlers/updateMessage.ts
Normal file
41
electron/cqrs/commands/handlers/updateMessage.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { UpdateMessageCommand } from '../../types';
|
||||
|
||||
export async function handleUpdateMessage(command: UpdateMessageCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
const { messageId, updates } = command.payload;
|
||||
const existing = await repo.findOne({ where: { id: messageId } });
|
||||
|
||||
if (!existing)
|
||||
return;
|
||||
|
||||
if (updates.channelId !== undefined)
|
||||
existing.channelId = updates.channelId ?? null;
|
||||
|
||||
if (updates.senderId !== undefined)
|
||||
existing.senderId = updates.senderId;
|
||||
|
||||
if (updates.senderName !== undefined)
|
||||
existing.senderName = updates.senderName;
|
||||
|
||||
if (updates.content !== undefined)
|
||||
existing.content = updates.content;
|
||||
|
||||
if (updates.timestamp !== undefined)
|
||||
existing.timestamp = updates.timestamp;
|
||||
|
||||
if (updates.editedAt !== undefined)
|
||||
existing.editedAt = updates.editedAt ?? null;
|
||||
|
||||
if (updates.reactions !== undefined)
|
||||
existing.reactions = JSON.stringify(updates.reactions ?? []);
|
||||
|
||||
if (updates.isDeleted !== undefined)
|
||||
existing.isDeleted = updates.isDeleted ? 1 : 0;
|
||||
|
||||
if (updates.replyToId !== undefined)
|
||||
existing.replyToId = updates.replyToId ?? null;
|
||||
|
||||
await repo.save(existing);
|
||||
}
|
||||
29
electron/cqrs/commands/handlers/updateRoom.ts
Normal file
29
electron/cqrs/commands/handlers/updateRoom.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { RoomEntity } from '../../../entities';
|
||||
import { UpdateRoomCommand } from '../../types';
|
||||
import {
|
||||
applyUpdates,
|
||||
boolToInt,
|
||||
jsonOrNull,
|
||||
TransformMap
|
||||
} from './utils/applyUpdates';
|
||||
|
||||
const ROOM_TRANSFORMS: TransformMap = {
|
||||
isPrivate: boolToInt,
|
||||
userCount: (val) => (val ?? 0),
|
||||
permissions: jsonOrNull,
|
||||
channels: jsonOrNull
|
||||
};
|
||||
|
||||
export async function handleUpdateRoom(command: UpdateRoomCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(RoomEntity);
|
||||
const { roomId, updates } = command.payload;
|
||||
const existing = await repo.findOne({ where: { id: roomId } });
|
||||
|
||||
if (!existing)
|
||||
return;
|
||||
|
||||
applyUpdates(existing, updates, ROOM_TRANSFORMS);
|
||||
await repo.save(existing);
|
||||
}
|
||||
|
||||
30
electron/cqrs/commands/handlers/updateUser.ts
Normal file
30
electron/cqrs/commands/handlers/updateUser.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { UserEntity } from '../../../entities';
|
||||
import { UpdateUserCommand } from '../../types';
|
||||
import {
|
||||
applyUpdates,
|
||||
boolToInt,
|
||||
jsonOrNull,
|
||||
TransformMap
|
||||
} from './utils/applyUpdates';
|
||||
|
||||
const USER_TRANSFORMS: TransformMap = {
|
||||
isOnline: boolToInt,
|
||||
isAdmin: boolToInt,
|
||||
isRoomOwner: boolToInt,
|
||||
voiceState: jsonOrNull,
|
||||
screenShareState: jsonOrNull
|
||||
};
|
||||
|
||||
export async function handleUpdateUser(command: UpdateUserCommand, dataSource: DataSource): Promise<void> {
|
||||
const repo = dataSource.getRepository(UserEntity);
|
||||
const { userId, updates } = command.payload;
|
||||
const existing = await repo.findOne({ where: { id: userId } });
|
||||
|
||||
if (!existing)
|
||||
return;
|
||||
|
||||
applyUpdates(existing, updates, USER_TRANSFORMS);
|
||||
await repo.save(existing);
|
||||
}
|
||||
|
||||
32
electron/cqrs/commands/handlers/utils/applyUpdates.ts
Normal file
32
electron/cqrs/commands/handlers/utils/applyUpdates.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/** Converts a boolean-like value to SQLite's 0/1 integer representation. */
|
||||
export const boolToInt = (val: unknown) => (val ? 1 : 0);
|
||||
|
||||
/** Serialises an object to a JSON string, or returns null if the value is null/undefined. */
|
||||
export const jsonOrNull = (val: unknown) => (val != null ? JSON.stringify(val) : null);
|
||||
|
||||
/** A map of field names to transform functions that handle special serialisation. */
|
||||
export type TransformMap = Partial<Record<string, (val: unknown) => unknown>>;
|
||||
|
||||
/**
|
||||
* Applies a partial `updates` object onto an existing entity.
|
||||
*
|
||||
* - Fields absent from `updates` (undefined) are skipped entirely.
|
||||
* - Fields listed in `transforms` are passed through their transform function first.
|
||||
* - All other fields are written as-is, falling back to null when the value is null/undefined.
|
||||
*/
|
||||
export function applyUpdates<T extends object>(
|
||||
entity: T,
|
||||
updates: Partial<Record<string, unknown>>,
|
||||
transforms: TransformMap = {}
|
||||
): void {
|
||||
const target = entity as unknown as Record<string, unknown>;
|
||||
|
||||
for (const [key, value] of Object.entries(updates)) {
|
||||
if (value === undefined)
|
||||
continue;
|
||||
|
||||
const transform = transforms[key];
|
||||
|
||||
target[key] = transform ? transform(value) : (value ?? null);
|
||||
}
|
||||
}
|
||||
59
electron/cqrs/commands/index.ts
Normal file
59
electron/cqrs/commands/index.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import {
|
||||
CommandType,
|
||||
CommandTypeKey,
|
||||
Command,
|
||||
SaveMessageCommand,
|
||||
DeleteMessageCommand,
|
||||
UpdateMessageCommand,
|
||||
ClearRoomMessagesCommand,
|
||||
SaveReactionCommand,
|
||||
RemoveReactionCommand,
|
||||
SaveUserCommand,
|
||||
SetCurrentUserIdCommand,
|
||||
UpdateUserCommand,
|
||||
SaveRoomCommand,
|
||||
DeleteRoomCommand,
|
||||
UpdateRoomCommand,
|
||||
SaveBanCommand,
|
||||
RemoveBanCommand,
|
||||
SaveAttachmentCommand,
|
||||
DeleteAttachmentsForMessageCommand
|
||||
} from '../types';
|
||||
import { handleSaveMessage } from './handlers/saveMessage';
|
||||
import { handleDeleteMessage } from './handlers/deleteMessage';
|
||||
import { handleUpdateMessage } from './handlers/updateMessage';
|
||||
import { handleClearRoomMessages } from './handlers/clearRoomMessages';
|
||||
import { handleSaveReaction } from './handlers/saveReaction';
|
||||
import { handleRemoveReaction } from './handlers/removeReaction';
|
||||
import { handleSaveUser } from './handlers/saveUser';
|
||||
import { handleSetCurrentUserId } from './handlers/setCurrentUserId';
|
||||
import { handleUpdateUser } from './handlers/updateUser';
|
||||
import { handleSaveRoom } from './handlers/saveRoom';
|
||||
import { handleDeleteRoom } from './handlers/deleteRoom';
|
||||
import { handleUpdateRoom } from './handlers/updateRoom';
|
||||
import { handleSaveBan } from './handlers/saveBan';
|
||||
import { handleRemoveBan } from './handlers/removeBan';
|
||||
import { handleSaveAttachment } from './handlers/saveAttachment';
|
||||
import { handleDeleteAttachmentsForMessage } from './handlers/deleteAttachmentsForMessage';
|
||||
import { handleClearAllData } from './handlers/clearAllData';
|
||||
|
||||
export const buildCommandHandlers = (dataSource: DataSource): Record<CommandTypeKey, (command: Command) => Promise<unknown>> => ({
|
||||
[CommandType.SaveMessage]: (cmd) => handleSaveMessage(cmd as SaveMessageCommand, dataSource),
|
||||
[CommandType.DeleteMessage]: (cmd) => handleDeleteMessage(cmd as DeleteMessageCommand, dataSource),
|
||||
[CommandType.UpdateMessage]: (cmd) => handleUpdateMessage(cmd as UpdateMessageCommand, dataSource),
|
||||
[CommandType.ClearRoomMessages]: (cmd) => handleClearRoomMessages(cmd as ClearRoomMessagesCommand, dataSource),
|
||||
[CommandType.SaveReaction]: (cmd) => handleSaveReaction(cmd as SaveReactionCommand, dataSource),
|
||||
[CommandType.RemoveReaction]: (cmd) => handleRemoveReaction(cmd as RemoveReactionCommand, dataSource),
|
||||
[CommandType.SaveUser]: (cmd) => handleSaveUser(cmd as SaveUserCommand, dataSource),
|
||||
[CommandType.SetCurrentUserId]: (cmd) => handleSetCurrentUserId(cmd as SetCurrentUserIdCommand, dataSource),
|
||||
[CommandType.UpdateUser]: (cmd) => handleUpdateUser(cmd as UpdateUserCommand, dataSource),
|
||||
[CommandType.SaveRoom]: (cmd) => handleSaveRoom(cmd as SaveRoomCommand, dataSource),
|
||||
[CommandType.DeleteRoom]: (cmd) => handleDeleteRoom(cmd as DeleteRoomCommand, dataSource),
|
||||
[CommandType.UpdateRoom]: (cmd) => handleUpdateRoom(cmd as UpdateRoomCommand, dataSource),
|
||||
[CommandType.SaveBan]: (cmd) => handleSaveBan(cmd as SaveBanCommand, dataSource),
|
||||
[CommandType.RemoveBan]: (cmd) => handleRemoveBan(cmd as RemoveBanCommand, dataSource),
|
||||
[CommandType.SaveAttachment]: (cmd) => handleSaveAttachment(cmd as SaveAttachmentCommand, dataSource),
|
||||
[CommandType.DeleteAttachmentsForMessage]: (cmd) => handleDeleteAttachmentsForMessage(cmd as DeleteAttachmentsForMessageCommand, dataSource),
|
||||
[CommandType.ClearAllData]: () => handleClearAllData(dataSource)
|
||||
});
|
||||
103
electron/cqrs/mappers.ts
Normal file
103
electron/cqrs/mappers.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Takes TypeORM entity rows and converts them to plain DTO objects
|
||||
* matching the Angular-side interfaces.
|
||||
*/
|
||||
|
||||
import { MessageEntity } from '../entities/MessageEntity';
|
||||
import { UserEntity } from '../entities/UserEntity';
|
||||
import { RoomEntity } from '../entities/RoomEntity';
|
||||
import { ReactionEntity } from '../entities/ReactionEntity';
|
||||
import { BanEntity } from '../entities/BanEntity';
|
||||
import { AttachmentEntity } from '../entities/AttachmentEntity';
|
||||
|
||||
export function rowToMessage(row: MessageEntity) {
|
||||
return {
|
||||
id: row.id,
|
||||
roomId: row.roomId,
|
||||
channelId: row.channelId ?? undefined,
|
||||
senderId: row.senderId,
|
||||
senderName: row.senderName,
|
||||
content: row.content,
|
||||
timestamp: row.timestamp,
|
||||
editedAt: row.editedAt ?? undefined,
|
||||
reactions: JSON.parse(row.reactions || '[]') as unknown[],
|
||||
isDeleted: !!row.isDeleted,
|
||||
replyToId: row.replyToId ?? undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function rowToUser(row: UserEntity) {
|
||||
return {
|
||||
id: row.id,
|
||||
oderId: row.oderId ?? '',
|
||||
username: row.username ?? '',
|
||||
displayName: row.displayName ?? '',
|
||||
avatarUrl: row.avatarUrl ?? undefined,
|
||||
status: row.status ?? 'offline',
|
||||
role: row.role ?? 'member',
|
||||
joinedAt: row.joinedAt ?? 0,
|
||||
peerId: row.peerId ?? undefined,
|
||||
isOnline: !!row.isOnline,
|
||||
isAdmin: !!row.isAdmin,
|
||||
isRoomOwner: !!row.isRoomOwner,
|
||||
voiceState: row.voiceState ? JSON.parse(row.voiceState) : undefined,
|
||||
screenShareState: row.screenShareState ? JSON.parse(row.screenShareState) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function rowToRoom(row: RoomEntity) {
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
description: row.description ?? undefined,
|
||||
topic: row.topic ?? undefined,
|
||||
hostId: row.hostId,
|
||||
password: row.password ?? undefined,
|
||||
isPrivate: !!row.isPrivate,
|
||||
createdAt: row.createdAt,
|
||||
userCount: row.userCount,
|
||||
maxUsers: row.maxUsers ?? undefined,
|
||||
icon: row.icon ?? undefined,
|
||||
iconUpdatedAt: row.iconUpdatedAt ?? undefined,
|
||||
permissions: row.permissions ? JSON.parse(row.permissions) : undefined,
|
||||
channels: row.channels ? JSON.parse(row.channels) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function rowToReaction(row: ReactionEntity) {
|
||||
return {
|
||||
id: row.id,
|
||||
messageId: row.messageId,
|
||||
oderId: row.oderId ?? '',
|
||||
userId: row.userId ?? '',
|
||||
emoji: row.emoji,
|
||||
timestamp: row.timestamp
|
||||
};
|
||||
}
|
||||
|
||||
export function rowToAttachment(row: AttachmentEntity) {
|
||||
return {
|
||||
id: row.id,
|
||||
messageId: row.messageId,
|
||||
filename: row.filename,
|
||||
size: row.size,
|
||||
mime: row.mime,
|
||||
isImage: !!row.isImage,
|
||||
uploaderPeerId: row.uploaderPeerId ?? undefined,
|
||||
filePath: row.filePath ?? undefined,
|
||||
savedPath: row.savedPath ?? undefined
|
||||
};
|
||||
}
|
||||
|
||||
export function rowToBan(row: BanEntity) {
|
||||
return {
|
||||
oderId: row.oderId,
|
||||
userId: row.userId ?? '',
|
||||
roomId: row.roomId,
|
||||
bannedBy: row.bannedBy,
|
||||
displayName: row.displayName ?? undefined,
|
||||
reason: row.reason ?? undefined,
|
||||
expiresAt: row.expiresAt ?? undefined,
|
||||
timestamp: row.timestamp
|
||||
};
|
||||
}
|
||||
10
electron/cqrs/queries/handlers/getAllAttachments.ts
Normal file
10
electron/cqrs/queries/handlers/getAllAttachments.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AttachmentEntity } from '../../../entities';
|
||||
import { rowToAttachment } from '../../mappers';
|
||||
|
||||
export async function handleGetAllAttachments(dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(AttachmentEntity);
|
||||
const rows = await repo.find();
|
||||
|
||||
return rows.map(rowToAttachment);
|
||||
}
|
||||
10
electron/cqrs/queries/handlers/getAllRooms.ts
Normal file
10
electron/cqrs/queries/handlers/getAllRooms.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { RoomEntity } from '../../../entities';
|
||||
import { rowToRoom } from '../../mappers';
|
||||
|
||||
export async function handleGetAllRooms(dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(RoomEntity);
|
||||
const rows = await repo.find();
|
||||
|
||||
return rows.map(rowToRoom);
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getAttachmentsForMessage.ts
Normal file
11
electron/cqrs/queries/handlers/getAttachmentsForMessage.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { AttachmentEntity } from '../../../entities';
|
||||
import { GetAttachmentsForMessageQuery } from '../../types';
|
||||
import { rowToAttachment } from '../../mappers';
|
||||
|
||||
export async function handleGetAttachmentsForMessage(query: GetAttachmentsForMessageQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(AttachmentEntity);
|
||||
const rows = await repo.find({ where: { messageId: query.payload.messageId } });
|
||||
|
||||
return rows.map(rowToAttachment);
|
||||
}
|
||||
16
electron/cqrs/queries/handlers/getBansForRoom.ts
Normal file
16
electron/cqrs/queries/handlers/getBansForRoom.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { BanEntity } from '../../../entities';
|
||||
import { GetBansForRoomQuery } from '../../types';
|
||||
import { rowToBan } from '../../mappers';
|
||||
|
||||
export async function handleGetBansForRoom(query: GetBansForRoomQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(BanEntity);
|
||||
const now = Date.now();
|
||||
const rows = await repo
|
||||
.createQueryBuilder('ban')
|
||||
.where('ban.roomId = :roomId', { roomId: query.payload.roomId })
|
||||
.andWhere('(ban.expiresAt IS NULL OR ban.expiresAt > :now)', { now })
|
||||
.getMany();
|
||||
|
||||
return rows.map(rowToBan);
|
||||
}
|
||||
16
electron/cqrs/queries/handlers/getCurrentUser.ts
Normal file
16
electron/cqrs/queries/handlers/getCurrentUser.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { UserEntity, MetaEntity } from '../../../entities';
|
||||
import { rowToUser } from '../../mappers';
|
||||
|
||||
export async function handleGetCurrentUser(dataSource: DataSource) {
|
||||
const metaRepo = dataSource.getRepository(MetaEntity);
|
||||
const metaRow = await metaRepo.findOne({ where: { key: 'currentUserId' } });
|
||||
|
||||
if (!metaRow?.value)
|
||||
return null;
|
||||
|
||||
const userRepo = dataSource.getRepository(UserEntity);
|
||||
const userRow = await userRepo.findOne({ where: { id: metaRow.value } });
|
||||
|
||||
return userRow ? rowToUser(userRow) : null;
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getMessageById.ts
Normal file
11
electron/cqrs/queries/handlers/getMessageById.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { GetMessageByIdQuery } from '../../types';
|
||||
import { rowToMessage } from '../../mappers';
|
||||
|
||||
export async function handleGetMessageById(query: GetMessageByIdQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
const row = await repo.findOne({ where: { id: query.payload.messageId } });
|
||||
|
||||
return row ? rowToMessage(row) : null;
|
||||
}
|
||||
17
electron/cqrs/queries/handlers/getMessages.ts
Normal file
17
electron/cqrs/queries/handlers/getMessages.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { MessageEntity } from '../../../entities';
|
||||
import { GetMessagesQuery } from '../../types';
|
||||
import { rowToMessage } from '../../mappers';
|
||||
|
||||
export async function handleGetMessages(query: GetMessagesQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(MessageEntity);
|
||||
const { roomId, limit = 100, offset = 0 } = query.payload;
|
||||
const rows = await repo.find({
|
||||
where: { roomId },
|
||||
order: { timestamp: 'ASC' },
|
||||
take: limit,
|
||||
skip: offset
|
||||
});
|
||||
|
||||
return rows.map(rowToMessage);
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getReactionsForMessage.ts
Normal file
11
electron/cqrs/queries/handlers/getReactionsForMessage.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { ReactionEntity } from '../../../entities';
|
||||
import { GetReactionsForMessageQuery } from '../../types';
|
||||
import { rowToReaction } from '../../mappers';
|
||||
|
||||
export async function handleGetReactionsForMessage(query: GetReactionsForMessageQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(ReactionEntity);
|
||||
const rows = await repo.find({ where: { messageId: query.payload.messageId } });
|
||||
|
||||
return rows.map(rowToReaction);
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getRoom.ts
Normal file
11
electron/cqrs/queries/handlers/getRoom.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { RoomEntity } from '../../../entities';
|
||||
import { GetRoomQuery } from '../../types';
|
||||
import { rowToRoom } from '../../mappers';
|
||||
|
||||
export async function handleGetRoom(query: GetRoomQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(RoomEntity);
|
||||
const row = await repo.findOne({ where: { id: query.payload.roomId } });
|
||||
|
||||
return row ? rowToRoom(row) : null;
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getUser.ts
Normal file
11
electron/cqrs/queries/handlers/getUser.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { UserEntity } from '../../../entities';
|
||||
import { GetUserQuery } from '../../types';
|
||||
import { rowToUser } from '../../mappers';
|
||||
|
||||
export async function handleGetUser(query: GetUserQuery, dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(UserEntity);
|
||||
const row = await repo.findOne({ where: { id: query.payload.userId } });
|
||||
|
||||
return row ? rowToUser(row) : null;
|
||||
}
|
||||
11
electron/cqrs/queries/handlers/getUsersByRoom.ts
Normal file
11
electron/cqrs/queries/handlers/getUsersByRoom.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { UserEntity } from '../../../entities';
|
||||
import { rowToUser } from '../../mappers';
|
||||
|
||||
/** Returns all stored users (room filtering not applicable in this schema). */
|
||||
export async function handleGetUsersByRoom(dataSource: DataSource) {
|
||||
const repo = dataSource.getRepository(UserEntity);
|
||||
const rows = await repo.find();
|
||||
|
||||
return rows.map(rowToUser);
|
||||
}
|
||||
16
electron/cqrs/queries/handlers/isUserBanned.ts
Normal file
16
electron/cqrs/queries/handlers/isUserBanned.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import { BanEntity } from '../../../entities';
|
||||
import { IsUserBannedQuery } from '../../types';
|
||||
|
||||
export async function handleIsUserBanned(query: IsUserBannedQuery, dataSource: DataSource): Promise<boolean> {
|
||||
const repo = dataSource.getRepository(BanEntity);
|
||||
const now = Date.now();
|
||||
const { userId, roomId } = query.payload;
|
||||
const rows = await repo
|
||||
.createQueryBuilder('ban')
|
||||
.where('ban.roomId = :roomId', { roomId })
|
||||
.andWhere('(ban.expiresAt IS NULL OR ban.expiresAt > :now)', { now })
|
||||
.getMany();
|
||||
|
||||
return rows.some((row) => row.oderId === userId);
|
||||
}
|
||||
41
electron/cqrs/queries/index.ts
Normal file
41
electron/cqrs/queries/index.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { DataSource } from 'typeorm';
|
||||
import {
|
||||
QueryType,
|
||||
QueryTypeKey,
|
||||
Query,
|
||||
GetMessagesQuery,
|
||||
GetMessageByIdQuery,
|
||||
GetReactionsForMessageQuery,
|
||||
GetUserQuery,
|
||||
GetRoomQuery,
|
||||
GetBansForRoomQuery,
|
||||
IsUserBannedQuery,
|
||||
GetAttachmentsForMessageQuery
|
||||
} from '../types';
|
||||
import { handleGetMessages } from './handlers/getMessages';
|
||||
import { handleGetMessageById } from './handlers/getMessageById';
|
||||
import { handleGetReactionsForMessage } from './handlers/getReactionsForMessage';
|
||||
import { handleGetUser } from './handlers/getUser';
|
||||
import { handleGetCurrentUser } from './handlers/getCurrentUser';
|
||||
import { handleGetUsersByRoom } from './handlers/getUsersByRoom';
|
||||
import { handleGetRoom } from './handlers/getRoom';
|
||||
import { handleGetAllRooms } from './handlers/getAllRooms';
|
||||
import { handleGetBansForRoom } from './handlers/getBansForRoom';
|
||||
import { handleIsUserBanned } from './handlers/isUserBanned';
|
||||
import { handleGetAttachmentsForMessage } from './handlers/getAttachmentsForMessage';
|
||||
import { handleGetAllAttachments } from './handlers/getAllAttachments';
|
||||
|
||||
export const buildQueryHandlers = (dataSource: DataSource): Record<QueryTypeKey, (query: Query) => Promise<unknown>> => ({
|
||||
[QueryType.GetMessages]: (query) => handleGetMessages(query as GetMessagesQuery, dataSource),
|
||||
[QueryType.GetMessageById]: (query) => handleGetMessageById(query as GetMessageByIdQuery, dataSource),
|
||||
[QueryType.GetReactionsForMessage]: (query) => handleGetReactionsForMessage(query as GetReactionsForMessageQuery, dataSource),
|
||||
[QueryType.GetUser]: (query) => handleGetUser(query as GetUserQuery, dataSource),
|
||||
[QueryType.GetCurrentUser]: () => handleGetCurrentUser(dataSource),
|
||||
[QueryType.GetUsersByRoom]: () => handleGetUsersByRoom(dataSource),
|
||||
[QueryType.GetRoom]: (query) => handleGetRoom(query as GetRoomQuery, dataSource),
|
||||
[QueryType.GetAllRooms]: () => handleGetAllRooms(dataSource),
|
||||
[QueryType.GetBansForRoom]: (query) => handleGetBansForRoom(query as GetBansForRoomQuery, dataSource),
|
||||
[QueryType.IsUserBanned]: (query) => handleIsUserBanned(query as IsUserBannedQuery, dataSource),
|
||||
[QueryType.GetAttachmentsForMessage]: (query) => handleGetAttachmentsForMessage(query as GetAttachmentsForMessageQuery, dataSource),
|
||||
[QueryType.GetAllAttachments]: () => handleGetAllAttachments(dataSource)
|
||||
});
|
||||
197
electron/cqrs/types.ts
Normal file
197
electron/cqrs/types.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* CQRS type definitions for the MetoYou electron main process. */
|
||||
/* Commands mutate state; queries read state. */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
// --------------- Command types ---------------
|
||||
|
||||
export const CommandType = {
|
||||
SaveMessage: 'save-message',
|
||||
DeleteMessage: 'delete-message',
|
||||
UpdateMessage: 'update-message',
|
||||
ClearRoomMessages: 'clear-room-messages',
|
||||
SaveReaction: 'save-reaction',
|
||||
RemoveReaction: 'remove-reaction',
|
||||
SaveUser: 'save-user',
|
||||
SetCurrentUserId: 'set-current-user-id',
|
||||
UpdateUser: 'update-user',
|
||||
SaveRoom: 'save-room',
|
||||
DeleteRoom: 'delete-room',
|
||||
UpdateRoom: 'update-room',
|
||||
SaveBan: 'save-ban',
|
||||
RemoveBan: 'remove-ban',
|
||||
SaveAttachment: 'save-attachment',
|
||||
DeleteAttachmentsForMessage: 'delete-attachments-for-message',
|
||||
ClearAllData: 'clear-all-data'
|
||||
} as const;
|
||||
|
||||
export type CommandTypeKey = typeof CommandType[keyof typeof CommandType];
|
||||
|
||||
// --------------- Query types ---------------
|
||||
|
||||
export const QueryType = {
|
||||
GetMessages: 'get-messages',
|
||||
GetMessageById: 'get-message-by-id',
|
||||
GetReactionsForMessage: 'get-reactions-for-message',
|
||||
GetUser: 'get-user',
|
||||
GetCurrentUser: 'get-current-user',
|
||||
GetUsersByRoom: 'get-users-by-room',
|
||||
GetRoom: 'get-room',
|
||||
GetAllRooms: 'get-all-rooms',
|
||||
GetBansForRoom: 'get-bans-for-room',
|
||||
IsUserBanned: 'is-user-banned',
|
||||
GetAttachmentsForMessage: 'get-attachments-for-message',
|
||||
GetAllAttachments: 'get-all-attachments'
|
||||
} as const;
|
||||
|
||||
export type QueryTypeKey = typeof QueryType[keyof typeof QueryType];
|
||||
|
||||
// --------------- Payload interfaces ---------------
|
||||
|
||||
export interface MessagePayload {
|
||||
id: string;
|
||||
roomId: string;
|
||||
channelId?: string;
|
||||
senderId: string;
|
||||
senderName: string;
|
||||
content: string;
|
||||
timestamp: number;
|
||||
editedAt?: number;
|
||||
reactions?: ReactionPayload[];
|
||||
isDeleted?: boolean;
|
||||
replyToId?: string;
|
||||
}
|
||||
|
||||
export interface ReactionPayload {
|
||||
id: string;
|
||||
messageId: string;
|
||||
oderId: string;
|
||||
userId: string;
|
||||
emoji: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface UserPayload {
|
||||
id: string;
|
||||
oderId?: string;
|
||||
username?: string;
|
||||
displayName?: string;
|
||||
avatarUrl?: string;
|
||||
status?: string;
|
||||
role?: string;
|
||||
joinedAt?: number;
|
||||
peerId?: string;
|
||||
isOnline?: boolean;
|
||||
isAdmin?: boolean;
|
||||
isRoomOwner?: boolean;
|
||||
voiceState?: unknown;
|
||||
screenShareState?: unknown;
|
||||
}
|
||||
|
||||
export interface RoomPayload {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
topic?: string;
|
||||
hostId: string;
|
||||
password?: string;
|
||||
isPrivate?: boolean;
|
||||
createdAt: number;
|
||||
userCount?: number;
|
||||
maxUsers?: number;
|
||||
icon?: string;
|
||||
iconUpdatedAt?: number;
|
||||
permissions?: unknown;
|
||||
channels?: unknown[];
|
||||
}
|
||||
|
||||
export interface BanPayload {
|
||||
oderId: string;
|
||||
roomId: string;
|
||||
userId?: string;
|
||||
bannedBy: string;
|
||||
displayName?: string;
|
||||
reason?: string;
|
||||
expiresAt?: number;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface AttachmentPayload {
|
||||
id: string;
|
||||
messageId: string;
|
||||
filename: string;
|
||||
size: number;
|
||||
mime: string;
|
||||
isImage?: boolean;
|
||||
uploaderPeerId?: string;
|
||||
filePath?: string;
|
||||
savedPath?: string;
|
||||
}
|
||||
|
||||
// --------------- Command interfaces ---------------
|
||||
|
||||
export interface SaveMessageCommand { type: typeof CommandType.SaveMessage; payload: { message: MessagePayload } }
|
||||
export interface DeleteMessageCommand { type: typeof CommandType.DeleteMessage; payload: { messageId: string } }
|
||||
export interface UpdateMessageCommand { type: typeof CommandType.UpdateMessage; payload: { messageId: string; updates: Partial<MessagePayload> } }
|
||||
export interface ClearRoomMessagesCommand { type: typeof CommandType.ClearRoomMessages; payload: { roomId: string } }
|
||||
export interface SaveReactionCommand { type: typeof CommandType.SaveReaction; payload: { reaction: ReactionPayload } }
|
||||
export interface RemoveReactionCommand { type: typeof CommandType.RemoveReaction; payload: { messageId: string; userId: string; emoji: string } }
|
||||
export interface SaveUserCommand { type: typeof CommandType.SaveUser; payload: { user: UserPayload } }
|
||||
export interface SetCurrentUserIdCommand { type: typeof CommandType.SetCurrentUserId; payload: { userId: string } }
|
||||
export interface UpdateUserCommand { type: typeof CommandType.UpdateUser; payload: { userId: string; updates: Partial<UserPayload> } }
|
||||
export interface SaveRoomCommand { type: typeof CommandType.SaveRoom; payload: { room: RoomPayload } }
|
||||
export interface DeleteRoomCommand { type: typeof CommandType.DeleteRoom; payload: { roomId: string } }
|
||||
export interface UpdateRoomCommand { type: typeof CommandType.UpdateRoom; payload: { roomId: string; updates: Partial<RoomPayload> } }
|
||||
export interface SaveBanCommand { type: typeof CommandType.SaveBan; payload: { ban: BanPayload } }
|
||||
export interface RemoveBanCommand { type: typeof CommandType.RemoveBan; payload: { oderId: string } }
|
||||
export interface SaveAttachmentCommand { type: typeof CommandType.SaveAttachment; payload: { attachment: AttachmentPayload } }
|
||||
export interface DeleteAttachmentsForMessageCommand { type: typeof CommandType.DeleteAttachmentsForMessage; payload: { messageId: string } }
|
||||
export interface ClearAllDataCommand { type: typeof CommandType.ClearAllData; payload: Record<string, never> }
|
||||
|
||||
export type Command =
|
||||
| SaveMessageCommand
|
||||
| DeleteMessageCommand
|
||||
| UpdateMessageCommand
|
||||
| ClearRoomMessagesCommand
|
||||
| SaveReactionCommand
|
||||
| RemoveReactionCommand
|
||||
| SaveUserCommand
|
||||
| SetCurrentUserIdCommand
|
||||
| UpdateUserCommand
|
||||
| SaveRoomCommand
|
||||
| DeleteRoomCommand
|
||||
| UpdateRoomCommand
|
||||
| SaveBanCommand
|
||||
| RemoveBanCommand
|
||||
| SaveAttachmentCommand
|
||||
| DeleteAttachmentsForMessageCommand
|
||||
| ClearAllDataCommand;
|
||||
|
||||
// --------------- Query interfaces ---------------
|
||||
|
||||
export interface GetMessagesQuery { type: typeof QueryType.GetMessages; payload: { roomId: string; limit?: number; offset?: number } }
|
||||
export interface GetMessageByIdQuery { type: typeof QueryType.GetMessageById; payload: { messageId: string } }
|
||||
export interface GetReactionsForMessageQuery { type: typeof QueryType.GetReactionsForMessage; payload: { messageId: string } }
|
||||
export interface GetUserQuery { type: typeof QueryType.GetUser; payload: { userId: string } }
|
||||
export interface GetCurrentUserQuery { type: typeof QueryType.GetCurrentUser; payload: Record<string, never> }
|
||||
export interface GetUsersByRoomQuery { type: typeof QueryType.GetUsersByRoom; payload: { roomId: string } }
|
||||
export interface GetRoomQuery { type: typeof QueryType.GetRoom; payload: { roomId: string } }
|
||||
export interface GetAllRoomsQuery { type: typeof QueryType.GetAllRooms; payload: Record<string, never> }
|
||||
export interface GetBansForRoomQuery { type: typeof QueryType.GetBansForRoom; payload: { roomId: string } }
|
||||
export interface IsUserBannedQuery { type: typeof QueryType.IsUserBanned; payload: { userId: string; roomId: string } }
|
||||
export interface GetAttachmentsForMessageQuery { type: typeof QueryType.GetAttachmentsForMessage; payload: { messageId: string } }
|
||||
export interface GetAllAttachmentsQuery { type: typeof QueryType.GetAllAttachments; payload: Record<string, never> }
|
||||
|
||||
export type Query =
|
||||
| GetMessagesQuery
|
||||
| GetMessageByIdQuery
|
||||
| GetReactionsForMessageQuery
|
||||
| GetUserQuery
|
||||
| GetCurrentUserQuery
|
||||
| GetUsersByRoomQuery
|
||||
| GetRoomQuery
|
||||
| GetAllRoomsQuery
|
||||
| GetBansForRoomQuery
|
||||
| IsUserBannedQuery
|
||||
| GetAttachmentsForMessageQuery
|
||||
| GetAllAttachmentsQuery;
|
||||
Reference in New Issue
Block a user