47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
export const MAX_FORM_ANSWER_IMAGE_BYTES = 50 * 1024 * 1024;
|
|
|
|
const ALLOWED_IMAGE_MIME_TYPES = new Set([
|
|
"image/png",
|
|
"image/jpeg",
|
|
"image/webp",
|
|
"image/gif",
|
|
]);
|
|
|
|
const ALLOWED_IMAGE_EXTENSIONS = new Set(["png", "jpg", "jpeg", "webp", "gif"]);
|
|
|
|
export function validateImageUploadFile(file: Pick<File, "name" | "type" | "size">) {
|
|
if (!ALLOWED_IMAGE_MIME_TYPES.has(file.type)) {
|
|
throw new Error("Only PNG, JPG, WebP, and GIF images are allowed");
|
|
}
|
|
|
|
if (file.size > MAX_FORM_ANSWER_IMAGE_BYTES) {
|
|
throw new Error("Image must be 50MB or smaller");
|
|
}
|
|
|
|
const extension = (file.name.split(".").pop() || "").toLowerCase();
|
|
if (!ALLOWED_IMAGE_EXTENSIONS.has(extension)) {
|
|
throw new Error("Invalid image extension");
|
|
}
|
|
}
|
|
|
|
export function cdnUrl(id: string | null | undefined) {
|
|
return id ? `/cdn/${id}` : "";
|
|
}
|
|
|
|
export type CdnResponseRecord = {
|
|
data: Buffer;
|
|
type: string;
|
|
size: number;
|
|
};
|
|
|
|
export function cdnImageResponse(record: CdnResponseRecord) {
|
|
return new Response(new Uint8Array(record.data), {
|
|
headers: {
|
|
"Content-Type": record.type,
|
|
"Content-Length": String(record.size),
|
|
"Cache-Control": "public, max-age=31536000, immutable",
|
|
"X-Content-Type-Options": "nosniff",
|
|
},
|
|
});
|
|
}
|