UNPKG

@techsio/storefront-data

Version:

Medusa-first storefront data layer built on TanStack Query.

147 lines (146 loc) • 5.21 kB
import js_sdk from "@medusajs/js-sdk"; import { getLocalStorageItem, removeLocalStorageItem, setLocalStorageItem } from "./local-storage.js"; import { omitKeys } from "./object-utils.js"; const LOCALE_STORAGE_KEY = "medusa_locale"; const patchStorageMethod = (storage, methodName, createFallback)=>{ const storagePrototype = Object.getPrototypeOf(storage); const prototypeDescriptor = storagePrototype ? Object.getOwnPropertyDescriptor(storagePrototype, methodName) : void 0; const ownDescriptor = Object.getOwnPropertyDescriptor(storage, methodName); const originalMethod = storage[methodName] ?? storagePrototype?.[methodName]; const fallbackMethod = createFallback(originalMethod); try { Object.defineProperty(storage, methodName, { configurable: true, enumerable: ownDescriptor?.enumerable ?? false, writable: true, value: fallbackMethod }); } catch { if (storagePrototype) Object.defineProperty(storagePrototype, methodName, { configurable: prototypeDescriptor?.configurable ?? true, enumerable: prototypeDescriptor?.enumerable ?? false, writable: prototypeDescriptor?.writable ?? true, value: fallbackMethod }); } return ()=>{ if (ownDescriptor) return void Object.defineProperty(storage, methodName, ownDescriptor); Reflect.deleteProperty(storage, methodName); if (prototypeDescriptor && storagePrototype) Object.defineProperty(storagePrototype, methodName, prototypeDescriptor); }; }; const createSafeStorage = (storage)=>{ const safeStorage = Object.create(storage); Object.defineProperties(safeStorage, { getItem: { configurable: true, value: (key)=>{ try { return storage.getItem(key); } catch { return null; } } }, setItem: { configurable: true, value: (key, value)=>{ try { storage.setItem(key, value); } catch { return; } } }, removeItem: { configurable: true, value: (key)=>{ try { storage.removeItem(key); } catch { return; } } } }); return safeStorage; }; const withSafeLocalStorageMethods = (callback)=>{ if ("undefined" == typeof window) return callback(); let storage; try { storage = window.localStorage; } catch { return callback(); } if (!storage) return callback(); const localStorageDescriptor = Object.getOwnPropertyDescriptor(window, "localStorage"); let replacedWindowLocalStorage = false; try { Object.defineProperty(window, "localStorage", { configurable: true, enumerable: localStorageDescriptor?.enumerable ?? true, value: createSafeStorage(storage) }); replacedWindowLocalStorage = true; } catch {} if (replacedWindowLocalStorage) try { return callback(); } finally{ if (localStorageDescriptor) Object.defineProperty(window, "localStorage", localStorageDescriptor); else Reflect.deleteProperty(window, "localStorage"); } const restoreGetItem = patchStorageMethod(storage, "getItem", (original)=>function(key) { try { return original.call(this, key); } catch { return null; } }); const restoreSetItem = patchStorageMethod(storage, "setItem", (original)=>function(key, value) { try { original.call(this, key, value); } catch { return; } }); const restoreRemoveItem = patchStorageMethod(storage, "removeItem", (original)=>function(key) { try { original.call(this, key); } catch { return; } }); try { return callback(); } finally{ restoreRemoveItem(); restoreSetItem(); restoreGetItem(); } }; const patchClientLocaleStorage = (sdk)=>{ if ("undefined" == typeof window) return sdk; const client = sdk.client; Object.defineProperty(client, "locale", { configurable: true, enumerable: true, get () { return getLocalStorageItem(LOCALE_STORAGE_KEY) ?? client.locale_ ?? ""; } }); client.setLocale = (locale)=>{ if (locale) setLocalStorageItem(LOCALE_STORAGE_KEY, locale); else removeLocalStorageItem(LOCALE_STORAGE_KEY); client.locale_ = locale; }; return sdk; }; function createMedusaSdk(config, options = {}) { const { disableAuthOnServer = true } = options; if (disableAuthOnServer && "undefined" == typeof window && config.auth) return new js_sdk(omitKeys(config, [ "auth" ])); return patchClientLocaleStorage(withSafeLocalStorageMethods(()=>new js_sdk(config))); } export { createMedusaSdk };