42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { mutation, query } from "./_generated/server";
|
|
import { v } from "convex/values";
|
|
import { getPublicStorageUrl, rewriteToPublicUrl } from "./storageUrl";
|
|
|
|
// Generate upload URL for client-side uploads
|
|
export const generateUploadUrl = mutation({
|
|
args: {},
|
|
returns: v.string(),
|
|
handler: async (ctx) => {
|
|
const url = await ctx.storage.generateUploadUrl();
|
|
return rewriteToPublicUrl(url);
|
|
},
|
|
});
|
|
|
|
const MAX_ATTACHMENT_SIZE = 500 * 1024 * 1024; // 500MB
|
|
|
|
// Validate uploaded file size and return its URL. Deletes file if too large.
|
|
export const validateUpload = mutation({
|
|
args: { storageId: v.id("_storage") },
|
|
returns: v.string(),
|
|
handler: async (ctx, args) => {
|
|
const meta = await ctx.storage.getMetadata(args.storageId);
|
|
if (!meta) throw new Error("File not found in storage");
|
|
if (meta.size > MAX_ATTACHMENT_SIZE) {
|
|
await ctx.storage.delete(args.storageId);
|
|
throw new Error("File must be under 500MB");
|
|
}
|
|
const url = await getPublicStorageUrl(ctx, args.storageId);
|
|
if (!url) throw new Error("Failed to get file URL");
|
|
return url;
|
|
},
|
|
});
|
|
|
|
// Get file URL from storage ID
|
|
export const getFileUrl = query({
|
|
args: { storageId: v.id("_storage") },
|
|
returns: v.union(v.string(), v.null()),
|
|
handler: async (ctx, args) => {
|
|
return await getPublicStorageUrl(ctx, args.storageId);
|
|
},
|
|
});
|