"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getTimeBounds = getTimeBounds; exports.timeScaleFn = void 0; var _momentTimezone = _interopRequireDefault(require("moment-timezone")); var _i18n = require("@kbn/i18n"); var _common = require("@kbn/expressions-plugin/common"); var _common2 = require("@kbn/data-plugin/common"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ const unitInMs = { s: 1000, m: 1000 * 60, h: 1000 * 60 * 60, d: 1000 * 60 * 60 * 24 }; function safelySetTimeZone(timeZone) { const zone = _momentTimezone.default.tz.zone(timeZone); if (zone) _momentTimezone.default.tz.setDefault(zone.name); } /** * This function can be called both from server side and from the client side. Each of them could have * a different configured timezone. To be sure the time bounds are computed relative to the same passed timezone, * temporarily switch the default moment timezone to the one passed, and switch it back after the calculation is done. */ function getTimeBounds(timeRange, timeZone, getForceNow) { if (timeZone) { var _moment$defaultZone; // the `defaultZone` property is injected by moment.timezone. // If is not available is it fine to keep undefined because calling setDefault() will automatically reset to default // https://github.com/moment/moment-timezone/blob/2448cdcbe15875bc22ddfbc184794d0a6b568b90/moment-timezone.js#L603 // @ts-expect-error because is not part of the exposed types unfortunately const currentDefaultTimeZone = (_moment$defaultZone = _momentTimezone.default.defaultZone) === null || _moment$defaultZone === void 0 ? void 0 : _moment$defaultZone.name; safelySetTimeZone(timeZone); const timeBounds = (0, _common2.calculateBounds)(timeRange, { forceNow: getForceNow === null || getForceNow === void 0 ? void 0 : getForceNow() }); safelySetTimeZone(currentDefaultTimeZone); return timeBounds; } else { return (0, _common2.calculateBounds)(timeRange, { forceNow: getForceNow === null || getForceNow === void 0 ? void 0 : getForceNow() }); } } const timeScaleFn = (getDatatableUtilities, getTimezone, getForceNow) => async (input, { dateColumnId, inputColumnId, outputColumnId, outputColumnName, targetUnit, reducedTimeRange }, context) => { let timeBounds; const contextTimeZone = await getTimezone(context); let getStartEndOfBucketMeta; if (dateColumnId) { const dateColumnDefinition = input.columns.find(column => column.id === dateColumnId); if (!dateColumnDefinition) { throw new Error(_i18n.i18n.translate('xpack.lens.functions.timeScale.dateColumnMissingMessage', { defaultMessage: 'Specified dateColumnId {columnId} does not exist.', values: { columnId: dateColumnId } })); } const datatableUtilities = await getDatatableUtilities(context); const timeInfo = datatableUtilities.getDateHistogramMeta(dateColumnDefinition, { timeZone: contextTimeZone }); const intervalDuration = (timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.interval) && (0, _common2.parseInterval)(timeInfo.interval); timeBounds = (timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.timeRange) && getTimeBounds(timeInfo.timeRange, timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.timeZone, getForceNow); getStartEndOfBucketMeta = row => { var _timeInfo$timeZone; const startOfBucket = _momentTimezone.default.tz(row[dateColumnId], (_timeInfo$timeZone = timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.timeZone) !== null && _timeInfo$timeZone !== void 0 ? _timeInfo$timeZone : contextTimeZone); return { startOfBucket, endOfBucket: startOfBucket.clone().add(intervalDuration) }; }; if (!timeInfo || !intervalDuration) { throw new Error(_i18n.i18n.translate('xpack.lens.functions.timeScale.timeInfoMissingMessage', { defaultMessage: 'Could not fetch date histogram information' })); } } else { const timeRange = context.getSearchContext().timeRange; timeBounds = getTimeBounds(timeRange, contextTimeZone, getForceNow); if (!timeBounds.max || !timeBounds.min) { throw new Error(_i18n.i18n.translate('xpack.lens.functions.timeScale.timeBoundsMissingMessage', { defaultMessage: 'Could not parse "Time Range"' })); } const endOfBucket = timeBounds.max; let startOfBucket = timeBounds.min; if (reducedTimeRange) { const reducedStartOfBucket = endOfBucket.clone().subtract((0, _common2.parseInterval)(reducedTimeRange)); if (reducedStartOfBucket > startOfBucket) { startOfBucket = reducedStartOfBucket; } } getStartEndOfBucketMeta = () => ({ startOfBucket, endOfBucket }); } const resultColumns = (0, _common.buildResultColumns)(input, outputColumnId, inputColumnId, outputColumnName, { allowColumnOverwrite: true }); if (!resultColumns) { return input; } return { ...input, columns: resultColumns, rows: input.rows.map(row => { const newRow = { ...row }; let { startOfBucket, endOfBucket } = getStartEndOfBucketMeta(row); if (timeBounds && timeBounds.min) { startOfBucket = _momentTimezone.default.max(startOfBucket, timeBounds.min); } if (timeBounds && timeBounds.max) { endOfBucket = _momentTimezone.default.min(endOfBucket, timeBounds.max); } const bucketSize = endOfBucket.diff(startOfBucket); const factor = bucketSize / unitInMs[targetUnit]; const currentValue = newRow[inputColumnId]; if (currentValue != null) { newRow[outputColumnId] = Number(currentValue) / factor; } return newRow; }) }; }; exports.timeScaleFn = timeScaleFn;