66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { publicProcedure, router } from "~/server/trpc";
|
|
import { db } from "~/server/db";
|
|
import { music } from "~/server/dbschema/schema";
|
|
import { eq } from "drizzle-orm";
|
|
import { isAdmin } from "~/app/actions";
|
|
import { TRPCError } from "@trpc/server";
|
|
import { z } from "zod";
|
|
import { createMusicInputSchema, updateMusicInputSchema, setStreamInputSchema } from "~/lib/trpc/music/schemas";
|
|
import { utapi } from "../uploadthing";
|
|
export const musicRouter = router({
|
|
list: publicProcedure.query(async () => {
|
|
let res = await db.select().from(music).orderBy(music.createdAt);
|
|
console.log(res);
|
|
return res;
|
|
}),
|
|
create: publicProcedure
|
|
.input(
|
|
createMusicInputSchema
|
|
)
|
|
.mutation(async ({ input }) => {
|
|
const admin = await isAdmin();
|
|
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
|
let res = await db.insert(music).values(input).returning();
|
|
return res.at(0);
|
|
}),
|
|
update: publicProcedure
|
|
.input(
|
|
updateMusicInputSchema
|
|
)
|
|
.mutation(async ({ input }) => {
|
|
const admin = await isAdmin();
|
|
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
|
const { id, ...data } = input;
|
|
return db.update(music).set(data).where(eq(music.id, id)).returning();
|
|
}),
|
|
setStream: publicProcedure
|
|
.input(setStreamInputSchema)
|
|
.mutation(async ({ input }) => {
|
|
const admin = await isAdmin();
|
|
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
|
const { id, ...data } = input;
|
|
const existing = await db.select().from(music).where(eq(music.id, id)).limit(1);
|
|
const prev = existing.at(0);
|
|
if (!prev) throw new TRPCError({ code: "NOT_FOUND", message: "Track not found" });
|
|
const res = await db.update(music).set(data).where(eq(music.id, id)).returning();
|
|
// Drop the previous stream transcode so we don't orphan it on UploadThing.
|
|
if (prev.streamKey && prev.streamKey !== data.streamKey) {
|
|
utapi.deleteFiles(prev.streamKey);
|
|
}
|
|
return res.at(0);
|
|
}),
|
|
delete: publicProcedure
|
|
.input(z.object({id:z.string().uuid()}))
|
|
.mutation(async ({ input }) => {
|
|
const admin = await isAdmin();
|
|
if (!admin) throw new TRPCError({ code: "FORBIDDEN", message: "Access denied" });
|
|
let res = await db.delete(music).where(eq(music.id, input.id)).returning();
|
|
let ret = res.at(0)
|
|
if (ret) {
|
|
const keys = [ret.fileKey, ret.streamKey].filter((k): k is string => !!k);
|
|
utapi.deleteFiles(keys)
|
|
}
|
|
return ret;
|
|
}),
|
|
});
|