Last active
January 1, 2019 23:30
-
-
Save thatkookooguy/b280eba86f8882bd9d673d0cdc6808e5 to your computer and use it in GitHub Desktop.
create a specific output value from any input object based on a mapper object. originally designed to allow achievibit (achievibit.kibibit.io) to work with multiple git cloud networks (GitHub, Gitlab, Bitbucket, etc.)
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
/** | |
* @fileOverview trying to create a general mapping utility. | |
* please credit me if you use this :-) | |
* | |
* @example | |
* const requestData = { | |
* user: 'thatkookooguy', | |
* project: 'achievibit', | |
* more: { | |
* user: 'ortichon' | |
* } | |
* }; | |
* | |
* const mapper = { | |
* pr: 'project', | |
* user: 'more.user', | |
* url: (data) => { | |
* return `http://github.com/${data.user}`; | |
* }, | |
* pizza: (data) => { | |
* return fetch(`https://api.github.com/users/${data.user}`) | |
* .then((res) => res.json()); | |
* } | |
* }; | |
* process(requestData, mapper) | |
* .then((result) => console.log(result)); | |
* | |
* // will print | |
* // { | |
* // pr: 'achievibit', | |
* // user: 'ortichon', | |
* // url: 'http://github.com/thatkookooguy', | |
* // pizza: { ... full github user data ... } | |
* // }; | |
* | |
* | |
* @author Neil Kalman neilkalman@gmail.com | |
* | |
* @requires NPM:lodash | |
*/ | |
const _ = require('lodash'); | |
// add isPromise check to lodash | |
_.mixin({ | |
isPromise: (obj) => _.isObject(obj) && _.isFunction(obj.then) | |
}); | |
/** | |
* Takes a data object and a mapping object | |
* and creates the result. | |
* | |
* | |
* @param {Object} data the data object (JSON). | |
* @param {Object} mappingObject javascript object | |
* each attribute is a output field name, | |
* and each value is either: | |
* - a string (based on the input of https://lodash.com/docs/4.17.10#get | |
* - a function returning a promise (will automatically wait) | |
* - a function returning a value (will wrap in a promise) | |
* | |
* @returns {Promise<Object>} promise that resolves to an object created from mapping data through the mappingObject | |
*/ | |
function process(data, mappingObject) { | |
let promiseArray = []; | |
let result = {}; | |
_.forOwn(mappingObject, (input, outputField) => { | |
const isSimpleMapping = _.isString(input); | |
const engineMapFunction = input; | |
const inputAttributePath = input; | |
let doAction = isSimpleMapping ? | |
get(data, inputAttributePath) : | |
engineMapFunction(data); | |
// make sure doAction is a promise at this point | |
doAction = _.isPromise(doAction) ? doAction : Promise.resolve(doAction); | |
doAction.then((value) => result[outputField] = value); | |
promiseArray.push(doAction); | |
}); | |
// | |
return Promise.all(promiseArray).then(() => result); | |
} | |
// promise wrapper for _.get | |
function get(data, path) { | |
return Promise.resolve(_.get(data, path)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment