@cubejs-client/core 1.5.1 → 1.5.2

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.
@@ -121,25 +121,17 @@
121
121
  };
122
122
  var DateRegex = /^\d\d\d\d-\d\d-\d\d$/;
123
123
  var LocalDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z?$/;
124
- var _dayRange = function dayRange(from, to) {
125
- return {
126
- by: function by(value) {
127
- var results = [];
128
- var start = internalDayjs(from);
129
- var end = internalDayjs(to);
130
- while (start.startOf(value).isBefore(end) || start.isSame(end)) {
131
- results.push(start);
132
- start = start.add(1, value);
133
- }
134
- return results;
135
- },
136
- snapTo: function snapTo(value) {
137
- return _dayRange(internalDayjs(from).startOf(value), internalDayjs(to).endOf(value));
138
- },
139
- start: internalDayjs(from),
140
- end: internalDayjs(to)
141
- };
142
- };
124
+
125
+ /**
126
+ * Parse PostgreSQL-like interval string into object
127
+ * E.g. '2 years 15 months 100 weeks 99 hours 15 seconds'
128
+ * Negative units are also supported
129
+ * E.g. '-2 months 5 days -10 hours'
130
+ *
131
+ * TODO: It's copy/paste of parseSqlInterval from @cubejs-backend/shared [time.ts]
132
+ * It's not referenced to omit imports of moment.js staff.
133
+ * Probably one day we should choose one implementation and reuse it in other places.
134
+ */
143
135
  function parseSqlInterval(intervalStr) {
144
136
  var interval = {};
145
137
  var parts = intervalStr.split(/\s+/);
@@ -226,12 +218,67 @@
226
218
  }
227
219
  return alignedDate;
228
220
  }
221
+ var _dayRange = function dayRange(from, to, annotations) {
222
+ return {
223
+ by: function by(value) {
224
+ var results = [];
225
+ var start = internalDayjs(from);
226
+ var end = internalDayjs(to);
227
+ while (start.startOf(value).isBefore(end) || start.isSame(end)) {
228
+ results.push(start);
229
+ start = start.add(1, value);
230
+ }
231
+ return results;
232
+ },
233
+ snapTo: function snapTo(value) {
234
+ // Check if this is a custom granularity
235
+ if (!isPredefinedGranularity(value) && annotations) {
236
+ var _customGranularity;
237
+ // Try to find the custom granularity metadata
238
+ // The annotation key might be in format "Cube.dimension.granularity"
239
+ // So we need to search through all annotations
240
+ var customGranularity;
241
+ for (var _i = 0, _Object$keys = Object.keys(annotations); _i < _Object$keys.length; _i++) {
242
+ var key = _Object$keys[_i];
243
+ if (key.endsWith(".".concat(value)) && annotations[key].granularity) {
244
+ customGranularity = annotations[key].granularity;
245
+ break;
246
+ }
247
+ }
248
+ if ((_customGranularity = customGranularity) !== null && _customGranularity !== void 0 && _customGranularity.interval) {
249
+ // For custom granularities, calculate the range for the bucket
250
+ var intervalParsed = parseSqlInterval(customGranularity.interval);
251
+ var intervalStart = internalDayjs(from);
229
252
 
230
- /**
231
- * Returns the time series points for the custom interval
232
- * TODO: It's almost a copy/paste of timeSeriesFromCustomInterval from
233
- * @cubejs-backend/shared [time.ts] but operates with dayjs instead of moment.js
234
- */
253
+ // origin and offset are mutually exclusive
254
+ // If either is specified, align to it
255
+ if (customGranularity.origin || customGranularity.offset) {
256
+ var origin;
257
+ if (customGranularity.origin) {
258
+ // Absolute origin time
259
+ origin = internalDayjs(customGranularity.origin);
260
+ } else {
261
+ // offset is relative to start of year
262
+ origin = addInterval(internalDayjs().startOf('year'), parseSqlInterval(customGranularity.offset));
263
+ }
264
+
265
+ // Align the value to the origin to find the actual bucket start
266
+ intervalStart = alignToOrigin(intervalStart, intervalParsed, origin);
267
+ }
268
+
269
+ // End is start + interval - 1 millisecond (to stay within the bucket)
270
+ var intervalEnd = addInterval(intervalStart, intervalParsed).subtract(1, 'millisecond');
271
+ return _dayRange(intervalStart, intervalEnd, annotations);
272
+ }
273
+ }
274
+
275
+ // Default behavior for predefined granularities
276
+ return _dayRange(internalDayjs(from).startOf(value), internalDayjs(to).endOf(value), annotations);
277
+ },
278
+ start: internalDayjs(from),
279
+ end: internalDayjs(to)
280
+ };
281
+ };
235
282
  var timeSeriesFromCustomInterval = function timeSeriesFromCustomInterval(from, to, granularity) {
236
283
  var intervalParsed = parseSqlInterval(granularity.interval);
237
284
  var start = internalDayjs(from);
@@ -741,7 +788,9 @@
741
788
  parentFilters = _this$query$filters === void 0 ? [] : _this$query$filters,
742
789
  _this$query$segments = _this$query.segments,
743
790
  segments = _this$query$segments === void 0 ? [] : _this$query$segments;
744
- var measures = this.loadResponses[0].annotation.measures;
791
+ var _this$loadResponses$ = this.loadResponses[0].annotation,
792
+ measures = _this$loadResponses$.measures,
793
+ timeDimensionsAnnotation = _this$loadResponses$.timeDimensions;
745
794
  var _ref = values.find(function (_ref3) {
746
795
  var _ref4 = _slicedToArray__default['default'](_ref3, 1),
747
796
  member = _ref4[0];
@@ -777,7 +826,8 @@
777
826
  granularity = _member$split2[2];
778
827
  if (granularity !== undefined) {
779
828
  var _query$timeDimensions;
780
- var range = _dayRange(value, value).snapTo(granularity);
829
+ // dayRange.snapTo now handles both predefined and custom granularities
830
+ var range = _dayRange(value, value, timeDimensionsAnnotation).snapTo(granularity);
781
831
  var originalTimeDimension = (_query$timeDimensions = query.timeDimensions) === null || _query$timeDimensions === void 0 ? void 0 : _query$timeDimensions.find(function (td) {
782
832
  return td.dimension;
783
833
  });
@@ -948,7 +998,7 @@
948
998
  _dateRange2 = _slicedToArray__default['default'](_dateRange, 2),
949
999
  start = _dateRange2[0],
950
1000
  end = _dateRange2[1];
951
- var range = _dayRange(start, end);
1001
+ var range = _dayRange(start, end, annotations);
952
1002
  if (isPredefinedGranularity(timeDimension.granularity)) {
953
1003
  return TIME_SERIES[timeDimension.granularity](padToDay ? range.snapTo('d') : range);
954
1004
  }
@@ -3426,10 +3476,10 @@
3426
3476
  isPredefinedGranularity: isPredefinedGranularity,
3427
3477
  DateRegex: DateRegex,
3428
3478
  LocalDateRegex: LocalDateRegex,
3429
- dayRange: _dayRange,
3430
3479
  parseSqlInterval: parseSqlInterval,
3431
3480
  addInterval: addInterval,
3432
3481
  subtractInterval: subtractInterval,
3482
+ dayRange: _dayRange,
3433
3483
  timeSeriesFromCustomInterval: timeSeriesFromCustomInterval,
3434
3484
  diffTimeUnitForInterval: diffTimeUnitForInterval,
3435
3485
  minGranularityForIntervals: minGranularityForIntervals,