Created
November 3, 2024 02:34
-
-
Save reececomo/3cade2a05e8130d987ec5a390aadc66d to your computer and use it in GitHub Desktop.
file uploads with r2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ----- 2. ----- | |
| // (scroll down for 1.) | |
| import { z } from "zod"; | |
| import { UploadConfig, uploadFile } from "@/utils/upload-client"; | |
| import { uploadsTable } from "@/server/db/schema"; | |
| import { userProcedure } from "@/server/api/procedures"; | |
| import { db } from "@/server/db"; | |
| const MAX_FILE_SIZE_BYTES = UploadConfig.MAX_FILESIZE_MB * 1024 * 1024; | |
| const uploadSchema = z.object({ | |
| file: z.instanceof(File).refine((file) => file.size <= MAX_FILE_SIZE_BYTES, { | |
| message: `File size should be less than ${UploadConfig.MAX_FILESIZE_MB}MB`, | |
| }), | |
| }); | |
| export const upload = userProcedure | |
| .input(uploadSchema) | |
| .mutation(async ({ input, ctx }) => { | |
| const { file } = input; | |
| const { path } = await uploadFile(file); | |
| // Save to database | |
| await db.insert(uploadsTable).values({ | |
| path, | |
| userId: ctx.user.id, | |
| filename: file.name, | |
| mimeType: file.type, | |
| size: file.size, | |
| }); | |
| // Save to database | |
| const [upload] = await ctx.db | |
| .insert(uploadsTable) | |
| .values({ | |
| path, | |
| userId: ctx.user.id, | |
| filename: file.name, | |
| mimeType: file.type, | |
| size: file.size, | |
| }) | |
| .returning(); | |
| return upload; | |
| }); | |
| // ----- 1. ----- | |
| import { api } from "@/utils/trpc/server"; | |
| import { db } from "@/server/db"; | |
| import { NextResponse } from "next/server"; | |
| import { uploadsTable } from "@/server/db/schema"; | |
| import { UploadConfig, uploadFile } from "@/utils/upload-client"; | |
| export async function POST(request: Request) { | |
| try { | |
| // Check authentication | |
| const me = await api.user.me(); | |
| if (!me) { | |
| return new NextResponse("Unauthorized", { status: 401 }); | |
| } | |
| // Get the form data | |
| const formData = await request.formData(); | |
| const file = formData.get("file") as File; | |
| if (!file) { | |
| return new NextResponse("No file provided", { status: 400 }); | |
| } | |
| // Validate file | |
| const maxSize = UploadConfig.MAX_FILESIZE_MB * 1024 * 1024; | |
| if (file.size > maxSize) { | |
| return new NextResponse("File too large", { status: 400 }); | |
| } | |
| const { path } = await uploadFile(file); | |
| // Save to database | |
| await db.insert(uploadsTable).values({ | |
| path, | |
| userId: me.user.id, | |
| filename: file.name, | |
| mimeType: file.type, | |
| size: file.size, | |
| }); | |
| return NextResponse.json({ path }); | |
| } catch (error) { | |
| console.error("Upload error:", error); | |
| return new NextResponse("Internal Server Error", { status: 500 }); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment