import Snowflake from "./snowflake";
import UserClient from "./userClient";
import User from "./user";
import { SnowflakeString } from "../types/snowflake";
import { RequestContext, RequestContextWithClient } from "./requestContext";
import { UserType } from "../types/basicUser";
import { MessageState } from "../types/message";
import {
DBMessage, DBMessageFull, DBMessageWithAuthor, DBMessageWithTarget, prisma
} from "../../prisma";
/**
* Holds message data
*/
class Message {
id: Snowflake;
ctx: RequestContext;
client: UserClient;
author: User;
target: User;
content: string;
state: MessageState;
reported?: boolean;
/**
* Creates new message data holder
* @param {object} data
*/
constructor({
id,
ctx,
author,
target,
content,
state,
reported
}: {
id: Snowflake,
ctx: RequestContextWithClient,
author: User,
target: User,
content: string,
state: MessageState,
reported?: boolean
}) {
this.id = id;
this.ctx = ctx;
this.client = ctx.client;
this.author = author;
this.target = target;
this.content = content;
this.state = state;
this.reported = reported;
}
/**
* @param {DBMessage | DBMessageWithAuthor | DBMessageWithTarget | DBMessageFull} data
* @param {RequestContextWithClient} ctx
* @return {Promise<Message>}
*/
static async fromDatabase(data: DBMessage | DBMessageWithAuthor |
DBMessageWithTarget | DBMessageFull, ctx: RequestContextWithClient): Promise<Message> {
if(
data.targetId !== ctx.client.user.id.toBigInt() &&
data.authorId !== ctx.client.user.id.toBigInt() &&
ctx.client.user.type < UserType.MODERATOR
) {
throw new Error("Message not found");
}
return new Message({
id: new Snowflake(data.snowflake),
ctx,
author: "author" in data ?
await User.fromDatabase(data.author, ctx) :
await User.getUser(data.authorId, ctx),
target: "target" in data ?
await User.fromDatabase(data.target, ctx) :
await User.getUser(data.targetId, ctx),
content: data.content,
state: data.state
});
}
/**
* Updates the message content
* @return {Promise<void>}
*/
async update(): Promise<void> {
await prisma.message.update({
where: {
snowflake: this.id.toBigInt()
},
data: {
content: this.content,
state: this.state
}
});
}
/**
* Deletes the message
* @return {Promise<void>}
*/
delete(): Promise<void> {
this.state = MessageState.DELETED;
return this.update();
}
/**
* Fetches given message
* @param {SnowflakeString | bigint} id
* @param {RequestContextWithClient} ctx
* @param {UserClient} client
* @return {Promise<Message>}
*/
static async getMessage(id: SnowflakeString | bigint, ctx: RequestContextWithClient):
Promise<Message> {
const data = await prisma.message.findUniqueOrThrow({
where: {
snowflake: BigInt(id)
}
});
const msg = await Message.fromDatabase(data, ctx);
if(ctx.user) {
const report = await prisma.modQueue.findUnique({
where: {
resourceId_reporterId: {
resourceId: msg.id.toBigInt(),
reporterId: ctx.user.id.toBigInt()
}
}
});
msg.reported = !!report;
}
return msg;
}
/**
* Creates a JSON-compatible object
* @return {Object}
*/
toJSON() {
return {
id: this.id.getSnowflake(),
time: this.id.time,
author: this.author.toJSON(),
target: this.target.toJSON(),
content: this.content,
state: this.state,
reported: this.reported
};
}
}
export default Message;
Source