@lightdash/common 0.1397.1 → 0.1398.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
- import { type CompiledExploreJoin, type CompiledTable, type Explore, type ExploreError, type InlineError } from './explore';
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 & Pick<CompiledTable, 'defaultTimeDimension'>;
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 {
@@ -21,6 +22,7 @@ export type MetricExploreDataPoint = {
21
22
  compareMetric: unknown;
22
23
  };
23
24
  export type MetricsExplorerQueryResults = {
25
+ metric: MetricWithAssociatedTimeDimension;
24
26
  rows: ResultRow[];
25
27
  comparisonRows: ResultRow[] | undefined;
26
28
  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
7
  import type { MetricExploreDataPoint, 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;
@@ -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,12 @@
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");
9
10
  const timeFrames_1 = require("../types/timeFrames");
10
11
  const assertUnreachable_1 = tslib_1.__importDefault(require("./assertUnreachable"));
11
12
  const item_1 = require("./item");
@@ -161,3 +162,50 @@ const getDefaultDateRangeFromInterval = (timeInterval) => {
161
162
  }
162
163
  };
163
164
  exports.getDefaultDateRangeFromInterval = getDefaultDateRangeFromInterval;
165
+ /**
166
+ * Default time interval to use when no time interval is provided.
167
+ * For example, when there is no default time dimension defined for a metric or table.
168
+ */
169
+ exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = timeFrames_1.TimeFrames.MONTH;
170
+ const getFirstAvailableTimeDimension = (metric) => {
171
+ if (metric.availableTimeDimensions &&
172
+ metric.availableTimeDimensions.length > 0) {
173
+ return {
174
+ table: metric.availableTimeDimensions[0].table,
175
+ field: metric.availableTimeDimensions[0].name,
176
+ interval: exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL,
177
+ };
178
+ }
179
+ return undefined;
180
+ };
181
+ exports.getFirstAvailableTimeDimension = getFirstAvailableTimeDimension;
182
+ const getDefaultTimeDimension = (metric, table) => {
183
+ // Priority 1: Use metric-level default time dimension if defined in yml
184
+ if (metric.defaultTimeDimension) {
185
+ return metric.defaultTimeDimension;
186
+ }
187
+ // Priority 2: Use model-level default time dimension if defined in yml
188
+ if (table?.defaultTimeDimension) {
189
+ return table.defaultTimeDimension;
190
+ }
191
+ // Priority 3: Use the only time dimension if there's exactly one
192
+ if (table?.dimensions) {
193
+ const timeDimensions = Object.values(table.dimensions).filter((dim) => (dim.type === field_1.DimensionType.DATE ||
194
+ dim.type === field_1.DimensionType.TIMESTAMP) &&
195
+ !!dim.isIntervalBase &&
196
+ !dim.hidden);
197
+ if (timeDimensions.length === 1) {
198
+ return {
199
+ field: timeDimensions[0].name,
200
+ interval: exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL,
201
+ };
202
+ }
203
+ }
204
+ return undefined;
205
+ };
206
+ exports.getDefaultTimeDimension = getDefaultTimeDimension;
207
+ const getAvailableTimeDimensionsFromTables = (tables) => Object.values(tables).flatMap((table) => Object.values(table.dimensions).filter((dim) => (dim.type === field_1.DimensionType.DATE ||
208
+ dim.type === field_1.DimensionType.TIMESTAMP) &&
209
+ !!dim.isIntervalBase &&
210
+ !dim.hidden));
211
+ exports.getAvailableTimeDimensionsFromTables = getAvailableTimeDimensionsFromTables;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1397.1",
3
+ "version": "0.1398.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [