@lightdash/common 0.1426.2 → 0.1427.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -425,19 +425,21 @@ function formatRawValue(field, value) {
425
425
  return value;
426
426
  }
427
427
  function formatRows(rows, itemsMap) {
428
- return rows.map((row) => Object.keys(row).reduce((acc, columnName) => {
429
- const col = row[columnName];
430
- const item = itemsMap[columnName];
431
- return {
432
- ...acc,
433
- [columnName]: {
428
+ return rows.map((row) => {
429
+ const resultRow = {};
430
+ const columnNames = Object.keys(row || {});
431
+ for (const columnName of columnNames) {
432
+ const value = row[columnName];
433
+ const item = itemsMap[columnName];
434
+ resultRow[columnName] = {
434
435
  value: {
435
- raw: formatRawValue(item, col),
436
- formatted: (0, formatting_1.formatItemValue)(item, col),
436
+ raw: formatRawValue(item, value),
437
+ formatted: (0, formatting_1.formatItemValue)(item, value),
437
438
  },
438
- },
439
- };
440
- }, {}));
439
+ };
440
+ }
441
+ return resultRow;
442
+ });
441
443
  }
442
444
  exports.formatRows = formatRows;
443
445
  const isObject = (object) => object != null && typeof object === 'object';
@@ -1,6 +1,5 @@
1
1
  import { type MetricWithAssociatedTimeDimension } from './catalog';
2
2
  import type { Dimension, ItemsMap } from './field';
3
- import type { ResultValue } from './results';
4
3
  export declare enum MetricExplorerComparison {
5
4
  NONE = "none",
6
5
  PREVIOUS_PERIOD = "previous_period",
@@ -26,12 +25,10 @@ export type MetricExploreDataPoint = {
26
25
  segment: string | null;
27
26
  metric: {
28
27
  value: number | null;
29
- formatted: string | null;
30
28
  label: string | null;
31
29
  };
32
30
  compareMetric: {
33
31
  value: number | null;
34
- formatted: string | null;
35
32
  label: string | null;
36
33
  };
37
34
  };
@@ -55,8 +52,9 @@ export declare enum MetricTotalComparisonType {
55
52
  PREVIOUS_PERIOD = "previous_period"
56
53
  }
57
54
  export type MetricTotalResults = {
58
- value: ResultValue | undefined;
59
- comparisonValue: ResultValue | undefined;
55
+ value: number | null;
56
+ comparisonValue: number | null;
57
+ metric: MetricWithAssociatedTimeDimension;
60
58
  };
61
59
  export type ApiMetricsExplorerTotalResults = {
62
60
  status: 'ok';
@@ -5,7 +5,6 @@ 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
7
  import { type MetricExploreDataPoint, type MetricExplorerDateRange, type MetricExplorerQuery } from '../types/metricsExplorer';
8
- import type { ResultRow } from '../types/results';
9
8
  import { TimeFrames, type DefaultTimeDimension } from '../types/timeFrames';
10
9
  type DateFilter = FilterRule<ConditionalOperator, FieldTarget, unknown, DateFilterSettings>;
11
10
  type ImpelemntedTimeframe = TimeFrames.DAY | TimeFrames.WEEK | TimeFrames.MONTH | TimeFrames.YEAR;
@@ -20,12 +19,13 @@ export declare const METRICS_EXPLORER_DATE_FORMAT = "YYYY-MM-DD";
20
19
  export declare const getDateRangeFromString: (dateRange: [string, string]) => MetricExplorerDateRange;
21
20
  export declare const getGrainForDateRange: (dateRange: [Date, Date]) => ImpelemntedTimeframe;
22
21
  export declare const getMetricExplorerDateRangeFilters: (timeDimensionConfig: TimeDimensionConfig, dateRange: MetricExplorerDateRange) => DateFilter[];
22
+ export declare const parseMetricValue: (value: unknown) => number | null;
23
23
  export declare const MAX_SEGMENT_DIMENSION_UNIQUE_VALUES = 10;
24
- export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], segmentDimensionId: string | null) => {
24
+ export declare const getMetricExplorerDataPoints: (dimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: Record<string, any>[], segmentDimensionId: string | null) => {
25
25
  dataPoints: Array<MetricExploreDataPoint>;
26
26
  isSegmentDimensionFiltered: boolean;
27
27
  };
28
- export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: ResultRow[], compareMetricRows: ResultRow[], query: MetricExplorerQuery, timeFrame: TimeFrames) => {
28
+ export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimension, compareDimension: Dimension, metric: MetricWithAssociatedTimeDimension, metricRows: Record<string, any>[], compareMetricRows: Record<string, any>[], query: MetricExplorerQuery, timeFrame: TimeFrames) => {
29
29
  dataPoints: Array<MetricExploreDataPoint>;
30
30
  };
31
31
  /**
@@ -38,7 +38,7 @@ export declare const getMetricExplorerDataPointsWithCompare: (dimension: Dimensi
38
38
  * @returns The date range
39
39
  */
40
40
  export declare const getDefaultDateRangeFromInterval: (timeInterval: TimeFrames) => MetricExplorerDateRange;
41
- export declare const getDefaultDateRangeForMetricTotal: (timeFrame: TimeFrames) => MetricExplorerDateRange;
41
+ export declare const getDefaultMetricTreeNodeDateRange: (timeFrame: TimeFrames) => MetricExplorerDateRange;
42
42
  /**
43
43
  * Default time interval to use when no time interval is provided.
44
44
  * For example, when there is no default time dimension defined for a metric or table.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getAvailableCompareMetrics = exports.getAvailableSegmentDimensions = exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultDateRangeForMetricTotal = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES = exports.getMetricExplorerDateRangeFilters = exports.getGrainForDateRange = exports.getDateRangeFromString = exports.METRICS_EXPLORER_DATE_FORMAT = exports.getDateCalcUtils = exports.getFieldIdForDateDimension = exports.assertUnimplementedTimeframe = void 0;
3
+ exports.getAvailableCompareMetrics = exports.getAvailableSegmentDimensions = exports.getAvailableTimeDimensionsFromTables = exports.getDefaultTimeDimension = exports.getFirstAvailableTimeDimension = exports.DEFAULT_METRICS_EXPLORER_TIME_INTERVAL = exports.getDefaultMetricTreeNodeDateRange = exports.getDefaultDateRangeFromInterval = exports.getMetricExplorerDataPointsWithCompare = exports.getMetricExplorerDataPoints = exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES = exports.parseMetricValue = 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 isoWeek_1 = tslib_1.__importDefault(require("dayjs/plugin/isoWeek"));
@@ -135,7 +135,6 @@ const getMetricExplorerDateRangeFilters = (timeDimensionConfig, dateRange) => {
135
135
  ];
136
136
  };
137
137
  exports.getMetricExplorerDateRangeFilters = getMetricExplorerDateRangeFilters;
138
- // TODO: Should we just use the formatted value instead?
139
138
  // Parse the metric value to a number, returning null if it's not a number
140
139
  const parseMetricValue = (value) => {
141
140
  if (value === null || value === undefined)
@@ -143,6 +142,7 @@ const parseMetricValue = (value) => {
143
142
  const parsed = Number(value);
144
143
  return Number.isNaN(parsed) ? null : parsed;
145
144
  };
145
+ exports.parseMetricValue = parseMetricValue;
146
146
  // we are assuming that the dimension value is a string and if it's not defined we just return null
147
147
  // so actually `null` value will be converted to `"null"` string
148
148
  const parseDimensionValue = (value) => {
@@ -157,28 +157,26 @@ const getMetricExplorerDataPoints = (dimension, metric, metricRows, segmentDimen
157
157
  let filteredMetricRows = metricRows;
158
158
  let isSegmentDimensionFiltered = false;
159
159
  if (segmentDimensionId) {
160
- const countUniqueValues = new Set(metricRows.map((row) => row[segmentDimensionId]?.value.raw)).size;
160
+ const countUniqueValues = new Set(metricRows.map((row) => row[segmentDimensionId])).size;
161
161
  if (countUniqueValues > exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES) {
162
162
  isSegmentDimensionFiltered = true;
163
- const first10Values = Array.from(new Set(metricRows.map((row) => row[segmentDimensionId]?.value.raw))).slice(0, exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES);
164
- filteredMetricRows = metricRows.filter((row) => first10Values.includes(row[segmentDimensionId]?.value.raw));
163
+ const first10Values = Array.from(new Set(metricRows.map((row) => row[segmentDimensionId]))).slice(0, exports.MAX_SEGMENT_DIMENSION_UNIQUE_VALUES);
164
+ filteredMetricRows = metricRows.filter((row) => first10Values.includes(row[segmentDimensionId]));
165
165
  }
166
166
  }
167
- const groupByMetricRows = (0, lodash_1.groupBy)(filteredMetricRows, (row) => new Date(String(row[dimensionId].value.raw)).toISOString());
167
+ const groupByMetricRows = (0, lodash_1.groupBy)(filteredMetricRows, (row) => new Date(String(row[dimensionId])).toISOString());
168
168
  const dataPoints = Object.entries(groupByMetricRows).flatMap(([date, rows]) => rows.map((row) => {
169
169
  const segmentValue = segmentDimensionId
170
- ? parseDimensionValue(row[segmentDimensionId]?.value.raw)
170
+ ? parseDimensionValue(row[segmentDimensionId])
171
171
  : null;
172
172
  return {
173
173
  date: new Date(date),
174
174
  segment: segmentValue,
175
175
  metric: {
176
- value: parseMetricValue(row[metricId]?.value.raw),
177
- formatted: row[metricId]?.value.formatted,
176
+ value: (0, exports.parseMetricValue)(row[metricId]),
178
177
  label: segmentValue ?? metric.label ?? metric.name,
179
178
  },
180
179
  compareMetric: {
181
- formatted: null,
182
180
  value: null,
183
181
  label: null,
184
182
  },
@@ -208,8 +206,8 @@ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, met
208
206
  const metricId = (0, item_1.getItemId)(metric);
209
207
  const dimensionId = (0, item_1.getItemId)(dimension);
210
208
  const compareDimensionId = (0, item_1.getItemId)(compareDimension);
211
- const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => new Date(String(row[dimensionId].value.raw)).toISOString());
212
- const groupByCompareMetricRows = (0, lodash_1.groupBy)(compareMetricRows, (row) => new Date(String(row[compareDimensionId].value.raw)).toISOString());
209
+ const groupByMetricRows = (0, lodash_1.groupBy)(metricRows, (row) => new Date(String(row[dimensionId])).toISOString());
210
+ const groupByCompareMetricRows = (0, lodash_1.groupBy)(compareMetricRows, (row) => new Date(String(row[compareDimensionId])).toISOString());
213
211
  const offsetGroupByCompareMetricRows = (0, lodash_1.mapKeys)(groupByCompareMetricRows, (_, date) => {
214
212
  if (query.comparison === metricsExplorer_1.MetricExplorerComparison.PREVIOUS_PERIOD) {
215
213
  if (timeFrame === timeFrames_1.TimeFrames.WEEK) {
@@ -242,15 +240,11 @@ const getMetricExplorerDataPointsWithCompare = (dimension, compareDimension, met
242
240
  date: new Date(date),
243
241
  segment: null,
244
242
  metric: {
245
- formatted: groupByMetricRows[date]?.[0]?.[metricId]?.value.formatted,
246
- value: parseMetricValue(groupByMetricRows[date]?.[0]?.[metricId]?.value.raw),
243
+ value: (0, exports.parseMetricValue)(groupByMetricRows[date]?.[0]?.[metricId]),
247
244
  label: metric.label ?? metric.name,
248
245
  },
249
246
  compareMetric: {
250
- formatted: offsetGroupByCompareMetricRows[date]?.[0]?.[compareMetricId]
251
- ?.value.formatted,
252
- value: parseMetricValue(offsetGroupByCompareMetricRows[date]?.[0]?.[compareMetricId]
253
- ?.value.raw),
247
+ value: (0, exports.parseMetricValue)(offsetGroupByCompareMetricRows[date]?.[0]?.[compareMetricId]),
254
248
  label: comparisonMetricLabel,
255
249
  },
256
250
  }));
@@ -291,25 +285,34 @@ const getDefaultDateRangeFromInterval = (timeInterval) => {
291
285
  }
292
286
  };
293
287
  exports.getDefaultDateRangeFromInterval = getDefaultDateRangeFromInterval;
294
- const getDefaultDateRangeForMetricTotal = (timeFrame) => {
288
+ const getDefaultMetricTreeNodeDateRange = (timeFrame) => {
295
289
  const now = (0, dayjs_1.default)();
296
290
  switch (timeFrame) {
297
291
  case timeFrames_1.TimeFrames.DAY:
298
- return [now.startOf('day').toDate(), now.endOf('day').toDate()];
292
+ return [
293
+ now.startOf('day').subtract(1, 'day').toDate(),
294
+ now.endOf('day').subtract(1, 'day').toDate(),
295
+ ];
299
296
  case timeFrames_1.TimeFrames.WEEK:
300
297
  return [
301
- now.startOf('isoWeek').toDate(),
302
- now.endOf('isoWeek').toDate(),
298
+ now.startOf('isoWeek').subtract(1, 'week').toDate(),
299
+ now.endOf('isoWeek').subtract(1, 'week').toDate(),
303
300
  ];
304
301
  case timeFrames_1.TimeFrames.MONTH:
305
- return [now.startOf('month').toDate(), now.endOf('month').toDate()];
302
+ return [
303
+ now.startOf('month').subtract(1, 'month').toDate(),
304
+ now.endOf('month').subtract(1, 'month').toDate(),
305
+ ];
306
306
  case timeFrames_1.TimeFrames.YEAR:
307
- return [now.startOf('year').toDate(), now.endOf('year').toDate()];
307
+ return [
308
+ now.startOf('year').subtract(1, 'year').toDate(),
309
+ now.endOf('year').subtract(1, 'year').toDate(),
310
+ ];
308
311
  default:
309
312
  return (0, exports.assertUnimplementedTimeframe)(timeFrame);
310
313
  }
311
314
  };
312
- exports.getDefaultDateRangeForMetricTotal = getDefaultDateRangeForMetricTotal;
315
+ exports.getDefaultMetricTreeNodeDateRange = getDefaultMetricTreeNodeDateRange;
313
316
  /**
314
317
  * Default time interval to use when no time interval is provided.
315
318
  * For example, when there is no default time dimension defined for a metric or table.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1426.2",
3
+ "version": "0.1427.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [