159 lines
3.3 KiB
TypeScript
159 lines
3.3 KiB
TypeScript
import { TRPCError } from "@trpc/server";
|
|
import type { MediaStorageId } from "~/schemas/public/MediaStorage";
|
|
import type {
|
|
Storage,
|
|
StorageId,
|
|
StorageUpdate,
|
|
} from "~/schemas/public/Storage";
|
|
import type { UsersId } from "~/schemas/public/Users";
|
|
import { db } from "~/server/db";
|
|
export type FileMetadata = Omit<Storage, "file_data">;
|
|
export type FileMetadataWithAdmin = FileMetadata & {
|
|
from_admin: boolean;
|
|
};
|
|
|
|
export const getFileInfo = async (fileId: StorageId) => {
|
|
try {
|
|
const file = await db
|
|
.$pickTables<"storage">()
|
|
.selectFrom("storage")
|
|
.select([
|
|
"id",
|
|
"created_at",
|
|
"expires_at",
|
|
"file_size_bytes",
|
|
"filename",
|
|
"mime_type",
|
|
"tag",
|
|
])
|
|
.where("id", "=", fileId)
|
|
.executeTakeFirst();
|
|
return file;
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to get file info: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const uploadFile = async ({
|
|
buffer,
|
|
filename,
|
|
mime_type,
|
|
expires_at,
|
|
userId,
|
|
tag,
|
|
}: {
|
|
buffer: Buffer;
|
|
filename: string;
|
|
mime_type: string;
|
|
expires_at?: Date;
|
|
userId?: UsersId;
|
|
tag?: string;
|
|
}) => {
|
|
try {
|
|
const storage = await db
|
|
.$pickTables<"storage">()
|
|
.insertInto("storage")
|
|
.values({
|
|
filename,
|
|
mime_type,
|
|
expires_at,
|
|
file_data: buffer,
|
|
file_size_bytes: buffer.length,
|
|
tag,
|
|
})
|
|
.returning("id")
|
|
.executeTakeFirstOrThrow();
|
|
if (userId) {
|
|
const userStorageId = await db
|
|
.$pickTables<"users_storage">()
|
|
.insertInto("users_storage")
|
|
.values({
|
|
userId,
|
|
storage_id: storage.id,
|
|
})
|
|
.returning("user_storage_id")
|
|
.executeTakeFirstOrThrow();
|
|
return {
|
|
storageId: storage.id,
|
|
userStorageId: userStorageId.user_storage_id,
|
|
};
|
|
}
|
|
return {
|
|
storageId: storage.id,
|
|
userStorageId: null,
|
|
};
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to upload file: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const getFile = async (fileId: StorageId) => {
|
|
try {
|
|
return await db
|
|
.$pickTables<"storage">()
|
|
.selectFrom("storage")
|
|
.selectAll()
|
|
.where("id", "=", fileId)
|
|
.executeTakeFirst();
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to get file: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const getMediaFile = async (fileId: MediaStorageId) => {
|
|
try {
|
|
return await db
|
|
.$pickTables<"media_storage">()
|
|
.selectFrom("media_storage")
|
|
.selectAll()
|
|
.where("id", "=", fileId)
|
|
.executeTakeFirst();
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to get media_file: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const editFile = async (fileId: StorageId, data: StorageUpdate) => {
|
|
try {
|
|
await db
|
|
.$pickTables<"storage">()
|
|
.updateTable("storage")
|
|
.set(data)
|
|
.where("id", "=", fileId)
|
|
.execute();
|
|
return true;
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to update file info: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const deleteFile = async (fileId: StorageId) => {
|
|
try {
|
|
await db
|
|
.$pickTables<"storage">()
|
|
.deleteFrom("storage")
|
|
.where("id", "=", fileId)
|
|
.execute();
|
|
return true;
|
|
} catch (e) {
|
|
throw new TRPCError({
|
|
code: "INTERNAL_SERVER_ERROR",
|
|
message: `Failed to delete file info: ${(e as Error).message}`,
|
|
});
|
|
}
|
|
};
|