Last active
July 25, 2016 13:36
-
-
Save alexandrebodin/020a77fcd2e46d9dc71ee205483f3619 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ from 'lodash/fp'; | |
const mapValuesWithKey = _.mapValues.convert({ cap: false}); | |
const internals = { | |
/** | |
* Returns a function that transforms an object's subObjects based on a mapping configuration | |
* @param Object mapping a mapping configuration | |
* @return Function transformer a transformer function | |
*/ | |
transformSubObjects(mapping) { | |
return mapValuesWithKey((val, key) => { | |
const mappingVal = mapping[key]; | |
if (_.isObject(val) && _.isObject(mappingVal)) { | |
return internals.buildTransformer(mappingVal)(val); | |
} | |
return val; | |
}); | |
}, | |
/** | |
* Returns a function that renames an object keys based on a mapping configuration | |
* @param Object mapping a mapping configuration | |
* @return Function transformer a transformer function | |
*/ | |
transformFlatKeys(mapping) { | |
return _.mapKeys(key => { | |
const mappingVal = mapping[key]; | |
if (mappingVal) { | |
// if the mapping is a string simply return it | |
if (_.isString(mappingVal)) return mappingVal; | |
// if the mapping value is an object check if there is a "key" field in the object to rename the subobject | |
if (_.isObject(mappingVal) && mappingVal.key) return mappingVal.key; | |
} | |
return key; | |
}); | |
}, | |
/** | |
* Returns a function that picks certain fields of an object | |
* @param Array|Function|Null picker | |
*/ | |
addPickerFlow(picker = null) { | |
if (picker) return typeof picker === 'function' ? picker : _.pick(picker); | |
return a => a; | |
}, | |
/** | |
* Returnes a function that applies the specified defaults to an object | |
* @param Object defaults | |
*/ | |
addDefaultsFlow(defaults = {}) { | |
return _.defaults(defaults); | |
}, | |
/** | |
* Returns a function that omits certain fields of an object | |
* @param Array|Function | |
*/ | |
addOmiterFlow(omiter = []) { | |
return typeof omiter === 'function' ? omiter : _.omit(omiter); | |
}, | |
/** | |
* Builds a function that transforms an object based on a mapping configuration | |
* @param Object arg a placeholder for the parameters to allow multiple ways of calling the function | |
* @return Function transformer a transformer function | |
*/ | |
buildTransformer(arg) { | |
const { | |
picker = null, | |
omiter = [], | |
defaults = {}, | |
} = arg; | |
const mapping = arg.mapping || arg; | |
// building the flow of transformation | |
// 1 - pick fields | |
// 2 - apply defaults | |
// 3 - omit fields | |
// 4 - transform subObjects with provided mappers | |
// 5 - transform flat keys | |
return _.flow( | |
internals.addPickerFlow(picker), | |
internals.addDefaultsFlow(defaults), | |
internals.addOmiterFlow(omiter), | |
internals.transformSubObjects(mapping), | |
internals.transformFlatKeys(mapping), | |
); | |
}, | |
}; | |
export default arg => internals.buildTransformer(arg); | |
/** | |
* | |
* Sample code | |
* | |
*/ | |
// mappings | |
const adressMapping = { | |
cityPlace: 'city' | |
} | |
const contactMapping = { | |
managerId: 'manager_id', | |
test: '100', | |
adress: { | |
key: 'location', | |
picker: ['cityPlace', 'postal'], | |
mapping: adressMapping, | |
defaults: { | |
number: '100', | |
} | |
} | |
}; | |
const userMapping = { | |
n1Id: 'n1_id', | |
contact: { | |
omiter: ['fieldIdontWant'], | |
defaults:{ | |
firstname: 'Cyndie', | |
adress: {}, | |
}, | |
mapping: contactMapping, | |
}, | |
}; | |
// data | |
const user = { | |
n1Id: 10, | |
firstname: 'Alex', | |
contact: { | |
managerId: 10, | |
id: 10, | |
fieldIdontWant: 'COUCOU', | |
adress: { | |
cityPlace: 'Orsay' | |
} | |
}, | |
}; | |
const transformer = mapper({ | |
mapping: userMapping, | |
picker: ['n1Id', 'firstname', 'contact'], | |
defaults: { | |
lastname: '', | |
} | |
}); | |
const sU = transformer(user); | |
console.log(sU); | |
console.log(sU.contact); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment