"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.isNumber = exports.isDataProviderEmpty = exports.getFieldEsTypes = exports.getBrowserFieldPath = exports.getBaseFields = exports.convertToBuildEsQuery = exports.convertNestedFieldToQuery = exports.convertNestedFieldToExistQuery = exports.convertKueryToElasticSearchQuery = exports.convertDateFieldToQuery = exports.combineQueries = exports.checkIfFieldTypeIsNested = exports.checkIfFieldTypeIsDate = exports.buildTimeRangeFilter = exports.buildGlobalQuery = void 0; var _esQuery = require("@kbn/es-query"); var _fp = require("lodash/fp"); var _memoizeOne = _interopRequireDefault(require("memoize-one")); var _kql = require("../../../../common/utils/kql"); var _timeline = require("../../../../common/api/timeline"); var _timeline2 = require("../../../../common/types/timeline"); /* * 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 convertKueryToElasticSearchQuery = (kueryExpression, indexPattern) => { try { return kueryExpression ? JSON.stringify((0, _esQuery.toElasticsearchQuery)((0, _esQuery.fromKueryExpression)(kueryExpression), indexPattern)) : ''; } catch (err) { return ''; } }; exports.convertKueryToElasticSearchQuery = convertKueryToElasticSearchQuery; const isNumber = value => !isNaN(Number(value)); exports.isNumber = isNumber; const convertDateFieldToQuery = (field, value) => `${field}: ${isNumber(value) ? value : new Date(value.toString()).valueOf()}`; exports.convertDateFieldToQuery = convertDateFieldToQuery; const getBaseFields = (0, _memoizeOne.default)(browserFields => { const baseFields = (0, _fp.get)('base', browserFields); if (baseFields != null && baseFields.fields != null) { return Object.keys(baseFields.fields); } return []; }); exports.getBaseFields = getBaseFields; const getBrowserFieldPath = (field, browserFields) => { const splitFields = field.split('.'); const baseFields = getBaseFields(browserFields); if (baseFields.includes(field)) { return ['base', 'fields', field]; } return [splitFields[0], 'fields', field]; }; exports.getBrowserFieldPath = getBrowserFieldPath; const getFieldEsTypes = (field, browserFields) => { const pathBrowserField = getBrowserFieldPath(field, browserFields); const browserField = (0, _fp.get)(pathBrowserField, browserFields); if (browserField != null) { return browserField.esTypes; } return []; }; exports.getFieldEsTypes = getFieldEsTypes; const checkIfFieldTypeIsDate = (field, browserFields) => { const pathBrowserField = getBrowserFieldPath(field, browserFields); const browserField = (0, _fp.get)(pathBrowserField, browserFields); if (browserField != null && browserField.type === 'date') { return true; } return false; }; exports.checkIfFieldTypeIsDate = checkIfFieldTypeIsDate; const convertNestedFieldToQuery = (field, value, browserFields) => { const pathBrowserField = getBrowserFieldPath(field, browserFields); const browserField = (0, _fp.get)(pathBrowserField, browserFields); const nestedPath = browserField.subType.nested.path; const key = field.replace(`${nestedPath}.`, ''); return `${nestedPath}: { ${key}: ${browserField.type === 'date' ? `"${value}"` : value} }`; }; exports.convertNestedFieldToQuery = convertNestedFieldToQuery; const convertNestedFieldToExistQuery = (field, browserFields) => { const pathBrowserField = getBrowserFieldPath(field, browserFields); const browserField = (0, _fp.get)(pathBrowserField, browserFields); const nestedPath = browserField.subType.nested.path; const key = field.replace(`${nestedPath}.`, ''); return `${nestedPath}: { ${key}: * }`; }; exports.convertNestedFieldToExistQuery = convertNestedFieldToExistQuery; const checkIfFieldTypeIsNested = (field, browserFields) => { const pathBrowserField = getBrowserFieldPath(field, browserFields); const browserField = (0, _fp.get)(pathBrowserField, browserFields); if (browserField != null && browserField.subType && browserField.subType.nested) { return true; } return false; }; exports.checkIfFieldTypeIsNested = checkIfFieldTypeIsNested; const buildQueryMatch = (dataProvider, browserFields) => `${dataProvider.excluded ? 'NOT ' : ''}${dataProvider.queryMatch.operator !== _timeline2.EXISTS_OPERATOR && dataProvider.type !== _timeline.DataProviderType.template ? checkIfFieldTypeIsNested(dataProvider.queryMatch.field, browserFields) ? convertNestedFieldToQuery(dataProvider.queryMatch.field, dataProvider.queryMatch.value, browserFields) : checkIfFieldTypeIsDate(dataProvider.queryMatch.field, browserFields) ? convertDateFieldToQuery(dataProvider.queryMatch.field, dataProvider.queryMatch.value) : `${dataProvider.queryMatch.field} : ${Array.isArray(dataProvider.queryMatch.value) ? dataProvider.queryMatch.value : (0, _kql.prepareKQLParam)(dataProvider.queryMatch.value)}` : checkIfFieldTypeIsNested(dataProvider.queryMatch.field, browserFields) ? convertNestedFieldToExistQuery(dataProvider.queryMatch.field, browserFields) : `${dataProvider.queryMatch.field} ${_timeline2.EXISTS_OPERATOR}`}`.trim(); const buildGlobalQuery = (dataProviders, browserFields) => dataProviders.reduce((queries, dataProvider) => { const flatDataProviders = [dataProvider, ...dataProvider.and]; const activeDataProviders = flatDataProviders.filter(flatDataProvider => flatDataProvider.enabled); if (!activeDataProviders.length) return queries; const activeDataProvidersQueries = activeDataProviders.map(activeDataProvider => buildQueryMatch(activeDataProvider, browserFields)); const activeDataProvidersQueryMatch = activeDataProvidersQueries.join(' and '); return [...queries, activeDataProvidersQueryMatch]; }, []).filter(queriesItem => !(0, _fp.isEmpty)(queriesItem)).reduce((globalQuery, queryMatch, index, queries) => { if (queries.length <= 1) return queryMatch; return !index ? `(${queryMatch})` : `${globalQuery} or (${queryMatch})`; }, ''); exports.buildGlobalQuery = buildGlobalQuery; const buildTimeRangeFilter = (from, to) => ({ range: { '@timestamp': { gte: from, lt: to, format: 'strict_date_optional_time' } }, meta: { type: 'range', disabled: false, negate: false, alias: null, key: '@timestamp', params: { gte: from, lt: to, format: 'strict_date_optional_time' } }, $state: { store: _esQuery.FilterStateStore.APP_STATE } }); exports.buildTimeRangeFilter = buildTimeRangeFilter; const isDataProviderEmpty = dataProviders => { return (0, _fp.isEmpty)(dataProviders) || (0, _fp.isEmpty)(dataProviders.filter(d => d.enabled === true)); }; exports.isDataProviderEmpty = isDataProviderEmpty; const convertToBuildEsQuery = ({ config, indexPattern, queries, filters }) => { try { return [JSON.stringify((0, _esQuery.buildEsQuery)(indexPattern, queries, filters.filter(f => f.meta.disabled === false), { nestedIgnoreUnmapped: true, // by default, prevent shard failures when unmapped `nested` fields are queried: https://github.com/elastic/kibana/issues/130340 ...config, dateFormatTZ: undefined })), undefined]; } catch (error) { return [undefined, error]; } }; exports.convertToBuildEsQuery = convertToBuildEsQuery; const combineQueries = ({ config, dataProviders, indexPattern, browserFields, filters = [], kqlQuery, kqlMode }) => { const kuery = { query: '', language: kqlQuery.language }; if (isDataProviderEmpty(dataProviders) && (0, _fp.isEmpty)(kqlQuery.query) && (0, _fp.isEmpty)(filters)) { return null; } else if (isDataProviderEmpty(dataProviders) && (0, _fp.isEmpty)(kqlQuery.query) && !(0, _fp.isEmpty)(filters)) { const [filterQuery, kqlError] = convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }); return { filterQuery, kqlError }; } const operatorKqlQuery = kqlMode === 'filter' ? 'and' : 'or'; const postpend = q => `${!(0, _fp.isEmpty)(q) ? `(${q})` : ''}`; const globalQuery = buildGlobalQuery(dataProviders, browserFields); // based on Data Providers const querySuffix = postpend(kqlQuery.query); // based on Unified Search bar const queryPrefix = globalQuery ? `(${globalQuery})` : ''; const queryOperator = queryPrefix && querySuffix ? operatorKqlQuery : ''; kuery.query = `(${queryPrefix} ${queryOperator} ${querySuffix})`; const [filterQuery, kqlError] = convertToBuildEsQuery({ config, queries: [kuery], indexPattern, filters }); return { filterQuery, kqlError }; }; exports.combineQueries = combineQueries;