infoalloggi-monorepo/apps/infoalloggi/src/server/services/storage.service.ts

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}`,
});
}
};