Skip to content

Instantly share code, notes, and snippets.

@reececomo
Created November 3, 2024 02:34
Show Gist options
  • Select an option

  • Save reececomo/3cade2a05e8130d987ec5a390aadc66d to your computer and use it in GitHub Desktop.

Select an option

Save reececomo/3cade2a05e8130d987ec5a390aadc66d to your computer and use it in GitHub Desktop.
file uploads with r2
// ----- 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