Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

gooddata

Package Overview
Dependencies
Maintainers
9
Versions
200
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gooddata - npm Package Compare versions

Comparing version 4.3.1 to 4.4.0

lib/execution/execute-afm.js

3

index.d.ts
// Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved.
import { AFM, Execution } from '@gooddata/typings';

@@ -344,2 +345,4 @@ export type SortDirection = 'asc' | 'desc';

export function getData(projectId: string, columns: string[], executionConfiguration: IExecutionConfiguration, settings: any): Promise<ISimpleExecutorResult>;
export function executeAfm(projectId: string, execution: AFM.IExecution): Promise<Execution.IExecutionResponses>;
}

@@ -346,0 +349,0 @@

4

lib/catalogue.js

@@ -16,3 +16,3 @@ 'use strict';

var _execution = require('./execution');
var _experimentalExecutions = require('./execution/experimental-executions');

@@ -46,3 +46,3 @@ var REQUEST_DEFAULTS = {

var categories = parseCategories(bucketItems);
var executionConfig = (0, _execution.mdToExecutionConfiguration)({
var executionConfig = (0, _experimentalExecutions.mdToExecutionConfiguration)({
buckets: _extends({}, bucketItems, {

@@ -49,0 +49,0 @@ categories: categories

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
exports.getDataForVis = exports.mdToExecutionConfiguration = undefined;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _experimentalExecutions = require('./execution/experimental-executions');
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _executeAfm = require('./execution/execute-afm');
exports.getData = getData;
var _executeAfm2 = _interopRequireDefault(_executeAfm);
var _md = require('md5');
var _md2 = _interopRequireDefault(_md);
var _invariant = require('invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _lodash = require('lodash');
var _xhr = require('./xhr');
var _rules = require('./utils/rules');
var _rules2 = _interopRequireDefault(_rules);
var _definitions = require('./utils/definitions');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } // Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.
var notEmpty = (0, _lodash.negate)(_lodash.isEmpty);
var findHeaderForMappingFn = function findHeaderForMappingFn(mapping, header) {
return (mapping.element === header.id || mapping.element === header.uri) && header.measureIndex === undefined;
};
var wrapMeasureIndexesFromMappings = function wrapMeasureIndexesFromMappings(metricMappings, headers) {
if (metricMappings) {
metricMappings.forEach(function (mapping) {
var header = (0, _lodash.find)(headers, (0, _lodash.partial)(findHeaderForMappingFn, mapping));
if (header) {
header.measureIndex = mapping.measureIndex;
header.isPoP = mapping.isPoP;
}
});
}
return headers;
};
var emptyResult = {
extendedTabularDataResult: {
values: [],
warnings: []
}
};
function loadExtendedDataResults(uri, settings) {
var prevResult = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : emptyResult;
return new Promise(function (resolve, reject) {
(0, _xhr.ajax)(uri, settings).then(function (r) {
if (r.status === 204) {
return {
status: r.status,
result: ''
};
}
return r.json().then(function (result) {
return {
status: r.status,
result: result
};
});
}).then(function (_ref) {
var status = _ref.status,
result = _ref.result;
var values = [].concat(_toConsumableArray((0, _lodash.get)(prevResult, 'extendedTabularDataResult.values', [])), _toConsumableArray((0, _lodash.get)(result, 'extendedTabularDataResult.values', [])));
var warnings = [].concat(_toConsumableArray((0, _lodash.get)(prevResult, 'extendedTabularDataResult.warnings', [])), _toConsumableArray((0, _lodash.get)(result, 'extendedTabularDataResult.warnings', [])));
var updatedResult = (0, _lodash.merge)({}, prevResult, {
extendedTabularDataResult: {
values: values,
warnings: warnings
}
});
var nextUri = (0, _lodash.get)(result, 'extendedTabularDataResult.paging.next');
if (nextUri) {
resolve(loadExtendedDataResults(nextUri, settings, updatedResult));
} else {
resolve({ status: status, result: updatedResult });
}
}, reject);
});
}
/**
* Module for execution on experimental execution resource
* Execution endpoints
*
* @module execution
* @class execution
* @module execution
*/
/**
* For the given projectId it returns table structure with the given
* elements in column headers.
*
* @method getData
* @param {String} projectId - GD project identifier
* @param {Array} columns - An array of attribute or metric identifiers.
* @param {Object} executionConfiguration - Execution configuration - can contain for example
* property "where" containing query-like filters
* property "orderBy" contains array of sorted properties to order in form
* [{column: 'identifier', direction: 'asc|desc'}]
* @param {Object} settings - Supports additional settings accepted by the underlying
* xhr.ajax() calls
*
* @return {Object} Structure with `headers` and `rawData` keys filled with values from execution.
*/
function getData(projectId, columns) {
var executionConfiguration = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var settings = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var executedReport = {
isLoaded: false
};
// Create request and result structures
var request = {
execution: { columns: columns }
};
// enrich configuration with supported properties such as
// where clause with query-like filters
['where', 'orderBy', 'definitions'].forEach(function (property) {
if (executionConfiguration[property]) {
request.execution[property] = executionConfiguration[property];
}
});
// Execute request
return (0, _xhr.post)('/gdc/internal/projects/' + projectId + '/experimental/executions', _extends({}, settings, {
body: JSON.stringify(request)
})).then(_xhr.parseJSON).then(function (result) {
executedReport.headers = wrapMeasureIndexesFromMappings((0, _lodash.get)(executionConfiguration, 'metricMappings'), result.executionResult.headers);
// Start polling on url returned in the executionResult for tabularData
return loadExtendedDataResults(result.executionResult.extendedTabularDataResult, settings);
}).then(function (r) {
var result = r.result,
status = r.status;
return Object.assign({}, executedReport, {
rawData: (0, _lodash.get)(result, 'extendedTabularDataResult.values', []),
warnings: (0, _lodash.get)(result, 'extendedTabularDataResult.warnings', []),
isLoaded: true,
isEmpty: status === 204
});
});
}
var MAX_TITLE_LENGTH = 1000;
var getMetricTitle = function getMetricTitle(suffix, title) {
var maxLength = MAX_TITLE_LENGTH - suffix.length;
if (title && title.length > maxLength) {
if (title[title.length - 1] === ')') {
return title.substring(0, maxLength - 2) + '\u2026)' + suffix;
}
return title.substring(0, maxLength - 1) + '\u2026' + suffix;
}
return '' + title + suffix;
};
var getBaseMetricTitle = (0, _lodash.partial)(getMetricTitle, '');
var POP_SUFFIX = ' - previous year';
var getPoPMetricTitle = (0, _lodash.partial)(getMetricTitle, POP_SUFFIX);
var CONTRIBUTION_METRIC_FORMAT = '#,##0.00%';
var allFiltersEmpty = function allFiltersEmpty(item) {
return (0, _lodash.every)((0, _lodash.map)((0, _lodash.get)(item, 'measureFilters', []), function (f) {
return (0, _lodash.isEmpty)((0, _lodash.get)(f, 'listAttributeFilter.default.attributeElements', []));
}));
};
var isDerived = function isDerived(measure) {
var type = (0, _lodash.get)(measure, 'type');
return type === 'fact' || type === 'attribute' || !allFiltersEmpty(measure);
};
var getFilterExpression = function getFilterExpression(listAttributeFilter) {
var attributeUri = (0, _lodash.get)(listAttributeFilter, 'listAttributeFilter.attribute');
var elements = (0, _lodash.get)(listAttributeFilter, 'listAttributeFilter.default.attributeElements', []);
if ((0, _lodash.isEmpty)(elements)) {
return null;
}
var elementsForQuery = (0, _lodash.map)(elements, function (e) {
return '[' + e + ']';
});
var negative = (0, _lodash.get)(listAttributeFilter, 'listAttributeFilter.default.negativeSelection') ? 'NOT ' : '';
return '[' + attributeUri + '] ' + negative + 'IN (' + elementsForQuery.join(',') + ')';
};
var getGeneratedMetricExpression = function getGeneratedMetricExpression(item) {
var aggregation = (0, _lodash.get)(item, 'aggregation', '').toUpperCase();
var objectUri = (0, _lodash.get)(item, 'objectUri');
var where = (0, _lodash.filter)((0, _lodash.map)((0, _lodash.get)(item, 'measureFilters'), getFilterExpression), function (e) {
return !!e;
});
return 'SELECT ' + (aggregation ? aggregation + '([' + objectUri + '])' : '[' + objectUri + ']') + (notEmpty(where) ? ' WHERE ' + where.join(' AND ') : '');
};
var getPercentMetricExpression = function getPercentMetricExpression(_ref2, measure) {
var category = _ref2.category;
var metricExpressionWithoutFilters = 'SELECT [' + (0, _lodash.get)(measure, 'objectUri') + ']';
if (isDerived(measure)) {
metricExpressionWithoutFilters = getGeneratedMetricExpression((0, _lodash.omit)(measure, 'measureFilters'));
}
var attributeUri = (0, _lodash.get)(category, 'attribute');
var whereFilters = (0, _lodash.filter)((0, _lodash.map)((0, _lodash.get)(measure, 'measureFilters'), getFilterExpression), function (e) {
return !!e;
});
var whereExpression = notEmpty(whereFilters) ? ' WHERE ' + whereFilters.join(' AND ') : '';
return 'SELECT (' + metricExpressionWithoutFilters + whereExpression + ') / (' + metricExpressionWithoutFilters + ' BY ALL [' + attributeUri + ']' + whereExpression + ')';
};
var getPoPExpression = function getPoPExpression(attribute, metricExpression) {
var attributeUri = (0, _lodash.get)(attribute, 'attribute');
return 'SELECT ' + metricExpression + ' FOR PREVIOUS ([' + attributeUri + '])';
};
var getGeneratedMetricHash = function getGeneratedMetricHash(title, format, expression) {
return (0, _md2.default)(expression + '#' + title + '#' + format);
};
var getGeneratedMetricIdentifier = function getGeneratedMetricIdentifier(item, aggregation, expressionCreator, hasher) {
var _get$split = (0, _lodash.get)(item, 'objectUri').split('/'),
_get$split2 = _slicedToArray(_get$split, 6),
prjId = _get$split2[3],
id = _get$split2[5];
var identifier = prjId + '_' + id;
var hash = hasher(expressionCreator(item));
var hasNoFilters = (0, _lodash.isEmpty)((0, _lodash.get)(item, 'measureFilters', []));
var type = (0, _lodash.get)(item, 'type');
var prefix = hasNoFilters || allFiltersEmpty(item) ? '' : '_filtered';
return type + '_' + identifier + '.generated.' + hash + prefix + '_' + aggregation;
};
var isDateCategory = function isDateCategory(_ref3) {
var category = _ref3.category;
return category.type === 'date';
};
var isDateFilter = function isDateFilter(_ref4) {
var dateFilter = _ref4.dateFilter;
return dateFilter;
};
var getCategories = function getCategories(_ref5) {
var categories = _ref5.categories;
return categories;
};
var getFilters = function getFilters(_ref6) {
var filters = _ref6.filters;
return filters;
};
var getDateCategory = function getDateCategory(mdObj) {
var category = (0, _lodash.find)(getCategories(mdObj), isDateCategory);
return (0, _lodash.get)(category, 'category');
};
var getDateFilter = function getDateFilter(mdObj) {
var dateFilter = (0, _lodash.find)(getFilters(mdObj), isDateFilter);
return (0, _lodash.get)(dateFilter, 'dateFilter');
};
var getDate = function getDate(mdObj) {
return getDateCategory(mdObj) || getDateFilter(mdObj);
};
var getMetricSort = function getMetricSort(sort, isPoPMetric) {
if ((0, _lodash.isString)(sort)) {
// TODO: backward compatibility, remove when not used plain "sort: asc | desc" in measures
return sort;
}
var sortByPoP = (0, _lodash.get)(sort, 'sortByPoP');
if (isPoPMetric && sortByPoP || !isPoPMetric && !sortByPoP) {
return (0, _lodash.get)(sort, 'direction');
}
return null;
};
var createPureMetric = function createPureMetric(measure, mdObj, measureIndex) {
return {
element: (0, _lodash.get)(measure, 'objectUri'),
sort: getMetricSort((0, _lodash.get)(measure, 'sort')),
meta: { measureIndex: measureIndex }
};
};
var createDerivedMetric = function createDerivedMetric(measure, mdObj, measureIndex) {
var format = measure.format,
sort = measure.sort;
var title = getBaseMetricTitle(measure.title);
var hasher = (0, _lodash.partial)(getGeneratedMetricHash, title, format);
var aggregation = (0, _lodash.get)(measure, 'aggregation', 'base').toLowerCase();
var element = getGeneratedMetricIdentifier(measure, aggregation, getGeneratedMetricExpression, hasher);
var definition = {
metricDefinition: {
identifier: element,
expression: getGeneratedMetricExpression(measure),
title: title,
format: format
}
};
return {
element: element,
definition: definition,
sort: getMetricSort(sort),
meta: {
measureIndex: measureIndex
}
};
};
var createContributionMetric = function createContributionMetric(measure, mdObj, measureIndex) {
var category = (0, _lodash.first)(getCategories(mdObj));
var getMetricExpression = (0, _lodash.partial)(getPercentMetricExpression, category);
var title = getBaseMetricTitle((0, _lodash.get)(measure, 'title'));
var hasher = (0, _lodash.partial)(getGeneratedMetricHash, title, CONTRIBUTION_METRIC_FORMAT);
return {
element: getGeneratedMetricIdentifier(measure, 'percent', getMetricExpression, hasher),
definition: {
metricDefinition: {
identifier: getGeneratedMetricIdentifier(measure, 'percent', getMetricExpression, hasher),
expression: getMetricExpression(measure),
title: title,
format: CONTRIBUTION_METRIC_FORMAT
}
},
sort: getMetricSort((0, _lodash.get)(measure, 'sort')),
meta: {
measureIndex: measureIndex
}
};
};
var createPoPMetric = function createPoPMetric(measure, mdObj, measureIndex) {
var title = getPoPMetricTitle((0, _lodash.get)(measure, 'title'));
var format = (0, _lodash.get)(measure, 'format');
var hasher = (0, _lodash.partial)(getGeneratedMetricHash, title, format);
var date = getDate(mdObj);
var generated = void 0;
var getMetricExpression = (0, _lodash.partial)(getPoPExpression, date, '[' + (0, _lodash.get)(measure, 'objectUri') + ']');
if (isDerived(measure)) {
generated = createDerivedMetric(measure, mdObj, measureIndex);
getMetricExpression = (0, _lodash.partial)(getPoPExpression, date, '(' + (0, _lodash.get)(generated, 'definition.metricDefinition.expression') + ')');
}
var identifier = getGeneratedMetricIdentifier(measure, 'pop', getMetricExpression, hasher);
var result = [{
element: identifier,
definition: {
metricDefinition: {
identifier: identifier,
expression: getMetricExpression(),
title: title,
format: format
}
},
sort: getMetricSort((0, _lodash.get)(measure, 'sort'), true),
meta: {
measureIndex: measureIndex,
isPoP: true
}
}];
if (generated) {
result.push(generated);
} else {
result.push(createPureMetric(measure, mdObj, measureIndex));
}
return result;
};
var createContributionPoPMetric = function createContributionPoPMetric(measure, mdObj, measureIndex) {
var date = getDate(mdObj);
var generated = createContributionMetric(measure, mdObj, measureIndex);
var title = getPoPMetricTitle((0, _lodash.get)(measure, 'title'));
var format = CONTRIBUTION_METRIC_FORMAT;
var hasher = (0, _lodash.partial)(getGeneratedMetricHash, title, format);
var getMetricExpression = (0, _lodash.partial)(getPoPExpression, date, '(' + (0, _lodash.get)(generated, 'definition.metricDefinition.expression') + ')');
var identifier = getGeneratedMetricIdentifier(measure, 'pop', getMetricExpression, hasher);
var result = [{
element: identifier,
definition: {
metricDefinition: {
identifier: identifier,
expression: getMetricExpression(),
title: title,
format: format
}
},
sort: getMetricSort((0, _lodash.get)(measure, 'sort'), true),
meta: {
measureIndex: measureIndex,
isPoP: true
}
}];
result.push(generated);
return result;
};
var categoryToElement = function categoryToElement(_ref7) {
var category = _ref7.category;
return { element: (0, _lodash.get)(category, 'displayForm'), sort: (0, _lodash.get)(category, 'sort') };
};
var attributeFilterToWhere = function attributeFilterToWhere(f) {
var elements = (0, _lodash.get)(f, 'listAttributeFilter.default.attributeElements', []);
var elementsForQuery = (0, _lodash.map)(elements, function (e) {
return { id: (0, _lodash.last)(e.split('=')) };
});
var dfUri = (0, _lodash.get)(f, 'listAttributeFilter.displayForm');
var negative = (0, _lodash.get)(f, 'listAttributeFilter.default.negativeSelection');
return negative ? _defineProperty({}, dfUri, { $not: { $in: elementsForQuery } }) : _defineProperty({}, dfUri, { $in: elementsForQuery });
};
var getFromFilter = function getFromFilter(f, property) {
return (0, _lodash.get)(f, 'dateFilter.' + property);
};
var toInteger = function toInteger(value) {
return parseInt(value, 10);
};
var dateFilterToWhere = function dateFilterToWhere(f) {
var dateUri = getFromFilter(f, 'dimension') || getFromFilter(f, 'dataSet') || getFromFilter(f, 'dataset'); // dataset with lowercase 's' is deprecated; kept here for backwards compatibility
var granularity = getFromFilter(f, 'granularity');
var isRelative = getFromFilter(f, 'type') === 'relative';
var filterFrom = getFromFilter(f, 'from');
var filterTo = getFromFilter(f, 'to');
var from = isRelative ? toInteger(filterFrom) : filterFrom;
var to = isRelative ? toInteger(filterTo) : filterTo;
var between = [from, to];
return _defineProperty({}, dateUri, { $between: between, $granularity: granularity });
};
var isPoP = function isPoP(_ref11) {
var showPoP = _ref11.showPoP;
return showPoP;
};
var isContribution = function isContribution(_ref12) {
var showInPercent = _ref12.showInPercent;
return showInPercent;
};
var isCalculatedMeasure = function isCalculatedMeasure(_ref13) {
var type = _ref13.type;
return type === 'metric';
};
var rules = new _rules2.default();
rules.addRule([isPoP, isContribution], createContributionPoPMetric);
rules.addRule([isPoP], createPoPMetric);
rules.addRule([isContribution], createContributionMetric);
rules.addRule([isDerived], createDerivedMetric);
rules.addRule([isCalculatedMeasure], createPureMetric);
function getMetricFactory(measure) {
var factory = rules.match(measure);
(0, _invariant2.default)(factory, 'Unknown factory for: ' + measure);
return factory;
}
var isDateFilterExecutable = function isDateFilterExecutable(dateFilter) {
return (0, _lodash.get)(dateFilter, 'from') !== undefined && (0, _lodash.get)(dateFilter, 'to') !== undefined;
};
var isAttributeFilterExecutable = function isAttributeFilterExecutable(listAttributeFilter) {
return notEmpty((0, _lodash.get)(listAttributeFilter, ['default', 'attributeElements']));
};
function getWhere(filters) {
var executableFilters = (0, _lodash.filter)(filters, function (_ref14) {
var listAttributeFilter = _ref14.listAttributeFilter;
return isAttributeFilterExecutable(listAttributeFilter);
});
var attributeFilters = (0, _lodash.map)(executableFilters, attributeFilterToWhere);
var dateFilters = (0, _lodash.map)((0, _lodash.filter)(filters, function (_ref15) {
var dateFilter = _ref15.dateFilter;
return isDateFilterExecutable(dateFilter);
}), dateFilterToWhere);
var resultDate = [].concat(_toConsumableArray(dateFilters)).reduce(_lodash.assign, {});
var resultAttribute = {
$and: attributeFilters
};
return _extends({}, resultDate, resultAttribute);
}
var sortToOrderBy = function sortToOrderBy(item) {
return { column: (0, _lodash.get)(item, 'element'), direction: (0, _lodash.get)(item, 'sort') };
};
var getOrderBy = function getOrderBy(metrics, categories, type) {
// For bar chart we always override sorting to sort by values (first metric)
if (type === 'bar' && notEmpty(metrics)) {
return [{
column: (0, _lodash.first)((0, _lodash.compact)((0, _lodash.map)(metrics, 'element'))),
direction: 'desc'
}];
}
return (0, _lodash.map)((0, _lodash.filter)([].concat(_toConsumableArray(categories), _toConsumableArray(metrics)), function (item) {
return item.sort;
}), sortToOrderBy);
};
var mdToExecutionConfiguration = exports.mdToExecutionConfiguration = function mdToExecutionConfiguration(mdObj) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var buckets = (0, _lodash.get)(mdObj, 'buckets');
var measures = (0, _lodash.map)(buckets.measures, function (_ref16) {
var measure = _ref16.measure;
return measure;
});
var metrics = (0, _lodash.flatten)((0, _lodash.map)(measures, function (measure, index) {
return getMetricFactory(measure)(measure, buckets, index);
}));
var categories = getCategories(buckets);
var filters = getFilters(buckets);
if (options.removeDateItems) {
categories = (0, _lodash.filter)(categories, function (_ref17) {
var category = _ref17.category;
return category.type !== 'date';
});
filters = (0, _lodash.filter)(filters, function (item) {
return !item.dateFilter;
});
}
categories = (0, _lodash.map)(categories, categoryToElement);
var columns = (0, _lodash.compact)((0, _lodash.map)([].concat(_toConsumableArray(categories), _toConsumableArray(metrics)), 'element'));
return {
columns: columns,
orderBy: getOrderBy(metrics, categories, (0, _lodash.get)(mdObj, 'type')),
definitions: (0, _definitions.sortDefinitions)((0, _lodash.compact)((0, _lodash.map)(metrics, 'definition'))),
where: columns.length ? getWhere(filters) : {},
metricMappings: (0, _lodash.map)(metrics, function (m) {
return _extends({ element: m.element }, m.meta);
})
};
};
var getOriginalMetricFormats = function getOriginalMetricFormats(mdObj) {
// for metrics with showPoP or measureFilters.length > 0 roundtrip for original metric format
return Promise.all((0, _lodash.map)((0, _lodash.map)((0, _lodash.get)(mdObj, 'buckets.measures'), function (_ref18) {
var measure = _ref18.measure;
return measure;
}), function (measure) {
if (measure.showPoP === true || measure.measureFilters.length > 0) {
return (0, _xhr.get)(measure.objectUri).then(function (obj) {
return _extends({}, measure, {
format: (0, _lodash.get)(obj, 'metric.content.format', measure.format)
});
});
}
return Promise.resolve(measure);
}));
};
var getDataForVis = function getDataForVis(projectId, mdObj, settings) {
return getOriginalMetricFormats(mdObj).then(function (measures) {
var metadata = mdObj;
metadata.buckets.measures = (0, _lodash.map)(measures, function (measure) {
return { measure: measure };
});
var _mdToExecutionConfigu = mdToExecutionConfiguration(mdObj),
columns = _mdToExecutionConfigu.columns,
executionConfiguration = _objectWithoutProperties(_mdToExecutionConfigu, ['columns']);
return getData(projectId, columns, executionConfiguration, settings);
});
};
exports.getDataForVis = getDataForVis;
// Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved.
exports.default = {
getData: _experimentalExecutions.getData,
getDataForVis: _experimentalExecutions.getDataForVis,
executeAfm: _executeAfm2.default
};

@@ -21,3 +21,3 @@ 'use strict';

var execution = _interopRequireWildcard(_execution);
var _execution2 = _interopRequireDefault(_execution);

@@ -62,5 +62,5 @@ var _project = require('./project');

// Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.
var gooddata = { config: config, xhr: xhr, user: user, md: md, execution: execution, project: project, catalogue: catalogue, admin: _admin2.default };
var gooddata = { config: config, xhr: xhr, user: user, md: md, execution: _execution2.default, project: project, catalogue: catalogue, admin: _admin2.default };
exports.default = gooddata;
module.exports = gooddata;

@@ -109,5 +109,7 @@ 'use strict';

return (0, _xhr.get)(uri).then(function (r) {
items.push.apply(items, _toConsumableArray(r.objects.items));
var nextUri = r.objects.paging.next;
return (0, _xhr.get)(uri).then(function (_ref) {
var objects = _ref.objects;
items.push.apply(items, _toConsumableArray(objects.items));
var nextUri = objects.paging.next;
return nextUri ? getOnePage(nextUri, items) : items;

@@ -275,7 +277,7 @@ });

default:
return Promise.all([getFolderEntries(projectId, 'fact'), getFolderEntries(projectId, 'metric'), getDimensions(projectId)]).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 3),
facts = _ref2[0],
metrics = _ref2[1],
attributes = _ref2[2];
return Promise.all([getFolderEntries(projectId, 'fact'), getFolderEntries(projectId, 'metric'), getDimensions(projectId)]).then(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 3),
facts = _ref3[0],
metrics = _ref3[1],
attributes = _ref3[2];

@@ -282,0 +284,0 @@ return { fact: facts, metric: metrics, attribute: attributes };

@@ -205,3 +205,3 @@ 'use strict';

// If response.status id 401 and it was a login request there is no need
// to cycle back for token - login does not need token and this meand you
// to cycle back for token - login does not need token and this meant you
// are not authorized

@@ -208,0 +208,0 @@ if (response.status === 401) {

{
"name": "gooddata",
"version": "4.3.1",
"version": "4.4.0",
"author": "GoodData",

@@ -66,2 +66,3 @@ "description": "GoodData JavaScript SDK",

"dependencies": {
"@gooddata/typings": "0.0.3",
"es6-promise": "3.0.2",

@@ -72,4 +73,5 @@ "fetch-cookie": "0.4.0",

"lodash": "4.17.4",
"md5": "2.2.1"
"md5": "2.2.1",
"qs": "6.5.1"
}
}
import { get, find, omit, cloneDeep } from 'lodash';
import { post, parseJSON } from './xhr';
import { mdToExecutionConfiguration } from './execution';
import { mdToExecutionConfiguration } from './execution/experimental-executions';

@@ -5,0 +5,0 @@ const REQUEST_DEFAULTS = {

@@ -1,588 +0,16 @@

// Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.
import md5 from 'md5';
import invariant from 'invariant';
import {
compact,
filter,
first,
find,
map,
merge,
every,
get,
isEmpty,
isString,
negate,
last,
assign,
partial,
flatten,
omit
} from 'lodash';
// Copyright (C) 2007-2017, GoodData(R) Corporation. All rights reserved.
import { getData, getDataForVis } from './execution/experimental-executions';
import executeAfm from './execution/execute-afm';
import {
ajax,
post,
get as xhrGet,
parseJSON
} from './xhr';
import Rules from './utils/rules';
import { sortDefinitions } from './utils/definitions';
const notEmpty = negate(isEmpty);
const findHeaderForMappingFn = (mapping, header) =>
((mapping.element === header.id || mapping.element === header.uri) &&
header.measureIndex === undefined);
const wrapMeasureIndexesFromMappings = (metricMappings, headers) => {
if (metricMappings) {
metricMappings.forEach((mapping) => {
const header = find(headers, partial(findHeaderForMappingFn, mapping));
if (header) {
header.measureIndex = mapping.measureIndex;
header.isPoP = mapping.isPoP;
}
});
}
return headers;
};
const emptyResult = {
extendedTabularDataResult: {
values: [],
warnings: []
}
};
function loadExtendedDataResults(uri, settings, prevResult = emptyResult) {
return new Promise((resolve, reject) => {
ajax(uri, settings)
.then((r) => {
if (r.status === 204) {
return {
status: r.status,
result: ''
};
}
return r.json().then((result) => {
return {
status: r.status,
result
};
});
})
.then(({ status, result }) => {
const values = [
...get(prevResult, 'extendedTabularDataResult.values', []),
...get(result, 'extendedTabularDataResult.values', [])
];
const warnings = [
...get(prevResult, 'extendedTabularDataResult.warnings', []),
...get(result, 'extendedTabularDataResult.warnings', [])
];
const updatedResult = merge({}, prevResult, {
extendedTabularDataResult: {
values,
warnings
}
});
const nextUri = get(result, 'extendedTabularDataResult.paging.next');
if (nextUri) {
resolve(loadExtendedDataResults(nextUri, settings, updatedResult));
} else {
resolve({ status, result: updatedResult });
}
}, reject);
});
}
/**
* Module for execution on experimental execution resource
* Execution endpoints
*
* @module execution
* @class execution
* @module execution
*/
/**
* For the given projectId it returns table structure with the given
* elements in column headers.
*
* @method getData
* @param {String} projectId - GD project identifier
* @param {Array} columns - An array of attribute or metric identifiers.
* @param {Object} executionConfiguration - Execution configuration - can contain for example
* property "where" containing query-like filters
* property "orderBy" contains array of sorted properties to order in form
* [{column: 'identifier', direction: 'asc|desc'}]
* @param {Object} settings - Supports additional settings accepted by the underlying
* xhr.ajax() calls
*
* @return {Object} Structure with `headers` and `rawData` keys filled with values from execution.
*/
export function getData(projectId, columns, executionConfiguration = {}, settings = {}) {
const executedReport = {
isLoaded: false
};
// Create request and result structures
const request = {
execution: { columns }
};
// enrich configuration with supported properties such as
// where clause with query-like filters
['where', 'orderBy', 'definitions'].forEach((property) => {
if (executionConfiguration[property]) {
request.execution[property] = executionConfiguration[property];
}
});
// Execute request
return post(`/gdc/internal/projects/${projectId}/experimental/executions`, {
...settings,
body: JSON.stringify(request)
})
.then(parseJSON)
.then((result) => {
executedReport.headers = wrapMeasureIndexesFromMappings(
get(executionConfiguration, 'metricMappings'), result.executionResult.headers);
// Start polling on url returned in the executionResult for tabularData
return loadExtendedDataResults(result.executionResult.extendedTabularDataResult, settings);
})
.then((r) => {
const { result, status } = r;
return Object.assign({}, executedReport, {
rawData: get(result, 'extendedTabularDataResult.values', []),
warnings: get(result, 'extendedTabularDataResult.warnings', []),
isLoaded: true,
isEmpty: status === 204
});
});
}
const MAX_TITLE_LENGTH = 1000;
const getMetricTitle = (suffix, title) => {
const maxLength = MAX_TITLE_LENGTH - suffix.length;
if (title && title.length > maxLength) {
if (title[title.length - 1] === ')') {
return `${title.substring(0, maxLength - 2)}…)${suffix}`;
}
return `${title.substring(0, maxLength - 1)}…${suffix}`;
}
return `${title}${suffix}`;
export default {
getData,
getDataForVis,
executeAfm
};
const getBaseMetricTitle = partial(getMetricTitle, '');
const POP_SUFFIX = ' - previous year';
const getPoPMetricTitle = partial(getMetricTitle, POP_SUFFIX);
const CONTRIBUTION_METRIC_FORMAT = '#,##0.00%';
const allFiltersEmpty = item => every(map(
get(item, 'measureFilters', []),
f => isEmpty(get(f, 'listAttributeFilter.default.attributeElements', []))
));
const isDerived = (measure) => {
const type = get(measure, 'type');
return (type === 'fact' || type === 'attribute' || !allFiltersEmpty(measure));
};
const getFilterExpression = (listAttributeFilter) => {
const attributeUri = get(listAttributeFilter, 'listAttributeFilter.attribute');
const elements = get(listAttributeFilter, 'listAttributeFilter.default.attributeElements', []);
if (isEmpty(elements)) {
return null;
}
const elementsForQuery = map(elements, e => `[${e}]`);
const negative = get(listAttributeFilter, 'listAttributeFilter.default.negativeSelection') ? 'NOT ' : '';
return `[${attributeUri}] ${negative}IN (${elementsForQuery.join(',')})`;
};
const getGeneratedMetricExpression = (item) => {
const aggregation = get(item, 'aggregation', '').toUpperCase();
const objectUri = get(item, 'objectUri');
const where = filter(map(get(item, 'measureFilters'), getFilterExpression), e => !!e);
return `SELECT ${aggregation ? `${aggregation}([${objectUri}])` : `[${objectUri}]`
}${notEmpty(where) ? ` WHERE ${where.join(' AND ')}` : ''}`;
};
const getPercentMetricExpression = ({ category }, measure) => {
let metricExpressionWithoutFilters = `SELECT [${get(measure, 'objectUri')}]`;
if (isDerived(measure)) {
metricExpressionWithoutFilters = getGeneratedMetricExpression(omit(measure, 'measureFilters'));
}
const attributeUri = get(category, 'attribute');
const whereFilters = filter(map(get(measure, 'measureFilters'), getFilterExpression), e => !!e);
const whereExpression = notEmpty(whereFilters) ? ` WHERE ${whereFilters.join(' AND ')}` : '';
return `SELECT (${metricExpressionWithoutFilters}${whereExpression}) / (${metricExpressionWithoutFilters} BY ALL [${attributeUri}]${whereExpression})`;
};
const getPoPExpression = (attribute, metricExpression) => {
const attributeUri = get(attribute, 'attribute');
return `SELECT ${metricExpression} FOR PREVIOUS ([${attributeUri}])`;
};
const getGeneratedMetricHash = (title, format, expression) => md5(`${expression}#${title}#${format}`);
const getGeneratedMetricIdentifier = (item, aggregation, expressionCreator, hasher) => {
const [, , , prjId, , id] = get(item, 'objectUri').split('/');
const identifier = `${prjId}_${id}`;
const hash = hasher(expressionCreator(item));
const hasNoFilters = isEmpty(get(item, 'measureFilters', []));
const type = get(item, 'type');
const prefix = (hasNoFilters || allFiltersEmpty(item)) ? '' : '_filtered';
return `${type}_${identifier}.generated.${hash}${prefix}_${aggregation}`;
};
const isDateCategory = ({ category }) => category.type === 'date';
const isDateFilter = ({ dateFilter }) => dateFilter;
const getCategories = ({ categories }) => categories;
const getFilters = ({ filters }) => filters;
const getDateCategory = (mdObj) => {
const category = find(getCategories(mdObj), isDateCategory);
return get(category, 'category');
};
const getDateFilter = (mdObj) => {
const dateFilter = find(getFilters(mdObj), isDateFilter);
return get(dateFilter, 'dateFilter');
};
const getDate = mdObj => (getDateCategory(mdObj) || getDateFilter(mdObj));
const getMetricSort = (sort, isPoPMetric) => {
if (isString(sort)) {
// TODO: backward compatibility, remove when not used plain "sort: asc | desc" in measures
return sort;
}
const sortByPoP = get(sort, 'sortByPoP');
if ((isPoPMetric && sortByPoP) || (!isPoPMetric && !sortByPoP)) {
return get(sort, 'direction');
}
return null;
};
const createPureMetric = (measure, mdObj, measureIndex) => ({
element: get(measure, 'objectUri'),
sort: getMetricSort(get(measure, 'sort')),
meta: { measureIndex }
});
const createDerivedMetric = (measure, mdObj, measureIndex) => {
const { format, sort } = measure;
const title = getBaseMetricTitle(measure.title);
const hasher = partial(getGeneratedMetricHash, title, format);
const aggregation = get(measure, 'aggregation', 'base').toLowerCase();
const element = getGeneratedMetricIdentifier(measure, aggregation, getGeneratedMetricExpression, hasher);
const definition = {
metricDefinition: {
identifier: element,
expression: getGeneratedMetricExpression(measure),
title,
format
}
};
return {
element,
definition,
sort: getMetricSort(sort),
meta: {
measureIndex
}
};
};
const createContributionMetric = (measure, mdObj, measureIndex) => {
const category = first(getCategories(mdObj));
const getMetricExpression = partial(getPercentMetricExpression, category);
const title = getBaseMetricTitle(get(measure, 'title'));
const hasher = partial(getGeneratedMetricHash, title, CONTRIBUTION_METRIC_FORMAT);
return {
element: getGeneratedMetricIdentifier(measure, 'percent', getMetricExpression, hasher),
definition: {
metricDefinition: {
identifier: getGeneratedMetricIdentifier(measure, 'percent', getMetricExpression, hasher),
expression: getMetricExpression(measure),
title,
format: CONTRIBUTION_METRIC_FORMAT
}
},
sort: getMetricSort(get(measure, 'sort')),
meta: {
measureIndex
}
};
};
const createPoPMetric = (measure, mdObj, measureIndex) => {
const title = getPoPMetricTitle(get(measure, 'title'));
const format = get(measure, 'format');
const hasher = partial(getGeneratedMetricHash, title, format);
const date = getDate(mdObj);
let generated;
let getMetricExpression = partial(getPoPExpression, date, `[${get(measure, 'objectUri')}]`);
if (isDerived(measure)) {
generated = createDerivedMetric(measure, mdObj, measureIndex);
getMetricExpression = partial(getPoPExpression, date, `(${get(generated, 'definition.metricDefinition.expression')})`);
}
const identifier = getGeneratedMetricIdentifier(measure, 'pop', getMetricExpression, hasher);
const result = [{
element: identifier,
definition: {
metricDefinition: {
identifier,
expression: getMetricExpression(),
title,
format
}
},
sort: getMetricSort(get(measure, 'sort'), true),
meta: {
measureIndex,
isPoP: true
}
}];
if (generated) {
result.push(generated);
} else {
result.push(createPureMetric(measure, mdObj, measureIndex));
}
return result;
};
const createContributionPoPMetric = (measure, mdObj, measureIndex) => {
const date = getDate(mdObj);
const generated = createContributionMetric(measure, mdObj, measureIndex);
const title = getPoPMetricTitle(get(measure, 'title'));
const format = CONTRIBUTION_METRIC_FORMAT;
const hasher = partial(getGeneratedMetricHash, title, format);
const getMetricExpression = partial(getPoPExpression, date, `(${get(generated, 'definition.metricDefinition.expression')})`);
const identifier = getGeneratedMetricIdentifier(measure, 'pop', getMetricExpression, hasher);
const result = [{
element: identifier,
definition: {
metricDefinition: {
identifier,
expression: getMetricExpression(),
title,
format
}
},
sort: getMetricSort(get(measure, 'sort'), true),
meta: {
measureIndex,
isPoP: true
}
}];
result.push(generated);
return result;
};
const categoryToElement = ({ category }) =>
({ element: get(category, 'displayForm'), sort: get(category, 'sort') });
const attributeFilterToWhere = (f) => {
const elements = get(f, 'listAttributeFilter.default.attributeElements', []);
const elementsForQuery = map(elements, e => ({ id: last(e.split('=')) }));
const dfUri = get(f, 'listAttributeFilter.displayForm');
const negative = get(f, 'listAttributeFilter.default.negativeSelection');
return negative ?
{ [dfUri]: { $not: { $in: elementsForQuery } } } :
{ [dfUri]: { $in: elementsForQuery } };
};
const getFromFilter = (f, property) => get(f, `dateFilter.${property}`);
const toInteger = value => parseInt(value, 10);
const dateFilterToWhere = (f) => {
const dateUri =
getFromFilter(f, 'dimension') ||
getFromFilter(f, 'dataSet') ||
getFromFilter(f, 'dataset'); // dataset with lowercase 's' is deprecated; kept here for backwards compatibility
const granularity = getFromFilter(f, 'granularity');
const isRelative = getFromFilter(f, 'type') === 'relative';
const filterFrom = getFromFilter(f, 'from');
const filterTo = getFromFilter(f, 'to');
const from = isRelative ? toInteger(filterFrom) : filterFrom;
const to = isRelative ? toInteger(filterTo) : filterTo;
const between = [from, to];
return { [dateUri]: { $between: between, $granularity: granularity } };
};
const isPoP = ({ showPoP }) => showPoP;
const isContribution = ({ showInPercent }) => showInPercent;
const isCalculatedMeasure = ({ type }) => type === 'metric';
const rules = new Rules();
rules.addRule(
[isPoP, isContribution],
createContributionPoPMetric
);
rules.addRule(
[isPoP],
createPoPMetric
);
rules.addRule(
[isContribution],
createContributionMetric
);
rules.addRule(
[isDerived],
createDerivedMetric
);
rules.addRule(
[isCalculatedMeasure],
createPureMetric
);
function getMetricFactory(measure) {
const factory = rules.match(measure);
invariant(factory, `Unknown factory for: ${measure}`);
return factory;
}
const isDateFilterExecutable = dateFilter =>
get(dateFilter, 'from') !== undefined &&
get(dateFilter, 'to') !== undefined;
const isAttributeFilterExecutable = listAttributeFilter =>
notEmpty(get(listAttributeFilter, ['default', 'attributeElements']));
function getWhere(filters) {
const executableFilters = filter(
filters, ({ listAttributeFilter }) => isAttributeFilterExecutable(listAttributeFilter)
);
const attributeFilters = map(executableFilters, attributeFilterToWhere);
const dateFilters = map(filter(filters, ({ dateFilter }) => isDateFilterExecutable(dateFilter)), dateFilterToWhere);
const resultDate = [...dateFilters].reduce(assign, {});
const resultAttribute = {
$and: attributeFilters
};
return {
...resultDate,
...resultAttribute
};
}
const sortToOrderBy = item => ({ column: get(item, 'element'), direction: get(item, 'sort') });
const getOrderBy = (metrics, categories, type) => {
// For bar chart we always override sorting to sort by values (first metric)
if (type === 'bar' && notEmpty(metrics)) {
return [{
column: first(compact(map(metrics, 'element'))),
direction: 'desc'
}];
}
return map(filter([...categories, ...metrics], item => item.sort), sortToOrderBy);
};
export const mdToExecutionConfiguration = (mdObj, options = {}) => {
const buckets = get(mdObj, 'buckets');
const measures = map(buckets.measures, ({ measure }) => measure);
const metrics = flatten(map(measures, (measure, index) => getMetricFactory(measure)(measure, buckets, index)));
let categories = getCategories(buckets);
let filters = getFilters(buckets);
if (options.removeDateItems) {
categories = filter(categories, ({ category }) => category.type !== 'date');
filters = filter(filters, item => !item.dateFilter);
}
categories = map(categories, categoryToElement);
const columns = compact(map([...categories, ...metrics], 'element'));
return {
columns,
orderBy: getOrderBy(metrics, categories, get(mdObj, 'type')),
definitions: sortDefinitions(compact(map(metrics, 'definition'))),
where: columns.length ? getWhere(filters) : {},
metricMappings: map(metrics, m => ({ element: m.element, ...m.meta }))
};
};
const getOriginalMetricFormats = (mdObj) => {
// for metrics with showPoP or measureFilters.length > 0 roundtrip for original metric format
return Promise.all(map(
map(get(mdObj, 'buckets.measures'), ({ measure }) => measure),
(measure) => {
if (measure.showPoP === true || measure.measureFilters.length > 0) {
return xhrGet(measure.objectUri).then((obj) => {
return {
...measure,
format: get(obj, 'metric.content.format', measure.format)
};
});
}
return Promise.resolve(measure);
}
));
};
export const getDataForVis = (projectId, mdObj, settings) => {
return getOriginalMetricFormats(mdObj).then((measures) => {
const metadata = mdObj;
metadata.buckets.measures = map(measures, measure => ({ measure }));
const { columns, ...executionConfiguration } = mdToExecutionConfiguration(mdObj);
return getData(projectId, columns, executionConfiguration, settings);
});
};

@@ -5,3 +5,3 @@ // Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.

import * as md from './metadata';
import * as execution from './execution';
import execution from './execution';
import * as project from './project';

@@ -8,0 +8,0 @@ import * as config from './config';

@@ -72,5 +72,5 @@ // Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.

return get(uri)
.then((r) => {
items.push(...r.objects.items);
const nextUri = r.objects.paging.next;
.then(({ objects }) => {
items.push(...objects.items);
const nextUri = objects.paging.next;
return nextUri ? getOnePage(nextUri, items) : items;

@@ -77,0 +77,0 @@ });

@@ -188,3 +188,3 @@ // Copyright (C) 2007-2013, GoodData(R) Corporation. All rights reserved.

// If response.status id 401 and it was a login request there is no need
// to cycle back for token - login does not need token and this meand you
// to cycle back for token - login does not need token and this meant you
// are not authorized

@@ -191,0 +191,0 @@ if (response.status === 401) {

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc