@lightdash/common 0.1411.2 → 0.1412.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.2",
3
+ "version": "0.1412.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [