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.
		
		
		
		
		
			
		
			
				
					114 lines
				
				2.7 KiB
			
		
		
			
		
	
	
					114 lines
				
				2.7 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var isBuffer = require('is-buffer')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = flatten
							 | 
						||
| 
								 | 
							
								flatten.flatten = flatten
							 | 
						||
| 
								 | 
							
								flatten.unflatten = unflatten
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function flatten (target, opts) {
							 | 
						||
| 
								 | 
							
								  opts = opts || {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var delimiter = opts.delimiter || '.'
							 | 
						||
| 
								 | 
							
								  var maxDepth = opts.maxDepth
							 | 
						||
| 
								 | 
							
								  var output = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function step (object, prev, currentDepth) {
							 | 
						||
| 
								 | 
							
								    currentDepth = currentDepth || 1
							 | 
						||
| 
								 | 
							
								    Object.keys(object).forEach(function (key) {
							 | 
						||
| 
								 | 
							
								      var value = object[key]
							 | 
						||
| 
								 | 
							
								      var isarray = opts.safe && Array.isArray(value)
							 | 
						||
| 
								 | 
							
								      var type = Object.prototype.toString.call(value)
							 | 
						||
| 
								 | 
							
								      var isbuffer = isBuffer(value)
							 | 
						||
| 
								 | 
							
								      var isobject = (
							 | 
						||
| 
								 | 
							
								        type === '[object Object]' ||
							 | 
						||
| 
								 | 
							
								        type === '[object Array]'
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      var newKey = prev
							 | 
						||
| 
								 | 
							
								        ? prev + delimiter + key
							 | 
						||
| 
								 | 
							
								        : key
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (!isarray && !isbuffer && isobject && Object.keys(value).length &&
							 | 
						||
| 
								 | 
							
								        (!opts.maxDepth || currentDepth < maxDepth)) {
							 | 
						||
| 
								 | 
							
								        return step(value, newKey, currentDepth + 1)
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      output[newKey] = value
							 | 
						||
| 
								 | 
							
								    })
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  step(target)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return output
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function unflatten (target, opts) {
							 | 
						||
| 
								 | 
							
								  opts = opts || {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var delimiter = opts.delimiter || '.'
							 | 
						||
| 
								 | 
							
								  var overwrite = opts.overwrite || false
							 | 
						||
| 
								 | 
							
								  var result = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var isbuffer = isBuffer(target)
							 | 
						||
| 
								 | 
							
								  if (isbuffer || Object.prototype.toString.call(target) !== '[object Object]') {
							 | 
						||
| 
								 | 
							
								    return target
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // safely ensure that the key is
							 | 
						||
| 
								 | 
							
								  // an integer.
							 | 
						||
| 
								 | 
							
								  function getkey (key) {
							 | 
						||
| 
								 | 
							
								    var parsedKey = Number(key)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (
							 | 
						||
| 
								 | 
							
								      isNaN(parsedKey) ||
							 | 
						||
| 
								 | 
							
								      key.indexOf('.') !== -1 ||
							 | 
						||
| 
								 | 
							
								      opts.object
							 | 
						||
| 
								 | 
							
								    ) ? key
							 | 
						||
| 
								 | 
							
								      : parsedKey
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var sortedKeys = Object.keys(target).sort(function (keyA, keyB) {
							 | 
						||
| 
								 | 
							
								    return keyA.length - keyB.length
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  sortedKeys.forEach(function (key) {
							 | 
						||
| 
								 | 
							
								    var split = key.split(delimiter)
							 | 
						||
| 
								 | 
							
								    var key1 = getkey(split.shift())
							 | 
						||
| 
								 | 
							
								    var key2 = getkey(split[0])
							 | 
						||
| 
								 | 
							
								    var recipient = result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (key2 !== undefined) {
							 | 
						||
| 
								 | 
							
								      if (key1 === '__proto__') {
							 | 
						||
| 
								 | 
							
								        return
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      var type = Object.prototype.toString.call(recipient[key1])
							 | 
						||
| 
								 | 
							
								      var isobject = (
							 | 
						||
| 
								 | 
							
								        type === '[object Object]' ||
							 | 
						||
| 
								 | 
							
								        type === '[object Array]'
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // do not write over falsey, non-undefined values if overwrite is false
							 | 
						||
| 
								 | 
							
								      if (!overwrite && !isobject && typeof recipient[key1] !== 'undefined') {
							 | 
						||
| 
								 | 
							
								        return
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
							 | 
						||
| 
								 | 
							
								        recipient[key1] = (
							 | 
						||
| 
								 | 
							
								          typeof key2 === 'number' &&
							 | 
						||
| 
								 | 
							
								          !opts.object ? [] : {}
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      recipient = recipient[key1]
							 | 
						||
| 
								 | 
							
								      if (split.length > 0) {
							 | 
						||
| 
								 | 
							
								        key1 = getkey(split.shift())
							 | 
						||
| 
								 | 
							
								        key2 = getkey(split[0])
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // unflatten again for 'messy objects'
							 | 
						||
| 
								 | 
							
								    recipient[key1] = unflatten(target[key], opts)
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return result
							 | 
						||
| 
								 | 
							
								}
							 |