Skip to content

Instantly share code, notes, and snippets.

@alexandrebodin
Last active July 25, 2016 13:36
Show Gist options
  • Save alexandrebodin/020a77fcd2e46d9dc71ee205483f3619 to your computer and use it in GitHub Desktop.
Save alexandrebodin/020a77fcd2e46d9dc71ee205483f3619 to your computer and use it in GitHub Desktop.
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