vgno/data-shaper

View on GitHub
index.js

Summary

Maintainability
A
1 hr
Test Coverage
'use strict';

var async = require('async');
var merge = require('lodash.merge');

var hashFetchDataCall = require('./lib/helpers').hashFetchDataCall;
var resolveValue = require('./lib/resolve-value');
var resolveFragment = require('./lib/resolve-fragment');
var shapeData = require('./lib/shape-data');

/**
 * Restructures data by creating entity collection arrays for each
 * collection.
 *
 * The property names in the raw data is split by :: which separates
 * the collection name and object id.
 *
 * @param {object} raw Raw data to restructure
 * @return {object} Restructured data
 */
function unserializeCollections(raw) {
    var res = {};

    for (var key in raw) {
        var keyData = key.split('::');
        var collection = keyData[0];
        var id = keyData[1];

        if (typeof res[collection] === 'undefined') {
            res[collection] = {};
        }

        res[collection][id] = raw[key];
    }

    return res;
}

/**
 * Shape an array of data object to a given shape
 *
 * @param {array} data Array of data objects
 * @param {object} shape Object describing the shape
 * @param {object} options Options object with functions to use in the shaping
 * @param {object} callback
 */
function dataShaper(data, shape, options, callback) {
    var shaperOptions = merge({
        shapeData: shapeData,
        resolveValue: resolveValue,
        resolveFragment: resolveFragment,
        memoize: true
    }, options);

    // Check that a data resolver was passed
    if (!shaperOptions.fetchData) {
        throw new Error('Missing fetchData function in options object');
    }

    // Memoize data fetching to speed things up
    if (shaperOptions.memoize) {
        shaperOptions.fetchData = async.memoize(shaperOptions.fetchData, hashFetchDataCall);
    }

    if (!Array.isArray(data)) {
        data = [data];
    }

    var result = {};

    async.each(data, function(item, cb) {
        shaperOptions.shapeData(item, shape, shaperOptions, function(err, res) {
            merge(result, res);
            cb(err);
        });
    }, function(err) {
        if (err) {
            callback(err);
            return;
        }

        callback(err, unserializeCollections(result));
    });
}

module.exports = dataShaper;