UNPKG

@fluid-app/storage-manager

Version:

Storage management utilities for Fluid Commerce applications

1 lines 13.9 kB
{"version":3,"sources":["../src/StorageKeys.ts","../src/utils/environment.ts","../src/StorageManager.ts"],"names":["psl"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Storage keys\n */\nexport const STORAGE_KEYS = {\n CART: \"fs_cart\",\n EVENT_QUEUE: \"fs_event_queue\",\n SERVER_SETTINGS: \"fs_server_settings\",\n SETTINGS_OVERRIDE: \"fs_settings_override\",\n ATTRIBUTION_CACHE: \"fs_attribution_cache\",\n AUTHENTICATED_USER: \"fs_authenticated_user\",\n} as const;\n\n/**\n * Cookie keys\n */\nexport const COOKIE_KEYS = {\n LOCALE: \"fluid_locale\",\n COUNTRY: \"fluid_country\",\n LANGUAGE: \"fluid_language\",\n JOURNEY: \"fluid_journey\",\n JOURNEY_SYNCED: \"fluid_journey_synced\",\n AFFILIATE: \"fluid_affiliate\",\n SESSION: \"fluid_session\",\n AUTHENTICATED_JWT: \"fluid_authenticated_jwt\",\n AUTHENTICATED_AT: \"fluid_authenticated_at\",\n} as const;\n","/**\n * Check if the code is running in a browser environment\n */\nexport const isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\n/**\n * Get a cookie value by name\n * @param name The name of the cookie to retrieve\n * @returns The cookie value or null if not found\n */\nexport const getCookie = (name: string): string | null => {\n if (!isBrowser) return null;\n\n try {\n const cookies = document.cookie.split(\";\");\n for (const cookieStr of cookies) {\n const cookie = cookieStr.trim();\n if (cookie.startsWith(name + \"=\")) {\n return cookie.substring(name.length + 1);\n }\n }\n return null;\n } catch (error) {\n console.error(\"Error reading cookie:\", error);\n return null;\n }\n};\n\n/**\n * Get a wrapper for localStorage with error handling\n * @returns An object with methods to interact with localStorage\n */\nexport const getLocalStorage = () => {\n return {\n /**\n * Get an item from localStorage\n * @param key The key to retrieve\n * @returns The value or null if not found or an error occurred\n */\n get: (key: string): string | null => {\n if (!isBrowser) return null;\n try {\n return localStorage.getItem(key);\n } catch (error) {\n console.error(\"Error accessing localStorage:\", error);\n return null;\n }\n },\n\n /**\n * Set an item in localStorage\n * @param key The key to set\n * @param value The value to store\n */\n set: (key: string, value: string): void => {\n if (!isBrowser) return;\n try {\n localStorage.setItem(key, value);\n } catch (error) {\n console.error(\"Error writing to localStorage:\", error);\n }\n },\n\n /**\n * Remove an item from localStorage\n * @param key The key to remove\n */\n remove: (key: string): void => {\n if (!isBrowser) return;\n try {\n localStorage.removeItem(key);\n } catch (error) {\n console.error(\"Error removing from localStorage:\", error);\n }\n },\n };\n};\n","import * as psl from \"psl\";\n\nimport { COOKIE_KEYS, STORAGE_KEYS } from \"./StorageKeys\";\nimport { getLocalStorage } from \"./utils/environment\";\n\n// Type definitions for discriminated union\n\ntype StorageKey = (typeof STORAGE_KEYS)[keyof typeof STORAGE_KEYS];\ntype CookieKey = (typeof COOKIE_KEYS)[keyof typeof COOKIE_KEYS];\n\ntype SetArg =\n | { key: StorageKey; value: string }\n | { key: CookieKey; value: string };\ntype GetArg = { key: StorageKey } | { key: CookieKey };\ntype SetObjectArg<T> =\n | { key: StorageKey; value: T }\n | { key: CookieKey; value: T };\ntype GetObjectArg = { key: StorageKey } | { key: CookieKey };\n\n/**\n * Manages storage operations\n */\nexport class StorageManager {\n private localStorage = getLocalStorage();\n\n // Type guards for key type\n private isCookieKey(key: unknown): key is CookieKey {\n return Object.values(COOKIE_KEYS).includes(key as CookieKey);\n }\n private isStorageKey(key: unknown): key is StorageKey {\n return Object.values(STORAGE_KEYS).includes(key as StorageKey);\n }\n\n /**\n * Set an item in storage (localStorage or cookie)\n */\n public setItem(arg: SetArg): void {\n if (this.isCookieKey(arg.key)) {\n this.setCookieOnApexAndSubdomains(arg.key, arg.value, {\n path: \"/\",\n secure:\n typeof window !== \"undefined\"\n ? window.location.protocol === \"https:\"\n : false,\n sameSite: \"Lax\",\n });\n } else if (this.isStorageKey(arg.key)) {\n this.localStorage.set(arg.key, arg.value);\n } else {\n throw new Error(\"Invalid key type for setItem\");\n }\n }\n\n /**\n * Get an item from storage (localStorage or cookie)\n */\n public getItem(arg: GetArg): string | null {\n if (this.isCookieKey(arg.key)) {\n if (typeof document === \"undefined\") return null;\n const regex = new RegExp(\"(^| )\" + arg.key + \"=([^;]+)\");\n const match = regex.exec(document.cookie);\n return match?.[2] ? decodeURIComponent(match[2]) : null;\n } else if (this.isStorageKey(arg.key)) {\n try {\n return this.localStorage.get(arg.key);\n } catch {\n return null;\n }\n } else {\n throw new Error(\"Invalid key type for getItem\");\n }\n }\n\n /**\n * Remove an item from storage (localStorage or cookie)\n */\n public removeItem(arg: GetArg): void {\n if (this.isCookieKey(arg.key)) {\n if (typeof document === \"undefined\") return;\n document.cookie = `${arg.key}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;\n } else if (this.isStorageKey(arg.key)) {\n try {\n this.localStorage.remove(arg.key);\n } catch {\n // ignore\n }\n } else {\n throw new Error(\"Invalid key type for removeItem\");\n }\n }\n\n /**\n * Set an object in storage (localStorage or cookie)\n */\n public setObject<T>(arg: SetObjectArg<T>): void {\n const stringified = JSON.stringify(arg.value);\n if (this.isCookieKey(arg.key)) {\n this.setCookieOnApexAndSubdomains(arg.key, stringified, {\n path: \"/\",\n secure:\n typeof window !== \"undefined\"\n ? window.location.protocol === \"https:\"\n : false,\n sameSite: \"Lax\",\n });\n } else if (this.isStorageKey(arg.key)) {\n this.localStorage.set(arg.key, stringified);\n } else {\n throw new Error(\"Invalid key type for setObject\");\n }\n }\n\n /**\n * Get an object from storage (localStorage or cookie)\n */\n public getObject<T>(arg: GetObjectArg): T | null {\n const value = this.getItem({ key: arg.key });\n if (!value) return null;\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n }\n\n /**\n * Utility to set a cookie on both the current domain and apex domain (if different)\n * @param name Cookie name\n * @param value Cookie value\n * @param options Optional cookie options (expires, path, secure, sameSite)\n */\n private setCookieOnApexAndSubdomains(\n name: string,\n value: string,\n options: {\n expires?: Date;\n path?: string;\n secure?: boolean;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n } = {},\n ): void {\n if (typeof document === \"undefined\" || typeof window === \"undefined\")\n return;\n const hostname = window.location.hostname;\n const parsed = psl.parse(hostname);\n // Type guard: check if parsed is ParsedDomain and has a string domain\n const apexDomain =\n typeof parsed === \"object\" &&\n \"domain\" in parsed &&\n typeof parsed.domain === \"string\" &&\n parsed.domain\n ? parsed.domain\n : hostname;\n const cookieParts = [\n `${encodeURIComponent(name)}=${encodeURIComponent(value)}`,\n `path=${options.path ?? \"/\"}`,\n options.expires ? `expires=${options.expires.toUTCString()}` : \"\",\n options.secure !== false ? \"Secure\" : \"\",\n options.sameSite ? `SameSite=${options.sameSite}` : \"SameSite=Lax\",\n ].filter(Boolean);\n // Set for current domain\n document.cookie = cookieParts.join(\"; \");\n // Set for apex domain if different\n if (apexDomain && apexDomain !== hostname) {\n document.cookie = cookieParts\n .concat([`domain=.${apexDomain}`])\n .join(\"; \");\n }\n }\n}\n"]}