mirror of
https://github.com/spacebarchat/server.git
synced 2026-05-15 03:05:18 +00:00
Add Decorators to clean classes before json serialization and remove invalid states.
This commit is contained in:
@@ -486,7 +486,7 @@ export async function postHandleMessage(message: Message) {
|
||||
const content = message.content?.replace(/ *`[^)]*` */g, ""); // remove markdown
|
||||
|
||||
const linkMatches = content?.match(LINK_REGEX) || [];
|
||||
|
||||
message.clean_data();
|
||||
const data = { ...message };
|
||||
|
||||
const currentNormalizedUrls = new Set<string>();
|
||||
|
||||
@@ -20,12 +20,40 @@ import { BaseEntity, BeforeInsert, BeforeUpdate, Column, ColumnOptions, FindOpti
|
||||
import { Snowflake } from "../util/Snowflake";
|
||||
import { getDatabase } from "../util/Database";
|
||||
import { OrmUtils } from "../imports/OrmUtils";
|
||||
import { annotationsKey } from "../util/Decorators";
|
||||
|
||||
export class BaseClassWithoutId extends BaseEntity {
|
||||
private get construct() {
|
||||
return this.constructor;
|
||||
}
|
||||
|
||||
// stores custom annotations we may stick on the properties
|
||||
[annotationsKey]: { [p: string]: string[] };
|
||||
|
||||
// retrieves the custom annotations as its not super straight forward
|
||||
get_annotations() {
|
||||
return Object.getPrototypeOf(this)[annotationsKey];
|
||||
}
|
||||
|
||||
// Loops through all the keys and compares it to annotations. If the RemoveEmpty is there it sets the value to undefined if null
|
||||
clean_data() {
|
||||
const annotations = this.get_annotations();
|
||||
for (const key in this) {
|
||||
if (
|
||||
key in this && // This object has this property, should never fail but better to be safe
|
||||
key in annotations && // If this property has an annotation
|
||||
annotations[key].indexOf("JsonRemoveEmpty") > -1 && // if one of the annotations is JsonRemoveEmpty
|
||||
(this[key] == null || // If this property is null
|
||||
(typeof this[key] == "object" && Object.keys(this[key]).length == 0))
|
||||
) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
this[key] = undefined; // set to undefined to remove
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private get metadata() {
|
||||
return getDatabase()?.getMetadata(this.construct);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import { Attachment } from "./Attachment";
|
||||
import { NewUrlUserSignatureData } from "../Signing";
|
||||
import { ActionRowComponent, ApplicationCommandType, Embed, MessageSnapshot, MessageType, PartialMessage, Poll, Reaction } from "@spacebar/schemas";
|
||||
import { MessageFlags } from "@spacebar/util";
|
||||
import { JsonRemoveEmpty } from "../util/Decorators";
|
||||
|
||||
@Entity({
|
||||
name: "messages",
|
||||
@@ -122,14 +123,17 @@ export class Message extends BaseClass {
|
||||
mention_everyone?: boolean;
|
||||
|
||||
@JoinTable({ name: "message_user_mentions" })
|
||||
@JsonRemoveEmpty
|
||||
@ManyToMany(() => User)
|
||||
mentions: User[];
|
||||
|
||||
@JoinTable({ name: "message_role_mentions" })
|
||||
@JsonRemoveEmpty
|
||||
@ManyToMany(() => Role)
|
||||
mention_roles: Role[];
|
||||
|
||||
@JoinTable({ name: "message_channel_mentions" })
|
||||
@JsonRemoveEmpty
|
||||
@ManyToMany(() => Channel)
|
||||
mention_channels: Channel[];
|
||||
|
||||
@@ -141,12 +145,15 @@ export class Message extends BaseClass {
|
||||
cascade: true,
|
||||
orphanedRowAction: "delete",
|
||||
})
|
||||
@JsonRemoveEmpty
|
||||
attachments?: Attachment[];
|
||||
|
||||
@Column({ type: "simple-json" })
|
||||
@JsonRemoveEmpty
|
||||
embeds: Embed[];
|
||||
|
||||
@Column({ type: "simple-json" })
|
||||
@JsonRemoveEmpty
|
||||
reactions: Reaction[];
|
||||
|
||||
@Column({ type: "text", nullable: true })
|
||||
@@ -201,9 +208,11 @@ export class Message extends BaseClass {
|
||||
};
|
||||
|
||||
@Column({ type: "simple-json", nullable: true })
|
||||
@JsonRemoveEmpty
|
||||
components?: ActionRowComponent[];
|
||||
|
||||
@Column({ type: "simple-json", nullable: true })
|
||||
@JsonRemoveEmpty
|
||||
poll?: Poll;
|
||||
|
||||
@Column({ nullable: true })
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { BaseClassWithoutId } from "@spacebar/util*";
|
||||
|
||||
export const annotationsKey = Symbol("Annotations");
|
||||
|
||||
// Generates an array using the annotationsKey as a property on a class when annotated with the below decorators
|
||||
export function initAnnotationMetadata(target: BaseClassWithoutId, propertyKey: string) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
target[annotationsKey] || (target[annotationsKey] = {});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||
target[annotationsKey][propertyKey] || (target[annotationsKey][propertyKey] = []);
|
||||
}
|
||||
|
||||
// Adds to the generated array on the class with the annotation added.
|
||||
export function addAnnotationMetadata(target: BaseClassWithoutId, propertyKey: string, annotation: string) {
|
||||
target[annotationsKey] = { ...target[annotationsKey], [propertyKey]: [...target[annotationsKey][propertyKey], annotation] };
|
||||
}
|
||||
|
||||
export function JsonRemoveEmpty(target: BaseClassWithoutId, propertyKey: string) {
|
||||
initAnnotationMetadata(target, propertyKey);
|
||||
addAnnotationMetadata(target, propertyKey, "JsonRemoveEmpty");
|
||||
}
|
||||
Reference in New Issue
Block a user