@techsio/storefront-data
Version:
Medusa-first storefront data layer built on TanStack Query.
147 lines (146 loc) • 5.21 kB
JavaScript
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 };