mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-22 15:24:55 +00:00
145 lines
4.3 KiB
TypeScript
145 lines
4.3 KiB
TypeScript
import IO, { Socket, SocketServer } from "../Infrastructure/SocketIO";
|
|
import logger from "./Logger";
|
|
import AnalyticsBaseModel, {
|
|
AnalyticsBaseModelType,
|
|
} from "Common/AnalyticsModels/BaseModel";
|
|
import BaseModel, { BaseModelType } from "Common/Models/BaseModel";
|
|
import DatabaseType from "Common/Types/BaseDatabase/DatabaseType";
|
|
import BadDataException from "Common/Types/Exception/BadDataException";
|
|
import { JSONObject } from "Common/Types/JSON";
|
|
import JSONFunctions from "Common/Types/JSONFunctions";
|
|
import ObjectID from "Common/Types/ObjectID";
|
|
import RealtimeUtil, {
|
|
EventName,
|
|
ListenToModelEventJSON,
|
|
ModelEventType,
|
|
} from "Common/Utils/Realtime";
|
|
|
|
export default abstract class Realtime {
|
|
private static socketServer: SocketServer | null = null;
|
|
|
|
public static isInitialized(): boolean {
|
|
return this.socketServer !== null;
|
|
}
|
|
|
|
public static async init(): Promise<SocketServer | null> {
|
|
if (!this.socketServer) {
|
|
this.socketServer = IO.getSocketServer();
|
|
logger.debug("Realtime socket server initialized");
|
|
}
|
|
|
|
this.socketServer!.on("connection", (socket: Socket) => {
|
|
socket.on(EventName.ListenToModalEvent, async (data: JSONObject) => {
|
|
// TODO: validate if this soocket has access to this tenant
|
|
|
|
// TODO: validate if this socket has access to this model
|
|
|
|
// TODO: validate if this socket has access to this event type
|
|
|
|
// TODO: validate if this socket has access to this query
|
|
|
|
// TODO: validate if this socket has access to this select
|
|
|
|
// validate data
|
|
|
|
if (typeof data["eventType"] !== "string") {
|
|
throw new BadDataException("eventType is not a string");
|
|
}
|
|
if (typeof data["modelType"] !== "string") {
|
|
throw new BadDataException("modelType is not a string");
|
|
}
|
|
if (typeof data["modelName"] !== "string") {
|
|
throw new BadDataException("modelName is not a string");
|
|
}
|
|
if (typeof data["query"] !== "object") {
|
|
throw new BadDataException("query is not an object");
|
|
}
|
|
if (typeof data["tenantId"] !== "string") {
|
|
throw new BadDataException("tenantId is not a string");
|
|
}
|
|
if (typeof data["select"] !== "object") {
|
|
throw new BadDataException("select is not an object");
|
|
}
|
|
|
|
await Realtime.listenToModelEvent(socket, {
|
|
eventType: data["eventType"] as ModelEventType,
|
|
modelType: data["modelType"] as DatabaseType,
|
|
modelName: data["modelName"] as string,
|
|
query: JSONFunctions.deserialize(data["query"] as JSONObject),
|
|
tenantId: data["tenantId"] as string,
|
|
select: JSONFunctions.deserialize(data["select"] as JSONObject),
|
|
});
|
|
});
|
|
});
|
|
|
|
return this.socketServer;
|
|
}
|
|
|
|
public static async listenToModelEvent(
|
|
socket: Socket,
|
|
data: ListenToModelEventJSON,
|
|
): Promise<void> {
|
|
if (!this.socketServer) {
|
|
await this.init();
|
|
}
|
|
|
|
const roomId: string = RealtimeUtil.getRoomId(
|
|
data.tenantId,
|
|
data.modelName,
|
|
data.eventType,
|
|
);
|
|
|
|
// join the room.
|
|
await socket.join(roomId);
|
|
}
|
|
|
|
public static async stopListeningToModelEvent(
|
|
socket: Socket,
|
|
data: ListenToModelEventJSON,
|
|
): Promise<void> {
|
|
if (!this.socketServer) {
|
|
await this.init();
|
|
}
|
|
|
|
// leave this room.
|
|
await socket.leave(
|
|
RealtimeUtil.getRoomId(data.tenantId, data.modelName, data.eventType),
|
|
);
|
|
}
|
|
|
|
public static async emitModelEvent(data: {
|
|
tenantId: string | ObjectID;
|
|
eventType: ModelEventType;
|
|
model: BaseModel | AnalyticsBaseModel;
|
|
modelType: { new (): BaseModel | AnalyticsBaseModel };
|
|
}): Promise<void> {
|
|
if (!this.socketServer) {
|
|
await this.init();
|
|
}
|
|
|
|
let jsonObject: JSONObject = {};
|
|
|
|
if (data.model instanceof BaseModel) {
|
|
jsonObject = BaseModel.toJSON(
|
|
data.model,
|
|
data.modelType as BaseModelType,
|
|
);
|
|
}
|
|
|
|
if (data.model instanceof AnalyticsBaseModel) {
|
|
jsonObject = AnalyticsBaseModel.toJSON(
|
|
data.model,
|
|
data.modelType as AnalyticsBaseModelType,
|
|
);
|
|
}
|
|
|
|
const roomId: string = RealtimeUtil.getRoomId(
|
|
data.tenantId,
|
|
data.model.tableName!,
|
|
data.eventType,
|
|
);
|
|
|
|
this.socketServer!.to(roomId).emit(roomId, jsonObject);
|
|
}
|
|
}
|