@gooddata/gooddata-js
Version:
GoodData JavaScript SDK
68 lines (53 loc) • 1.75 kB
text/typescript
// (C) 2007-2018 GoodData Corporation
import difference from "lodash/difference";
import map from "lodash/map";
const IDENTIFIER_REGEX = /{\S+}/g;
export interface IMetric {
// TODO
metricDefinition: {
expression: string;
identifier: string;
};
}
function getDependencies({ metricDefinition }: IMetric) {
return (metricDefinition.expression.match(IDENTIFIER_REGEX) || []).map((s: string) =>
s.substring(1, s.length - 1),
);
}
function getIdentifier({ metricDefinition }: IMetric) {
return metricDefinition.identifier;
}
function resolvedDependencies(resolved: any[], { dependencies }: any) {
const identifiers = map(resolved, "identifier");
return difference(dependencies, identifiers).length === 0;
}
function scan(resolved: any[], unresolved: any[]) {
for (let i = 0; i < unresolved.length; i += 1) {
const tested = unresolved[i];
if (resolvedDependencies(resolved, tested)) {
resolved.push(tested);
unresolved.splice(i, 1);
i -= 1;
}
}
}
function sort(unresolved: any[]) {
const resolved: any[] = [];
let lastLength;
while (unresolved.length > 0) {
lastLength = unresolved.length;
scan(resolved, unresolved);
if (unresolved.length === lastLength) {
throw new Error("Metric defintions cannot be sorted due to missing dependencies.");
}
}
return resolved;
}
export function sortDefinitions(definitions: any[]) {
const indexed = definitions.map((definition: any) => ({
definition,
identifier: getIdentifier(definition),
dependencies: getDependencies(definition),
}));
return map(sort(indexed), "definition");
}