# All files / src/utils Binary.ts

100% Statements 35/35
100% Branches 24/24
100% Functions 2/2
100% Lines 34/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83

    23x
    4x
    4x
    3x

    19x
    4x
    4x
    3x
    2x
    2x
    2x
    4x

    1x
    1x

    15x
    15x
    13x
    13x
    13x

    2x
    2x

    1x

    14x
    14x

    2x

    3x

    1x

    1x

    2x

    1x

    1x

    1x

    1x

    1x

     import fs from "fs";
    import path from "path";
    import { logger } from "./logger.js";

    export interface Base64Data {
      data: string;
      mimeType: string;
    }

    export class BinaryUtils {
      /**
       * Converts a URL (data:, http:, or local path) to a base64 string and mime type.
       */
      static async toBase64(url: string): Promise<Base64Data | null> {
        if (url.startsWith("data:")) {
          const match = url.match(/^data:([^;]+);base64,(.+)$/);
          if (match && match[1] && match[2]) {
            return {
              mimeType: match[1],
              data: match[2]
            };
          }
        } else if (url.startsWith("http")) {
          try {
            const response = await fetch(url);
            if (!response.ok) return null;
            const buffer = await response.arrayBuffer();
            const base64 = Buffer.from(buffer).toString("base64");
            const mimeType = response.headers.get("content-type") || this.guessMimeType(url);
            return {
              mimeType,
              data: base64
            };
          } catch (e) {
            logger.error("Error converting URL to base64:", e as Error);
            return null;
          }
        } else {
          // Assume local file path
          try {
            const buffer = await fs.promises.readFile(url);
            const base64 = buffer.toString("base64");
            const mimeType = this.guessMimeType(url);
            return {
              mimeType,
              data: base64
            };
          } catch (e) {
            logger.error("Error reading local file for base64:", e as Error);
            return null;
          }
        }
        return null;
      }

      private static guessMimeType(filePath: string): string {
        const ext = path.extname(filePath).toLowerCase();
        switch (ext) {
          case ".png":
            return "image/png";
          case ".jpg":
          case ".jpeg":
            return "image/jpeg";
          case ".webp":
            return "image/webp";
          case ".gif":
            return "image/gif";
          case ".mp3":
            return "audio/mpeg";
          case ".wav":
            return "audio/wav";
          case ".ogg":
            return "audio/ogg";
          case ".m4a":
            return "audio/mp4";
          case ".pdf":
            return "application/pdf";
          default:
            return "application/octet-stream";
        }
      }
    }