You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
7.1 KiB

4 years ago
(function (root, factory){
'use strict';
/*istanbul ignore next:cant test*/
if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
} else {
// Browser globals
root.objectPath = factory();
}
})(this, function(){
'use strict';
var toStr = Object.prototype.toString;
function hasOwnProperty(obj, prop) {
if(obj == null) {
return false
}
//to handle objects with null prototypes (too edge case?)
return Object.prototype.hasOwnProperty.call(obj, prop)
}
function isEmpty(value){
if (!value) {
return true;
}
if (isArray(value) && value.length === 0) {
return true;
} else if (typeof value !== 'string') {
for (var i in value) {
if (hasOwnProperty(value, i)) {
return false;
}
}
return true;
}
return false;
}
function toString(type){
return toStr.call(type);
}
function isObject(obj){
return typeof obj === 'object' && toString(obj) === "[object Object]";
}
var isArray = Array.isArray || function(obj){
/*istanbul ignore next:cant test*/
return toStr.call(obj) === '[object Array]';
}
function isBoolean(obj){
return typeof obj === 'boolean' || toString(obj) === '[object Boolean]';
}
function getKey(key){
var intKey = parseInt(key);
if (intKey.toString() === key) {
return intKey;
}
return key;
}
function factory(options) {
options = options || {}
var objectPath = function(obj) {
return Object.keys(objectPath).reduce(function(proxy, prop) {
if(prop === 'create') {
return proxy;
}
/*istanbul ignore else*/
if (typeof objectPath[prop] === 'function') {
proxy[prop] = objectPath[prop].bind(objectPath, obj);
}
return proxy;
}, {});
};
function hasShallowProperty(obj, prop) {
return (options.includeInheritedProps || (typeof prop === 'number' && Array.isArray(obj)) || hasOwnProperty(obj, prop))
}
function getShallowProperty(obj, prop) {
if (hasShallowProperty(obj, prop)) {
return obj[prop];
}
}
function set(obj, path, value, doNotReplace){
if (typeof path === 'number') {
path = [path];
}
if (!path || path.length === 0) {
return obj;
}
if (typeof path === 'string') {
return set(obj, path.split('.').map(getKey), value, doNotReplace);
}
var currentPath = path[0];
var currentValue = getShallowProperty(obj, currentPath);
if (path.length === 1) {
if (currentValue === void 0 || !doNotReplace) {
obj[currentPath] = value;
}
return currentValue;
}
if (currentValue === void 0) {
//check if we assume an array
if(typeof path[1] === 'number') {
obj[currentPath] = [];
} else {
obj[currentPath] = {};
}
}
return set(obj[currentPath], path.slice(1), value, doNotReplace);
}
objectPath.has = function (obj, path) {
if (typeof path === 'number') {
path = [path];
} else if (typeof path === 'string') {
path = path.split('.');
}
if (!path || path.length === 0) {
return !!obj;
}
for (var i = 0; i < path.length; i++) {
var j = getKey(path[i]);
if((typeof j === 'number' && isArray(obj) && j < obj.length) ||
(options.includeInheritedProps ? (j in Object(obj)) : hasOwnProperty(obj, j))) {
obj = obj[j];
} else {
return false;
}
}
return true;
};
objectPath.ensureExists = function (obj, path, value){
return set(obj, path, value, true);
};
objectPath.set = function (obj, path, value, doNotReplace){
return set(obj, path, value, doNotReplace);
};
objectPath.insert = function (obj, path, value, at){
var arr = objectPath.get(obj, path);
at = ~~at;
if (!isArray(arr)) {
arr = [];
objectPath.set(obj, path, arr);
}
arr.splice(at, 0, value);
};
objectPath.empty = function(obj, path) {
if (isEmpty(path)) {
return void 0;
}
if (obj == null) {
return void 0;
}
var value, i;
if (!(value = objectPath.get(obj, path))) {
return void 0;
}
if (typeof value === 'string') {
return objectPath.set(obj, path, '');
} else if (isBoolean(value)) {
return objectPath.set(obj, path, false);
} else if (typeof value === 'number') {
return objectPath.set(obj, path, 0);
} else if (isArray(value)) {
value.length = 0;
} else if (isObject(value)) {
for (i in value) {
if (hasShallowProperty(value, i)) {
delete value[i];
}
}
} else {
return objectPath.set(obj, path, null);
}
};
objectPath.push = function (obj, path /*, values */){
var arr = objectPath.get(obj, path);
if (!isArray(arr)) {
arr = [];
objectPath.set(obj, path, arr);
}
arr.push.apply(arr, Array.prototype.slice.call(arguments, 2));
};
objectPath.coalesce = function (obj, paths, defaultValue) {
var value;
for (var i = 0, len = paths.length; i < len; i++) {
if ((value = objectPath.get(obj, paths[i])) !== void 0) {
return value;
}
}
return defaultValue;
};
objectPath.get = function (obj, path, defaultValue){
if (typeof path === 'number') {
path = [path];
}
if (!path || path.length === 0) {
return obj;
}
if (obj == null) {
return defaultValue;
}
if (typeof path === 'string') {
return objectPath.get(obj, path.split('.'), defaultValue);
}
var currentPath = getKey(path[0]);
var nextObj = getShallowProperty(obj, currentPath)
if (nextObj === void 0) {
return defaultValue;
}
if (path.length === 1) {
return nextObj;
}
return objectPath.get(obj[currentPath], path.slice(1), defaultValue);
};
objectPath.del = function del(obj, path) {
if (typeof path === 'number') {
path = [path];
}
if (obj == null) {
return obj;
}
if (isEmpty(path)) {
return obj;
}
if(typeof path === 'string') {
return objectPath.del(obj, path.split('.'));
}
var currentPath = getKey(path[0]);
if (!hasShallowProperty(obj, currentPath)) {
return obj;
}
if(path.length === 1) {
if (isArray(obj)) {
obj.splice(currentPath, 1);
} else {
delete obj[currentPath];
}
} else {
return objectPath.del(obj[currentPath], path.slice(1));
}
return obj;
}
return objectPath;
}
var mod = factory();
mod.create = factory;
mod.withInheritedProps = factory({includeInheritedProps: true})
return mod;
});