New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@gooddata/sdk-model

Package Overview
Dependencies
Maintainers
39
Versions
2565
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gooddata/sdk-model - npm Package Compare versions

Comparing version 8.0.0-alpha.27 to 8.0.0-alpha.28

dist/execution/base/fingerprint.d.ts

23

dist/execution/attribute/factory.d.ts
import { IAttribute } from "./index";
import { ObjRef, Identifier } from "../base";
declare type AttributeBuilderInput = Identifier | ObjRef | IAttribute;
/**

@@ -10,8 +11,9 @@ * Builder for attributes.

*/
export declare class AttributeBuilder implements IAttribute {
attribute: IAttribute["attribute"];
export declare class AttributeBuilder {
private attribute;
private customLocalId;
/**
* @internal
*/
constructor(displayForm: ObjRef);
constructor(input: AttributeBuilderInput);
alias: (alias: string) => this;

@@ -26,2 +28,4 @@ localId: (localId: string) => this;

};
private getOrGenerateLocalId;
private calculateAliasHash;
}

@@ -36,6 +40,15 @@ /**

* Creates a new attribute with the specified display form ref and optional modifications and localIdentifier.
* @param displayForm - ref or identifier of the attribute display form
* @param displayFormRefOrId - ref or identifier of the attribute display form
* @param modifications - optional modifications (e.g. alias, etc.)
* @public
*/
export declare function newAttribute(displayForm: ObjRef | Identifier, modifications?: AttributeModifications): IAttribute;
export declare function newAttribute(displayFormRefOrId: ObjRef | Identifier, modifications?: AttributeModifications): IAttribute;
/**
* Allows modification of an existing attribute instance.
*
* @param attribute - attribute to modify
* @param modifications - modification function
* @public
*/
export declare function modifyAttribute(attribute: IAttribute, modifications?: AttributeModifications): IAttribute;
export {};
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019-2020 GoodData Corporation
var identity = require("lodash/identity");
var cloneDeep = require("lodash/cloneDeep");
var isEmpty = require("lodash/isEmpty");
var index_1 = require("./index");
var base_1 = require("../base");
var factory_1 = require("../base/factory");
var spark_md5_1 = __importDefault(require("spark-md5"));
/**

@@ -18,4 +36,5 @@ * Builder for attributes.

*/
function AttributeBuilder(displayForm) {
function AttributeBuilder(input) {
var _this = this;
this.customLocalId = false;
this.alias = function (alias) {

@@ -27,12 +46,39 @@ _this.attribute.alias = alias;

_this.attribute.localIdentifier = localId;
_this.customLocalId = true;
return _this;
};
this.build = function () {
return { attribute: _this.attribute };
var localIdentifier = _this.getOrGenerateLocalId();
return {
attribute: __assign(__assign({}, _this.attribute), { localIdentifier: localIdentifier }),
};
};
this.attribute = {
displayForm: displayForm,
localIdentifier: "a_" + base_1.objRefToString(displayForm),
};
if (index_1.isAttribute(input)) {
this.attribute = cloneDeep(input.attribute);
this.customLocalId = false;
}
else {
var displayForm = base_1.isObjRef(input) ? input : factory_1.idRef(input, "displayForm");
this.attribute = {
displayForm: displayForm,
localIdentifier: "",
};
}
}
AttributeBuilder.prototype.getOrGenerateLocalId = function () {
if (this.customLocalId && !isEmpty(this.attribute.localIdentifier)) {
return this.attribute.localIdentifier;
}
return ["a", this.calculateAliasHash(), base_1.objRefToString(this.attribute.displayForm)]
.filter(function (part) { return !isEmpty(part); })
.join("_");
};
AttributeBuilder.prototype.calculateAliasHash = function () {
if (!this.attribute.alias) {
return "";
}
var hasher = new spark_md5_1.default();
hasher.append(this.attribute.alias);
return hasher.end().substr(0, 8);
};
return AttributeBuilder;

@@ -43,12 +89,24 @@ }());

* Creates a new attribute with the specified display form ref and optional modifications and localIdentifier.
* @param displayForm - ref or identifier of the attribute display form
* @param displayFormRefOrId - ref or identifier of the attribute display form
* @param modifications - optional modifications (e.g. alias, etc.)
* @public
*/
function newAttribute(displayForm, modifications) {
function newAttribute(displayFormRefOrId, modifications) {
if (modifications === void 0) { modifications = identity; }
var ref = base_1.isObjRef(displayForm) ? displayForm : factory_1.idRef(displayForm);
var builder = new AttributeBuilder(ref);
var builder = new AttributeBuilder(displayFormRefOrId);
return modifications(builder).build();
}
exports.newAttribute = newAttribute;
/**
* Allows modification of an existing attribute instance.
*
* @param attribute - attribute to modify
* @param modifications - modification function
* @public
*/
function modifyAttribute(attribute, modifications) {
if (modifications === void 0) { modifications = identity; }
var builder = new AttributeBuilder(attribute);
return modifications(builder).build();
}
exports.modifyAttribute = modifyAttribute;

@@ -107,4 +107,4 @@ /**

/**
* Retrieves string representation of object reference. This is purely for purposes for representation of
* references in text, debug and test purposes.
* Retrieves string representation of object reference. This is purely for for representation of
* references in text, debug and tests.
*

@@ -111,0 +111,0 @@ * @internal

@@ -49,4 +49,4 @@ "use strict";

/**
* Retrieves string representation of object reference. This is purely for purposes for representation of
* references in text, debug and test purposes.
* Retrieves string representation of object reference. This is purely for for representation of
* references in text, debug and tests.
*

@@ -58,4 +58,3 @@ * @internal

if (isIdentifierRef(objRef)) {
var typePrefix = objRef.type ? objRef.type + "_" : "";
return "" + typePrefix + objRef.identifier;
return "" + objRef.identifier;
}

@@ -62,0 +61,0 @@ else if (isUriRef(objRef)) {

@@ -17,3 +17,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
var isEmpty = require("lodash/isEmpty");

@@ -24,2 +24,3 @@ var attribute_1 = require("../attribute");

var ts_invariant_1 = __importDefault(require("ts-invariant"));
var __1 = require("../..");
/**

@@ -266,6 +267,6 @@ * This predicate evaluates true for any bucket.

function disableComputeRatio(item) {
if (measure_1.isMeasure(item)) {
return measure_1.measureDisableComputeRatio(item);
if (measure_1.isSimpleMeasure(item)) {
return __1.modifySimpleMeasure(item, function (m) { return m.noRatio(); });
}
return item;
}
import { IAttribute } from "../attribute";
import { IDimension } from "../base/dimension";
import { SortItem } from "../base/sort";
import { IFilter } from "../filter";
import { IMeasure } from "../measure";
/**

@@ -13,14 +10,2 @@ * @internal

*/
export declare function filterFingerprint(filter: IFilter): string;
/**
* @internal
*/
export declare function measureFingerprint(measure: IMeasure): string;
/**
* @internal
*/
export declare function dimensionFingerprint(dim: IDimension): string;
/**
* @internal
*/
export declare function sortFingerprint(sort: SortItem): string;

@@ -6,3 +6,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
var json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
var ts_invariant_1 = __importDefault(require("ts-invariant"));

@@ -14,3 +15,3 @@ /**

ts_invariant_1.default(attribute, "attribute must not be undefined");
return JSON.stringify(attribute);
return json_stable_stringify_1.default(attribute);
}

@@ -21,26 +22,5 @@ exports.attributeFingerprint = attributeFingerprint;

*/
function filterFingerprint(filter) {
return JSON.stringify(filter);
}
exports.filterFingerprint = filterFingerprint;
/**
* @internal
*/
function measureFingerprint(measure) {
return JSON.stringify(measure);
}
exports.measureFingerprint = measureFingerprint;
/**
* @internal
*/
function dimensionFingerprint(dim) {
return JSON.stringify(dim);
}
exports.dimensionFingerprint = dimensionFingerprint;
/**
* @internal
*/
function sortFingerprint(sort) {
return JSON.stringify(sort);
return json_stable_stringify_1.default(sort);
}
exports.sortFingerprint = sortFingerprint;

@@ -0,5 +1,5 @@

import { IAttribute } from "../attribute";
import { IDimension } from "../base/dimension";
import { SortItem } from "../base/sort";
import { ITotal } from "../base/totals";
import { IAttribute } from "../attribute";
import { IBucket } from "../buckets";

@@ -6,0 +6,0 @@ import { IFilter } from "../filter";

@@ -17,9 +17,13 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
var isEmpty = require("lodash/isEmpty");
var isString = require("lodash/isString");
var spark_md5_1 = __importDefault(require("spark-md5"));
var ts_invariant_1 = __importDefault(require("ts-invariant"));
var dimension_1 = require("../base/dimension");
var filterMerge_1 = require("../filter/filterMerge");
var fingerprint_1 = require("../measure/fingerprint");
var fingerprints_1 = require("./fingerprints");
var dimension_1 = require("../base/dimension");
var fingerprint_2 = require("../base/fingerprint");
var fingerprint_3 = require("../filter/fingerprint");
/**

@@ -109,8 +113,11 @@ * Creates new execution definition by merging new filters into an existing definition.

def.attributes.map(fingerprints_1.attributeFingerprint).forEach(hashFun);
def.measures.map(fingerprints_1.measureFingerprint).forEach(hashFun);
def.filters.map(fingerprints_1.filterFingerprint).forEach(hashFun);
def.measures.map(fingerprint_1.measureFingerprint).forEach(hashFun);
def.filters
.map(fingerprint_3.filterFingerprint)
.filter(isString)
.forEach(hashFun);
def.sortBy.map(fingerprints_1.sortFingerprint).forEach(hashFun);
def.dimensions.map(fingerprints_1.dimensionFingerprint).forEach(hashFun);
def.dimensions.map(fingerprint_2.dimensionFingerprint).forEach(hashFun);
return hasher.end();
}
exports.defFingerprint = defFingerprint;

@@ -270,2 +270,10 @@ import { ObjRef, ObjRefInScope } from "../base";

/**
* Tests whether the attribute elements object is empty.
*
* @param attributeElements - object to test
* @returns true if empty = attribute elements not specified in any way (URI or value)
* @internal
*/
export declare function attributeElementsIsEmpty(attributeElements: AttributeElements): boolean;
/**
* Gets attribute elements for attribute filters.

@@ -272,0 +280,0 @@ *

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
var isEmpty = require("lodash/isEmpty");

@@ -179,2 +179,3 @@ var ts_invariant_1 = __importDefault(require("ts-invariant"));

}
exports.attributeElementsIsEmpty = attributeElementsIsEmpty;
function filterAttributeElements(filter) {

@@ -181,0 +182,0 @@ ts_invariant_1.default(filter, "attribute elements must be specified");

@@ -11,2 +11,3 @@ import { ArithmeticMeasureOperator, IArithmeticMeasureDefinition, IMeasure, IMeasureDefinition, IMeasureDefinitionType, IPoPMeasureDefinition, IPreviousPeriodMeasureDefinition, MeasureAggregation } from "./index";

}
declare type MeasureEnvelope = Omit<IMeasure["measure"], "definition">;
/**

@@ -21,5 +22,5 @@ * Abstract base class for measure builders. Measure builders allow for incremental, fluent construction

*/
export declare abstract class MeasureBuilderBase<T extends IMeasureDefinitionType> implements IMeasure<T> {
measure: IMeasure<T>["measure"];
export declare abstract class MeasureBuilderBase<T extends IMeasureDefinitionType> {
protected customLocalId: boolean;
private measure;
/**

@@ -29,7 +30,35 @@ * @internal

protected constructor();
localId: (localId: string) => this;
alias: (alias: string) => this;
format: (format: string) => this;
localId: (localId: string) => this;
title: (title: string) => this;
build: () => IMeasure<T>;
protected initializeFromExisting(measure: MeasureEnvelope): void;
/**
* Generation of local identifier is a responsibility shared with the the subclass - so that the concrete
* builders can use their concrete definition to provide additional parts of the local id.
*
* @returns local identifier
*/
protected abstract generateLocalId(): string;
/**
* Build of measure definition is responsibility of the subclass.
*
* @returns new instance
*/
protected abstract buildDefinition(): T;
/**
* If custom localId has been set using localId() function, then use it unless it is empty.
*
* In all other cases generate localId. The localId generation consists up from three parts:
*
* - local identifier always starts with letter 'm'
* - IF alias, title or format is specified, it is hashed and first 8 chars of the hash will follow
* - The measure type specific part of the local identifier follows
*
* These three parts are separated using underscore.
*/
private getOrGenerateLocalId;
private buildEnvelopeLocalIdPart;
private buildEnvelope;
}

@@ -44,3 +73,3 @@ /**

export declare class MeasureBuilder extends MeasureBuilderBase<IMeasureDefinition> {
private readonly measureId;
private readonly measureDefinition;
/**

@@ -51,5 +80,14 @@ * @internal

aggregation: (aggregation: MeasureAggregation) => this;
noAggregation: () => this;
ratio: () => this;
noRatio: () => this;
filters: (...filters: (import("../filter").IPositiveAttributeFilter | import("../filter").INegativeAttributeFilter | import("../filter").IAbsoluteDateFilter | import("../filter").IRelativeDateFilter)[]) => this;
protected generateLocalId(): string;
protected buildDefinition(): IMeasureDefinition;
private filterLocalIdString;
}
declare type ArithmeticMeasureBuilderInput = {
measuresOrIds: ReadonlyArray<IMeasure | Identifier>;
operator: ArithmeticMeasureOperator;
} | IMeasure<IArithmeticMeasureDefinition>;
/**

@@ -63,7 +101,14 @@ * Builder for arithmetic measures.

export declare class ArithmeticMeasureBuilder extends MeasureBuilderBase<IArithmeticMeasureDefinition> {
private arithmeticMeasure;
/**
* @internal
*/
constructor(measureIds: Identifier[], operator: ArithmeticMeasureOperator);
constructor(input: ArithmeticMeasureBuilderInput);
protected buildDefinition(): IArithmeticMeasureDefinition;
protected generateLocalId(): string;
}
declare type PoPMeasureBuilderInput = {
measureOrLocalId: IMeasure | Identifier;
popAttrIdOrRef: ObjRef | Identifier;
} | IMeasure<IPoPMeasureDefinition>;
/**

@@ -77,7 +122,14 @@ * Builder for period-over-period measures.

export declare class PoPMeasureBuilder extends MeasureBuilderBase<IPoPMeasureDefinition> {
private popMeasureDefinition;
/**
* @internal
*/
constructor(measureId: Identifier, popAttributeId: Identifier);
constructor(input: PoPMeasureBuilderInput);
protected buildDefinition(): IPoPMeasureDefinition;
protected generateLocalId(): string;
}
declare type PreviousPeriodMeasureBuilderInput = {
measureIdOrLocalId: IMeasure | string;
dateDataSets: IPreviousPeriodDateDataSetSimple[];
} | IMeasure<IPreviousPeriodMeasureDefinition>;
/**

@@ -91,6 +143,9 @@ * Builder for previous period measures.

export declare class PreviousPeriodMeasureBuilder extends MeasureBuilderBase<IPreviousPeriodMeasureDefinition> {
private previousPeriodMeasure;
/**
* @internal
*/
constructor(measureId: string, dateDataSets: IPreviousPeriodDateDataSetSimple[]);
constructor(input: PreviousPeriodMeasureBuilderInput);
protected buildDefinition(): IPreviousPeriodMeasureDefinition;
protected generateLocalId(): string;
}

@@ -111,2 +166,15 @@ /**

/**
* Creates a new measure by applying modifications on top of an existing measure. This generic function can
* accept measure of any type and thus in returns allows modifications on the properties that are common
* in any type of measure.
*
* This operation is immutable and will not alter the input measure.
*
* @param measure - measure to use as template for the new measure
* @param modifications - modifications to apply
* @returns new instance
* @public
*/
export declare function modifyMeasure<T extends IMeasureDefinitionType>(measure: IMeasure<T>, modifications?: MeasureModifications<MeasureBuilderBase<IMeasureDefinitionType>>): IMeasure<T>;
/**
* Creates a new simple measure by applying modifications on top of an existing measure.

@@ -121,3 +189,3 @@ *

*/
export declare function modifyMeasure(measure: IMeasure<IMeasureDefinition>, modifications?: MeasureModifications<MeasureBuilder>): IMeasure<IMeasureDefinition>;
export declare function modifySimpleMeasure(measure: IMeasure<IMeasureDefinition>, modifications?: MeasureModifications<MeasureBuilder>): IMeasure<IMeasureDefinition>;
/**

@@ -134,7 +202,7 @@ * Creates a new arithmetic measure with the specified measure identifiers and operator and optional modifications and localIdentifier.

* @param measureOrLocalId - measure or local identifier of the measure
* @param popAttributeId - identifier of the PoP attribute
* @param popAttrIdOrRef - identifier or a reference to PoP attribute
* @param modifications - optional modifications (e.g. alias, title, etc.)
* @public
*/
export declare function newPopMeasure(measureOrLocalId: IMeasure | Identifier, popAttributeId: string, modifications?: MeasureModifications<PoPMeasureBuilder>): IMeasure<IPoPMeasureDefinition>;
export declare function newPopMeasure(measureOrLocalId: IMeasure | Identifier, popAttrIdOrRef: ObjRef | Identifier, modifications?: MeasureModifications<PoPMeasureBuilder>): IMeasure<IPoPMeasureDefinition>;
/**

@@ -148,1 +216,2 @@ * Creates a new Previous Period measure with the specified measure identifier and date data sets and optional modifications and localIdentifier.

export declare function newPreviousPeriodMeasure(measureIdOrLocalId: IMeasure | Identifier, dateDataSets: IPreviousPeriodDateDataSetSimple[], modifications?: MeasureModifications<PreviousPeriodMeasureBuilder>): IMeasure<IPreviousPeriodMeasureDefinition>;
export {};

@@ -26,5 +26,9 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019-2020 GoodData Corporation
var cloneDeep = require("lodash/cloneDeep");
var isEmpty = require("lodash/isEmpty");
var identity = require("lodash/identity");

@@ -34,2 +38,3 @@ var index_1 = require("./index");

var factory_1 = require("../base/factory");
var spark_md5_1 = __importDefault(require("spark-md5"));
/**

@@ -51,2 +56,7 @@ * Abstract base class for measure builders. Measure builders allow for incremental, fluent construction

this.customLocalId = false;
this.localId = function (localId) {
_this.measure.localIdentifier = localId;
_this.customLocalId = true;
return _this;
};
this.alias = function (alias) {

@@ -60,7 +70,2 @@ _this.measure.alias = alias;

};
this.localId = function (localId) {
_this.measure.localIdentifier = localId;
_this.customLocalId = true;
return _this;
};
this.title = function (title) {

@@ -71,7 +76,46 @@ _this.measure.title = title;

this.build = function () {
return { measure: _this.measure };
var envelope = _this.buildEnvelope();
return {
measure: __assign(__assign({}, envelope), { definition: _this.buildDefinition() }),
};
};
// definition is added in subclass
this.measure = {};
}
MeasureBuilderBase.prototype.initializeFromExisting = function (measure) {
this.measure = cloneDeep(measure);
this.customLocalId = false;
};
/**
* If custom localId has been set using localId() function, then use it unless it is empty.
*
* In all other cases generate localId. The localId generation consists up from three parts:
*
* - local identifier always starts with letter 'm'
* - IF alias, title or format is specified, it is hashed and first 8 chars of the hash will follow
* - The measure type specific part of the local identifier follows
*
* These three parts are separated using underscore.
*/
MeasureBuilderBase.prototype.getOrGenerateLocalId = function () {
if (this.customLocalId && !isEmpty(this.measure.localIdentifier)) {
return this.measure.localIdentifier;
}
return ["m", this.buildEnvelopeLocalIdPart(), this.generateLocalId()]
.filter(function (part) { return !isEmpty(part); })
.join("_");
};
MeasureBuilderBase.prototype.buildEnvelopeLocalIdPart = function () {
var _a = this.measure, alias = _a.alias, format = _a.format, title = _a.title;
if (!alias && !format && !title) {
return "";
}
var hasher = new spark_md5_1.default();
hasher.append("alias_" + ((alias !== null && alias !== void 0 ? alias : "")));
hasher.append("format_" + ((format !== null && format !== void 0 ? format : "")));
hasher.append("title_" + ((title !== null && title !== void 0 ? title : "")));
return hasher.end().substr(0, 8);
};
MeasureBuilderBase.prototype.buildEnvelope = function () {
return __assign(__assign({}, this.measure), { localIdentifier: this.getOrGenerateLocalId() });
};
return MeasureBuilderBase;

@@ -95,12 +139,17 @@ }());

_this.aggregation = function (aggregation) {
_this.measure.definition.measureDefinition.aggregation = aggregation;
if (!_this.customLocalId) {
_this.measure.localIdentifier = "m_" + _this.measureId + "_" + aggregation;
}
_this.measureDefinition.aggregation = aggregation;
return _this;
};
_this.noAggregation = function () {
delete _this.measureDefinition.aggregation;
return _this;
};
_this.ratio = function () {
_this.measure.definition.measureDefinition.computeRatio = true;
_this.measureDefinition.computeRatio = true;
return _this;
};
_this.noRatio = function () {
delete _this.measureDefinition.computeRatio;
return _this;
};
_this.filters = function () {

@@ -111,22 +160,34 @@ var filters = [];

}
_this.measure.definition.measureDefinition.filters = filters;
_this.measureDefinition.filters = filters;
return _this;
};
if (base_1.isObjRef(measureOrRef)) {
_this.measure.definition = {
measureDefinition: {
item: measureOrRef,
},
};
var refValue = base_1.objRefToString(measureOrRef);
_this.measure.localIdentifier = "m_" + refValue;
_this.measureId = refValue;
if (index_1.isMeasure(measureOrRef)) {
_this.initializeFromExisting(measureOrRef.measure);
_this.measureDefinition = cloneDeep(measureOrRef.measure.definition.measureDefinition);
}
else {
_this.measure = cloneDeep(measureOrRef.measure);
_this.customLocalId = true;
_this.measureId = index_1.measureIdentifier(measureOrRef);
_this.measureDefinition = {
item: measureOrRef,
};
}
return _this;
}
MeasureBuilder.prototype.generateLocalId = function () {
var aggString = this.measureDefinition.aggregation ? "_" + this.measureDefinition.aggregation : "";
var ratioString = this.measureDefinition.computeRatio ? "_ratio" : "";
return "" + base_1.objRefToString(this.measureDefinition.item) + aggString + ratioString + this.filterLocalIdString();
};
MeasureBuilder.prototype.buildDefinition = function () {
return {
measureDefinition: this.measureDefinition,
};
};
MeasureBuilder.prototype.filterLocalIdString = function () {
if (isEmpty(this.measureDefinition.filters)) {
return "";
}
var hasher = new spark_md5_1.default();
hasher.append(JSON.stringify(this.measureDefinition.filters));
return "_" + hasher.end().substr(0, 8);
};
return MeasureBuilder;

@@ -147,13 +208,29 @@ }(MeasureBuilderBase));

*/
function ArithmeticMeasureBuilder(measureIds, operator) {
function ArithmeticMeasureBuilder(input) {
var _this = _super.call(this) || this;
_this.measure.definition = {
arithmeticMeasure: {
measureIdentifiers: measureIds,
operator: operator,
},
};
_this.measure.localIdentifier = "m_" + measureIds.join("_");
if (index_1.isArithmeticMeasure(input)) {
_this.initializeFromExisting(input.measure);
_this.arithmeticMeasure = cloneDeep(input.measure.definition.arithmeticMeasure);
}
else {
var measureIdentifiers = input.measuresOrIds.map(function (m) {
return index_1.isMeasure(m) ? index_1.measureLocalId(m) : m;
});
_this.arithmeticMeasure = {
measureIdentifiers: measureIdentifiers,
operator: input.operator,
};
}
return _this;
}
ArithmeticMeasureBuilder.prototype.buildDefinition = function () {
return {
arithmeticMeasure: this.arithmeticMeasure,
};
};
ArithmeticMeasureBuilder.prototype.generateLocalId = function () {
var hasher = new spark_md5_1.default();
this.arithmeticMeasure.measureIdentifiers.forEach(function (id) { return hasher.append(id); });
return hasher.end();
};
return ArithmeticMeasureBuilder;

@@ -174,15 +251,30 @@ }(MeasureBuilderBase));

*/
function PoPMeasureBuilder(measureId, popAttributeId) {
function PoPMeasureBuilder(input) {
var _this = _super.call(this) || this;
_this.measure.definition = {
popMeasureDefinition: {
measureIdentifier: measureId,
popAttribute: {
identifier: popAttributeId,
},
},
};
_this.measure.localIdentifier = "m_" + measureId + "_" + popAttributeId;
if (index_1.isPoPMeasure(input)) {
_this.initializeFromExisting(input.measure);
_this.popMeasureDefinition = cloneDeep(input.measure.definition.popMeasureDefinition);
}
else {
var measureIdentifier = index_1.isMeasure(input.measureOrLocalId)
? index_1.measureLocalId(input.measureOrLocalId)
: input.measureOrLocalId;
var popAttribute = base_1.isObjRef(input.popAttrIdOrRef)
? input.popAttrIdOrRef
: factory_1.idRef(input.popAttrIdOrRef, "attribute");
_this.popMeasureDefinition = {
measureIdentifier: measureIdentifier,
popAttribute: popAttribute,
};
}
return _this;
}
PoPMeasureBuilder.prototype.buildDefinition = function () {
return {
popMeasureDefinition: this.popMeasureDefinition,
};
};
PoPMeasureBuilder.prototype.generateLocalId = function () {
return this.popMeasureDefinition.measureIdentifier + "_" + base_1.objRefToString(this.popMeasureDefinition.popAttribute);
};
return PoPMeasureBuilder;

@@ -203,13 +295,26 @@ }(MeasureBuilderBase));

*/
function PreviousPeriodMeasureBuilder(measureId, dateDataSets) {
function PreviousPeriodMeasureBuilder(input) {
var _this = _super.call(this) || this;
_this.measure.definition = {
previousPeriodMeasure: {
measureIdentifier: measureId,
dateDataSets: dateDataSets.map(function (d) { return (__assign(__assign({}, d), { dataSet: typeof d.dataSet === "string" ? { identifier: d.dataSet } : d.dataSet })); }),
},
};
_this.measure.localIdentifier = "m_" + measureId + "_previous_period";
if (index_1.isPreviousPeriodMeasure(input)) {
_this.initializeFromExisting(input.measure);
_this.previousPeriodMeasure = cloneDeep(input.measure.definition.previousPeriodMeasure);
}
else {
_this.previousPeriodMeasure = {
measureIdentifier: index_1.isMeasure(input.measureIdOrLocalId)
? index_1.measureLocalId(input.measureIdOrLocalId)
: input.measureIdOrLocalId,
dateDataSets: input.dateDataSets.map(function (d) { return (__assign(__assign({}, d), { dataSet: typeof d.dataSet === "string" ? { identifier: d.dataSet } : d.dataSet })); }),
};
}
return _this;
}
PreviousPeriodMeasureBuilder.prototype.buildDefinition = function () {
return {
previousPeriodMeasure: this.previousPeriodMeasure,
};
};
PreviousPeriodMeasureBuilder.prototype.generateLocalId = function () {
return this.previousPeriodMeasure.measureIdentifier + "_previous_period";
};
return PreviousPeriodMeasureBuilder;

@@ -232,3 +337,5 @@ }(MeasureBuilderBase));

/**
* Creates a new simple measure by applying modifications on top of an existing measure.
* Creates a new measure by applying modifications on top of an existing measure. This generic function can
* accept measure of any type and thus in returns allows modifications on the properties that are common
* in any type of measure.
*

@@ -244,7 +351,38 @@ * This operation is immutable and will not alter the input measure.

if (modifications === void 0) { modifications = identity; }
var builder = new MeasureBuilder(measure);
var builder = createBuilder(measure);
return modifications(builder).build();
}
exports.modifyMeasure = modifyMeasure;
function createBuilder(measure) {
if (index_1.isSimpleMeasure(measure)) {
return new MeasureBuilder(measure);
}
else if (index_1.isArithmeticMeasure(measure)) {
return new ArithmeticMeasureBuilder(measure);
}
else if (index_1.isPoPMeasure(measure)) {
return new PoPMeasureBuilder(measure);
}
else if (index_1.isPreviousPeriodMeasure(measure)) {
return new PreviousPeriodMeasureBuilder(measure);
}
throw new Error();
}
/**
* Creates a new simple measure by applying modifications on top of an existing measure.
*
* This operation is immutable and will not alter the input measure.
*
* @param measure - measure to use as template for the new measure
* @param modifications - modifications to apply
* @returns new instance
* @public
*/
function modifySimpleMeasure(measure, modifications) {
if (modifications === void 0) { modifications = identity; }
var builder = new MeasureBuilder(measure);
return modifications(builder).build();
}
exports.modifySimpleMeasure = modifySimpleMeasure;
/**
* Creates a new arithmetic measure with the specified measure identifiers and operator and optional modifications and localIdentifier.

@@ -258,4 +396,3 @@ * @param measuresOrIds - measures or identifiers of the measures to be included in this arithmetic measure

if (modifications === void 0) { modifications = identity; }
var measureIds = measuresOrIds.map(function (m) { return (typeof m === "string" ? m : index_1.measureLocalId(m)); });
var builder = new ArithmeticMeasureBuilder(measureIds, operator);
var builder = new ArithmeticMeasureBuilder({ measuresOrIds: measuresOrIds, operator: operator });
return modifications(builder).build();

@@ -267,10 +404,9 @@ }

* @param measureOrLocalId - measure or local identifier of the measure
* @param popAttributeId - identifier of the PoP attribute
* @param popAttrIdOrRef - identifier or a reference to PoP attribute
* @param modifications - optional modifications (e.g. alias, title, etc.)
* @public
*/
function newPopMeasure(measureOrLocalId, popAttributeId, modifications) {
function newPopMeasure(measureOrLocalId, popAttrIdOrRef, modifications) {
if (modifications === void 0) { modifications = identity; }
var measureId = typeof measureOrLocalId === "string" ? measureOrLocalId : index_1.measureLocalId(measureOrLocalId);
var builder = new PoPMeasureBuilder(measureId, popAttributeId);
var builder = new PoPMeasureBuilder({ measureOrLocalId: measureOrLocalId, popAttrIdOrRef: popAttrIdOrRef });
return modifications(builder).build();

@@ -288,6 +424,5 @@ }

if (modifications === void 0) { modifications = identity; }
var measureId = typeof measureIdOrLocalId === "string" ? measureIdOrLocalId : index_1.measureLocalId(measureIdOrLocalId);
var builder = new PreviousPeriodMeasureBuilder(measureId, dateDataSets);
var builder = new PreviousPeriodMeasureBuilder({ measureIdOrLocalId: measureIdOrLocalId, dateDataSets: dateDataSets });
return modifications(builder).build();
}
exports.newPreviousPeriodMeasure = newPreviousPeriodMeasure;

@@ -236,11 +236,2 @@ import { Identifier, ObjRef } from "../base";

/**
* Disables compute ratio on the provided measure. This is an immutable function - returning new
* measure with the ratio disabled.
*
* @param measure - measure to disable compute ratio for
* @returns new measure with disabled ratio; same measure if ratio was not enabled in the first place
* @public
*/
export declare function measureDisableComputeRatio(measure: IMeasure): IMeasure;
/**
* Gets identifier of master measure for the provided derived measure (PoP measure or Previous Period measure).

@@ -247,0 +238,0 @@ * If the measure is not derived or is derived and does not specify master measure id, then undefined is returned.

@@ -6,6 +6,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
// (C) 2019 GoodData Corporation
var cloneDeep = require("lodash/cloneDeep");
// (C) 2019-2020 GoodData Corporation
var isEmpty = require("lodash/isEmpty");
var unset = require("lodash/unset");
var ts_invariant_1 = __importDefault(require("ts-invariant"));

@@ -170,26 +168,6 @@ var base_1 = require("../base");

}
var computeRatio = measure.measure.definition.measureDefinition.computeRatio;
return computeRatio ? computeRatio : false;
return !!measure.measure.definition.measureDefinition.computeRatio;
}
exports.measureDoesComputeRatio = measureDoesComputeRatio;
/**
* Disables compute ratio on the provided measure. This is an immutable function - returning new
* measure with the ratio disabled.
*
* @param measure - measure to disable compute ratio for
* @returns new measure with disabled ratio; same measure if ratio was not enabled in the first place
* @public
*/
function measureDisableComputeRatio(measure) {
ts_invariant_1.default(measure, "measure must be specified");
if (!measureDoesComputeRatio(measure)) {
return measure;
}
var newItem = cloneDeep(measure);
// I was not able to get any other way working for a while so doing this dirty stuff.
unset(newItem, ["measure", "definition", "measureDefinition", "computeRatio"]);
return newItem;
}
exports.measureDisableComputeRatio = measureDisableComputeRatio;
/**
* Gets identifier of master measure for the provided derived measure (PoP measure or Previous Period measure).

@@ -196,0 +174,0 @@ * If the measure is not derived or is derived and does not specify master measure id, then undefined is returned.

export { IAttribute, isAttribute, attributeLocalId, AttributePredicate, anyAttribute, idMatchAttribute, attributesFind, attributeUri, attributeIdentifier, attributeAlias, attributeAttributeDisplayFormObjRef, } from "./execution/attribute";
export { newAttribute, AttributeBuilder, AttributeModifications } from "./execution/attribute/factory";
export { newAttribute, modifyAttribute, AttributeBuilder, AttributeModifications, } from "./execution/attribute/factory";
export { IAttributeDisplayForm, attributeDisplayFormId, attributeDisplayFormTitle, attributeDisplayFormAttributeId, attributeDisplayFormAttributeUri, } from "./ldm/attributeDisplayForm";

@@ -11,4 +11,4 @@ export { ObjectType, Identifier, Uri, UriRef, IdentifierRef, LocalIdRef, ObjRef, ObjRefInScope, isUriRef, isIdentifierRef, objRefToString, isLocalIdRef, areObjRefsEqual, isObjRef, } from "./execution/base";

export { newAbsoluteDateFilter, newNegativeAttributeFilter, newPositiveAttributeFilter, newRelativeDateFilter, newMeasureValueFilter, } from "./execution/filter/factory";
export { IMeasureTitle, IMeasureDefinitionType, IMeasureDefinition, ArithmeticMeasureOperator, IArithmeticMeasureDefinition, IPoPMeasureDefinition, IMeasure, MeasureAggregation, IPreviousPeriodMeasureDefinition, IPreviousPeriodDateDataSet, isMeasure, isSimpleMeasure, isPoPMeasure, isPreviousPeriodMeasure, isArithmeticMeasure, isMeasureDefinition, isPoPMeasureDefinition, isPreviousPeriodMeasureDefinition, isArithmeticMeasureDefinition, measureLocalId, MeasurePredicate, anyMeasure, idMatchMeasure, measureDoesComputeRatio, measureUri, measureIdentifier, measureMasterIdentifier, measureArithmeticOperands, measureDisableComputeRatio, measureAlias, measureTitle, measureArithmeticOperator, measureFormat, measureAggregation, measureFilters, measurePopAttribute, measurePreviousPeriodDateDataSets, } from "./execution/measure";
export { IPreviousPeriodDateDataSetSimple, ArithmeticMeasureBuilder, MeasureBuilder, MeasureModifications, PoPMeasureBuilder, PreviousPeriodMeasureBuilder, MeasureBuilderBase, newMeasure, modifyMeasure, newArithmeticMeasure, newPopMeasure, newPreviousPeriodMeasure, } from "./execution/measure/factory";
export { IMeasureTitle, IMeasureDefinitionType, IMeasureDefinition, ArithmeticMeasureOperator, IArithmeticMeasureDefinition, IPoPMeasureDefinition, IMeasure, MeasureAggregation, IPreviousPeriodMeasureDefinition, IPreviousPeriodDateDataSet, isMeasure, isSimpleMeasure, isPoPMeasure, isPreviousPeriodMeasure, isArithmeticMeasure, isMeasureDefinition, isPoPMeasureDefinition, isPreviousPeriodMeasureDefinition, isArithmeticMeasureDefinition, measureLocalId, MeasurePredicate, anyMeasure, idMatchMeasure, measureDoesComputeRatio, measureUri, measureIdentifier, measureMasterIdentifier, measureArithmeticOperands, measureAlias, measureTitle, measureArithmeticOperator, measureFormat, measureAggregation, measureFilters, measurePopAttribute, measurePreviousPeriodDateDataSets, } from "./execution/measure";
export { IPreviousPeriodDateDataSetSimple, ArithmeticMeasureBuilder, MeasureBuilder, MeasureModifications, PoPMeasureBuilder, PreviousPeriodMeasureBuilder, MeasureBuilderBase, newMeasure, modifyMeasure, modifySimpleMeasure, newArithmeticMeasure, newPopMeasure, newPreviousPeriodMeasure, } from "./execution/measure/factory";
export { AttributeOrMeasure, IBucket, isBucket, idMatchBucket, anyBucket, MeasureInBucket, AttributeInBucket, newBucket, bucketIsEmpty, bucketAttributes, bucketAttribute, bucketMeasure, bucketMeasures, bucketTotals, bucketItems, BucketPredicate, applyRatioRule, ComputeRatioRule, } from "./execution/buckets";

@@ -15,0 +15,0 @@ export { bucketsFind, bucketsMeasures, bucketsIsEmpty, bucketsAttributes, bucketsFindMeasure, bucketsById, bucketsFindAttribute, bucketsItems, bucketsTotals, } from "./execution/buckets/bucketArray";

@@ -16,2 +16,3 @@ "use strict";

exports.newAttribute = factory_1.newAttribute;
exports.modifyAttribute = factory_1.modifyAttribute;
exports.AttributeBuilder = factory_1.AttributeBuilder;

@@ -101,3 +102,2 @@ var attributeDisplayForm_1 = require("./ldm/attributeDisplayForm");

exports.measureArithmeticOperands = measure_1.measureArithmeticOperands;
exports.measureDisableComputeRatio = measure_1.measureDisableComputeRatio;
exports.measureAlias = measure_1.measureAlias;

@@ -119,2 +119,3 @@ exports.measureTitle = measure_1.measureTitle;

exports.modifyMeasure = factory_4.modifyMeasure;
exports.modifySimpleMeasure = factory_4.modifySimpleMeasure;
exports.newArithmeticMeasure = factory_4.newArithmeticMeasure;

@@ -121,0 +122,0 @@ exports.newPopMeasure = factory_4.newPopMeasure;

@@ -67,5 +67,5 @@ /**

dataHeader: IDataHeader;
dataSetId: string;
datasetId: string;
loadedRowCount: number;
dataSetLoadStatus: DatasetLoadStatus;
datasetLoadStatus: DatasetLoadStatus;
firstSuccessfulUpdate?: IDatasetLoadInfo;

@@ -72,0 +72,0 @@ lastSuccessfulUpdate?: IDatasetLoadInfo;

{
"name": "@gooddata/sdk-model",
"version": "8.0.0-alpha.27",
"version": "8.0.0-alpha.28",
"author": "GoodData",

@@ -33,2 +33,3 @@ "description": "GoodData Model definitions used by UI components and Backend SPI and its implementations",

"dependencies": {
"json-stable-stringify": "^1.0.1",
"lodash": "^4.17.15",

@@ -43,2 +44,3 @@ "spark-md5": "^3.0.0",

"@types/jest": "^25.1.2",
"@types/json-stable-stringify": "^1.0.32",
"@types/lodash": "^4.14.123",

@@ -45,0 +47,0 @@ "@types/node": "^12.12.26",

// (C) 2019-2020 GoodData Corporation
import identity = require("lodash/identity");
import { IAttribute } from "./index";
import cloneDeep = require("lodash/cloneDeep");
import isEmpty = require("lodash/isEmpty");
import { IAttribute, isAttribute } from "./index";
import { ObjRef, objRefToString, Identifier, isObjRef } from "../base";
import { idRef } from "../base/factory";
import SparkMD5 from "spark-md5";
type AttributeBuilderInput = Identifier | ObjRef | IAttribute;
/**

@@ -14,4 +19,5 @@ * Builder for attributes.

*/
export class AttributeBuilder implements IAttribute {
public attribute: IAttribute["attribute"];
export class AttributeBuilder {
private attribute: IAttribute["attribute"];
private customLocalId: boolean = false;

@@ -21,7 +27,14 @@ /**

*/
constructor(displayForm: ObjRef) {
this.attribute = {
displayForm,
localIdentifier: `a_${objRefToString(displayForm)}`,
};
constructor(input: AttributeBuilderInput) {
if (isAttribute(input)) {
this.attribute = cloneDeep(input.attribute);
this.customLocalId = false;
} else {
const displayForm: ObjRef = isObjRef(input) ? input : idRef(input, "displayForm");
this.attribute = {
displayForm,
localIdentifier: "",
};
}
}

@@ -31,2 +44,3 @@

this.attribute.alias = alias;
return this;

@@ -37,2 +51,4 @@ };

this.attribute.localIdentifier = localId;
this.customLocalId = true;
return this;

@@ -42,4 +58,32 @@ };

public build = () => {
return { attribute: this.attribute };
const localIdentifier = this.getOrGenerateLocalId();
return {
attribute: {
...this.attribute,
localIdentifier,
},
};
};
private getOrGenerateLocalId(): string {
if (this.customLocalId && !isEmpty(this.attribute.localIdentifier)) {
return this.attribute.localIdentifier;
}
return ["a", this.calculateAliasHash(), objRefToString(this.attribute.displayForm)]
.filter(part => !isEmpty(part))
.join("_");
}
private calculateAliasHash(): string {
if (!this.attribute.alias) {
return "";
}
const hasher = new SparkMD5();
hasher.append(this.attribute.alias);
return hasher.end().substr(0, 8);
}
}

@@ -56,3 +100,3 @@

* Creates a new attribute with the specified display form ref and optional modifications and localIdentifier.
* @param displayForm - ref or identifier of the attribute display form
* @param displayFormRefOrId - ref or identifier of the attribute display form
* @param modifications - optional modifications (e.g. alias, etc.)

@@ -62,8 +106,24 @@ * @public

export function newAttribute(
displayForm: ObjRef | Identifier,
displayFormRefOrId: ObjRef | Identifier,
modifications: AttributeModifications = identity,
): IAttribute {
const ref = isObjRef(displayForm) ? displayForm : idRef(displayForm);
const builder = new AttributeBuilder(ref);
const builder = new AttributeBuilder(displayFormRefOrId);
return modifications(builder).build();
}
/**
* Allows modification of an existing attribute instance.
*
* @param attribute - attribute to modify
* @param modifications - modification function
* @public
*/
export function modifyAttribute(
attribute: IAttribute,
modifications: AttributeModifications = identity,
): IAttribute {
const builder = new AttributeBuilder(attribute);
return modifications(builder).build();
}

@@ -92,4 +92,8 @@ // (C) 2019-2020 GoodData Corporation

const Scenarios: Array<[string, any, ObjRef]> = [
["return id ref if attribute has id ref", Account.Default, { identifier: "label.account.id" }],
[
"return id ref if attribute has id ref",
Account.Default,
{ identifier: "label.account.id", type: "displayForm" },
],
[
"return uri ref if attribute defined as such",

@@ -96,0 +100,0 @@ UriDefinedAttribute,

@@ -1,18 +0,29 @@

// (C) 2019 GoodData Corporation
import { newAttribute } from "../factory";
// (C) 2019-2020 GoodData Corporation
import { modifyAttribute, newAttribute } from "../factory";
import { Account } from "../../../../__mocks__/model";
describe("attribute factory", () => {
describe("visualizationAttribute", () => {
it("should return a simple attribute", () => {
expect(newAttribute("foo")).toMatchSnapshot();
});
describe("newAttribute", () => {
it("should return a simple attribute", () => {
expect(newAttribute("foo")).toMatchSnapshot();
});
it("should return an attribute with an alias", () => {
expect(newAttribute("foo", a => a.alias("alias"))).toMatchSnapshot();
});
it("should return an attribute with an alias", () => {
expect(newAttribute("foo", a => a.alias("alias"))).toMatchSnapshot();
});
it("should return an attribute with a custom localId", () => {
expect(newAttribute("foo", a => a.localId("custom"))).toMatchSnapshot();
});
it("should return an attribute with a custom localId", () => {
expect(newAttribute("foo", a => a.localId("custom"))).toMatchSnapshot();
});
});
describe("modifyAttribute", () => {
it("should generate new localId if one not provided during modification", () => {
expect(modifyAttribute(Account.Name, m => m.alias("My Account Name"))).toMatchSnapshot();
});
it("should use localId provided during modification", () => {
expect(
modifyAttribute(Account.Name, m => m.alias("My Account Name").localId("my_custom_id")),
).toMatchSnapshot();
});
});

@@ -137,4 +137,4 @@ // (C) 2019-2020 GoodData Corporation

/**
* Retrieves string representation of object reference. This is purely for purposes for representation of
* references in text, debug and test purposes.
* Retrieves string representation of object reference. This is purely for for representation of
* references in text, debug and tests.
*

@@ -147,5 +147,3 @@ * @internal

if (isIdentifierRef(objRef)) {
const typePrefix = objRef.type ? `${objRef.type}_` : "";
return `${typePrefix}${objRef.identifier}`;
return `${objRef.identifier}`;
} else if (isUriRef(objRef)) {

@@ -152,0 +150,0 @@ return objRef.uri;

@@ -1,2 +0,2 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
import isEmpty = require("lodash/isEmpty");

@@ -10,3 +10,3 @@ import { anyAttribute, AttributePredicate, IAttribute, idMatchAttribute, isAttribute } from "../attribute";

isMeasure,
measureDisableComputeRatio,
isSimpleMeasure,
MeasurePredicate,

@@ -16,2 +16,3 @@ } from "../measure";

import invariant from "ts-invariant";
import { modifySimpleMeasure } from "../..";

@@ -345,6 +346,7 @@ /**

function disableComputeRatio<T extends AttributeOrMeasure>(item: T): T {
if (isMeasure(item)) {
return measureDisableComputeRatio(item) as T;
if (isSimpleMeasure(item)) {
return modifySimpleMeasure(item, m => m.noRatio()) as T;
}
return item;
}

@@ -21,3 +21,3 @@ // (C) 2019-2020 GoodData Corporation

import { idMatchMeasure, IMeasure, measureLocalId } from "../../measure";
import { modifyMeasure } from "../../../index";
import { modifySimpleMeasure } from "../../../index";

@@ -230,4 +230,4 @@ describe("newBucket", () => {

describe("applyRatioRule", () => {
const MeasureWithRatio1 = modifyMeasure(Won, m => m.ratio());
const MeasureWithRatio2 = modifyMeasure(Velocity.Avg, m => m.ratio());
const MeasureWithRatio1 = modifySimpleMeasure(Won, m => m.ratio());
const MeasureWithRatio2 = modifySimpleMeasure(Velocity.Avg, m => m.ratio());

@@ -285,3 +285,3 @@ const Scenarios: Array<[string, any, any, any]> = [

it.each(Scenarios)("should return %s", (_desc, itemsArg, ruleArg, expectedResult) => {
it.each(Scenarios)("should %s", (_desc, itemsArg, ruleArg, expectedResult) => {
expect(applyRatioRule(itemsArg, ruleArg)).toEqual(expectedResult);

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

@@ -1,8 +0,6 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
import stringify from "json-stable-stringify";
import invariant from "ts-invariant";
import { IAttribute } from "../attribute";
import { IDimension } from "../base/dimension";
import { SortItem } from "../base/sort";
import { IFilter } from "../filter";
import { IMeasure } from "../measure";

@@ -15,3 +13,3 @@ /**

return JSON.stringify(attribute);
return stringify(attribute);
}

@@ -22,25 +20,4 @@

*/
export function filterFingerprint(filter: IFilter): string {
return JSON.stringify(filter);
}
/**
* @internal
*/
export function measureFingerprint(measure: IMeasure): string {
return JSON.stringify(measure);
}
/**
* @internal
*/
export function dimensionFingerprint(dim: IDimension): string {
return JSON.stringify(dim);
}
/**
* @internal
*/
export function sortFingerprint(sort: SortItem): string {
return JSON.stringify(sort);
return stringify(sort);
}

@@ -1,20 +0,18 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
import isEmpty = require("lodash/isEmpty");
import isString = require("lodash/isString");
import SparkMD5 from "spark-md5";
import invariant from "ts-invariant";
import { mergeFilters } from "../filter/filterMerge";
import {
attributeFingerprint,
dimensionFingerprint,
filterFingerprint,
measureFingerprint,
sortFingerprint,
} from "./fingerprints";
import { IDimension, dimensionTotals } from "../base/dimension";
import { IAttribute } from "../attribute";
import { dimensionTotals, IDimension } from "../base/dimension";
import { SortItem } from "../base/sort";
import { ITotal } from "../base/totals";
import { IAttribute } from "../attribute";
import { IBucket } from "../buckets";
import { IFilter } from "../filter";
import { mergeFilters } from "../filter/filterMerge";
import { IMeasure } from "../measure";
import { measureFingerprint } from "../measure/fingerprint";
import { attributeFingerprint, sortFingerprint } from "./fingerprints";
import { dimensionFingerprint } from "../base/fingerprint";
import { filterFingerprint } from "../filter/fingerprint";

@@ -148,3 +146,6 @@ /**

def.measures.map(measureFingerprint).forEach(hashFun);
def.filters.map(filterFingerprint).forEach(hashFun);
def.filters
.map(filterFingerprint)
.filter(isString)
.forEach(hashFun);
def.sortBy.map(sortFingerprint).forEach(hashFun);

@@ -151,0 +152,0 @@ def.dimensions.map(dimensionFingerprint).forEach(hashFun);

@@ -1,2 +0,2 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
import isEmpty = require("lodash/isEmpty");

@@ -378,3 +378,3 @@ import invariant from "ts-invariant";

*/
function attributeElementsIsEmpty(attributeElements: AttributeElements): boolean {
export function attributeElementsIsEmpty(attributeElements: AttributeElements): boolean {
invariant(attributeElements, "attribute elements must be specified");

@@ -381,0 +381,0 @@

// (C) 2019-2020 GoodData Corporation
import cloneDeep = require("lodash/cloneDeep");
import isEmpty = require("lodash/isEmpty");
import identity = require("lodash/identity");

@@ -13,9 +14,14 @@ import {

IPreviousPeriodMeasureDefinition,
isArithmeticMeasure,
isMeasure,
isPoPMeasure,
isPreviousPeriodMeasure,
isSimpleMeasure,
MeasureAggregation,
measureIdentifier,
measureLocalId,
} from "./index";
import { Identifier, ObjRef, isObjRef, objRefToString } from "../base";
import { Identifier, isObjRef, ObjRef, objRefToString } from "../base";
import { IMeasureFilter } from "../filter";
import { idRef } from "../base/factory";
import SparkMD5 from "spark-md5";

@@ -31,2 +37,4 @@ /**

type MeasureEnvelope = Omit<IMeasure["measure"], "definition">;
/**

@@ -41,5 +49,5 @@ * Abstract base class for measure builders. Measure builders allow for incremental, fluent construction

*/
export abstract class MeasureBuilderBase<T extends IMeasureDefinitionType> implements IMeasure<T> {
public measure: IMeasure<T>["measure"];
export abstract class MeasureBuilderBase<T extends IMeasureDefinitionType> {
protected customLocalId: boolean = false;
private measure: MeasureEnvelope;

@@ -50,6 +58,12 @@ /**

protected constructor() {
// definition is added in subclass
this.measure = {} as any;
}
public localId = (localId: Identifier) => {
this.measure.localIdentifier = localId;
this.customLocalId = true;
return this;
};
public alias = (alias: string) => {

@@ -62,8 +76,3 @@ this.measure.alias = alias;

this.measure.format = format;
return this;
};
public localId = (localId: Identifier) => {
this.measure.localIdentifier = localId;
this.customLocalId = true;
return this;

@@ -74,2 +83,3 @@ };

this.measure.title = title;
return this;

@@ -79,4 +89,74 @@ };

public build = (): IMeasure<T> => {
return { measure: this.measure };
const envelope = this.buildEnvelope();
return {
measure: {
...envelope,
definition: this.buildDefinition(),
},
};
};
protected initializeFromExisting(measure: MeasureEnvelope): void {
this.measure = cloneDeep(measure);
this.customLocalId = false;
}
/**
* Generation of local identifier is a responsibility shared with the the subclass - so that the concrete
* builders can use their concrete definition to provide additional parts of the local id.
*
* @returns local identifier
*/
protected abstract generateLocalId(): string;
/**
* Build of measure definition is responsibility of the subclass.
*
* @returns new instance
*/
protected abstract buildDefinition(): T;
/**
* If custom localId has been set using localId() function, then use it unless it is empty.
*
* In all other cases generate localId. The localId generation consists up from three parts:
*
* - local identifier always starts with letter 'm'
* - IF alias, title or format is specified, it is hashed and first 8 chars of the hash will follow
* - The measure type specific part of the local identifier follows
*
* These three parts are separated using underscore.
*/
private getOrGenerateLocalId(): string {
if (this.customLocalId && !isEmpty(this.measure.localIdentifier)) {
return this.measure.localIdentifier!;
}
return ["m", this.buildEnvelopeLocalIdPart(), this.generateLocalId()]
.filter(part => !isEmpty(part))
.join("_");
}
private buildEnvelopeLocalIdPart(): string {
const { alias, format, title } = this.measure;
if (!alias && !format && !title) {
return "";
}
const hasher = new SparkMD5();
hasher.append("alias_" + (alias ?? ""));
hasher.append("format_" + (format ?? ""));
hasher.append("title_" + (title ?? ""));
return hasher.end().substr(0, 8);
}
private buildEnvelope(): MeasureEnvelope {
return {
...this.measure,
localIdentifier: this.getOrGenerateLocalId(),
};
}
}

@@ -92,3 +172,3 @@

export class MeasureBuilder extends MeasureBuilderBase<IMeasureDefinition> {
private readonly measureId: Identifier;
private readonly measureDefinition: IMeasureDefinition["measureDefinition"];

@@ -101,15 +181,9 @@ /**

if (isObjRef(measureOrRef)) {
this.measure.definition = {
measureDefinition: {
item: measureOrRef,
},
if (isMeasure(measureOrRef)) {
this.initializeFromExisting(measureOrRef.measure);
this.measureDefinition = cloneDeep(measureOrRef.measure.definition.measureDefinition);
} else {
this.measureDefinition = {
item: measureOrRef,
};
const refValue = objRefToString(measureOrRef);
this.measure.localIdentifier = `m_${refValue}`;
this.measureId = refValue;
} else {
this.measure = cloneDeep(measureOrRef.measure);
this.customLocalId = true;
this.measureId = measureIdentifier(measureOrRef)!;
}

@@ -119,20 +193,65 @@ }

public aggregation = (aggregation: MeasureAggregation) => {
this.measure.definition.measureDefinition.aggregation = aggregation;
if (!this.customLocalId) {
this.measure.localIdentifier = `m_${this.measureId}_${aggregation}`;
}
this.measureDefinition.aggregation = aggregation;
return this;
};
public noAggregation = () => {
delete this.measureDefinition.aggregation;
return this;
};
public ratio = () => {
this.measure.definition.measureDefinition.computeRatio = true;
this.measureDefinition.computeRatio = true;
return this;
};
public noRatio = () => {
delete this.measureDefinition.computeRatio;
return this;
};
public filters = (...filters: IMeasureFilter[]) => {
this.measure.definition.measureDefinition.filters = filters;
this.measureDefinition.filters = filters;
return this;
};
protected generateLocalId(): string {
const aggString = this.measureDefinition.aggregation ? `_${this.measureDefinition.aggregation}` : "";
const ratioString = this.measureDefinition.computeRatio ? `_ratio` : "";
return `${objRefToString(
this.measureDefinition.item,
)}${aggString}${ratioString}${this.filterLocalIdString()}`;
}
protected buildDefinition(): IMeasureDefinition {
return {
measureDefinition: this.measureDefinition,
};
}
private filterLocalIdString(): string {
if (isEmpty(this.measureDefinition.filters)) {
return "";
}
const hasher = new SparkMD5();
hasher.append(JSON.stringify(this.measureDefinition.filters));
return "_" + hasher.end().substr(0, 8);
}
}
type ArithmeticMeasureBuilderInput =
| {
measuresOrIds: ReadonlyArray<IMeasure | Identifier>;
operator: ArithmeticMeasureOperator;
}
| IMeasure<IArithmeticMeasureDefinition>;
/**

@@ -146,17 +265,43 @@ * Builder for arithmetic measures.

export class ArithmeticMeasureBuilder extends MeasureBuilderBase<IArithmeticMeasureDefinition> {
private arithmeticMeasure: IArithmeticMeasureDefinition["arithmeticMeasure"];
/**
* @internal
*/
constructor(measureIds: Identifier[], operator: ArithmeticMeasureOperator) {
constructor(input: ArithmeticMeasureBuilderInput) {
super();
this.measure.definition = {
arithmeticMeasure: {
measureIdentifiers: measureIds,
operator,
},
if (isArithmeticMeasure(input)) {
this.initializeFromExisting(input.measure);
this.arithmeticMeasure = cloneDeep(input.measure.definition.arithmeticMeasure);
} else {
const measureIdentifiers: Identifier[] = input.measuresOrIds.map(m =>
isMeasure(m) ? measureLocalId(m) : m,
);
this.arithmeticMeasure = {
measureIdentifiers,
operator: input.operator,
};
}
}
protected buildDefinition(): IArithmeticMeasureDefinition {
return {
arithmeticMeasure: this.arithmeticMeasure,
};
this.measure.localIdentifier = `m_${measureIds.join("_")}`;
}
protected generateLocalId(): string {
const hasher = new SparkMD5();
this.arithmeticMeasure.measureIdentifiers.forEach(id => hasher.append(id));
return hasher.end();
}
}
type PoPMeasureBuilderInput =
| { measureOrLocalId: IMeasure | Identifier; popAttrIdOrRef: ObjRef | Identifier }
| IMeasure<IPoPMeasureDefinition>;
/**

@@ -170,19 +315,48 @@ * Builder for period-over-period measures.

export class PoPMeasureBuilder extends MeasureBuilderBase<IPoPMeasureDefinition> {
private popMeasureDefinition: IPoPMeasureDefinition["popMeasureDefinition"];
/**
* @internal
*/
constructor(measureId: Identifier, popAttributeId: Identifier) {
constructor(input: PoPMeasureBuilderInput) {
super();
this.measure.definition = {
popMeasureDefinition: {
measureIdentifier: measureId,
popAttribute: {
identifier: popAttributeId,
},
},
if (isPoPMeasure(input)) {
this.initializeFromExisting(input.measure);
this.popMeasureDefinition = cloneDeep(input.measure.definition.popMeasureDefinition);
} else {
const measureIdentifier = isMeasure(input.measureOrLocalId)
? measureLocalId(input.measureOrLocalId)
: input.measureOrLocalId;
const popAttribute = isObjRef(input.popAttrIdOrRef)
? input.popAttrIdOrRef
: idRef(input.popAttrIdOrRef, "attribute");
this.popMeasureDefinition = {
measureIdentifier,
popAttribute,
};
}
}
protected buildDefinition(): IPoPMeasureDefinition {
return {
popMeasureDefinition: this.popMeasureDefinition,
};
this.measure.localIdentifier = `m_${measureId}_${popAttributeId}`;
}
protected generateLocalId(): string {
return `${this.popMeasureDefinition.measureIdentifier}_${objRefToString(
this.popMeasureDefinition.popAttribute,
)}`;
}
}
type PreviousPeriodMeasureBuilderInput =
| {
measureIdOrLocalId: IMeasure | string;
dateDataSets: IPreviousPeriodDateDataSetSimple[];
}
| IMeasure<IPreviousPeriodMeasureDefinition>;
/**

@@ -196,11 +370,19 @@ * Builder for previous period measures.

export class PreviousPeriodMeasureBuilder extends MeasureBuilderBase<IPreviousPeriodMeasureDefinition> {
private previousPeriodMeasure: IPreviousPeriodMeasureDefinition["previousPeriodMeasure"];
/**
* @internal
*/
constructor(measureId: string, dateDataSets: IPreviousPeriodDateDataSetSimple[]) {
constructor(input: PreviousPeriodMeasureBuilderInput) {
super();
this.measure.definition = {
previousPeriodMeasure: {
measureIdentifier: measureId,
dateDataSets: dateDataSets.map(
if (isPreviousPeriodMeasure(input)) {
this.initializeFromExisting(input.measure);
this.previousPeriodMeasure = cloneDeep(input.measure.definition.previousPeriodMeasure);
} else {
this.previousPeriodMeasure = {
measureIdentifier: isMeasure(input.measureIdOrLocalId)
? measureLocalId(input.measureIdOrLocalId)
: input.measureIdOrLocalId,
dateDataSets: input.dateDataSets.map(
(d): IPreviousPeriodDateDataSet => ({

@@ -211,6 +393,15 @@ ...d,

),
},
};
}
}
protected buildDefinition(): IPreviousPeriodMeasureDefinition {
return {
previousPeriodMeasure: this.previousPeriodMeasure,
};
this.measure.localIdentifier = `m_${measureId}_previous_period`;
}
protected generateLocalId(): string {
return `${this.previousPeriodMeasure.measureIdentifier}_previous_period`;
}
}

@@ -242,2 +433,37 @@

/**
* Creates a new measure by applying modifications on top of an existing measure. This generic function can
* accept measure of any type and thus in returns allows modifications on the properties that are common
* in any type of measure.
*
* This operation is immutable and will not alter the input measure.
*
* @param measure - measure to use as template for the new measure
* @param modifications - modifications to apply
* @returns new instance
* @public
*/
export function modifyMeasure<T extends IMeasureDefinitionType>(
measure: IMeasure<T>,
modifications: MeasureModifications<MeasureBuilderBase<IMeasureDefinitionType>> = identity,
): IMeasure<T> {
const builder = createBuilder(measure);
return modifications(builder).build() as IMeasure<T>;
}
function createBuilder(measure: IMeasure): MeasureBuilderBase<IMeasureDefinitionType> {
if (isSimpleMeasure(measure)) {
return new MeasureBuilder(measure);
} else if (isArithmeticMeasure(measure)) {
return new ArithmeticMeasureBuilder(measure);
} else if (isPoPMeasure(measure)) {
return new PoPMeasureBuilder(measure);
} else if (isPreviousPeriodMeasure(measure)) {
return new PreviousPeriodMeasureBuilder(measure);
}
throw new Error();
}
/**
* Creates a new simple measure by applying modifications on top of an existing measure.

@@ -252,3 +478,3 @@ *

*/
export function modifyMeasure(
export function modifySimpleMeasure(
measure: IMeasure<IMeasureDefinition>,

@@ -274,4 +500,3 @@ modifications: MeasureModifications<MeasureBuilder> = identity,

): IMeasure<IArithmeticMeasureDefinition> {
const measureIds = measuresOrIds.map(m => (typeof m === "string" ? m : measureLocalId(m)));
const builder = new ArithmeticMeasureBuilder(measureIds, operator);
const builder = new ArithmeticMeasureBuilder({ measuresOrIds, operator });

@@ -284,3 +509,3 @@ return modifications(builder).build();

* @param measureOrLocalId - measure or local identifier of the measure
* @param popAttributeId - identifier of the PoP attribute
* @param popAttrIdOrRef - identifier or a reference to PoP attribute
* @param modifications - optional modifications (e.g. alias, title, etc.)

@@ -291,8 +516,6 @@ * @public

measureOrLocalId: IMeasure | Identifier,
popAttributeId: string,
popAttrIdOrRef: ObjRef | Identifier,
modifications: MeasureModifications<PoPMeasureBuilder> = identity,
): IMeasure<IPoPMeasureDefinition> {
const measureId =
typeof measureOrLocalId === "string" ? measureOrLocalId : measureLocalId(measureOrLocalId);
const builder = new PoPMeasureBuilder(measureId, popAttributeId);
const builder = new PoPMeasureBuilder({ measureOrLocalId, popAttrIdOrRef });

@@ -314,7 +537,5 @@ return modifications(builder).build();

): IMeasure<IPreviousPeriodMeasureDefinition> {
const measureId =
typeof measureIdOrLocalId === "string" ? measureIdOrLocalId : measureLocalId(measureIdOrLocalId);
const builder = new PreviousPeriodMeasureBuilder(measureId, dateDataSets);
const builder = new PreviousPeriodMeasureBuilder({ measureIdOrLocalId, dateDataSets });
return modifications(builder).build();
}

@@ -1,5 +0,3 @@

// (C) 2019 GoodData Corporation
import cloneDeep = require("lodash/cloneDeep");
// (C) 2019-2020 GoodData Corporation
import isEmpty = require("lodash/isEmpty");
import unset = require("lodash/unset");
import invariant from "ts-invariant";

@@ -333,29 +331,6 @@ import { Identifier, isIdentifierRef, isUriRef, ObjRef } from "../base";

const computeRatio = measure.measure.definition.measureDefinition.computeRatio;
return computeRatio ? computeRatio : false;
return !!measure.measure.definition.measureDefinition.computeRatio;
}
/**
* Disables compute ratio on the provided measure. This is an immutable function - returning new
* measure with the ratio disabled.
*
* @param measure - measure to disable compute ratio for
* @returns new measure with disabled ratio; same measure if ratio was not enabled in the first place
* @public
*/
export function measureDisableComputeRatio(measure: IMeasure): IMeasure {
invariant(measure, "measure must be specified");
if (!measureDoesComputeRatio(measure)) {
return measure;
}
const newItem: IMeasure = cloneDeep(measure);
// I was not able to get any other way working for a while so doing this dirty stuff.
unset(newItem, ["measure", "definition", "measureDefinition", "computeRatio"]);
return newItem;
}
/**
* Gets identifier of master measure for the provided derived measure (PoP measure or Previous Period measure).

@@ -362,0 +337,0 @@ * If the measure is not derived or is derived and does not specify master measure id, then undefined is returned.

@@ -1,2 +0,2 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
import { Velocity, Won } from "../../../../__mocks__/model";

@@ -6,2 +6,3 @@ import { newPositiveAttributeFilter } from "../../filter/factory";

modifyMeasure,
modifySimpleMeasure,
newArithmeticMeasure,

@@ -12,10 +13,4 @@ newMeasure,

} from "../factory";
import {
IMeasure,
IMeasureDefinition,
IArithmeticMeasureDefinition,
IPoPMeasureDefinition,
IPreviousPeriodMeasureDefinition,
measureLocalId,
} from "../index";
import { measureLocalId } from "../index";
import { idRef } from "../../base/factory";

@@ -25,137 +20,26 @@ describe("measure factories", () => {

it("should return a simple measure", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
},
},
localIdentifier: "m_foo",
},
};
expect(newMeasure("foo")).toEqual(expected);
expect(newMeasure("foo")).toMatchSnapshot();
});
it("should return a simple measure with different aggregation", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
aggregation: "sum",
},
},
localIdentifier: "m_foo_sum",
},
};
expect(newMeasure("foo", m => m.aggregation("sum"))).toEqual(expected);
expect(newMeasure("foo", m => m.aggregation("sum"))).toMatchSnapshot();
});
it("should honor custom-set localId for simple measures with aggregation", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
aggregation: "sum",
},
},
localIdentifier: "bar",
},
};
expect(newMeasure("foo", m => m.localId("bar").aggregation("sum"))).toEqual(expected);
expect(newMeasure("foo", m => m.localId("bar").aggregation("sum"))).toMatchSnapshot();
});
it("should return a measure with alias", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
alias: "bar",
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
},
},
localIdentifier: "m_foo",
},
};
expect(newMeasure("foo", m => m.alias("bar"))).toEqual(expected);
expect(newMeasure("foo", m => m.alias("bar"))).toMatchSnapshot();
});
it("should return a measure with custom localIdentifier", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
},
},
localIdentifier: "custom",
},
};
expect(newMeasure("foo", m => m.localId("custom"))).toEqual(expected);
expect(newMeasure("foo", m => m.localId("custom"))).toMatchSnapshot();
});
it("should return a measure with format", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
},
},
format: "bar",
localIdentifier: "m_foo",
},
};
expect(newMeasure("foo", m => m.format("bar"))).toEqual(expected);
expect(newMeasure("foo", m => m.format("bar"))).toMatchSnapshot();
});
it("should return a measure with title", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
title: "bar",
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
},
},
localIdentifier: "m_foo",
},
};
expect(newMeasure("foo", m => m.title("bar"))).toEqual(expected);
expect(newMeasure("foo", m => m.title("bar"))).toMatchSnapshot();
});
it("should return a measure with a filter", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "foo",
},
filters: [
{
positiveAttributeFilter: {
displayForm: {
identifier: "filter",
},
in: { uris: ["baz"] },
},
},
],
},
},
localIdentifier: "m_foo",
},
};
expect(
newMeasure("foo", m => m.filters(newPositiveAttributeFilter("filter", { uris: ["baz"] }))),
).toEqual(expected);
).toMatchSnapshot();
});

@@ -173,36 +57,25 @@ });

it("should create new measure with modified local id", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "measure1",
},
},
},
localIdentifier: "measure2",
},
};
it("should generate new local id when not explicitly specified", () => {
const newMeasure = modifyMeasure(ExistingMeasure);
expect(modifyMeasure(ExistingMeasure, m => m.localId("measure2"))).toEqual(expected);
expect(measureLocalId(ExistingMeasure)).not.toEqual(measureLocalId(newMeasure));
});
it("should create new measure with modified aggregation and same local id", () => {
const expected: IMeasure<IMeasureDefinition> = {
measure: {
definition: {
measureDefinition: {
item: {
identifier: "measure1",
},
aggregation: "min",
},
},
localIdentifier: "measure1",
},
};
it("should create new measure with modified local id", () => {
expect(modifyMeasure(ExistingMeasure, m => m.localId("measure2"))).toMatchSnapshot();
});
});
expect(modifyMeasure(ExistingMeasure, m => m.aggregation("min"))).toEqual(expected);
describe("modifySimpleMeasure", () => {
const ExistingMeasure = newMeasure("measure1", m => m.localId("measure1"));
it("should create new measure with modified aggregation and generated local id", () => {
expect(modifySimpleMeasure(ExistingMeasure, m => m.aggregation("min"))).toMatchSnapshot();
});
it("should create new measure with modified aggregation and custom local id", () => {
expect(
modifySimpleMeasure(ExistingMeasure, m => m.aggregation("min").localId("customLocalId")),
).toMatchSnapshot();
});
});

@@ -212,29 +85,7 @@

it("should return a simple arithmetic measure", () => {
const expected: IMeasure<IArithmeticMeasureDefinition> = {
measure: {
definition: {
arithmeticMeasure: {
measureIdentifiers: ["foo", "bar"],
operator: "sum",
},
},
localIdentifier: "m_foo_bar",
},
};
expect(newArithmeticMeasure(["foo", "bar"], "sum")).toEqual(expected);
expect(newArithmeticMeasure(["foo", "bar"], "sum")).toMatchSnapshot();
});
it("should return a simple arithmetic measure from two measure objects", () => {
const expected: IMeasure<IArithmeticMeasureDefinition> = {
measure: {
definition: {
arithmeticMeasure: {
measureIdentifiers: ["m_afSEwRwdbMeQ", "m_fact.stagehistory.velocity_min"],
operator: "sum",
},
},
localIdentifier: "m_m_afSEwRwdbMeQ_m_fact.stagehistory.velocity_min",
},
};
expect(newArithmeticMeasure([Won, Velocity.Min], "sum")).toEqual(expected);
expect(newArithmeticMeasure([Won, Velocity.Min], "sum")).toMatchSnapshot();
});

@@ -244,31 +95,13 @@ });

describe("newPopMeasure", () => {
it("should return a simple PoP measure", () => {
const expected: IMeasure<IPoPMeasureDefinition> = {
measure: {
definition: {
popMeasureDefinition: {
measureIdentifier: "foo",
popAttribute: { identifier: "attr" },
},
},
localIdentifier: "m_foo_attr",
},
};
expect(newPopMeasure("foo", "attr")).toEqual(expected);
it("should return a simple PoP measure from shorthand attribute identifier", () => {
expect(newPopMeasure("foo", "attr")).toMatchSnapshot();
});
it("should return a simple PoP measure object", () => {
const expected: IMeasure<IPoPMeasureDefinition> = {
measure: {
definition: {
popMeasureDefinition: {
measureIdentifier: "m_afSEwRwdbMeQ",
popAttribute: { identifier: "attr" },
},
},
localIdentifier: "m_m_afSEwRwdbMeQ_attr",
},
};
expect(newPopMeasure(Won, "attr")).toEqual(expected);
it("should return a simple PoP measure from attribute ref", () => {
expect(newPopMeasure("foo", idRef("attr"))).toMatchSnapshot();
});
it("should return a simple PoP measure from other measure object", () => {
expect(newPopMeasure(Won, "attr")).toMatchSnapshot();
});
});

@@ -278,31 +111,9 @@

it("should return a simple PP measure when supplied with strings", () => {
const expected: IMeasure<IPreviousPeriodMeasureDefinition> = {
measure: {
definition: {
previousPeriodMeasure: {
measureIdentifier: "foo",
dateDataSets: [{ dataSet: { identifier: "bar" }, periodsAgo: 3 }],
},
},
localIdentifier: "m_foo_previous_period",
},
};
expect(newPreviousPeriodMeasure("foo", [{ dataSet: "bar", periodsAgo: 3 }])).toEqual(expected);
expect(newPreviousPeriodMeasure("foo", [{ dataSet: "bar", periodsAgo: 3 }])).toMatchSnapshot();
});
it("should return a simple PP measure when supplied with objects", () => {
const expected: IMeasure<IPreviousPeriodMeasureDefinition> = {
measure: {
definition: {
previousPeriodMeasure: {
measureIdentifier: "m_afSEwRwdbMeQ",
dateDataSets: [{ dataSet: { identifier: "bar" }, periodsAgo: 3 }],
},
},
localIdentifier: "m_m_afSEwRwdbMeQ_previous_period",
},
};
expect(newPreviousPeriodMeasure(Won, [{ dataSet: "bar", periodsAgo: 3 }])).toEqual(expected);
expect(newPreviousPeriodMeasure(Won, [{ dataSet: "bar", periodsAgo: 3 }])).toMatchSnapshot();
});
});
});
// (C) 2019-2020 GoodData Corporation
import { Velocity, Won } from "../../../../__mocks__/model";
import { modifyMeasure, newArithmeticMeasure, newPopMeasure, newPreviousPeriodMeasure } from "../factory";
import {
measureLocalId,
measureUri,
measureIdentifier,
measureDoesComputeRatio,
measureMasterIdentifier,
modifyMeasure,
modifySimpleMeasure,
newArithmeticMeasure,
newPopMeasure,
newPreviousPeriodMeasure,
} from "../factory";
import {
IPreviousPeriodDateDataSet,
measureAggregation,
measureAlias,
measureArithmeticOperands,
measureArithmeticOperator,
measureAlias,
measureTitle,
measureDoesComputeRatio,
measureFilters,
measureFormat,
measureAggregation,
measureIdentifier,
measureLocalId,
measureMasterIdentifier,
measurePopAttribute,
measurePreviousPeriodDateDataSets,
IPreviousPeriodDateDataSet,
measureFilters,
measureTitle,
measureUri,
} from "../index";

@@ -28,6 +34,6 @@ import { ObjRef } from "../../base";

const SimpleMeasureWithIdentifier = Won;
const SimpleMeasureWithRatio = modifyMeasure(Won, m => m.ratio());
const SimpleMeasureWithUri = modifyMeasure(Won);
const SimpleMeasureWithRatio = modifySimpleMeasure(Won, m => m.ratio());
const SimpleMeasureWithUri = modifySimpleMeasure(Won);
SimpleMeasureWithUri.measure.definition.measureDefinition.item = { uri: "/uri" };
const SimpleMeasureWithFilters = modifyMeasure(Won, m =>
const SimpleMeasureWithFilters = modifySimpleMeasure(Won, m =>
m.filters(newPositiveAttributeFilter(idRef("myAttribute"), ["foo"])),

@@ -203,3 +209,5 @@ );

describe("measureAggregation", () => {
const MeasureWithAggregation = modifyMeasure(SimpleMeasureWithIdentifier, m => m.aggregation("median"));
const MeasureWithAggregation = modifySimpleMeasure(SimpleMeasureWithIdentifier, m =>
m.aggregation("median"),
);
const Scenarios: Array<[string, any, string | undefined]> = [

@@ -248,3 +256,3 @@ ["undefined for measure without aggregation", SimpleMeasureWithIdentifier, undefined],

["undefined for measure without PoP attribute", SimpleMeasureWithIdentifier, undefined],
["PoP attribute value when defined", PopMeasure, { identifier: "myPopAttribute" }],
["PoP attribute value when defined", PopMeasure, { identifier: "myPopAttribute", type: "attribute" }],
];

@@ -251,0 +259,0 @@

@@ -17,3 +17,8 @@ // (C) 2019-2020 GoodData Corporation

export { newAttribute, AttributeBuilder, AttributeModifications } from "./execution/attribute/factory";
export {
newAttribute,
modifyAttribute,
AttributeBuilder,
AttributeModifications,
} from "./execution/attribute/factory";

@@ -161,3 +166,2 @@ export {

measureArithmeticOperands,
measureDisableComputeRatio,
measureAlias,

@@ -183,2 +187,3 @@ measureTitle,

modifyMeasure,
modifySimpleMeasure,
newArithmeticMeasure,

@@ -185,0 +190,0 @@ newPopMeasure,

@@ -1,2 +0,2 @@

// (C) 2019 GoodData Corporation
// (C) 2019-2020 GoodData Corporation
/**

@@ -74,5 +74,5 @@ * Represents the current status of CSV source.

dataHeader: IDataHeader;
dataSetId: string;
datasetId: string;
loadedRowCount: number;
dataSetLoadStatus: DatasetLoadStatus;
datasetLoadStatus: DatasetLoadStatus;
firstSuccessfulUpdate?: IDatasetLoadInfo;

@@ -79,0 +79,0 @@ lastSuccessfulUpdate?: IDatasetLoadInfo;

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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