🎨 add orphanedRowAction and cascade onDelete to entities

This commit is contained in:
Flam3rboy 2021-09-19 18:47:38 +02:00
parent 994406e5ce
commit 705206ec1b
7 changed files with 173 additions and 20 deletions

BIN
util/package-lock.json generated

Binary file not shown.

View File

@ -31,6 +31,7 @@
"@types/amqplib": "^0.8.1", "@types/amqplib": "^0.8.1",
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-autopopulate": "^0.10.1",
"@types/multer": "^1.4.7",
"@types/node": "^14.17.9", "@types/node": "^14.17.9",
"@types/node-fetch": "^2.5.12", "@types/node-fetch": "^2.5.12",
"jest": "^27.0.6" "jest": "^27.0.6"
@ -44,6 +45,7 @@
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"lambert-server": "^1.2.10", "lambert-server": "^1.2.10",
"missing-native-js-functions": "^1.2.15", "missing-native-js-functions": "^1.2.15",
"multer": "^1.4.3",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"patch-package": "^6.4.7", "patch-package": "^6.4.7",
"pg": "^8.7.1", "pg": "^8.7.1",

View File

@ -1,12 +1,26 @@
import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToMany, RelationId } from "typeorm"; import {
Column,
Entity,
FindConditions,
JoinColumn,
ManyToOne,
ObjectID,
OneToMany,
RelationId,
RemoveOptions,
} from "typeorm";
import { BaseClass } from "./BaseClass"; import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild"; import { Guild } from "./Guild";
import { Message } from "./Message";
import { User } from "./User"; import { User } from "./User";
import { HTTPError } from "lambert-server"; import { HTTPError } from "lambert-server";
import { emitEvent, getPermission, Snowflake } from "../util"; import { emitEvent, getPermission, Snowflake } from "../util";
import { ChannelCreateEvent } from "../interfaces"; import { ChannelCreateEvent } from "../interfaces";
import { Recipient } from "./Recipient"; import { Recipient } from "./Recipient";
import { Message } from "./Message";
import { ReadState } from "./ReadState";
import { Invite } from "./Invite";
import { VoiceState } from "./VoiceState";
import { Webhook } from "./Webhook";
export enum ChannelType { export enum ChannelType {
GUILD_TEXT = 0, // a text channel within a server GUILD_TEXT = 0, // a text channel within a server
@ -31,20 +45,22 @@ export class Channel extends BaseClass {
@Column({ nullable: true }) @Column({ nullable: true })
name?: string; name?: string;
@Column({ type: "text", nullable: true })
icon?: string | null;
@Column({ type: "simple-enum", enum: ChannelType }) @Column({ type: "simple-enum", enum: ChannelType })
type: ChannelType; type: ChannelType;
@OneToMany(() => Recipient, (recipient: Recipient) => recipient.channel, { cascade: true }) @OneToMany(() => Recipient, (recipient: Recipient) => recipient.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
recipients?: Recipient[]; recipients?: Recipient[];
@Column({ nullable: true }) @Column({ nullable: true })
@RelationId((channel: Channel) => channel.last_message)
last_message_id: string; last_message_id: string;
@JoinColumn({ name: "last_message_id" })
@ManyToOne(() => Message)
last_message?: Message;
@Column({ nullable: true }) @Column({ nullable: true })
@RelationId((channel: Channel) => channel.guild) @RelationId((channel: Channel) => channel.guild)
guild_id?: string; guild_id?: string;
@ -100,6 +116,41 @@ export class Channel extends BaseClass {
@Column({ nullable: true }) @Column({ nullable: true })
topic?: string; topic?: string;
@OneToMany(() => Invite, (invite: Invite) => invite.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
invites?: Invite[];
@OneToMany(() => Message, (message: Message) => message.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
messages?: Message[];
@OneToMany(() => VoiceState, (voice_state: VoiceState) => voice_state.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
voice_states?: VoiceState[];
@OneToMany(() => ReadState, (read_state: ReadState) => read_state.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
read_states?: ReadState[];
@OneToMany(() => Webhook, (webhook: Webhook) => webhook.channel, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
webhooks?: Webhook[];
// TODO: DM channel // TODO: DM channel
static async createChannel( static async createChannel(
channel: Partial<Channel>, channel: Partial<Channel>,
@ -162,6 +213,10 @@ export class Channel extends BaseClass {
return channel; return channel;
} }
isDm() {
return this.type === ChannelType.DM || this.type === ChannelType.GROUP_DM;
}
} }
export interface ChannelPermissionOverwrite { export interface ChannelPermissionOverwrite {

View File

@ -81,7 +81,11 @@ export class Guild extends BaseClass {
// application?: string; // application?: string;
@JoinColumn({ name: "ban_ids" }) @JoinColumn({ name: "ban_ids" })
@OneToMany(() => Ban, (ban: Ban) => ban.guild) @OneToMany(() => Ban, (ban: Ban) => ban.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
bans: Ban[]; bans: Ban[];
@Column({ nullable: true }) @Column({ nullable: true })
@ -124,15 +128,27 @@ export class Guild extends BaseClass {
@Column({ nullable: true }) @Column({ nullable: true })
presence_count?: number; // users online presence_count?: number; // users online
@OneToMany(() => Member, (member: Member) => member.guild) @OneToMany(() => Member, (member: Member) => member.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
members: Member[]; members: Member[];
@JoinColumn({ name: "role_ids" }) @JoinColumn({ name: "role_ids" })
@OneToMany(() => Role, (role: Role) => role.guild) @OneToMany(() => Role, (role: Role) => role.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
roles: Role[]; roles: Role[];
@JoinColumn({ name: "channel_ids" }) @JoinColumn({ name: "channel_ids" })
@OneToMany(() => Channel, (channel: Channel) => channel.guild) @OneToMany(() => Channel, (channel: Channel) => channel.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
channels: Channel[]; channels: Channel[];
@Column({ nullable: true }) @Column({ nullable: true })
@ -144,23 +160,43 @@ export class Guild extends BaseClass {
template: Template; template: Template;
@JoinColumn({ name: "emoji_ids" }) @JoinColumn({ name: "emoji_ids" })
@OneToMany(() => Emoji, (emoji: Emoji) => emoji.guild) @OneToMany(() => Emoji, (emoji: Emoji) => emoji.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
emojis: Emoji[]; emojis: Emoji[];
@JoinColumn({ name: "sticker_ids" }) @JoinColumn({ name: "sticker_ids" })
@OneToMany(() => Sticker, (sticker: Sticker) => sticker.guild) @OneToMany(() => Sticker, (sticker: Sticker) => sticker.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
stickers: Sticker[]; stickers: Sticker[];
@JoinColumn({ name: "invite_ids" }) @JoinColumn({ name: "invite_ids" })
@OneToMany(() => Invite, (invite: Invite) => invite.guild) @OneToMany(() => Invite, (invite: Invite) => invite.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
invites: Invite[]; invites: Invite[];
@JoinColumn({ name: "voice_state_ids" }) @JoinColumn({ name: "voice_state_ids" })
@OneToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.guild) @OneToMany(() => VoiceState, (voicestate: VoiceState) => voicestate.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
voice_states: VoiceState[]; voice_states: VoiceState[];
@JoinColumn({ name: "webhook_ids" }) @JoinColumn({ name: "webhook_ids" })
@OneToMany(() => Webhook, (webhook: Webhook) => webhook.guild) @OneToMany(() => Webhook, (webhook: Webhook) => webhook.guild, {
cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
webhooks: Webhook[]; webhooks: Webhook[];
@Column({ nullable: true }) @Column({ nullable: true })

View File

@ -8,12 +8,14 @@ import {
Column, Column,
CreateDateColumn, CreateDateColumn,
Entity, Entity,
FindConditions,
JoinColumn, JoinColumn,
JoinTable, JoinTable,
ManyToMany, ManyToMany,
ManyToOne, ManyToOne,
OneToMany, OneToMany,
RelationId, RelationId,
RemoveOptions,
UpdateDateColumn, UpdateDateColumn,
} from "typeorm"; } from "typeorm";
import { BaseClass } from "./BaseClass"; import { BaseClass } from "./BaseClass";
@ -112,7 +114,7 @@ export class Message extends BaseClass {
mention_everyone?: boolean; mention_everyone?: boolean;
@JoinTable({ name: "message_user_mentions" }) @JoinTable({ name: "message_user_mentions" })
@ManyToMany(() => User) @ManyToMany(() => User, { orphanedRowAction: "delete", onDelete: "CASCADE", cascade: true })
mentions: User[]; mentions: User[];
@JoinTable({ name: "message_role_mentions" }) @JoinTable({ name: "message_role_mentions" })
@ -127,8 +129,11 @@ export class Message extends BaseClass {
@ManyToMany(() => Sticker) @ManyToMany(() => Sticker)
sticker_items?: Sticker[]; sticker_items?: Sticker[];
@JoinColumn({ name: "attachment_ids" }) @OneToMany(() => Attachment, (attachment: Attachment) => attachment.message, {
@OneToMany(() => Attachment, (attachment: Attachment) => attachment.message, { cascade: true }) cascade: true,
orphanedRowAction: "delete",
onDelete: "CASCADE",
})
attachments?: Attachment[]; attachments?: Attachment[];
@Column({ type: "simple-json" }) @Column({ type: "simple-json" })

54
util/src/util/cdn.ts Normal file
View File

@ -0,0 +1,54 @@
import FormData from "form-data";
import { HTTPError } from "lambert-server";
import fetch from "node-fetch";
import { Config } from "./Config";
import multer from "multer";
export async function uploadFile(path: string, file: Express.Multer.File) {
const form = new FormData();
form.append("file", file.buffer, {
contentType: file.mimetype,
filename: file.originalname,
});
const response = await fetch(`${Config.get().cdn.endpoint || "http://localhost:3003"}${path}`, {
headers: {
signature: Config.get().security.requestSignature,
...form.getHeaders(),
},
method: "POST",
body: form,
});
const result = await response.json();
if (response.status !== 200) throw result;
return result;
}
export async function handleFile(path: string, body?: string): Promise<string | undefined> {
if (!body || !body.startsWith("data:")) return body;
try {
const mimetype = body.split(":")[1].split(";")[0];
const buffer = Buffer.from(body.split(",")[1], "base64");
// @ts-ignore
const { id } = await uploadFile(path, { buffer, mimetype, originalname: "banner" });
return id;
} catch (error) {
console.error(error);
throw new HTTPError("Invalid " + path);
}
}
export async function deleteFile(path: string) {
const response = await fetch(`${Config.get().cdn.endpoint || "http://localhost:3003"}${path}`, {
headers: {
signature: Config.get().security.requestSignature,
},
method: "DELETE",
});
const result = await response.json();
if (response.status !== 200) throw result;
return result;
}

View File

@ -1,6 +1,7 @@
export * from "./ApiError"; export * from "./ApiError";
export * from "./BitField"; export * from "./BitField";
export * from "./checkToken"; export * from "./checkToken";
export * from "./cdn";
export * from "./Config"; export * from "./Config";
export * from "./Constants"; export * from "./Constants";
export * from "./Database"; export * from "./Database";