Skip to content

Instantly share code, notes, and snippets.

@thatkookooguy
Last active January 1, 2019 23:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thatkookooguy/b280eba86f8882bd9d673d0cdc6808e5 to your computer and use it in GitHub Desktop.
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.)
/**
* @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