import { type MultipartPart, parseMultipart } from '@mjackson/multipart-parser'; import type { HttpResponse } from '@yaakapp-internal/models'; import { useState } from 'react'; import { useResponseBodyBytes } from '../../hooks/useResponseBodyText'; import { getMimeTypeFromContentType, languageFromContentType } from '../../lib/contentType'; import { getContentTypeFromHeaders } from '../../lib/model_util'; import { Editor } from '../core/Editor/LazyEditor'; import { Icon } from '../core/Icon'; import { TabContent, Tabs } from '../core/Tabs/Tabs'; import { CsvViewerInner } from './CsvViewer'; import { ImageViewer } from './ImageViewer'; interface Props { response: HttpResponse; } export function MultipartViewer({ response }: Props) { const body = useResponseBodyBytes({ response }); const [tab, setTab] = useState(); if (body.data == null) return null; const contentTypeHeader = getContentTypeFromHeaders(response.headers); const boundary = contentTypeHeader?.split('boundary=')[1] ?? 'unknown'; const parsed = parseMultipart(body.data, { boundary }); const parts = Array.from(parsed); return ( ({ label: part.name ?? '', value: part.name ?? '', rightSlot: part.filename && part.headers.contentType.mediaType?.startsWith('image/') ? (
) : part.filename ? ( ) : null, }))} > {parts.map((part, i) => ( ))}
); } function Part({ part }: { part: MultipartPart }) { const contentType = part.headers.get('content-type'); const mimeType = contentType == null ? null : getMimeTypeFromContentType(contentType).essence; if (mimeType?.match(/^image/i)) { return ; } if (mimeType?.match(/csv|tab-separated/i)) { const content = new TextDecoder().decode(part.arrayBuffer); return ; } const content = new TextDecoder().decode(part.arrayBuffer); const language = languageFromContentType(contentType, content); return ; }