import { TRPCError } from "@trpc/server"; import { z } from "zod/v4"; import { adminProcedure, createTRPCRouter, protectedProcedure, } from "~/server/api/trpc"; import { addUserStorageHandler, deleteUserStorageHandler, getAllHandler, getFromIdHandler, getMultipleWithRelations, getUserStorageHandler, } from "~/server/controllers/storage.controller"; import { RateLimiterHandler } from "~/server/services/ratelimiter"; import { addUserStorageJunc, deleteFile, deleteUserStorageJunc, getNewTokenHandler, updateFile, } from "~/server/services/storage.service"; import { zStorageIndexId, zUserId } from "~/server/utils/zod_types"; import { db } from "~/server/db"; const ratelimit = new RateLimiterHandler({ maxRequests: 50, windowSize: 60, analytics: false, }); export const storageRouter = createTRPCRouter({ getAll: protectedProcedure.query(async () => { return await getAllHandler({ db }); }), getStorageToken: protectedProcedure.mutation(async () => { const { success } = await ratelimit.limit("getStorageToken"); if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" }); const token = (await getNewTokenHandler({ db }))[0]; if (!token) { throw new TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Error while creating token", }); } return token; }), getStorageTokenM: protectedProcedure .input(z.object({ num: z.number() })) .mutation(async ({ input }) => { const { success } = await ratelimit.limit("getStorageToken"); if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" }); return await getNewTokenHandler({ db, num: input.num }); }), deleteStorage: protectedProcedure .input(z.object({ storageId: zStorageIndexId })) .mutation(async ({ input }) => { return await deleteFile({ db, fileId: input.storageId, cb: async (fileId) => { await db .deleteFrom("storageindex") .where("id", "=", fileId) .execute(); }, }); }), getUserStorage: protectedProcedure .input(z.object({ userId: zUserId })) .query(async ({ input }) => { return await getUserStorageHandler({ db, userId: input.userId }); }), addUserStorage: protectedProcedure .input( z.object({ userId: zUserId, fileId: zStorageIndexId, }), ) .mutation(async ({ input }) => { return await addUserStorageHandler({ db, userId: input.userId, storageId: input.fileId, }); }), deleteUserStorage: protectedProcedure .input(z.object({ userId: zUserId, fileId: zStorageIndexId })) .mutation(async ({ input }) => { return await deleteUserStorageHandler({ db, userId: input.userId, storageId: input.fileId, }); }), getStorageFromId: protectedProcedure .input(z.object({ storageId: zStorageIndexId })) .query(async ({ input }) => { return await getFromIdHandler({ db, storage_id: input.storageId, }); }), renameFile: adminProcedure .input(z.object({ fileId: zStorageIndexId, name: z.string() })) .mutation(async ({ input }) => { return await updateFile({ db, fileId: input.fileId, data: { filename: input.name }, }); }), getStorageVisibility: adminProcedure .input(z.object({ storageIds: zStorageIndexId.array() })) .query(async ({ input }) => { return await getMultipleWithRelations({ db, ids: input.storageIds, }); }), addStorageVisibility: adminProcedure .input(z.object({ storageId: zStorageIndexId, userId: zUserId })) .mutation(async ({ input }) => { await addUserStorageJunc({ db, storageId: input.storageId, userId: input.userId, }); }), removeStorageVisibility: adminProcedure .input(z.object({ storageId: zStorageIndexId, userId: zUserId })) .mutation(async ({ input }) => { await deleteUserStorageJunc({ db, storageId: input.storageId, userId: input.userId, }); }), resetStorageVisibility: adminProcedure .input(z.object({ storageId: zStorageIndexId.array() })) .mutation(async ({ input }) => { await db .deleteFrom("users_storage") .where("storageid", "in", input.storageId) .execute(); return "ok"; }), });