report-builder
Version:
Complex JSON reports made easy
263 lines (202 loc) • 5.26 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
(factory());
}(this, (function () { 'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Op = require('object-path');
var getOrDefault = require('./utils');
/**
* Represents the report that we are generating
*
*/
var Report = function () {
/**
* Creates an instance of Report.
*
* @param {string} notes
* @param {string} totalLabel
* @param {any} [timestamp=Date.now()]
*
*/
function Report(notes, totalLabel) {
var timestamp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Date.now();
_classCallCheck(this, Report);
this.report = {
summary: {
total: {
count: 0,
label: totalLabel
},
timestamp: timestamp,
notes: notes
},
results: {}
};
}
/**
*
*
* @param {string} name
* @returns a new {@link Section} under that name
*
*/
Report.prototype.section = function section(name) {
return new Section(getOrDefault(this.report, name, {}), this.report);
};
/**
*
*
* @param {any} value
*
*/
Report.prototype.setTotal = function setTotal(value) {
this.report.summary.total.count = value;
return this;
};
/**
*
*
* @param {string} path
* @param {string} totalRef
* @returns this
*
*/
Report.prototype.calcPercentOf = function calcPercentOf(path, totalRef) {
if (typeof totalRef !== 'string') {
totalRef = 'summary.total.count'; // default reference is inside summary
} else {
totalRef = ['results', totalRef, 'count'].join('.'); // any other ref is under results namespace
}
if (typeof path !== 'string' || !Op.get(this.report.results, path) || isNaN(Op.get(this.report, totalRef))) {
return this;
}
var count = Op.get(this.report, ['results', path, 'count'].join('.'));
var total = Op.get(this.report, totalRef);
var percent = count * 100 / total;
Op.set(this.report.results, path + '.percent', percent);
return this;
};
/**
*
*
* @returns internal report
*
*/
Report.prototype.toJSON = function toJSON() {
return this.report;
};
return Report;
}();
/**
* Class that represents a section of the main report.
* **You should not try to instantiate it directly**.
*/
var Section = function () {
/**
* Creates an instance of Section.
* This constructor should only be called by the {@link Report} class
*
* @param {any} store
* @param {any} reportTree
*
*/
function Section(store, reportTree) {
_classCallCheck(this, Section);
this.tree = reportTree;
this.store = store;
}
/**
* Returns the object that should be serialized
* as a JSON representation of the report
* @returns internal report
* @public
*/
Section.prototype.toJSON = function toJSON() {
return this.tree;
};
/**
* Legacy method from v1.0.0 Will be removed soon
* @deprecated Legacy method from v1.0.0 Will be removed soon
* @returns new Section under name
*
*/
Section.prototype.subSection = function subSection() {
return this.section.apply(this, arguments);
};
/**
*
*
* @param {string} name
* @returns new Section under name
*
*/
Section.prototype.section = function section(name) {
return new Section(getOrDefault(this.store, name, {}), this.tree);
};
/**
*
*
* @returns summary Section
*
*/
Section.prototype.summary = function summary() {
return new Section(this.tree.summary, this.tree);
};
/**
*
*
* @param {string} totalRef
* @returns this
*
*/
Section.prototype.calcPercent = function calcPercent(totalRef) {
if (typeof this.store.count !== 'number') {
return this;
}
var count = this.store.count;
var total = typeof totalRef !== 'string' ? this.tree.summary.total.count : Op.get(this.tree, totalRef);
this.store.percent = count * 100 / total;
return this;
};
/**
*
*
* @param {string} path
* @param {any} value
* @returns this
*
*/
Section.prototype.set = function set(path, value) {
if (!path || !value) {
return this;
}
Op.set(this.store, path, value);
return this;
};
/**
*
*
* @param {string} path
* @param {number} [value=1]
* @returns this
*
*/
Section.prototype.increment = function increment(path) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
if (typeof path === 'number') {
value = path;
path = 'count';
} else {
path = typeof path === 'string' ? path.split('.') : [];
path.push('count');
}
var currVal = Op.get(this.store, path, 0);
Op.set(this.store, path, currVal + value);
return this;
};
return Section;
}();
module.exports = Report;
module.exports.Section = Section;
})));