refactor(database): ♻️ Make emojis use a Media instead of just rawdogging the URI

This commit is contained in:
Jesse Wierzbinski 2025-01-28 17:43:43 +01:00
parent c7aae24d42
commit cf1104d762
No known key found for this signature in database
18 changed files with 4823 additions and 128 deletions

View file

@ -1,6 +1,7 @@
import { apiRoute, auth, emojiValidator, jsonOrForm } from "@/api";
import { mimeLookup } from "@/content_types";
import { createRoute } from "@hono/zod-openapi";
import type { ContentFormat } from "@versia/federation/types";
import { Emoji, Media, db } from "@versia/kit/db";
import { Emojis, RolePermissions } from "@versia/kit/tables";
import { eq } from "drizzle-orm";
@ -230,8 +231,6 @@ export default apiRoute((app) => {
);
}
const mediaManager = new MediaManager(config);
const {
global: emojiGlobal,
alt,
@ -248,11 +247,12 @@ export default apiRoute((app) => {
);
}
const modifiedMedia = structuredClone(emoji.data.media);
const modified = structuredClone(emoji.data);
if (element) {
// Check of emoji is an image
let contentType =
const contentType =
element instanceof File
? element.type
: await mimeLookup(element);
@ -265,23 +265,33 @@ export default apiRoute((app) => {
);
}
let url = "";
let contentFormat: ContentFormat | undefined;
if (element instanceof File) {
const uploaded = await mediaManager.addFile(element);
const mediaManager = new MediaManager(config);
url = Media.getUrl(uploaded.path);
contentType = uploaded.uploadedFile.type;
const { uploadedFile, path } =
await mediaManager.addFile(element);
contentFormat = await Media.fileToContentFormat(
uploadedFile,
Media.getUrl(path),
{ description: alt },
);
} else {
url = element;
contentFormat = {
[contentType]: {
content: element,
remote: true,
description: alt,
},
};
}
modified.url = url;
modified.contentType = contentType;
modifiedMedia.content = contentFormat;
}
modified.shortcode = shortcode ?? modified.shortcode;
modified.alt = alt ?? modified.alt;
modified.category = category ?? modified.category;
if (emojiGlobal !== undefined) {
@ -317,7 +327,7 @@ export default apiRoute((app) => {
const mediaManager = new MediaManager(config);
await mediaManager.deleteFileByUrl(emoji.data.url);
await mediaManager.deleteFileByUrl(emoji.media.getUrl());
await db.delete(Emojis).where(eq(Emojis.id, id));

View file

@ -1,6 +1,7 @@
import { apiRoute, auth, emojiValidator, jsonOrForm } from "@/api";
import { mimeLookup } from "@/content_types";
import { createRoute } from "@hono/zod-openapi";
import type { ContentFormat } from "@versia/federation/types";
import { Emoji, Media } from "@versia/kit/db";
import { Emojis, RolePermissions } from "@versia/kit/tables";
import { and, eq, isNull, or } from "drizzle-orm";
@ -130,10 +131,8 @@ export default apiRoute((app) =>
);
}
let url = "";
// Check of emoji is an image
let contentType =
const contentType =
element instanceof File ? element.type : await mimeLookup(element);
if (!contentType.startsWith("image/")) {
@ -144,25 +143,38 @@ export default apiRoute((app) =>
);
}
let contentFormat: ContentFormat | undefined;
if (element instanceof File) {
const mediaManager = new MediaManager(config);
const uploaded = await mediaManager.addFile(element);
const { uploadedFile, path } = await mediaManager.addFile(element);
url = Media.getUrl(uploaded.path);
contentType = uploaded.uploadedFile.type;
contentFormat = await Media.fileToContentFormat(
uploadedFile,
Media.getUrl(path),
{ description: alt },
);
} else {
url = element;
contentFormat = {
[contentType]: {
content: element,
remote: true,
description: alt,
},
};
}
const media = await Media.insert({
content: contentFormat,
});
const emoji = await Emoji.insert({
shortcode,
url,
mediaId: media.id,
visibleInPicker: true,
ownerId: global ? null : user.id,
category,
contentType,
alt,
});
return context.json(emoji.toApi(), 201);

View file

@ -1,12 +1,13 @@
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import type { Status as ApiStatus } from "@versia/client/types";
import { db } from "@versia/kit/db";
import { Media, db } from "@versia/kit/db";
import { Emojis } from "@versia/kit/tables";
import { eq } from "drizzle-orm";
import { config } from "~/packages/config-manager/index.ts";
import { fakeRequest, getTestUsers } from "~/tests/utils";
const { users, tokens, deleteUsers } = await getTestUsers(5);
let media: Media;
afterAll(async () => {
await deleteUsers();
@ -14,10 +15,17 @@ afterAll(async () => {
});
beforeAll(async () => {
media = await Media.insert({
content: {
"image/png": {
content: "https://example.com/test.png",
remote: true,
},
},
});
await db.insert(Emojis).values({
contentType: "image/png",
shortcode: "test",
url: "https://example.com/test.png",
mediaId: media.id,
visibleInPicker: true,
});
});