@lightdash/common 0.1397.2 → 0.1399.0
Sign up to get free protection for your applications and to get access to all the features.
package/dist/types/catalog.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { type CompiledExploreJoin, type
|
2
|
-
import { type CompiledDimension, type CompiledMetric, type Dimension, type Field, type FieldType } from './field';
|
1
|
+
import { type CompiledExploreJoin, type Explore, type ExploreError, type InlineError } from './explore';
|
2
|
+
import { DimensionType, type CompiledDimension, type CompiledMetric, type Dimension, type Field, type FieldType } from './field';
|
3
3
|
import type { KnexPaginatedData } from './knex-paginate';
|
4
4
|
import { type ChartSummary } from './savedCharts';
|
5
5
|
import { type TableBase } from './table';
|
@@ -70,7 +70,14 @@ export type ApiMetricsCatalog = {
|
|
70
70
|
status: 'ok';
|
71
71
|
results: KnexPaginatedData<ApiMetricsCatalogResults>;
|
72
72
|
};
|
73
|
-
export type MetricWithAssociatedTimeDimension = CompiledMetric &
|
73
|
+
export type MetricWithAssociatedTimeDimension = CompiledMetric & {
|
74
|
+
timeDimension: (CompiledMetric['defaultTimeDimension'] & {
|
75
|
+
table: string;
|
76
|
+
}) | undefined;
|
77
|
+
availableTimeDimensions?: (CompiledDimension & {
|
78
|
+
type: DimensionType.DATE | DimensionType.TIMESTAMP;
|
79
|
+
})[];
|
80
|
+
};
|
74
81
|
export type ApiGetMetricPeek = {
|
75
82
|
status: 'ok';
|
76
83
|
results: MetricWithAssociatedTimeDimension;
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { type MetricWithAssociatedTimeDimension } from './catalog';
|
1
2
|
import type { ItemsMap } from './field';
|
2
3
|
import type { ResultRow } from './results';
|
3
4
|
export declare enum MetricExplorerComparison {
|
@@ -13,6 +14,7 @@ export type MetricExplorerComparisonType = {
|
|
13
14
|
type: MetricExplorerComparison.PREVIOUS_PERIOD;
|
14
15
|
} | {
|
15
16
|
type: MetricExplorerComparison.DIFFERENT_METRIC;
|
17
|
+
metricTable: string;
|
16
18
|
metricName: string;
|
17
19
|
};
|
18
20
|
export type MetricExploreDataPoint = {
|
@@ -21,6 +23,7 @@ export type MetricExploreDataPoint = {
|
|
21
23
|
compareMetric: unknown;
|
22
24
|
};
|
23
25
|
export type MetricsExplorerQueryResults = {
|
26
|
+
metric: MetricWithAssociatedTimeDimension;
|
24
27
|
rows: ResultRow[];
|
25
28
|
comparisonRows: ResultRow[] | undefined;
|
26
29
|
fields: ItemsMap;
|
@@ -1,10 +1,12 @@
|
|
1
1
|
import type { MetricWithAssociatedTimeDimension } from '../types/catalog';
|
2
2
|
import { ConditionalOperator } from '../types/conditionalRule';
|
3
|
+
import { type CompiledTable } from '../types/explore';
|
3
4
|
import type { Dimension } from '../types/field';
|
5
|
+
import { DimensionType, type CompiledDimension, type CompiledMetric } from '../types/field';
|
4
6
|
import { type DateFilterSettings, type FieldTarget, type FilterRule } from '../types/filter';
|
5
|
-
import type
|
7
|
+
import { type MetricExploreDataPoint, type MetricExplorerComparisonType, type MetricExplorerDateRange } from '../types/metricsExplorer';
|
6
8
|
import type { ResultRow } from '../types/results';
|
7
|
-
import { TimeFrames } from '../types/timeFrames';
|
9
|
+
import { TimeFrames, type DefaultTimeDimension } from '../types/timeFrames';
|
8
10
|
type DateFilter = FilterRule<ConditionalOperator, FieldTarget, unknown, DateFilterSettings>;
|
9
11
|
type ImpelemntedTimeframe = TimeFrames.DAY | TimeFrames.WEEK | TimeFrames.MONTH | TimeFrames.YEAR;
|
10
12
|
export declare const getFieldIdForDateDimension: (fieldId: string, timeframe: TimeFrames) => string;
|
@@ -13,7 +15,7 @@ export declare const oneYearForward: (date: Date) => Date;
|
|
13
15
|
export declare const getGrainForDateRange: (dateRange: [Date, Date]) => ImpelemntedTimeframe;
|
14
16
|
export declare const getMetricExplorerDateRangeFilters: (exploreName: string, dimensionName: string, dateRange: MetricExplorerDateRange) => DateFilter[];
|
15
17
|
export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[]) => Array<MetricExploreDataPoint>;
|
16
|
-
export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[],
|
18
|
+
export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], comparison: MetricExplorerComparisonType) => Array<MetricExploreDataPoint>;
|
17
19
|
/**
|
18
20
|
* Get the date range for a given time interval, based on the current date and the time interval
|
19
21
|
* Time grain Year: -> past 5 years (i.e. 5 completed years + this uncompleted year)
|
@@ -24,4 +26,17 @@ export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimensi
|
|
24
26
|
* @returns The date range
|
25
27
|
*/
|
26
28
|
export declare const getDefaultDateRangeFromInterval: (timeInterval: TimeFrames) => MetricExplorerDateRange;
|
29
|
+
/**
|
30
|
+
* Default time interval to use when no time interval is provided.
|
31
|
+
* For example, when there is no default time dimension defined for a metric or table.
|
32
|
+
*/
|
33
|
+
export declare const DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = TimeFrames.MONTH;
|
34
|
+
export type TimeDimensionConfig = DefaultTimeDimension & {
|
35
|
+
table: string;
|
36
|
+
};
|
37
|
+
export declare const getFirstAvailableTimeDimension: (metric: MetricWithAssociatedTimeDimension) => TimeDimensionConfig | undefined;
|
38
|
+
export declare const getDefaultTimeDimension: (metric: CompiledMetric, table?: CompiledTable) => DefaultTimeDimension | undefined;
|
39
|
+
export declare const getAvailableTimeDimensionsFromTables: (tables: Record<string, CompiledTable>) => (CompiledDimension & {
|
40
|
+
type: DimensionType.DATE | DimensionType.TIMESTAMP;
|
41
|
+
})[];
|
27
42
|
export {};
|
@@ -1,11 +1,13 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.oneYearForward = exports.oneYearBack = exports.getFieldIdForDateDimension = void 0;
|
3
|
+
exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.oneYearForward = exports.oneYearBack = exports.getFieldIdForDateDimension = void 0;
|
4
4
|
const tslib_1 = require("tslib");
|
5
5
|
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
6
6
|
const lodash_1 = require("lodash");
|
7
7
|
const uuid_1 = require("uuid");
|
8
8
|
const conditionalRule_1 = require("../types/conditionalRule");
|
9
|
+
const field_1 = require("../types/field");
|
10
|
+
const metricsExplorer_1 = require("../types/metricsExplorer");
|
9
11
|
const timeFrames_1 = require("../types/timeFrames");
|
10
12
|
const assertUnreachable_1 = tslib_1.__importDefault(require("./assertUnreachable"));
|
11
13
|
const item_1 = require("./item");
|
@@ -105,22 +107,33 @@ const getMetricExplorerDataPoints = (dimension, metric, metricRows) => {
|
|
105
107
|
}));
|
106
108
|
};
|
107
109
|
exports.getMetricExplorerDataPoints = getMetricExplorerDataPoints;
|
108
|
-
const getMetricExplorerDataPointsWithCompare = (dimension, metric, metricRows, compareMetricRows,
|
110
|
+
const getMetricExplorerDataPointsWithCompare = (dimension, metric, metricRows, compareMetricRows, comparison) => {
|
111
|
+
if (comparison.type === metricsExplorer_1.MetricExplorerComparison.NONE) {
|
112
|
+
throw new Error('Comparison type is required');
|
113
|
+
}
|
109
114
|
const dimensionId = (0, item_1.getItemId)(dimension);
|
110
115
|
const metricId = (0, item_1.getItemId)(metric);
|
111
116
|
const mapDateField = (row) => new Date(String(row[dimensionId].value.raw)).toString();
|
112
117
|
const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => mapDateField(row));
|
113
118
|
const groupByCompareMetricRows = (0, lodash_1.groupBy)(compareMetricRows, (row) => mapDateField(row));
|
114
|
-
const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) =>
|
119
|
+
const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => comparison.type === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
|
120
|
+
? (0, exports.oneYearForward)(new Date(date)).toString()
|
121
|
+
: date);
|
115
122
|
const dates = new Set([
|
116
123
|
...Object.keys(groupByMetricRows),
|
117
124
|
...Object.keys(offsetGroupByCompareMetricRows),
|
118
125
|
]);
|
126
|
+
const compareMetricId = comparison.type === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
|
127
|
+
? metricId
|
128
|
+
: (0, item_1.getItemId)({
|
129
|
+
table: comparison.metricTable,
|
130
|
+
name: comparison.metricName,
|
131
|
+
});
|
119
132
|
return Array.from(dates).map((date) => ({
|
120
133
|
date: new Date(date),
|
121
134
|
metric: groupByMetricRows[date]?.[0]?.[metricId]?.value.raw ?? null,
|
122
|
-
compareMetric: offsetGroupByCompareMetricRows[date]?.[0]?.[
|
123
|
-
null,
|
135
|
+
compareMetric: offsetGroupByCompareMetricRows[date]?.[0]?.[compareMetricId]?.value
|
136
|
+
.raw ?? null,
|
124
137
|
}));
|
125
138
|
};
|
126
139
|
exports.getMetricExplorerDataPointsWithCompare = getMetricExplorerDataPointsWithCompare;
|
@@ -161,3 +174,50 @@ const getDefaultDateRangeFromInterval = (timeInterval) => {
|
|
161
174
|
}
|
162
175
|
};
|
163
176
|
exports.getDefaultDateRangeFromInterval = getDefaultDateRangeFromInterval;
|
177
|
+
/**
|
178
|
+
* Default time interval to use when no time interval is provided.
|
179
|
+
* For example, when there is no default time dimension defined for a metric or table.
|
180
|
+
*/
|
181
|
+
exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = timeFrames_1.TimeFrames.MONTH;
|
182
|
+
const getFirstAvailableTimeDimension = (metric) => {
|
183
|
+
if (metric.availableTimeDimensions &&
|
184
|
+
metric.availableTimeDimensions.length > 0) {
|
185
|
+
return {
|
186
|
+
table: metric.availableTimeDimensions[0].table,
|
187
|
+
field: metric.availableTimeDimensions[0].name,
|
188
|
+
interval: exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL,
|
189
|
+
};
|
190
|
+
}
|
191
|
+
return undefined;
|
192
|
+
};
|
193
|
+
exports.getFirstAvailableTimeDimension = getFirstAvailableTimeDimension;
|
194
|
+
const getDefaultTimeDimension = (metric, table) => {
|
195
|
+
// Priority 1: Use metric-level default time dimension if defined in yml
|
196
|
+
if (metric.defaultTimeDimension) {
|
197
|
+
return metric.defaultTimeDimension;
|
198
|
+
}
|
199
|
+
// Priority 2: Use model-level default time dimension if defined in yml
|
200
|
+
if (table?.defaultTimeDimension) {
|
201
|
+
return table.defaultTimeDimension;
|
202
|
+
}
|
203
|
+
// Priority 3: Use the only time dimension if there's exactly one
|
204
|
+
if (table?.dimensions) {
|
205
|
+
const timeDimensions = Object.values(table.dimensions).filter((dim) => (dim.type === field_1.DimensionType.DATE ||
|
206
|
+
dim.type === field_1.DimensionType.TIMESTAMP) &&
|
207
|
+
!!dim.isIntervalBase &&
|
208
|
+
!dim.hidden);
|
209
|
+
if (timeDimensions.length === 1) {
|
210
|
+
return {
|
211
|
+
field: timeDimensions[0].name,
|
212
|
+
interval: exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL,
|
213
|
+
};
|
214
|
+
}
|
215
|
+
}
|
216
|
+
return undefined;
|
217
|
+
};
|
218
|
+
exports.getDefaultTimeDimension = getDefaultTimeDimension;
|
219
|
+
const getAvailableTimeDimensionsFromTables = (tables) => Object.values(tables).flatMap((table) => Object.values(table.dimensions).filter((dim) => (dim.type === field_1.DimensionType.DATE ||
|
220
|
+
dim.type === field_1.DimensionType.TIMESTAMP) &&
|
221
|
+
!!dim.isIntervalBase &&
|
222
|
+
!dim.hidden));
|
223
|
+
exports.getAvailableTimeDimensionsFromTables = getAvailableTimeDimensionsFromTables;
|