Openstatus
www.openstatus.dev
1import { put } from "@vercel/blob";
2import { z } from "zod";
3
4import { TRPCError } from "@trpc/server";
5import { createTRPCRouter, protectedProcedure } from "../trpc";
6
7export const blobRouter = createTRPCRouter({
8 upload: protectedProcedure
9 .input(
10 z.object({
11 filename: z.string().min(1),
12 // Base64 encoded string (without data: prefix)
13 file: z.string().min(1),
14 }),
15 )
16 .mutation(async (opts) => {
17 const { filename, file } = opts.input;
18
19 // If the client sent a data URL, strip the prefix
20 const base64 = file.includes("base64,")
21 ? file.split("base64,").pop()
22 : file;
23
24 if (!base64) {
25 throw new TRPCError({
26 code: "BAD_REQUEST",
27 message: "Invalid file",
28 });
29 }
30
31 const buffer = Buffer.from(base64, "base64");
32
33 const blob = await put(`${opts.ctx.workspace.slug}/${filename}`, buffer, {
34 access: "public",
35 });
36
37 return blob;
38 }),
39});