From f10d7584d286c9ed9b643564f29994a412801853 Mon Sep 17 00:00:00 2001 From: jenstandstad Date: Tue, 18 Aug 2026 19:12:53 +0200 Subject: [PATCH] Importer: set asset mime type from file extension Uploaded manifest assets previously became application/octet-stream because the Blob carried no type, so images/audio/pdf didn't display or thumbnail correctly. Derive the mime from the extension. (Existing deduplicated assets keep their old mime; only fresh uploads are affected.) Co-Authored-By: Claude Opus 4.8 --- scripts/importMysteryTemplate.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/importMysteryTemplate.ts b/scripts/importMysteryTemplate.ts index ff63712..3982c49 100644 --- a/scripts/importMysteryTemplate.ts +++ b/scripts/importMysteryTemplate.ts @@ -41,11 +41,18 @@ function requireOk(response: Response, action: string) { return response.text().then(body => { throw new Error(`${action} failed (${response.status}): ${body}`) }) } +const MIME_BY_EXT: Record = { + png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml', + pdf: 'application/pdf', mp3: 'audio/mpeg', wav: 'audio/wav', ogg: 'audio/ogg', m4a: 'audio/mp4', txt: 'text/plain', +} +function mimeFor(filename: string) { return MIME_BY_EXT[filename.split('.').pop()?.toLowerCase() || ''] || 'application/octet-stream' } + async function uploadAsset(baseUrl: string, levelId: string, manifestDir: string, document: MysteryDocument, authorization?: string) { if (!document.asset) return undefined const assetPath = path.resolve(manifestDir, document.asset) + const filename = path.basename(assetPath) const form = new FormData() - form.append('file', new Blob([await readFile(assetPath)]), path.basename(assetPath)) + form.append('file', new Blob([await readFile(assetPath)], { type: mimeFor(filename) }), filename) const response = await requireOk(await fetch(`${baseUrl}/api/levels/${levelId}/documents?edit=1`, { method: 'POST', headers: authorization ? { authorization } : undefined, body: form }), `Upload ${document.asset}`) return await response.json() as CaseDocument }