Refacor electron app and add migrations

This commit is contained in:
2026-03-04 01:38:43 +01:00
parent 4e95ae77c5
commit be91b6dfe8
70 changed files with 1824 additions and 923 deletions

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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;
}

View 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;
}

View 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);
}

View 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);
}

View 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;
}

View 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;
}

View 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);
}

View 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);
}

View 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)
});