From 036ed842551ef9486f4fbdf61bc8096ba800bbce Mon Sep 17 00:00:00 2001 From: maaz519 Date: Mon, 20 Jul 2026 14:29:21 +0530 Subject: [PATCH] feat(media): infer MIME from extension for empty-type uploads (.md, .html) Browsers report an empty file.type for files with no OS-registered MIME (esp. .md), which then went up as application/octet-stream and got rejected. Infer the type from the extension for the text types IIOS allows (md/markdown/html/ htm/txt/csv) so those attachments upload. Co-Authored-By: Claude Opus 4.8 --- src/lib/media-api.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib/media-api.ts b/src/lib/media-api.ts index 3a3f73d..20a62bc 100644 --- a/src/lib/media-api.ts +++ b/src/lib/media-api.ts @@ -14,12 +14,25 @@ export function isImage(mime?: string | null): boolean { return !!mime && mime.startsWith("image/"); } +// Some types (notably .md) have no OS-registered MIME, so the browser reports an empty file.type. +// Fall back to the extension for the text types IIOS allows, else a generic binary. +const EXT_MIME: Record = { + md: "text/markdown", markdown: "text/markdown", + html: "text/html", htm: "text/html", + txt: "text/plain", csv: "text/csv", +}; +function mimeForFile(file: File): string { + if (file.type) return file.type; + const ext = file.name.toLowerCase().split(".").pop() ?? ""; + return EXT_MIME[ext] ?? "application/octet-stream"; +} + /** Upload a File → { contentRef, mimeType, sizeBytes, filename }. Throws on oversize / failure. */ export function useUploadAttachment() { const { sdk } = useAppShell(); return useCallback(async (file: File): Promise => { if (file.size > MAX_ATTACHMENT_BYTES) throw new Error("File is too large (max 25 MB)."); - const mime = file.type || "application/octet-stream"; + const mime = mimeForFile(file); const { objectKey, uploadUrl } = (await sdk.command("crm.media.presignUpload", { mime, sizeBytes: file.size })) as { objectKey: string; uploadUrl: string }; const res = await fetch(uploadUrl, { method: "PUT", body: file }); if (!res.ok) throw new Error(`Upload failed (${res.status}).`);