storages-proxy
Version:
A simple, lightweight JavaScript API for handling browser storages
519 lines (480 loc) • 15.7 kB
JavaScript
/*! storages-proxy v2.1.0 | MIT */
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/** Built-in value references. */
var Symbol = root.Symbol;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto$1.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$1.toString;
/** Built-in value references. */
var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
/**
* A specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {Array} [array] The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
*/
function arrayMap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = Array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** Used to convert symbols to primitives and strings. */
var symbolProto = Symbol ? Symbol.prototype : undefined,
symbolToString = symbolProto ? symbolProto.toString : undefined;
/**
* The base implementation of `_.toString` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value The value to process.
* @returns {string} Returns the string.
*/
function baseToString(value) {
// Exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isArray(value)) {
// Recursively convert values (susceptible to call stack limits).
return arrayMap(value, baseToString) + '';
}
if (isSymbol(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
/**
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
* @example
*
* _.toString(null);
* // => ''
*
* _.toString(-0);
* // => '-0'
*
* _.toString([1, 2, 3]);
* // => '1,2,3'
*/
function toString(value) {
return value == null ? '' : baseToString(value);
}
/**
* Used to match `RegExp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
reHasRegExpChar = RegExp(reRegExpChar.source);
/**
* Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to escape.
* @returns {string} Returns the escaped string.
* @example
*
* _.escapeRegExp('[lodash](https://lodash.com/)');
* // => '\[lodash\]\(https://lodash\.com/\)'
*/
function escapeRegExp(string) {
string = toString(string);
return (string && reHasRegExpChar.test(string))
? string.replace(reRegExpChar, '\\$&')
: string;
}
/**
* Checks if `value` is `null` or `undefined`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
* @example
*
* _.isNil(null);
* // => true
*
* _.isNil(void 0);
* // => true
*
* _.isNil(NaN);
* // => false
*/
function isNil(value) {
return value == null;
}
function formatPath(type, path) {
if (!isNil(path)) {
if (typeof path === 'function') {
return path();
}
return path;
}
if (typeof window.__STORAGES_DEFAULT__[type].path === 'function') {
return window.__STORAGES_DEFAULT__[type].path();
}
return window.__STORAGES_DEFAULT__[type].path;
}
function getPrefix(type, path) {
return "path=".concat(formatPath(type, path), ";");
}
function isInclude(key, type) {
if (window.__STORAGES_DEFAULT__[type].include) {
return window.__STORAGES_DEFAULT__[type].include.includes(key);
}
if (window.__STORAGES_DEFAULT__[type].exclude) {
return !window.__STORAGES_DEFAULT__[type].exclude.includes(key);
}
return true;
}
function getKey(key, type, path) {
if (typeof key === 'symbol')
return key;
if (!isInclude(key, type))
return key;
return "".concat(getPrefix(type, path)).concat(key, "=");
}
function storage(type) {
return new Proxy(window[type], {
set: function (target, property, value) {
return Reflect.set(target, getKey(property, type), value);
},
get: function (target, property) {
if (property === 'setItem') {
return function (key, value, path) {
if (path === null) {
return target.setItem(key, value);
}
return target.setItem(getKey(key, type, path), value);
};
}
if (property === 'getItem') {
return function (key, path) {
if (path === null) {
return target.getItem(key);
}
return target.getItem(getKey(key, type, path));
};
}
if (property === 'removeItem') {
return function (key, path) {
if (path === null) {
return target.removeItem(key);
}
return target.removeItem(getKey(key, type, path));
};
}
if (property === 'key') {
return function (num, path) {
if (path === null) {
return target.key(num);
}
var reg = new RegExp("^".concat(escapeRegExp(getPrefix(type, path)), "(.+)=$"));
var index = 0;
for (var _i = 0, _a = Object.keys(target); _i < _a.length; _i++) {
var key = _a[_i];
if (!isInclude(key, type)) {
if (num === index)
return key;
++index;
continue;
}
var match = key.match(reg);
if (match === null || match === void 0 ? void 0 : match[1]) {
if (num === index)
return match[1];
++index;
}
}
return null;
};
}
if (property === 'clear') {
return function (path) {
if (path === null) {
return target.clear();
}
var reg = new RegExp("^".concat(escapeRegExp(getPrefix(type, path)), ".+=$"));
Object.keys(target).forEach(function (key) {
if (!isInclude(key, type) || reg.test(key)) {
target.removeItem(key);
}
});
return undefined;
};
}
if (property === 'length') {
var reg_1 = new RegExp("^".concat(escapeRegExp(getPrefix(type)), ".+=$"));
return Object.keys(target).filter(function (key) {
if (!isInclude(key, type))
return true;
return reg_1.test(key);
}).length;
}
return Reflect.get(target, getKey(property, type));
},
deleteProperty: function (target, property) {
return Reflect.deleteProperty(target, getKey(property, type));
},
});
}
var getPath = function () { var _a; return "/".concat((_a = window.location.pathname.split('/')[1]) !== null && _a !== void 0 ? _a : ''); };
function getDefaultOptions() {
return {
path: getPath(),
};
}
window.__STORAGES_DEFAULT__ = {
localStorage: getDefaultOptions(),
sessionStorage: getDefaultOptions(),
};
window.__STORAGES_INIT__ = {
localStorage: false,
sessionStorage: false,
};
function createGlobalStorage(type, options) {
updateGlobalStorage(type, options, true);
if (window.__STORAGES_INIT__[type])
return;
Object.defineProperty(window, type, {
configurable: true,
enumerable: true,
value: storage(type),
});
window.__STORAGES_INIT__[type] = true;
}
function updateGlobalStorage(type, options, force) {
var _a;
if (options === void 0) { options = getDefaultOptions(); }
if (force === void 0) { force = false; }
if ((options === null || options === void 0 ? void 0 : options.include) && (options === null || options === void 0 ? void 0 : options.exclude)) {
throw new Error("Cannot configure INCLUDE and EXCLUDE at the same time.");
}
if (force) {
window.__STORAGES_DEFAULT__[type] = __assign(__assign({}, options), { path: formatPath(type, (_a = options === null || options === void 0 ? void 0 : options.path) !== null && _a !== void 0 ? _a : getPath()) });
}
else {
Object.entries(options).forEach(function (_a) {
var key = _a[0], value = _a[1];
if (key === 'path') {
window.__STORAGES_DEFAULT__[type][key] = formatPath(type, value);
}
else {
window.__STORAGES_DEFAULT__[type][key] = value;
}
});
}
}
function length(type, path) {
var keys = Object.keys(window[type]);
if (path === null) {
return keys.length;
}
var reg = new RegExp("^".concat(escapeRegExp(getPrefix(type, path)), ".+=$"));
return keys.filter(function (key) {
if (!isInclude(key, type))
return true;
return reg.test(key);
}).length;
}
export { createGlobalStorage, length, updateGlobalStorage };
//# sourceMappingURL=index.js.map