57 lines
1.5 KiB
TypeScript
57 lines
1.5 KiB
TypeScript
import { z } from "zod";
|
|
|
|
export const uploadKindSchema = z.enum(["image", "audio"]);
|
|
|
|
export type UploadKind = z.infer<typeof uploadKindSchema>;
|
|
|
|
export const uploadRequestSchema = z.object({
|
|
kind: uploadKindSchema,
|
|
fileName: z.string().trim().min(1).max(255),
|
|
mimeType: z.string().trim().min(1).max(120),
|
|
size: z.number().int().positive(),
|
|
});
|
|
|
|
export const uploadedFileSchema = z.object({
|
|
kind: uploadKindSchema,
|
|
url: z.string().startsWith("/api/uploads/"),
|
|
fileName: z.string().min(1),
|
|
mimeType: z.string().min(1),
|
|
size: z.number().int().positive(),
|
|
});
|
|
|
|
export type UploadRequest = z.infer<typeof uploadRequestSchema>;
|
|
export type UploadedFileMetadata = z.infer<typeof uploadedFileSchema>;
|
|
|
|
export const UPLOAD_RULES: Record<
|
|
UploadKind,
|
|
{
|
|
maxBytes: number;
|
|
accept: string;
|
|
mimeTypes: readonly string[];
|
|
}
|
|
> = {
|
|
image: {
|
|
maxBytes: 10 * 1024 * 1024,
|
|
accept: "image/jpeg,image/png,image/webp",
|
|
mimeTypes: ["image/jpeg", "image/png", "image/webp"],
|
|
},
|
|
audio: {
|
|
maxBytes: 50 * 1024 * 1024,
|
|
accept: "audio/mpeg,audio/wav,audio/x-wav,audio/ogg,audio/webm,audio/mp4,audio/aac,audio/flac",
|
|
mimeTypes: [
|
|
"audio/mpeg",
|
|
"audio/wav",
|
|
"audio/x-wav",
|
|
"audio/ogg",
|
|
"audio/webm",
|
|
"audio/mp4",
|
|
"audio/aac",
|
|
"audio/flac",
|
|
],
|
|
},
|
|
};
|
|
|
|
export function isAllowedUploadMimeType(kind: UploadKind, mimeType: string) {
|
|
return UPLOAD_RULES[kind].mimeTypes.includes(mimeType.toLowerCase());
|
|
}
|