UNPKG

@fto-consult/node-utils

Version:

Bibliothèque d'outils pour application nodeJS

179 lines (170 loc) 6.73 kB
const isDateObj = require("./isDateObj"); const isRegExp = require("./isRegex"); function isPlainObject ( obj ) { if(!obj || typeof obj =='boolean' || typeof obj =="number" || typeof obj =='string' || isDateObj(obj)) return false; const tStr = Object.prototype.toString.call(obj); if(tStr !== "[object Object]" || tStr == '[object global]' || tStr == '[object Window]' || tStr == '[object DOMWindow]' || isRegExp(obj)){ return false; } var proto, Ctor; proto = Object.getPrototypeOf( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } var class2type = {}; var hasOwn = Object.prototype.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; } module.exports.isPlainObject = isPlainObject; module.exports.isPlainObj = isPlainObject; /*** ajout de la fonction filter dans la props extendObj, pour filtrer les paramètres d'extension à la fonction * si la liste des arguments passés en paramètres est supérieure ou égale à deux et que le dernier paramètres est une fonction * alors celui-ci est considéré comme un filtre sur les props à appeler */ function extendObj (){ let name, src, copy, copyIsArray, clone,deepArray,filter = x=>true,//si l'on doit copier les tableaux en profondeur target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; if(typeof target === 'boolean') { deepArray = target; i++; target = arguments[i] || {}; } i++; } if(length >=2 && typeof (arguments[length-1]) =="function"){ filter = arguments[length-1]; length = length-1; } // Handle case when target is a string or something (possible in deep copy) if (!Array.isArray(target) && typeof target !== "object" && !isFunction(target)) { target = {}; } for ( ; i < length; i++ ) { const options = arguments[i]; // Only deal with non-null/undefined values if ( options != null && typeof options =='object') { // Extend the base object for ( name in options ) { if(!Object.prototype.hasOwnProperty.call(options,name)) continue; copy = options[ name ]; // Prevent Object.prototype pollution // Prevent never-ending loop if ( name === "__proto__" || target === copy || filter(copy,name) === false) { continue; } // Prevent never-ending loop if ( target === copy ) { continue; } copyIsArray = Array.isArray( copy ) // Recurse if we're merging plain objects or arrays if ( deep && copy && ( isPlainObject( copy ) || ( copyIsArray) ) ) { src = target[ name ]; if(copyIsArray){ clone = Array.isArray(src)? src : []; } else if (!isPlainObject( src ) ) { // Ensure proper type for the source value clone = {}; } else { clone = src; } if(copyIsArray && !deepArray){ target[name] = copy; } else { // Never move original objects, clone them const value = extendObj( deep,deepArray, clone, copy,filter); if(false && deepArray && Array.isArray(target)){ target.push(value); } else target[ name ] = value; } // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; } module.exports.extendObj = extendObj; const cloneObject = function (source,cloneLevel) { let level = 1; if (Array.isArray(source)) { const clone = []; for (var i=0; i<source.length; i++) { clone[i] = cloneObject(source[i],i+1); } return clone; } else if (isPlainObject(source)) { const clone = {}; for (var prop in source) { if (source.hasOwnProperty(prop)) { clone[prop] = cloneObject(source[prop],level); level ++; } } return clone; } else { if(source === undefined && typeof cloneLevel !=='number'){ return {}; } return source; } } module.exports.cloneObject = cloneObject; Object.clone = Object.copy = cloneObject; module.exports.map = Object.map = function(obj,fn){ if(typeof fn != 'function') { return {}; } if(Array.isArray(obj)) return obj.map((item,index)=>{ return fn(item,index,index); }); if(!(obj) || typeof obj !=='object') { return {}; } var oReturn = {}; let mapI=0; for (let sCurObjectPropertyName in obj) { if(obj.hasOwnProperty(sCurObjectPropertyName)) { oReturn[sCurObjectPropertyName] = fn.call(obj,obj[sCurObjectPropertyName], sCurObjectPropertyName,mapI,true); mapI++; } } return oReturn; } /**** * détermine la taille d'un tableau/object * @param : l'objet à déterminer la taille @param : breakonFirstElementFound {boolean}, retourne immédiatement après le premier élément trouvé */ module.exports.size = Object.size = function(obj,breakonFirstElementFound) { if(!obj || typeof obj != "object") return 0; if(Array.isArray(obj)){ return obj.length; } if(typeof breakonFirstElementFound !=='boolean'){ breakonFirstElementFound = false; } let size = 0; for (let key in obj) { if (obj.hasOwnProperty(key)) { size++; if(breakonFirstElementFound === true) return size; } } return size; }