cipherguard-mad
Version:
Cipherguard javascript application library for the open source password manager for teams
154 lines (134 loc) • 4.52 kB
JavaScript
/**
* Cipherguard ~ Open source password manager for teams
* Copyright (c) KhulnaSoft Ltd (https://www.khulnasoft.com)
*
* Licensed under GNU Affero General Public License version 3 of the or any later version.
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) KhulnaSoft Ltd (https://www.khulnasoft.com)
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
* @link https://www.khulnasoft.com KhulnaSoft(tm)
*/
import Construct from 'can-construct';
/**
* @parent Mad.core_api
* @inherits mad.Construct
*
* The aim of the object Map is to help developers to transform an object into another, by mapping
* its fields following another structure.
*/
const MadMap = Construct.extend('mad.Map', /** @static */ {
/**
* @deprecated {0.0.2} Please call the function mapObject directly on the map object.
*/
mapObject: function(object, map) {
console.warn('Please call the function mapObject directly on the map object.');
return map.mapObject(object);
},
/**
* @deprecated {0.0.2} Please call the function mapObject directly on the map object.
*/
mapObjects: function(arr, map) {
console.warn('Please call the function mapObject directly on the map object.');
return map.mapObjects(arr);
}
}, /** @prototype */ {
/**
* The map setting to use for the mapping.
*/
map: {},
/**
* Constructor.
*
* @param {object} map The map setting to use for the mapping.
* @return {mad.object.Map}
*
* @body
* TBD some example of map setting.
*/
init: function(map) {
this.map = map;
},
/**
* Retrieve the value of a nested key (level1.level2.level3...) into an object.
* @param {object} object The object to look into
* @param {string} key The key to look for
* @return {mixed}
*/
_getObjFieldPointer: function(object, key) {
let returnValue = object;
const split = key.split('.');
for (let i = 0; i < split.length; i++) {
// Failed to find the subkey.
if (returnValue[split[i]] === undefined) {
return null;
}
returnValue = returnValue[split[i]];
}
return returnValue;
},
/**
* Map an object into another.
*
* @param {Object} object The object to map
* @return {Object} The mapped object
*/
mapObject: function(object) {
const returnValue = {};
for (const key in this.map) {
const mapKeyElts = key.split('.');
// the map keys (targetKey || targetKeyLvl1.targetKeyLvl2)
let current = returnValue;
// the current position in the final object
let position = 0; // position of the cursors in the mapKeyElts
/*
* foreach mapKeyElts we add add a level in the final object
* at the leaf we insert the value
*/
for (const i in mapKeyElts) {
const mapKeyElt = mapKeyElts[i];
// if the leaf is reached
if (position == mapKeyElts.length - 1) {
// if a transformation func is given
if (typeof this.map[key] == 'object') {
const func = this.map[key].func;
const keyToMap = this.map[key].key;
const objectFieldToMap = this._getObjFieldPointer(object, keyToMap);
// @todo what to do if the key to map does not exist
if (objectFieldToMap != null) {
current[mapKeyElt] = func(objectFieldToMap, this, object, returnValue);
}
} else {
const objectFieldToMap = this._getObjFieldPointer(object, this.map[key]);
// @todo what to do if the key to map does not exist
if (objectFieldToMap != null) {
current[mapKeyElt] = objectFieldToMap;
}
}
} else {
// else we move the cursor in the mapKeyElts
if (typeof current[mapKeyElt] == 'undefined') { current[mapKeyElt] = []; }
current = current[mapKeyElt];
}
position++;
}
}
return returnValue;
},
/**
* Map an array of objects into an array of transformed objects.
*
* @param {mixed} data The array of objects to map.
* @return {array} The array of mapped objects.
*/
mapObjects: function(data) {
const self = this;
const returnValue = [];
data.forEach((elt, i) => {
returnValue[i] = self.mapObject(elt);
});
return returnValue;
}
});
export default MadMap;