{"version":3,"file":"StorageUtils.mjs","sources":["../src/StorageUtils.ts"],"sourcesContent":["/**\n * @module StorageUtils\n * @description Utility functions for managing browser storage (localStorage, sessionStorage, cookies) with support for encryption, expiration, and type-safe operations. Includes methods for getting, setting, and removing values, as well as managing storage quotas and handling storage availability.\n * @example\n * ```typescript\n * import { StorageUtils } from 'houser-js-utils';\n *\n * // Set and get values from localStorage\n * StorageUtils.setLocal('user', { id: 1, name: 'John' });\n * const user = StorageUtils.getLocal<{ id: number; name: string }>('user');\n *\n * // Set and get values from sessionStorage with encryption\n * StorageUtils.setSession('token', 'secret-token', { encrypt: true });\n * const token = StorageUtils.getSession<string>('token', { decrypt: true });\n *\n * // Set and get cookies with options\n * StorageUtils.setCookie('theme', 'dark', { expires: 86400000, secure: true });\n * const theme = StorageUtils.getCookie('theme');\n *\n * // Check storage availability\n * if (StorageUtils.isStorageAvailable('localStorage')) {\n *   // Use localStorage\n * }\n * ```\n */\nexport const StorageUtils = {\n  /**\n   * Clears all cookies.\n   * @param options - Clear options\n   * @param options.exclude - Cookie names to exclude from clearing\n   * @param options.path - Cookie path\n   * @param options.domain - Cookie domain\n   * @example\n   * ```typescript\n   * // Clear all cookies\n   * StorageUtils.clearCookies();\n   *\n   * // Clear cookies except 'session'\n   * StorageUtils.clearCookies({ exclude: ['session'] });\n   * ```\n   */\n  clearCookies(\n    options: {\n      exclude?: string[];\n      path?: string;\n      domain?: string;\n    } = {}\n  ): void {\n    try {\n      const { exclude = [], path = \"/\", domain } = options;\n      const cookies = this.getAllCookies();\n      Object.keys(cookies).forEach((name) => {\n        if (!exclude.includes(name)) {\n          this.removeCookie(name, { path, domain });\n        }\n      });\n    } catch (error) {\n      console.error(\"Error clearing cookies:\", error);\n    }\n  },\n\n  /**\n   * Clears all values from localStorage.\n   * @param options - Clear options\n   * @param options.exclude - Keys to exclude from clearing\n   * @example\n   * ```typescript\n   * // Clear all localStorage\n   * StorageUtils.clearLocal();\n   *\n   * // Clear localStorage except 'settings'\n   * StorageUtils.clearLocal({ exclude: ['settings'] });\n   * ```\n   */\n  clearLocal(\n    options: {\n      exclude?: string[];\n    } = {}\n  ): void {\n    try {\n      const { exclude = [] } = options;\n      if (exclude.length === 0) {\n        localStorage.clear();\n      } else {\n        Object.keys(localStorage).forEach((key) => {\n          if (!exclude.includes(key)) {\n            localStorage.removeItem(key);\n          }\n        });\n      }\n    } catch (error) {\n      console.error(\"Error clearing localStorage:\", error);\n    }\n  },\n\n  /**\n   * Clears all values from sessionStorage.\n   * @param options - Clear options\n   * @param options.exclude - Keys to exclude from clearing\n   * @example\n   * ```typescript\n   * // Clear all sessionStorage\n   * StorageUtils.clearSession();\n   *\n   * // Clear sessionStorage except 'temp'\n   * StorageUtils.clearSession({ exclude: ['temp'] });\n   * ```\n   */\n  clearSession(\n    options: {\n      exclude?: string[];\n    } = {}\n  ): void {\n    try {\n      const { exclude = [] } = options;\n      if (exclude.length === 0) {\n        sessionStorage.clear();\n      } else {\n        Object.keys(sessionStorage).forEach((key) => {\n          if (!exclude.includes(key)) {\n            sessionStorage.removeItem(key);\n          }\n        });\n      }\n    } catch (error) {\n      console.error(\"Error clearing sessionStorage:\", error);\n    }\n  },\n\n  /**\n   * Decrypts an encrypted string value.\n   * @param value - Value to decrypt\n   * @param key - Optional encryption key (defaults to a secure key)\n   * @returns Promise resolving to decrypted value\n   * @throws Error if decryption fails\n   * @example\n   * ```typescript\n   * const decrypted = await StorageUtils.decrypt(encryptedValue);\n   * ```\n   */\n  async decrypt(value: string, key?: string): Promise<string> {\n    try {\n      const encryptedData = JSON.parse(atob(value));\n      const { iv, data } = encryptedData;\n\n      const cryptoKey = await this.getCryptoKey(key);\n\n      const encryptedBuffer = new Uint8Array(data.split(\",\").map(Number));\n      const ivBuffer = new Uint8Array(iv.split(\",\").map(Number));\n\n      const decryptedBuffer = await window.crypto.subtle.decrypt(\n        {\n          name: \"AES-GCM\",\n          iv: ivBuffer,\n        },\n        cryptoKey,\n        encryptedBuffer\n      );\n\n      return new TextDecoder().decode(decryptedBuffer);\n    } catch (error) {\n      console.error(\"Error decrypting value:\", error);\n      throw new Error(\"Failed to decrypt value\");\n    }\n  },\n\n  /**\n   * Encrypts a string value.\n   * @param value - Value to encrypt\n   * @param key - Optional encryption key (defaults to a secure key)\n   * @returns Promise resolving to encrypted value\n   * @throws Error if encryption fails\n   * @example\n   * ```typescript\n   * const encrypted = await StorageUtils.encrypt('sensitive-data');\n   * ```\n   */\n  async encrypt(value: string, key?: string): Promise<string> {\n    try {\n      const cryptoKey = await this.getCryptoKey(key);\n      const iv = window.crypto.getRandomValues(new Uint8Array(12));\n      const dataBuffer = new TextEncoder().encode(value);\n\n      const encryptedBuffer = await window.crypto.subtle.encrypt(\n        {\n          name: \"AES-GCM\",\n          iv,\n        },\n        cryptoKey,\n        dataBuffer\n      );\n\n      const encryptedData = {\n        iv: Array.from(iv),\n        data: Array.from(new Uint8Array(encryptedBuffer)),\n      };\n\n      return btoa(JSON.stringify(encryptedData));\n    } catch (error) {\n      console.error(\"Error encrypting value:\", error);\n      throw new Error(\"Failed to encrypt value\");\n    }\n  },\n\n  /**\n   * Gets all cookies.\n   * @param options - Cookie options\n   * @param options.decrypt - Whether to decrypt the values\n   * @returns Object containing all cookies\n   * @example\n   * ```typescript\n   * // Get all cookies\n   * const cookies = StorageUtils.getAllCookies();\n   *\n   * // Get all cookies with decryption\n   * const decryptedCookies = await StorageUtils.getAllCookies({ decrypt: true });\n   * ```\n   */\n  async getAllCookies(\n    options: {\n      decrypt?: boolean;\n    } = {}\n  ): Promise<Record<string, string>> {\n    try {\n      const { decrypt = false } = options;\n      const cookies: Record<string, string> = {};\n      const cookiePromises = document.cookie.split(\";\").map(async (cookie) => {\n        const [name, value] = cookie.trim().split(\"=\");\n        const decodedName = decodeURIComponent(name);\n        const decodedValue = decodeURIComponent(value);\n        cookies[decodedName] = decrypt\n          ? await this.decrypt(decodedValue)\n          : decodedValue;\n      });\n      await Promise.all(cookiePromises);\n      return cookies;\n    } catch (error) {\n      console.error(\"Error getting all cookies:\", error);\n      return {};\n    }\n  },\n\n  /**\n   * Gets a cookie value.\n   * @param name - Cookie name\n   * @param options - Cookie options\n   * @param options.decrypt - Whether to decrypt the value\n   * @returns Cookie value or null if not found\n   * @example\n   * ```typescript\n   * // Get a cookie\n   * const value = StorageUtils.getCookie('theme');\n   *\n   * // Get and decrypt a cookie\n   * const decryptedValue = await StorageUtils.getCookie('token', { decrypt: true });\n   * ```\n   */\n  async getCookie(\n    name: string,\n    options: {\n      decrypt?: boolean;\n    } = {}\n  ): Promise<string | null> {\n    try {\n      const { decrypt = false } = options;\n      const cookies = document.cookie.split(\";\");\n      const cookie = cookies.find((c) => c.trim().startsWith(`${name}=`));\n\n      if (!cookie) return null;\n\n      const value = decodeURIComponent(cookie.split(\"=\")[1]);\n      return decrypt ? await this.decrypt(value) : value;\n    } catch (error) {\n      console.error(\"Error getting cookie:\", error);\n      return null;\n    }\n  },\n\n  /**\n   * Gets or generates a crypto key for encryption/decryption.\n   * @param key - Optional encryption key\n   * @returns Promise resolving to CryptoKey\n   * @private\n   */\n  async getCryptoKey(key?: string): Promise<CryptoKey> {\n    try {\n      const keyMaterial = key\n        ? await window.crypto.subtle.importKey(\n            \"raw\",\n            new TextEncoder().encode(key),\n            { name: \"PBKDF2\" },\n            false,\n            [\"deriveBits\", \"deriveKey\"]\n          )\n        : await window.crypto.subtle.generateKey(\n            {\n              name: \"AES-GCM\",\n              length: 256,\n            },\n            true,\n            [\"encrypt\", \"decrypt\"]\n          );\n\n      if (key) {\n        return window.crypto.subtle.deriveKey(\n          {\n            name: \"PBKDF2\",\n            salt: new TextEncoder().encode(\"storage-salt\"),\n            iterations: 100000,\n            hash: \"SHA-256\",\n          },\n          keyMaterial,\n          { name: \"AES-GCM\", length: 256 },\n          false,\n          [\"encrypt\", \"decrypt\"]\n        );\n      }\n\n      return keyMaterial as CryptoKey;\n    } catch (error) {\n      console.error(\"Error getting crypto key:\", error);\n      throw new Error(\"Failed to get encryption key\");\n    }\n  },\n\n  /**\n   * Gets a value from localStorage.\n   * @template T\n   * @param key - Storage key\n   * @param options - Storage options\n   * @param options.decrypt - Whether to decrypt the value\n   * @param options.defaultValue - Default value if not found/expired\n   * @returns Stored value or null if not found/expired\n   * @example\n   * ```typescript\n   * // Get a value\n   * const value = StorageUtils.getLocal<string>('name');\n   *\n   * // Get and decrypt a value with default\n   * const decryptedValue = await StorageUtils.getLocal<string>('token', {\n   *   decrypt: true,\n   *   defaultValue: 'default-token'\n   * });\n   * ```\n   */\n  async getLocal<T>(\n    key: string,\n    options: {\n      decrypt?: boolean;\n      defaultValue?: T;\n    } = {}\n  ): Promise<T | null> {\n    try {\n      const { decrypt = false, defaultValue = null } = options;\n      const item = localStorage.getItem(key);\n\n      if (!item) return defaultValue;\n\n      const serialized = decrypt ? await this.decrypt(item) : item;\n      const data = JSON.parse(serialized);\n\n      if (data.expires && Date.now() > data.expires) {\n        localStorage.removeItem(key);\n        return defaultValue;\n      }\n\n      return data.value as T;\n    } catch (error) {\n      console.error(\"Error getting localStorage item:\", error);\n      return options.defaultValue ?? null;\n    }\n  },\n\n  /**\n   * Gets a value from sessionStorage.\n   * @template T\n   * @param key - Storage key\n   * @param options - Storage options\n   * @param options.decrypt - Whether to decrypt the value\n   * @param options.defaultValue - Default value if not found/expired\n   * @returns Stored value or null if not found/expired\n   * @example\n   * ```typescript\n   * // Get a value\n   * const value = StorageUtils.getSession<string>('temp');\n   *\n   * // Get and decrypt a value with default\n   * const decryptedValue = await StorageUtils.getSession<string>('token', {\n   *   decrypt: true,\n   *   defaultValue: 'default-token'\n   * });\n   * ```\n   */\n  async getSession<T>(\n    key: string,\n    options: {\n      decrypt?: boolean;\n      defaultValue?: T;\n    } = {}\n  ): Promise<T | null> {\n    try {\n      const { decrypt = false, defaultValue = null } = options;\n      const item = sessionStorage.getItem(key);\n\n      if (!item) return defaultValue;\n\n      const serialized = decrypt ? await this.decrypt(item) : item;\n      const data = JSON.parse(serialized);\n\n      if (data.expires && Date.now() > data.expires) {\n        sessionStorage.removeItem(key);\n        return defaultValue;\n      }\n\n      return data.value as T;\n    } catch (error) {\n      console.error(\"Error getting sessionStorage item:\", error);\n      return options.defaultValue ?? null;\n    }\n  },\n\n  /**\n   * Gets the storage quota and usage.\n   * @returns Promise resolving to object containing quota and usage information\n   * @example\n   * ```typescript\n   * const quota = await StorageUtils.getStorageQuota();\n   * console.log(`Usage: ${quota?.usage} / ${quota?.quota}`);\n   * ```\n   */\n  async getStorageQuota(): Promise<{\n    quota: number;\n    usage: number;\n    remaining: number;\n  } | null> {\n    try {\n      if (\"storage\" in navigator && \"estimate\" in navigator.storage) {\n        const { quota, usage } = await navigator.storage.estimate();\n        return {\n          quota: quota ?? 0,\n          usage: usage ?? 0,\n          remaining: (quota ?? 0) - (usage ?? 0),\n        };\n      }\n      return null;\n    } catch (error) {\n      console.error(\"Error getting storage quota:\", error);\n      return null;\n    }\n  },\n\n  /**\n   * Gets the size of a stored value.\n   * @param value - Value to measure\n   * @returns Size in bytes\n   * @example\n   * ```typescript\n   * const size = StorageUtils.getStorageSize({ data: 'large' });\n   * console.log(`Size: ${size} bytes`);\n   * ```\n   */\n  getStorageSize(value: unknown): number {\n    try {\n      const serialized = JSON.stringify(value);\n      return new Blob([serialized]).size;\n    } catch (error) {\n      console.error(\"Error getting storage size:\", error);\n      return 0;\n    }\n  },\n\n  /**\n   * Gets the total size of all stored values.\n   * @param type - Storage type ('localStorage' or 'sessionStorage')\n   * @returns Total size in bytes\n   * @example\n   * ```typescript\n   * const totalSize = StorageUtils.getTotalStorageSize('localStorage');\n   * console.log(`Total size: ${totalSize} bytes`);\n   * ```\n   */\n  getTotalStorageSize(type: \"localStorage\" | \"sessionStorage\"): number {\n    try {\n      const storage = type === \"localStorage\" ? localStorage : sessionStorage;\n      let total = 0;\n      for (let i = 0; i < storage.length; i++) {\n        const key = storage.key(i);\n        if (key) {\n          const value = storage.getItem(key);\n          if (value) {\n            total += this.getStorageSize(value);\n          }\n        }\n      }\n      return total;\n    } catch (error) {\n      console.error(\"Error getting total storage size:\", error);\n      return 0;\n    }\n  },\n\n  /**\n   * Checks if storage is available.\n   * @param type - Storage type ('localStorage', 'sessionStorage', or 'cookie')\n   * @returns True if storage is available\n   * @example\n   * ```typescript\n   * if (StorageUtils.isStorageAvailable('localStorage')) {\n   *   // Use localStorage\n   * }\n   * ```\n   */\n  isStorageAvailable(\n    type: \"localStorage\" | \"sessionStorage\" | \"cookie\"\n  ): boolean {\n    try {\n      switch (type) {\n        case \"localStorage\":\n          localStorage.setItem(\"test\", \"test\");\n          localStorage.removeItem(\"test\");\n          return true;\n        case \"sessionStorage\":\n          sessionStorage.setItem(\"test\", \"test\");\n          sessionStorage.removeItem(\"test\");\n          return true;\n        case \"cookie\":\n          document.cookie = \"test=test\";\n          document.cookie = \"test=; expires=Thu, 01 Jan 1970 00:00:00 GMT\";\n          return true;\n        default:\n          return false;\n      }\n    } catch (error) {\n      return false;\n    }\n  },\n\n  /**\n   * Removes a cookie.\n   * @param name - Cookie name\n   * @param options - Cookie options\n   * @param options.path - Cookie path\n   * @param options.domain - Cookie domain\n   * @example\n   * ```typescript\n   * StorageUtils.removeCookie('session');\n   * ```\n   */\n  removeCookie(\n    name: string,\n    options: {\n      path?: string;\n      domain?: string;\n    } = {}\n  ): void {\n    try {\n      const { path = \"/\", domain } = options;\n      this.setCookie(name, \"\", {\n        expires: new Date(0),\n        path,\n        domain,\n      });\n    } catch (error) {\n      console.error(\"Error removing cookie:\", error);\n    }\n  },\n\n  /**\n   * Removes a value from localStorage.\n   * @param key - Storage key\n   * @example\n   * ```typescript\n   * StorageUtils.removeLocal('user');\n   * ```\n   */\n  removeLocal(key: string): void {\n    try {\n      localStorage.removeItem(key);\n    } catch (error) {\n      console.error(\"Error removing localStorage item:\", error);\n    }\n  },\n\n  /**\n   * Removes a value from sessionStorage.\n   * @param key - Storage key\n   * @example\n   * ```typescript\n   * StorageUtils.removeSession('temp');\n   * ```\n   */\n  removeSession(key: string): void {\n    try {\n      sessionStorage.removeItem(key);\n    } catch (error) {\n      console.error(\"Error removing sessionStorage item:\", error);\n    }\n  },\n\n  /**\n   * Sets a cookie.\n   * @param name - Cookie name\n   * @param value - Cookie value\n   * @param options - Cookie options\n   * @param options.expires - Expiration time in milliseconds or Date\n   * @param options.path - Cookie path\n   * @param options.domain - Cookie domain\n   * @param options.secure - Whether the cookie requires HTTPS\n   * @param options.sameSite - SameSite attribute\n   * @param options.encrypt - Whether to encrypt the value\n   * @example\n   * ```typescript\n   * // Set a basic cookie\n   * StorageUtils.setCookie('theme', 'dark');\n   *\n   * // Set a secure cookie with expiration\n   * StorageUtils.setCookie('token', 'secret', {\n   *   expires: 86400000,\n   *   secure: true,\n   *   sameSite: 'Strict'\n   * });\n   * ```\n   */\n  async setCookie(\n    name: string,\n    value: string,\n    options: {\n      expires?: number | Date;\n      path?: string;\n      domain?: string;\n      secure?: boolean;\n      sameSite?: \"Strict\" | \"Lax\" | \"None\";\n      encrypt?: boolean;\n    } = {}\n  ): Promise<void> {\n    try {\n      const {\n        expires,\n        path = \"/\",\n        domain,\n        secure = false,\n        sameSite = \"Lax\",\n        encrypt = false,\n      } = options;\n\n      const finalValue = encrypt ? await this.encrypt(value) : value;\n      let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(\n        finalValue\n      )}`;\n\n      if (expires) {\n        const date =\n          expires instanceof Date ? expires : new Date(Date.now() + expires);\n        cookie += `; expires=${date.toUTCString()}`;\n      }\n\n      if (path) cookie += `; path=${path}`;\n      if (domain) cookie += `; domain=${domain}`;\n      if (secure) cookie += \"; secure\";\n      if (sameSite) cookie += `; samesite=${sameSite}`;\n\n      document.cookie = cookie;\n    } catch (error) {\n      console.error(\"Error setting cookie:\", error);\n    }\n  },\n\n  /**\n   * Sets a value in localStorage.\n   * @param key - Storage key\n   * @param value - Value to store\n   * @param options - Storage options\n   * @param options.expires - Expiration time in milliseconds\n   * @param options.encrypt - Whether to encrypt the value\n   * @example\n   * ```typescript\n   * // Set a basic value\n   * StorageUtils.setLocal('user', { id: 1, name: 'John' });\n   *\n   * // Set an encrypted value with expiration\n   * StorageUtils.setLocal('token', 'secret', {\n   *   expires: 3600000,\n   *   encrypt: true\n   * });\n   * ```\n   */\n  async setLocal(\n    key: string,\n    value: unknown,\n    options: {\n      expires?: number;\n      encrypt?: boolean;\n    } = {}\n  ): Promise<void> {\n    try {\n      const { expires, encrypt = false } = options;\n      const data = {\n        value,\n        timestamp: Date.now(),\n        expires: expires ? Date.now() + expires : undefined,\n      };\n\n      const serialized = JSON.stringify(data);\n      const finalValue = encrypt ? await this.encrypt(serialized) : serialized;\n      localStorage.setItem(key, finalValue);\n    } catch (error) {\n      console.error(\"Error setting localStorage item:\", error);\n    }\n  },\n\n  /**\n   * Sets a value in sessionStorage.\n   * @param key - Storage key\n   * @param value - Value to store\n   * @param options - Storage options\n   * @param options.expires - Expiration time in milliseconds\n   * @param options.encrypt - Whether to encrypt the value\n   * @example\n   * ```typescript\n   * // Set a basic value\n   * StorageUtils.setSession('temp', { id: 1 });\n   *\n   * // Set an encrypted value with expiration\n   * StorageUtils.setSession('token', 'secret', {\n   *   expires: 3600000,\n   *   encrypt: true\n   * });\n   * ```\n   */\n  async setSession(\n    key: string,\n    value: unknown,\n    options: {\n      expires?: number;\n      encrypt?: boolean;\n    } = {}\n  ): Promise<void> {\n    try {\n      const { expires, encrypt = false } = options;\n      const data = {\n        value,\n        timestamp: Date.now(),\n        expires: expires ? Date.now() + expires : undefined,\n      };\n\n      const serialized = JSON.stringify(data);\n      const finalValue = encrypt ? await this.encrypt(serialized) : serialized;\n      sessionStorage.setItem(key, finalValue);\n    } catch (error) {\n      console.error(\"Error setting sessionStorage item:\", error);\n    }\n  },\n};\n"],"names":[],"mappings":"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"}