"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.timelionFunctionFactory = timelionFunctionFactory; var _lodash = require("lodash"); var _momentTimezone = _interopRequireDefault(require("moment-timezone")); var _i18n = require("@kbn/i18n"); var _fetch = require("../../common/lib/fetch"); var _build_bool_array = require("../../common/lib/build_bool_array"); var _i18n2 = require("../../i18n"); /* * 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. */ // @ts-expect-error untyped local const errors = { timelionError: () => new Error(_i18n.i18n.translate('xpack.canvas.functions.timelion.executionError', { defaultMessage: 'There was an error executing the Timelion query. Check your syntax and try again.' })) }; /** * This function parses a given time range containing date math * and returns ISO dates. Parsing is done respecting the given time zone. * @param timeRange time range to parse * @param timeZone time zone to do the parsing in */ function parseDateMath(timeRange, timeZone, timefilter) { // the datemath plugin always parses dates by using the current default moment time zone. // to use the configured time zone, we are switching just for the bounds calculation. const defaultTimezone = (0, _momentTimezone.default)().zoneName(); _momentTimezone.default.tz.setDefault(timeZone); const parsedRange = timefilter.calculateBounds(timeRange); // reset default moment timezone _momentTimezone.default.tz.setDefault(defaultTimezone); return parsedRange; } function timelionFunctionFactory(initialize) { return () => { const { help, args: argHelp } = (0, _i18n2.getFunctionHelp)().timelion; return { name: 'timelion', type: 'datatable', inputTypes: ['filter'], help, args: { query: { types: ['string'], aliases: ['_', 'q'], help: argHelp.query, default: '".es(*)"' }, interval: { types: ['string'], help: argHelp.interval, default: 'auto' }, from: { types: ['string'], help: argHelp.from, default: 'now-1y' }, to: { types: ['string'], help: argHelp.to, default: 'now' }, timezone: { types: ['string'], help: argHelp.timezone, default: 'UTC' } }, fn: async (input, args) => { // Timelion requires a time range. Use the time range from the timefilter element in the // workpad, if it exists. Otherwise fall back on the function args. const timeFilter = input.and.find(and => and.filterType === 'time'); const range = timeFilter ? { min: timeFilter.from, max: timeFilter.to } : parseDateMath({ from: args.from, to: args.to }, args.timezone, initialize.timefilter); const body = { extended: { es: { filter: { bool: { must: (0, _build_bool_array.buildBoolArray)(input.and) } } } }, sheet: [args.query], time: { from: range.min, to: range.max, interval: args.interval, timezone: args.timezone } }; let result; try { result = await (0, _fetch.fetch)(initialize.prependBasePath(`/internal/timelion/run`), { method: 'POST', responseType: 'json', data: body }); } catch (e) { throw errors.timelionError(); } const seriesList = result.data.sheet[0].list; const rows = (0, _lodash.flatten)(seriesList.map(series => series.data.map(row => ({ '@timestamp': row[0], value: row[1], label: series.label })))); return { type: 'datatable', meta: { source: 'timelion' }, columns: [{ id: '@timestamp', name: '@timestamp', meta: { type: 'date' } }, { id: 'value', name: 'value', meta: { type: 'number' } }, { id: 'label', name: 'label', meta: { type: 'string' } }], rows }; } }; }; }