@lightdash/common 0.1411.3 → 0.1412.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -176,4 +176,8 @@ export type ApiMetricsWithAssociatedTimeDimensionResponse = {
176
176
  status: 'ok';
177
177
  results: MetricWithAssociatedTimeDimension[];
178
178
  };
179
+ export type ApiSegmentDimensionsResponse = {
180
+ status: 'ok';
181
+ results: CompiledDimension[];
182
+ };
179
183
  export {};
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { type MetricWithAssociatedTimeDimension } from './catalog';
3
- import type { ItemsMap } from './field';
3
+ import type { Dimension, ItemsMap } from './field';
4
4
  import type { ResultValue } from './results';
5
5
  export declare enum MetricExplorerComparison {
6
6
  NONE = "none",
@@ -9,12 +9,13 @@ export declare enum MetricExplorerComparison {
9
9
  }
10
10
  export type MetricExplorerPartialDateRange = [Date | null, Date | null];
11
11
  export type MetricExplorerDateRange = [Date, Date];
12
- export type MetricExplorerComparisonType = {
13
- type: MetricExplorerComparison.NONE;
12
+ export type MetricExplorerQuery = {
13
+ comparison: MetricExplorerComparison.NONE;
14
+ segmentDimension: string | null;
14
15
  } | {
15
- type: MetricExplorerComparison.PREVIOUS_PERIOD;
16
+ comparison: MetricExplorerComparison.PREVIOUS_PERIOD;
16
17
  } | {
17
- type: MetricExplorerComparison.DIFFERENT_METRIC;
18
+ comparison: MetricExplorerComparison.DIFFERENT_METRIC;
18
19
  metric: {
19
20
  label: string;
20
21
  table: string;
@@ -23,6 +24,7 @@ export type MetricExplorerComparisonType = {
23
24
  };
24
25
  export declare const metricExploreDataPointWithDateValueSchema: z.ZodObject<z.objectUtil.extendShape<{
25
26
  date: z.ZodDate;
27
+ segment: z.ZodNullable<z.ZodString>;
26
28
  metric: z.ZodObject<{
27
29
  value: z.ZodNullable<z.ZodNumber>;
28
30
  label: z.ZodNullable<z.ZodString>;
@@ -51,6 +53,7 @@ export declare const metricExploreDataPointWithDateValueSchema: z.ZodObject<z.ob
51
53
  value: number | null;
52
54
  };
53
55
  date: Date;
56
+ segment: string | null;
54
57
  compareMetric: {
55
58
  label: string | null;
56
59
  value: number | null;
@@ -62,6 +65,7 @@ export declare const metricExploreDataPointWithDateValueSchema: z.ZodObject<z.ob
62
65
  value: number | null;
63
66
  };
64
67
  date: Date;
68
+ segment: string | null;
65
69
  compareMetric: {
66
70
  label: string | null;
67
71
  value: number | null;
@@ -70,6 +74,7 @@ export declare const metricExploreDataPointWithDateValueSchema: z.ZodObject<z.ob
70
74
  }>;
71
75
  export type MetricExploreDataPoint = {
72
76
  date: Date;
77
+ segment: string | null;
73
78
  metric: {
74
79
  value: number | null;
75
80
  label: string | null;
@@ -84,7 +89,8 @@ export type MetricExploreDataPointWithDateValue = MetricExploreDataPoint & {
84
89
  };
85
90
  export type MetricsExplorerQueryResults = {
86
91
  metric: MetricWithAssociatedTimeDimension;
87
- compareMetric: MetricWithAssociatedTimeDimension | undefined;
92
+ compareMetric: MetricWithAssociatedTimeDimension | null;
93
+ segmentDimension: Dimension | null;
88
94
  fields: ItemsMap;
89
95
  results: MetricExploreDataPointWithDateValue[];
90
96
  };
@@ -10,6 +10,7 @@ var MetricExplorerComparison;
10
10
  })(MetricExplorerComparison = exports.MetricExplorerComparison || (exports.MetricExplorerComparison = {}));
11
11
  const metricExploreDataPointSchema = zod_1.z.object({
12
12
  date: zod_1.z.date({ coerce: true }),
13
+ segment: zod_1.z.string().nullable(),
13
14
  metric: zod_1.z.object({
14
15
  value: zod_1.z.number().nullable(),
15
16
  label: zod_1.z.string().nullable(),
@@ -4,7 +4,7 @@ import { type CompiledTable } from '../types/explore';
4
4
  import type { Dimension } from '../types/field';
5
5
  import { DimensionType, type CompiledDimension, type CompiledMetric } from '../types/field';
6
6
  import { type DateFilterSettings, type FieldTarget, type FilterRule } from '../types/filter';
7
- import { type MetricExploreDataPoint, type MetricExplorerComparisonType, type MetricExplorerDateRange } from '../types/metricsExplorer';
7
+ import { type MetricExploreDataPoint, type MetricExplorerDateRange, type MetricExplorerQuery } from '../types/metricsExplorer';
8
8
  import type { ResultRow } from '../types/results';
9
9
  import { TimeFrames, type DefaultTimeDimension } from '../types/timeFrames';
10
10
  type DateFilter = FilterRule<ConditionalOperator, FieldTarget, unknown, DateFilterSettings>;
@@ -16,10 +16,12 @@ export declare const getDateCalcUtils: (timeFrame: TimeFrames) => {
16
16
  forward: (date: Date) => Date;
17
17
  back: (date: Date) => Date;
18
18
  };
19
+ export declare const METRICS_EXPLORER_DATE_FORMAT = "YYYY-MM-DD";
20
+ export declare const getDateRangeFromString: (dateRange: [string, string]) => MetricExplorerDateRange;
19
21
  export declare const getGrainForDateRange: (dateRange: [Date, Date]) => ImpelemntedTimeframe;
20
- export declare const getMetricExplorerDateRangeFilters: (exploreName: string, dimensionName: string, dateRange: MetricExplorerDateRange) => DateFilter[];
21
- export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[]) => Array<MetricExploreDataPoint>;
22
- export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], comparison: MetricExplorerComparisonType) => Array<MetricExploreDataPoint>;
22
+ export declare const getMetricExplorerDateRangeFilters: (timeDimensionConfig: TimeDimensionConfig, dateRange: MetricExplorerDateRange) => DateFilter[];
23
+ export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], segmentDimensionId: string | null) => Array<MetricExploreDataPoint>;
24
+ export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], query: MetricExplorerQuery) => Array<MetricExploreDataPoint>;
23
25
  /**
24
26
  * Get the date range for a given time interval, based on the current date and the time interval
25
27
  * Time grain Year: -> past 5 years (i.e. 5 completed years + this uncompleted year)
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultDateRangeForMetricTotal = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.getDateCalcUtils = exports.getFieldIdForDateDimension = exports.assertUnimplementedTimeframe = void 0;
3
+ exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultDateRangeForMetricTotal = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.getDateRangeFromString = exports.METRICS_EXPLORER_DATE_FORMAT = exports.getDateCalcUtils = exports.getFieldIdForDateDimension = exports.assertUnimplementedTimeframe = 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");
@@ -79,6 +79,12 @@ const getDateCalcUtils = (timeFrame) => {
79
79
  }
80
80
  };
81
81
  exports.getDateCalcUtils = getDateCalcUtils;
82
+ exports.METRICS_EXPLORER_DATE_FORMAT = 'YYYY-MM-DD';
83
+ const getDateRangeFromString = (dateRange) => [
84
+ (0, dayjs_1.default)(dateRange[0], exports.METRICS_EXPLORER_DATE_FORMAT).toDate(),
85
+ (0, dayjs_1.default)(dateRange[1], exports.METRICS_EXPLORER_DATE_FORMAT).toDate(),
86
+ ];
87
+ exports.getDateRangeFromString = getDateRangeFromString;
82
88
  // TODO: refine the time grain for each time frame
83
89
  // Time grain Year: -> past 5 years (i.e. 5 completed years + this uncompleted year)
84
90
  // Time grain Month -> past 12 months (i.e. 12 completed months + this uncompleted month)
@@ -100,18 +106,17 @@ const getGrainForDateRange = (dateRange) => {
100
106
  return timeFrames_1.TimeFrames.YEAR;
101
107
  };
102
108
  exports.getGrainForDateRange = getGrainForDateRange;
103
- const getMetricExplorerDateRangeFilters = (exploreName, dimensionName, dateRange) => {
104
- const defaultGrain = (0, exports.getGrainForDateRange)(dateRange);
109
+ const getMetricExplorerDateRangeFilters = (timeDimensionConfig, dateRange) => {
105
110
  const targetFieldId = (0, item_1.getItemId)({
106
- table: exploreName,
107
- name: (0, exports.getFieldIdForDateDimension)(dimensionName, defaultGrain),
111
+ table: timeDimensionConfig.table,
112
+ name: (0, exports.getFieldIdForDateDimension)(timeDimensionConfig.field, timeDimensionConfig.interval),
108
113
  });
109
114
  return [
110
115
  {
111
116
  id: (0, uuid_1.v4)(),
112
117
  target: { fieldId: targetFieldId },
113
118
  operator: conditionalRule_1.ConditionalOperator.IN_BETWEEN,
114
- values: dateRange,
119
+ values: dateRange.map((date) => (0, dayjs_1.default)(date).format(exports.METRICS_EXPLORER_DATE_FORMAT)),
115
120
  },
116
121
  ];
117
122
  };
@@ -124,25 +129,38 @@ const parseMetricValue = (value) => {
124
129
  const parsed = Number(value);
125
130
  return Number.isNaN(parsed) ? null : parsed;
126
131
  };
127
- const getMetricExplorerDataPoints = (dimension, metric, metricRows) => {
132
+ // we are assuming that the dimension value is a string and if it's not defined we just return null
133
+ // so actually `null` value will be converted to `"null"` string
134
+ const parseDimensionValue = (value) => {
135
+ if (value === undefined)
136
+ return null;
137
+ return String(value);
138
+ };
139
+ const getMetricExplorerDataPoints = (dimension, metric, metricRows, segmentDimensionId) => {
128
140
  const dimensionId = (0, item_1.getItemId)(dimension);
129
141
  const metricId = (0, item_1.getItemId)(metric);
130
142
  const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => new Date(String(row[dimensionId].value.raw)).toISOString());
131
- return Object.keys(groupByMetricRows).map((date) => ({
132
- date: new Date(date),
133
- metric: {
134
- value: parseMetricValue(groupByMetricRows[date]?.[0]?.[metricId]?.value.raw),
135
- label: metric.label ?? metric.name,
136
- },
137
- compareMetric: {
138
- value: null,
139
- label: null,
140
- },
143
+ return Object.entries(groupByMetricRows).flatMap(([date, rows]) => rows.map((row) => {
144
+ const segmentValue = segmentDimensionId
145
+ ? parseDimensionValue(row[segmentDimensionId]?.value.raw)
146
+ : null;
147
+ return {
148
+ date: new Date(date),
149
+ segment: segmentValue,
150
+ metric: {
151
+ value: parseMetricValue(row[metricId]?.value.raw),
152
+ label: segmentValue ?? metric.label ?? metric.name,
153
+ },
154
+ compareMetric: {
155
+ value: null,
156
+ label: null,
157
+ },
158
+ };
141
159
  }));
142
160
  };
143
161
  exports.getMetricExplorerDataPoints = getMetricExplorerDataPoints;
144
- const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, metric, metricRows, compareMetricRows, comparison) => {
145
- if (comparison.type === metricsExplorer_1.MetricExplorerComparison.NONE) {
162
+ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, metric, metricRows, compareMetricRows, query) => {
163
+ if (query.comparison === metricsExplorer_1.MetricExplorerComparison.NONE) {
146
164
  throw new Error('Comparison type is required');
147
165
  }
148
166
  const metricId = (0, item_1.getItemId)(metric);
@@ -150,7 +168,7 @@ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, met
150
168
  const compareDimensionId = (0, item_1.getItemId)(compareDimension);
151
169
  const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => new Date(String(row[dimensionId].value.raw)).toISOString());
152
170
  const groupByCompareMetricRows = (0, lodash_1.groupBy)(compareMetricRows, (row) => new Date(String(row[compareDimensionId].value.raw)).toISOString());
153
- const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => comparison.type === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
171
+ const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
154
172
  ? (0, exports.getDateCalcUtils)(timeFrames_1.TimeFrames.YEAR)
155
173
  .forward(new Date(date))
156
174
  .toISOString()
@@ -159,22 +177,22 @@ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, met
159
177
  ...Object.keys(groupByMetricRows),
160
178
  ...Object.keys(offsetGroupByCompareMetricRows),
161
179
  ]);
162
- const compareMetricId = comparison.type === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
180
+ const compareMetricId = query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD
163
181
  ? metricId
164
182
  : (0, item_1.getItemId)({
165
- table: comparison.metric.table,
166
- name: comparison.metric.name,
183
+ table: query.metric.table,
184
+ name: query.metric.name,
167
185
  });
168
186
  let comparisonMetricLabel = null;
169
- if (comparison.type === metricsExplorer_1.MetricExplorerComparison.DIFFERENT_METRIC) {
170
- comparisonMetricLabel =
171
- comparison.metric.label ?? comparison.metric.name;
187
+ if (query.comparison === metricsExplorer_1.MetricExplorerComparison.DIFFERENT_METRIC) {
188
+ comparisonMetricLabel = query.metric.label ?? query.metric.name;
172
189
  }
173
- else if (comparison.type === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD) {
190
+ else if (query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD) {
174
191
  comparisonMetricLabel = 'Previous Period';
175
192
  }
176
193
  return Array.from(dates).map((date) => ({
177
194
  date: new Date(date),
195
+ segment: null,
178
196
  metric: {
179
197
  value: parseMetricValue(groupByMetricRows[date]?.[0]?.[metricId]?.value.raw),
180
198
  label: metric.label ?? metric.name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1411.3",
3
+ "version": "0.1412.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [