mirror of
https://github.com/versia-pub/server.git
synced 2026-03-13 05:49:16 +01:00
refactor(database): 🚚 Rename "Attachment" to "Media"
This commit is contained in:
parent
bbd56b600d
commit
2f61cd8f0a
21 changed files with 2429 additions and 101 deletions
|
|
@ -2,7 +2,7 @@ import { proxyUrl } from "@/response";
|
|||
import type { Attachment as ApiAttachment } from "@versia/client/types";
|
||||
import type { ContentFormat } from "@versia/federation/types";
|
||||
import { db } from "@versia/kit/db";
|
||||
import { Attachments } from "@versia/kit/tables";
|
||||
import { Medias } from "@versia/kit/tables";
|
||||
import {
|
||||
type InferInsertModel,
|
||||
type InferSelectModel,
|
||||
|
|
@ -20,9 +20,9 @@ import { MediaManager } from "../media/media-manager.ts";
|
|||
import { MediaJobType, mediaQueue } from "../queues/media.ts";
|
||||
import { BaseInterface } from "./base.ts";
|
||||
|
||||
type AttachmentType = InferSelectModel<typeof Attachments>;
|
||||
type MediaType = InferSelectModel<typeof Medias>;
|
||||
|
||||
export class Attachment extends BaseInterface<typeof Attachments> {
|
||||
export class Media extends BaseInterface<typeof Medias> {
|
||||
public static schema: z.ZodType<ApiAttachment> = z.object({
|
||||
id: z.string().uuid(),
|
||||
type: z.enum(["unknown", "image", "gifv", "video", "audio"]),
|
||||
|
|
@ -51,10 +51,10 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
blurhash: z.string().nullable(),
|
||||
});
|
||||
|
||||
public static $type: AttachmentType;
|
||||
public static $type: MediaType;
|
||||
|
||||
public async reload(): Promise<void> {
|
||||
const reloaded = await Attachment.fromId(this.data.id);
|
||||
const reloaded = await Media.fromId(this.data.id);
|
||||
|
||||
if (!reloaded) {
|
||||
throw new Error("Failed to reload attachment");
|
||||
|
|
@ -63,23 +63,23 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
this.data = reloaded.data;
|
||||
}
|
||||
|
||||
public static async fromId(id: string | null): Promise<Attachment | null> {
|
||||
public static async fromId(id: string | null): Promise<Media | null> {
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await Attachment.fromSql(eq(Attachments.id, id));
|
||||
return await Media.fromSql(eq(Medias.id, id));
|
||||
}
|
||||
|
||||
public static async fromIds(ids: string[]): Promise<Attachment[]> {
|
||||
return await Attachment.manyFromSql(inArray(Attachments.id, ids));
|
||||
public static async fromIds(ids: string[]): Promise<Media[]> {
|
||||
return await Media.manyFromSql(inArray(Medias.id, ids));
|
||||
}
|
||||
|
||||
public static async fromSql(
|
||||
sql: SQL<unknown> | undefined,
|
||||
orderBy: SQL<unknown> | undefined = desc(Attachments.id),
|
||||
): Promise<Attachment | null> {
|
||||
const found = await db.query.Attachments.findFirst({
|
||||
orderBy: SQL<unknown> | undefined = desc(Medias.id),
|
||||
): Promise<Media | null> {
|
||||
const found = await db.query.Medias.findFirst({
|
||||
where: sql,
|
||||
orderBy,
|
||||
});
|
||||
|
|
@ -87,17 +87,17 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
if (!found) {
|
||||
return null;
|
||||
}
|
||||
return new Attachment(found);
|
||||
return new Media(found);
|
||||
}
|
||||
|
||||
public static async manyFromSql(
|
||||
sql: SQL<unknown> | undefined,
|
||||
orderBy: SQL<unknown> | undefined = desc(Attachments.id),
|
||||
orderBy: SQL<unknown> | undefined = desc(Medias.id),
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
extra?: Parameters<typeof db.query.Attachments.findMany>[0],
|
||||
): Promise<Attachment[]> {
|
||||
const found = await db.query.Attachments.findMany({
|
||||
extra?: Parameters<typeof db.query.Medias.findMany>[0],
|
||||
): Promise<Media[]> {
|
||||
const found = await db.query.Medias.findMany({
|
||||
where: sql,
|
||||
orderBy,
|
||||
limit,
|
||||
|
|
@ -105,18 +105,16 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
with: extra?.with,
|
||||
});
|
||||
|
||||
return found.map((s) => new Attachment(s));
|
||||
return found.map((s) => new Media(s));
|
||||
}
|
||||
|
||||
public async update(
|
||||
newAttachment: Partial<AttachmentType>,
|
||||
): Promise<AttachmentType> {
|
||||
public async update(newAttachment: Partial<MediaType>): Promise<MediaType> {
|
||||
await db
|
||||
.update(Attachments)
|
||||
.update(Medias)
|
||||
.set(newAttachment)
|
||||
.where(eq(Attachments.id, this.id));
|
||||
.where(eq(Medias.id, this.id));
|
||||
|
||||
const updated = await Attachment.fromId(this.data.id);
|
||||
const updated = await Media.fromId(this.data.id);
|
||||
|
||||
if (!updated) {
|
||||
throw new Error("Failed to update attachment");
|
||||
|
|
@ -126,26 +124,24 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
return updated.data;
|
||||
}
|
||||
|
||||
public save(): Promise<AttachmentType> {
|
||||
public save(): Promise<MediaType> {
|
||||
return this.update(this.data);
|
||||
}
|
||||
|
||||
public async delete(ids?: string[]): Promise<void> {
|
||||
if (Array.isArray(ids)) {
|
||||
await db.delete(Attachments).where(inArray(Attachments.id, ids));
|
||||
await db.delete(Medias).where(inArray(Medias.id, ids));
|
||||
} else {
|
||||
await db.delete(Attachments).where(eq(Attachments.id, this.id));
|
||||
await db.delete(Medias).where(eq(Medias.id, this.id));
|
||||
}
|
||||
}
|
||||
|
||||
public static async insert(
|
||||
data: InferInsertModel<typeof Attachments>,
|
||||
): Promise<Attachment> {
|
||||
const inserted = (
|
||||
await db.insert(Attachments).values(data).returning()
|
||||
)[0];
|
||||
data: InferInsertModel<typeof Medias>,
|
||||
): Promise<Media> {
|
||||
const inserted = (await db.insert(Medias).values(data).returning())[0];
|
||||
|
||||
const attachment = await Attachment.fromId(inserted.id);
|
||||
const attachment = await Media.fromId(inserted.id);
|
||||
|
||||
if (!attachment) {
|
||||
throw new Error("Failed to insert attachment");
|
||||
|
|
@ -160,7 +156,7 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
description?: string;
|
||||
thumbnail?: File;
|
||||
},
|
||||
): Promise<Attachment> {
|
||||
): Promise<Media> {
|
||||
if (file.size > config.validation.max_media_size) {
|
||||
throw new ApiError(
|
||||
413,
|
||||
|
|
@ -191,17 +187,17 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
|
||||
const { path } = await mediaManager.addFile(file);
|
||||
|
||||
const url = Attachment.getUrl(path);
|
||||
const url = Media.getUrl(path);
|
||||
|
||||
let thumbnailUrl = "";
|
||||
|
||||
if (options?.thumbnail) {
|
||||
const { path } = await mediaManager.addFile(options.thumbnail);
|
||||
|
||||
thumbnailUrl = Attachment.getUrl(path);
|
||||
thumbnailUrl = Media.getUrl(path);
|
||||
}
|
||||
|
||||
const newAttachment = await Attachment.insert({
|
||||
const newAttachment = await Media.insert({
|
||||
url,
|
||||
thumbnailUrl: thumbnailUrl || undefined,
|
||||
sha256: sha256.update(await file.arrayBuffer()).digest("hex"),
|
||||
|
|
@ -319,11 +315,11 @@ export class Attachment extends BaseInterface<typeof Attachments> {
|
|||
|
||||
public static fromVersia(
|
||||
attachmentToConvert: ContentFormat,
|
||||
): Promise<Attachment> {
|
||||
): Promise<Media> {
|
||||
const key = Object.keys(attachmentToConvert)[0];
|
||||
const value = attachmentToConvert[key];
|
||||
|
||||
return Attachment.insert({
|
||||
return Media.insert({
|
||||
mimeType: key,
|
||||
url: value.content,
|
||||
description: value.description || undefined,
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import type {
|
|||
} from "@versia/federation/types";
|
||||
import { Instance, db } from "@versia/kit/db";
|
||||
import {
|
||||
Attachments,
|
||||
EmojiToNote,
|
||||
Medias,
|
||||
NoteToMentions,
|
||||
Notes,
|
||||
Users,
|
||||
|
|
@ -44,7 +44,7 @@ import {
|
|||
import { config } from "~/packages/config-manager";
|
||||
import { DeliveryJobType, deliveryQueue } from "../queues/delivery.ts";
|
||||
import { Application } from "./application.ts";
|
||||
import { Attachment } from "./attachment.ts";
|
||||
import { Media } from "./attachment.ts";
|
||||
import { BaseInterface } from "./base.ts";
|
||||
import { Emoji } from "./emoji.ts";
|
||||
import { User } from "./user.ts";
|
||||
|
|
@ -56,7 +56,7 @@ type NoteTypeWithRelations = NoteType & {
|
|||
mentions: (InferSelectModel<typeof Users> & {
|
||||
instance: typeof Instance.$type | null;
|
||||
})[];
|
||||
attachments: (typeof Attachment.$type)[];
|
||||
attachments: (typeof Media.$type)[];
|
||||
reblog: NoteTypeWithoutRecursiveRelations | null;
|
||||
emojis: (typeof Emoji.$type)[];
|
||||
reply: NoteType | null;
|
||||
|
|
@ -102,7 +102,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
sensitive: z.boolean(),
|
||||
spoiler_text: z.string(),
|
||||
visibility: z.enum(["public", "unlisted", "private", "direct"]),
|
||||
media_attachments: z.array(Attachment.schema),
|
||||
media_attachments: z.array(Media.schema),
|
||||
mentions: z.array(
|
||||
z.object({
|
||||
id: z.string().uuid(),
|
||||
|
|
@ -442,7 +442,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
uri?: string;
|
||||
mentions?: User[];
|
||||
/** List of IDs of database Attachment objects */
|
||||
mediaAttachments?: Attachment[];
|
||||
mediaAttachments?: Media[];
|
||||
replyId?: string;
|
||||
quoteId?: string;
|
||||
application?: Application;
|
||||
|
|
@ -515,7 +515,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
emojis?: Emoji[];
|
||||
uri?: string;
|
||||
mentions?: User[];
|
||||
mediaAttachments?: Attachment[];
|
||||
mediaAttachments?: Media[];
|
||||
replyId?: string;
|
||||
quoteId?: string;
|
||||
application?: Application;
|
||||
|
|
@ -623,28 +623,26 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
* Deletes all existing attachments associated with this note, then replaces them with the provided attachments.
|
||||
* @param mediaAttachments - The IDs of the attachments to associate with this note
|
||||
*/
|
||||
public async updateAttachments(
|
||||
mediaAttachments: Attachment[],
|
||||
): Promise<void> {
|
||||
public async updateAttachments(mediaAttachments: Media[]): Promise<void> {
|
||||
if (mediaAttachments.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove old attachments
|
||||
await db
|
||||
.update(Attachments)
|
||||
.update(Medias)
|
||||
.set({
|
||||
noteId: null,
|
||||
})
|
||||
.where(eq(Attachments.noteId, this.data.id));
|
||||
.where(eq(Medias.noteId, this.data.id));
|
||||
await db
|
||||
.update(Attachments)
|
||||
.update(Medias)
|
||||
.set({
|
||||
noteId: this.data.id,
|
||||
})
|
||||
.where(
|
||||
inArray(
|
||||
Attachments.id,
|
||||
Medias.id,
|
||||
mediaAttachments.map((i) => i.id),
|
||||
),
|
||||
);
|
||||
|
|
@ -740,16 +738,16 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
}
|
||||
}
|
||||
|
||||
const attachments: Attachment[] = [];
|
||||
const attachments: Media[] = [];
|
||||
|
||||
for (const attachment of note.attachments ?? []) {
|
||||
const resolvedAttachment = await Attachment.fromVersia(
|
||||
attachment,
|
||||
).catch((e) => {
|
||||
logger.error`${e}`;
|
||||
sentry?.captureException(e);
|
||||
return null;
|
||||
});
|
||||
const resolvedAttachment = await Media.fromVersia(attachment).catch(
|
||||
(e) => {
|
||||
logger.error`${e}`;
|
||||
sentry?.captureException(e);
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
if (resolvedAttachment) {
|
||||
attachments.push(resolvedAttachment);
|
||||
|
|
@ -908,7 +906,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
favourited: data.liked,
|
||||
favourites_count: data.likeCount,
|
||||
media_attachments: (data.attachments ?? []).map(
|
||||
(a) => new Attachment(a).toApi() as ApiAttachment,
|
||||
(a) => new Media(a).toApi() as ApiAttachment,
|
||||
),
|
||||
mentions: data.mentions.map((mention) => ({
|
||||
id: mention.id,
|
||||
|
|
@ -1014,7 +1012,7 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
|
|||
},
|
||||
},
|
||||
attachments: (status.attachments ?? []).map((attachment) =>
|
||||
new Attachment(attachment).toVersia(),
|
||||
new Media(attachment).toVersia(),
|
||||
),
|
||||
is_sensitive: status.sensitive,
|
||||
mentions: status.mentions.map((mention) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue