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.
		
		
		
		
		
			
		
			
				
					
					
						
							126 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							126 lines
						
					
					
						
							2.5 KiB
						
					
					
				'use strict';
 | 
						|
 | 
						|
function undefsafe(obj, path, value, __res) {
 | 
						|
  // I'm not super keen on this private function, but it's because
 | 
						|
  // it'll also be use in the browser and I wont *one* function exposed
 | 
						|
  function split(path) {
 | 
						|
    var res = [];
 | 
						|
    var level = 0;
 | 
						|
    var key = '';
 | 
						|
 | 
						|
    for (var i = 0; i < path.length; i++) {
 | 
						|
      var c = path.substr(i, 1);
 | 
						|
 | 
						|
      if (level === 0 && (c === '.' || c === '[')) {
 | 
						|
        if (c === '[') {
 | 
						|
          level++;
 | 
						|
          i++;
 | 
						|
          c = path.substr(i, 1);
 | 
						|
        }
 | 
						|
 | 
						|
        if (key) {
 | 
						|
          // the first value could be a string
 | 
						|
          res.push(key);
 | 
						|
        }
 | 
						|
        key = '';
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      if (c === ']') {
 | 
						|
        level--;
 | 
						|
        key = key.slice(0, -1);
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      key += c;
 | 
						|
    }
 | 
						|
 | 
						|
    res.push(key);
 | 
						|
 | 
						|
    return res;
 | 
						|
  }
 | 
						|
 | 
						|
  // bail if there's nothing
 | 
						|
  if (obj === undefined || obj === null) {
 | 
						|
    return undefined;
 | 
						|
  }
 | 
						|
 | 
						|
  var parts = split(path);
 | 
						|
  var key = null;
 | 
						|
  var type = typeof obj;
 | 
						|
  var root = obj;
 | 
						|
  var parent = obj;
 | 
						|
 | 
						|
  var star =
 | 
						|
    parts.filter(function(_) {
 | 
						|
      return _ === '*';
 | 
						|
    }).length > 0;
 | 
						|
 | 
						|
  // we're dealing with a primitive
 | 
						|
  if (type !== 'object' && type !== 'function') {
 | 
						|
    return obj;
 | 
						|
  } else if (path.trim() === '') {
 | 
						|
    return obj;
 | 
						|
  }
 | 
						|
 | 
						|
  key = parts[0];
 | 
						|
  var i = 0;
 | 
						|
  for (; i < parts.length; i++) {
 | 
						|
    key = parts[i];
 | 
						|
    parent = obj;
 | 
						|
 | 
						|
    if (key === '*') {
 | 
						|
      // loop through each property
 | 
						|
      var prop = '';
 | 
						|
      var res = __res || [];
 | 
						|
 | 
						|
      for (prop in parent) {
 | 
						|
        var shallowObj = undefsafe(
 | 
						|
          obj[prop],
 | 
						|
          parts.slice(i + 1).join('.'),
 | 
						|
          value,
 | 
						|
          res
 | 
						|
        );
 | 
						|
        if (shallowObj && shallowObj !== res) {
 | 
						|
          if ((value && shallowObj === value) || value === undefined) {
 | 
						|
            if (value !== undefined) {
 | 
						|
              return shallowObj;
 | 
						|
            }
 | 
						|
 | 
						|
            res.push(shallowObj);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (res.length === 0) {
 | 
						|
        return undefined;
 | 
						|
      }
 | 
						|
 | 
						|
      return res;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Object.getOwnPropertyNames(obj).indexOf(key) == -1) {
 | 
						|
      return undefined;
 | 
						|
    }
 | 
						|
 | 
						|
    obj = obj[key];
 | 
						|
    if (obj === undefined || obj === null) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // if we have a null object, make sure it's the one the user was after,
 | 
						|
  // if it's not (i.e. parts has a length) then give undefined back.
 | 
						|
  if (obj === null && i !== parts.length - 1) {
 | 
						|
    obj = undefined;
 | 
						|
  } else if (!star && value) {
 | 
						|
    key = path.split('.').pop();
 | 
						|
    parent[key] = value;
 | 
						|
  }
 | 
						|
  return obj;
 | 
						|
}
 | 
						|
 | 
						|
if (typeof module !== 'undefined') {
 | 
						|
  module.exports = undefsafe;
 | 
						|
}
 |