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 | ||
|  | } |