Data URL Parser With Base64 Decoding

Parse data URLs into media type, parameters and bytes, handling percent-encoded and Base64 payloads plus decoded text.

TypescriptData Integrity

Code

snippet
export interface ParsedDataUrl {
  mediaType: string;
  parameters: Record<string, string>;
  base64: boolean;
  data: Uint8Array;
  text: () => string;
}

export function parseDataUrl(url: string): ParsedDataUrl {
  if (typeof url !== "string" || !url.startsWith("data:")) {
    throw new TypeError("url must start with data:");
  }
  const comma = url.indexOf(",");
  if (comma === -1) throw new RangeError("data URL must contain a comma");
  const metadata = url.slice(5, comma);
  const payload = url.slice(comma + 1);
  const parts = metadata.split(";");
  const mediaType = parts[0] || "text/plain";
  const base64 = parts.includes("base64");
  const parameters: Record<string, string> = {};
  for (const part of parts.slice(1)) {
    if (part === "base64") continue;
    const separator = part.indexOf("=");
    if (separator === -1) continue;
    const key = part.slice(0, separator);
    if (key) parameters[key] = decodeURIComponent(part.slice(separator + 1));
  }
  let bytes: Uint8Array;
  if (base64) {
    const binary = atob(payload);
    bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
  } else {
    bytes = new TextEncoder().encode(decodeURIComponent(payload));
  }
  return {
    mediaType,
    parameters,
    base64,
    data: bytes,
    text: () => new TextDecoder().decode(bytes),
  };
}