import { consumeMediaParam, decode2331Encoding } from "./_util.ts";
export function parseMediaType( v: string,): [mediaType: string, params: Record<string, string> | undefined] { const [base] = v.split(";") as [string]; const mediaType = base.toLowerCase().trim();
const params: Record<string, string> = {}; const continuation = new Map<string, Record<string, string>>();
v = v.slice(base.length); while (v.length) { v = v.trimStart(); if (v.length === 0) { break; } const [key, value, rest] = consumeMediaParam(v); if (!key) { if (rest.trim() === ";") { break; } throw new TypeError("Invalid media parameter."); }
let pmap = params; const [baseName, rest2] = key.split("*"); if (baseName && rest2 !== undefined) { if (!continuation.has(baseName)) { continuation.set(baseName, {}); } pmap = continuation.get(baseName)!; } if (key in pmap) { throw new TypeError("Duplicate key parsed."); } pmap[key] = value; v = rest; }
let str = ""; for (const [key, pieceMap] of continuation) { const singlePartKey = `${key}*`; const v = pieceMap[singlePartKey]; if (v) { const decv = decode2331Encoding(v); if (decv) { params[key] = decv; } continue; }
str = ""; let valid = false; for (let n = 0;; n++) { const simplePart = `${key}*${n}`; let v = pieceMap[simplePart]; if (v) { valid = true; str += v; continue; } const encodedPart = `${simplePart}*`; v = pieceMap[encodedPart]; if (!v) { break; } valid = true; if (n === 0) { const decv = decode2331Encoding(v); if (decv) { str += decv; } } else { const decv = decodeURI(v); str += decv; } } if (valid) { params[key] = str; } }
return Object.keys(params).length ? [mediaType, params] : [mediaType, undefined];}