UNPKG

@gooddata/gooddata-js

Version:
68 lines (53 loc) 1.75 kB
// (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"); }