Hello from MCP server

List Files | Just Commands | Repo | Logs

← back |
/**
 * Logo Storage using IndexedDB
 * Stores custom logos (logo-square and logo) as base64 data URLs
 */

const DB_NAME = 'LogoStorage';
const DB_VERSION = 1;
const STORE_NAME = 'logos';

export type LogoType = 'logo-square' | 'logo';

interface LogoData {
  type: LogoType;
  dataUrl: string;
  uploadedAt: number;
}

// Open or create the IndexedDB database
const openDB = (): Promise<IDBDatabase> => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);

    request.onerror = () => reject(request.error);
    request.onsuccess = () => resolve(request.result);

    request.onupgradeneeded = (event) => {
      const db = (event.target as IDBOpenDBRequest).result;

      // Create object store if it doesn't exist
      if (!db.objectStoreNames.contains(STORE_NAME)) {
        db.createObjectStore(STORE_NAME, { keyPath: 'type' });
      }
    };
  });
};

/**
 * Save a logo to IndexedDB
 */
export const saveLogo = async (type: LogoType, dataUrl: string): Promise<void> => {
  const db = await openDB();

  return new Promise((resolve, reject) => {
    const transaction = db.transaction(STORE_NAME, 'readwrite');
    const store = transaction.objectStore(STORE_NAME);

    const logoData: LogoData = {
      type,
      dataUrl,
      uploadedAt: Date.now()
    };

    const request = store.put(logoData);

    request.onsuccess = () => {
      console.log(`[LogoStorage] Saved ${type} logo`);
      resolve();
    };
    request.onerror = () => reject(request.error);

    transaction.oncomplete = () => db.close();
  });
};

/**
 * Get a logo from IndexedDB
 */
export const getLogo = async (type: LogoType): Promise<string | null> => {
  const db = await openDB();

  return new Promise((resolve, reject) => {
    const transaction = db.transaction(STORE_NAME, 'readonly');
    const store = transaction.objectStore(STORE_NAME);

    const request = store.get(type);

    request.onsuccess = () => {
      const result = request.result as LogoData | undefined;
      resolve(result ? result.dataUrl : null);
    };
    request.onerror = () => reject(request.error);

    transaction.oncomplete = () => db.close();
  });
};

/**
 * Delete a logo from IndexedDB
 */
export const deleteLogo = async (type: LogoType): Promise<void> => {
  const db = await openDB();

  return new Promise((resolve, reject) => {
    const transaction = db.transaction(STORE_NAME, 'readwrite');
    const store = transaction.objectStore(STORE_NAME);

    const request = store.delete(type);

    request.onsuccess = () => {
      console.log(`[LogoStorage] Deleted ${type} logo`);
      resolve();
    };
    request.onerror = () => reject(request.error);

    transaction.oncomplete = () => db.close();
  });
};

/**
 * Get all logos from IndexedDB
 */
export const getAllLogos = async (): Promise<Record<LogoType, string | null>> => {
  const db = await openDB();

  return new Promise((resolve, reject) => {
    const transaction = db.transaction(STORE_NAME, 'readonly');
    const store = transaction.objectStore(STORE_NAME);

    const request = store.getAll();

    request.onsuccess = () => {
      const results = request.result as LogoData[];
      const logos: Record<LogoType, string | null> = {
        'logo-square': null,
        'logo': null
      };

      results.forEach(data => {
        logos[data.type] = data.dataUrl;
      });

      resolve(logos);
    };
    request.onerror = () => reject(request.error);

    transaction.oncomplete = () => db.close();
  });
};

/**
 * Convert a File to a base64 data URL
 */
export const fileToDataUrl = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onload = () => {
      if (typeof reader.result === 'string') {
        resolve(reader.result);
      } else {
        reject(new Error('Failed to convert file to data URL'));
      }
    };

    reader.onerror = () => reject(reader.error);
    reader.readAsDataURL(file);
  });
};