Compare commits
4 Commits
0049bb9a53
...
f0edd3b63e
Author | SHA1 | Date |
---|---|---|
Sven Slootweg | f0edd3b63e | 7 years ago |
Sven Slootweg | 8c380ff7d6 | 7 years ago |
Sven Slootweg | fda5765197 | 7 years ago |
Sven Slootweg | 68da848e76 | 7 years ago |
@ -0,0 +1,90 @@
|
||||
'use strict';
|
||||
|
||||
const dotty = require("dotty");
|
||||
const deepAssign = require("deep-assign");
|
||||
|
||||
module.exports = function createPropertyMapper(propertyMap) {
|
||||
let mappings = Object.keys(propertyMap).map((sourceProperty) => {
|
||||
let destinationPath = propertyMap[sourceProperty];
|
||||
|
||||
if (typeof destinationPath === "function") {
|
||||
return {
|
||||
sourceProperty: sourceProperty,
|
||||
transformer: destinationPath
|
||||
}
|
||||
} else {
|
||||
let destinationObject, destinationProperty;
|
||||
|
||||
if (destinationPath.includes(".")) {
|
||||
let destinationPathParts = destinationPath.split(".");
|
||||
|
||||
destinationObject = destinationPathParts[0];
|
||||
destinationProperty = destinationPathParts.slice(1).join(".");
|
||||
} else {
|
||||
destinationObject = destinationPath;
|
||||
destinationProperty = sourceProperty;
|
||||
}
|
||||
|
||||
return {
|
||||
sourceProperty: sourceProperty,
|
||||
destinationObject: destinationObject,
|
||||
destinationProperty: destinationProperty
|
||||
}
|
||||
}
|
||||
}).reduce((mappings, item) => {
|
||||
mappings[item.sourceProperty] = item;
|
||||
return mappings;
|
||||
}, {});
|
||||
|
||||
return function mapProperties(properties) {
|
||||
return Object.keys(properties).map((propertyName) => {
|
||||
let propertyValue = properties[propertyName];
|
||||
|
||||
if (propertyName.includes(".")) {
|
||||
/* Property names with a dot are attempts to directly access an
|
||||
* object within a composite object; they need to be handled
|
||||
* specially since they essentially bypass the mapping step.
|
||||
* If there is *more* than a single dot, then this is an attempt
|
||||
* to access a *nested* composite object, and therefore we should
|
||||
* keep the entire property name after the first dot intact. */
|
||||
|
||||
let propertyNameSegments = propertyName.split(".");
|
||||
let destinationObject = propertyNameSegments[0];
|
||||
let realPropertyName = propertyNameSegments.slice(1).join(".");
|
||||
|
||||
return {
|
||||
sourceProperty: propertyName,
|
||||
destinationObject: destinationObject,
|
||||
destinationProperty: realPropertyName,
|
||||
value: propertyValue
|
||||
}
|
||||
} else if (mappings[propertyName] != null) {
|
||||
return Object.assign({
|
||||
value: propertyValue
|
||||
}, mappings[propertyName]);
|
||||
}
|
||||
}).filter((item) => {
|
||||
return (item != null);
|
||||
}).reduce((objects, item) => {
|
||||
function ensureObject(object) {
|
||||
if (objects[object] == null) {
|
||||
objects[object] = {};
|
||||
}
|
||||
}
|
||||
|
||||
if (item.destinationProperty != null) {
|
||||
ensureObject(item.destinationObject);
|
||||
dotty.put(objects[item.destinationObject], item.destinationProperty, item.value);
|
||||
} else {
|
||||
let results = item.transformer(item.value);
|
||||
|
||||
Object.keys(results).forEach((object) => {
|
||||
ensureObject(object);
|
||||
deepAssign(objects[object], results[object]);
|
||||
});
|
||||
}
|
||||
|
||||
return objects;
|
||||
}, {})
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue