mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution] getDataViewStateFromIndexFields was using wrong type as part of a cast (#158594)
## Summary Fixes an issue with the field browser where all types currently display as unkown, this was because in a code path where a type cast happens, we were using the wrong type. To see this, remove the as unknown from the cast, and the typescript compiler will show the problem: ``` 'BrowserField' is deprecated.ts(6385) index.ts(70, 4): The declaration was marked as deprecated here. Conversion of type 'DataViewField' to type 'BrowserField' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Type 'DataViewField' is missing the following properties from type 'BrowserField': category, description, example, fields, and 2 more.ts(2352) ``` DataViewField actually only has spec and kbnFieldType properties, spec is of type FieldSpec which is basically the same type as BrowserField, and has sufficient overlap for the (still unsafe, but more safe than as unknown) cast to occur. Before: <img width="338" alt="image" src="f31c1f9e
-25f0-41ee-9e1c-a70171e41d29"> After: <img width="555" alt="image" src="8b462477
-2dce-41bb-9592-f34b20634b84"> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
a21ddd02b4
commit
1c75903f92
27 changed files with 131 additions and 239 deletions
|
@ -11,9 +11,14 @@ import type {
|
|||
MappingRuntimeField,
|
||||
MappingRuntimeFields,
|
||||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { RuntimeFieldSpec, RuntimePrimitiveTypes } from '@kbn/data-views-plugin/common';
|
||||
import type { BoolQuery } from '@kbn/es-query';
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
type RunTimeMappings =
|
||||
| Record<string, Omit<RuntimeFieldSpec, 'type'> & { type: RuntimePrimitiveTypes }>
|
||||
| undefined;
|
||||
|
||||
interface BoolAgg {
|
||||
bool: BoolQuery;
|
||||
}
|
||||
|
@ -29,7 +34,7 @@ export interface GroupingQueryArgs {
|
|||
from: string;
|
||||
groupByField: string;
|
||||
rootAggregations?: NamedAggregation[];
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
runtimeMappings?: RunTimeMappings;
|
||||
additionalAggregationsRoot?: NamedAggregation[];
|
||||
pageNumber?: number;
|
||||
uniqueValue: string;
|
||||
|
|
|
@ -27,8 +27,8 @@ import type {
|
|||
TimelineRequestSortField,
|
||||
TimelineStrategyResponseType,
|
||||
} from '@kbn/timelines-plugin/common/search_strategy';
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
|
||||
import { dataTableActions, Direction, TableId } from '@kbn/securitysolution-data-table';
|
||||
import type { RunTimeMappings } from '../../store/sourcerer/model';
|
||||
import { TimelineEventsQueries } from '../../../../common/search_strategy';
|
||||
import type { KueryFilterQueryKind } from '../../../../common/types';
|
||||
import type { ESQuery } from '../../../../common/typed_json';
|
||||
|
@ -77,7 +77,7 @@ export interface UseTimelineEventsProps {
|
|||
indexNames: string[];
|
||||
language?: KueryFilterQueryKind;
|
||||
limit: number;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
skip?: boolean;
|
||||
sort?: TimelineRequestSortField[];
|
||||
startDate: string;
|
||||
|
@ -321,7 +321,7 @@ export const useTimelineEventsHandler = ({
|
|||
querySize: prevRequest?.pagination.querySize ?? 0,
|
||||
sort: prevRequest?.sort ?? initSortDefault,
|
||||
timerange: prevRequest?.timerange ?? {},
|
||||
runtimeMappings: prevRequest?.runtimeMappings ?? {},
|
||||
runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as RunTimeMappings,
|
||||
filterStatus: prevRequest?.filterStatus,
|
||||
};
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
import numeral from '@elastic/numeral';
|
||||
import { css } from '@emotion/react';
|
||||
import type { EuiMarkdownEditorUiPluginEditorProps } from '@elastic/eui/src/components/markdown_editor/markdown_types';
|
||||
import { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { Filter } from '@kbn/es-query';
|
||||
import { FilterStateStore } from '@kbn/es-query';
|
||||
|
@ -245,7 +246,16 @@ const InsightEditorComponent = ({
|
|||
ui: { FiltersBuilderLazy },
|
||||
},
|
||||
uiSettings,
|
||||
fieldFormats,
|
||||
} = useKibana().services;
|
||||
const dataView = useMemo(() => {
|
||||
if (sourcererDataView != null) {
|
||||
return new DataView({ spec: sourcererDataView, fieldFormats });
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [sourcererDataView, fieldFormats]);
|
||||
|
||||
const [providers, setProviders] = useState<Provider[][]>([[]]);
|
||||
const dateRangeChoices = useMemo(() => {
|
||||
const settings: Array<{ from: string; to: string; display: string }> = uiSettings.get(
|
||||
|
@ -419,11 +429,11 @@ const InsightEditorComponent = ({
|
|||
/>
|
||||
</EuiFormRow>
|
||||
<EuiFormRow label={i18n.FILTER_BUILDER} helpText={i18n.FILTER_BUILDER_TEXT} fullWidth>
|
||||
{sourcererDataView ? (
|
||||
{dataView ? (
|
||||
<FiltersBuilderLazy
|
||||
filters={filtersStub}
|
||||
onChange={onChange}
|
||||
dataView={sourcererDataView}
|
||||
dataView={dataView}
|
||||
maxDepth={2}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`source/index.tsx getAllBrowserFields it returns an array of all fields in the BrowserFields argument 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"count": 10,
|
||||
"esTypes": Array [
|
||||
"long",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "bytes",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "number",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"count": 20,
|
||||
"esTypes": Array [
|
||||
"boolean",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "ssl",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "boolean",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"count": 30,
|
||||
"esTypes": Array [
|
||||
"date",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "@timestamp",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "date",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`source/index.tsx getBrowserFields it transforms input into output as expected 1`] = `
|
||||
Object {
|
||||
"base": Object {
|
||||
"fields": Object {
|
||||
"@timestamp": Object {
|
||||
"aggregatable": true,
|
||||
"count": 30,
|
||||
"esTypes": Array [
|
||||
"date",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "@timestamp",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "date",
|
||||
},
|
||||
"bytes": Object {
|
||||
"aggregatable": true,
|
||||
"count": 10,
|
||||
"esTypes": Array [
|
||||
"long",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "bytes",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "number",
|
||||
},
|
||||
"ssl": Object {
|
||||
"aggregatable": true,
|
||||
"count": 20,
|
||||
"esTypes": Array [
|
||||
"boolean",
|
||||
],
|
||||
"isMapped": true,
|
||||
"name": "ssl",
|
||||
"readFromDocValues": true,
|
||||
"scripted": false,
|
||||
"searchable": true,
|
||||
"type": "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
|
@ -5,8 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { IndexField } from '../../../../common/search_strategy/index_fields';
|
||||
import { getBrowserFields, getAllBrowserFields } from '.';
|
||||
import type { IndexFieldSearch } from './use_data_view';
|
||||
import { useDataView } from './use_data_view';
|
||||
import { mocksSource } from './mock';
|
||||
|
@ -27,32 +25,6 @@ jest.mock('../../lib/kibana');
|
|||
jest.mock('../../lib/apm/use_track_http_request');
|
||||
|
||||
describe('source/index.tsx', () => {
|
||||
describe('getAllBrowserFields', () => {
|
||||
test('it returns an array of all fields in the BrowserFields argument', () => {
|
||||
expect(
|
||||
getAllBrowserFields(getBrowserFields('title 1', mocksSource.indexFields as IndexField[]))
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('getBrowserFields', () => {
|
||||
test('it returns an empty object given an empty array', () => {
|
||||
const fields = getBrowserFields('title 1', []);
|
||||
expect(fields).toEqual({});
|
||||
});
|
||||
|
||||
test('it returns the same input given the same title and same fields length', () => {
|
||||
const oldFields = getBrowserFields('title 1', mocksSource.indexFields as IndexField[]);
|
||||
const newFields = getBrowserFields('title 1', mocksSource.indexFields as IndexField[]);
|
||||
// Since it is memoized it will return the same object instance
|
||||
expect(newFields).toBe(oldFields);
|
||||
});
|
||||
|
||||
test('it transforms input into output as expected', () => {
|
||||
const fields = getBrowserFields('title 2', mocksSource.indexFields as IndexField[]);
|
||||
expect(fields).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useDataView hook', () => {
|
||||
const mockSearchResponse = {
|
||||
...mocksSource,
|
||||
|
@ -74,8 +46,8 @@ describe('source/index.tsx', () => {
|
|||
data: {
|
||||
dataViews: {
|
||||
...useKibana().services.data.dataViews,
|
||||
get: async (dataViewId: string, displayErrors?: boolean, refreshFields = false) =>
|
||||
Promise.resolve({
|
||||
get: async (dataViewId: string, displayErrors?: boolean, refreshFields = false) => {
|
||||
const dataViewMock = {
|
||||
id: dataViewId,
|
||||
matchedIndices: refreshFields
|
||||
? ['hello', 'world', 'refreshed']
|
||||
|
@ -88,7 +60,12 @@ describe('source/index.tsx', () => {
|
|||
type: 'keyword',
|
||||
},
|
||||
}),
|
||||
}),
|
||||
};
|
||||
return Promise.resolve({
|
||||
toSpec: () => dataViewMock,
|
||||
...dataViewMock,
|
||||
});
|
||||
},
|
||||
getFieldsForWildcard: async () => Promise.resolve(),
|
||||
},
|
||||
search: {
|
||||
|
@ -178,7 +155,6 @@ describe('source/index.tsx', () => {
|
|||
const {
|
||||
payload: { patternList: newPatternList },
|
||||
} = mockDispatch.mock.calls[1][0];
|
||||
|
||||
expect(patternList).not.toBe(newPatternList);
|
||||
expect(patternList).not.toContain('refreshed*');
|
||||
expect(newPatternList).toContain('refreshed*');
|
||||
|
|
|
@ -9,9 +9,9 @@ import { isEmpty, isEqual, keyBy, pick } from 'lodash/fp';
|
|||
import memoizeOne from 'memoize-one';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type { DataViewBase } from '@kbn/es-query';
|
||||
import type { BrowserField, BrowserFields, IndexField } from '@kbn/timelines-plugin/common';
|
||||
import type { DataView, IIndexPatternFieldList } from '@kbn/data-views-plugin/common';
|
||||
import { getCategory } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { BrowserField, BrowserFields } from '@kbn/timelines-plugin/common';
|
||||
import type { IIndexPatternFieldList } from '@kbn/data-views-plugin/common';
|
||||
import type { DataViewSpec } from '@kbn/data-views-plugin/public';
|
||||
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
import * as i18n from './translations';
|
||||
|
@ -72,35 +72,6 @@ export const getIndexFields = memoizeOne(
|
|||
newArgs[2] === lastArgs[2]
|
||||
);
|
||||
|
||||
/**
|
||||
* HOT Code path where the fields can be 16087 in length or larger. This is
|
||||
* VERY mutatious on purpose to improve the performance of the transform.
|
||||
*/
|
||||
export const getBrowserFields = memoizeOne(
|
||||
(_title: string, fields: IndexField[]): BrowserFields => {
|
||||
// Adds two dangerous casts to allow for mutations within this function
|
||||
type DangerCastForMutation = Record<string, {}>;
|
||||
type DangerCastForBrowserFieldsMutation = Record<
|
||||
string,
|
||||
Omit<BrowserField, 'fields'> & { fields: Record<string, BrowserField> }
|
||||
>;
|
||||
|
||||
// We mutate this instead of using lodash/set to keep this as fast as possible
|
||||
return fields.reduce<DangerCastForBrowserFieldsMutation>((accumulator, field) => {
|
||||
const category = getCategory(field.name);
|
||||
if (accumulator[category] == null) {
|
||||
(accumulator as DangerCastForMutation)[category] = {};
|
||||
}
|
||||
if (accumulator[category].fields == null) {
|
||||
accumulator[category].fields = {};
|
||||
}
|
||||
accumulator[category].fields[field.name] = field as unknown as BrowserField;
|
||||
return accumulator;
|
||||
}, {});
|
||||
},
|
||||
(newArgs, lastArgs) => newArgs[0] === lastArgs[0] && newArgs[1].length === lastArgs[1].length
|
||||
);
|
||||
|
||||
const DEFAULT_BROWSER_FIELDS = {};
|
||||
const DEFAULT_INDEX_PATTERNS = { fields: [], title: '' };
|
||||
interface FetchIndexReturn {
|
||||
|
@ -115,7 +86,7 @@ interface FetchIndexReturn {
|
|||
indexes: string[];
|
||||
indexExists: boolean;
|
||||
indexPatterns: DataViewBase;
|
||||
dataView: DataView | undefined;
|
||||
dataView: DataViewSpec | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,9 +120,10 @@ export const useFetchIndex = (
|
|||
setState({ ...state, loading: true });
|
||||
abortCtrl.current = new AbortController();
|
||||
const dv = await data.dataViews.create({ title: iNames.join(','), allowNoIndex: true });
|
||||
const dataView = dv.toSpec();
|
||||
const { browserFields } = getDataViewStateFromIndexFields(
|
||||
iNames,
|
||||
dv.fields,
|
||||
dataView.fields,
|
||||
includeUnmapped
|
||||
);
|
||||
|
||||
|
@ -159,7 +131,7 @@ export const useFetchIndex = (
|
|||
|
||||
setState({
|
||||
loading: false,
|
||||
dataView: dv,
|
||||
dataView,
|
||||
browserFields,
|
||||
indexes: dv.getIndexPattern().split(','),
|
||||
indexExists: dv.getIndexPattern().split(',').length > 0,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { MappingRuntimeFieldType } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants';
|
||||
import type { BrowserFields } from '../../../../common/search_strategy/index_fields';
|
||||
|
||||
|
@ -577,11 +577,13 @@ export const mockBrowserFields: BrowserFields = {
|
|||
},
|
||||
};
|
||||
|
||||
export const mockRuntimeMappings: MappingRuntimeFields = {
|
||||
const runTimeType: MappingRuntimeFieldType = 'keyword' as const;
|
||||
|
||||
export const mockRuntimeMappings = {
|
||||
'@a.runtime.field': {
|
||||
script: {
|
||||
source: 'emit("Radical dude: " + doc[\'host.name\'].value)',
|
||||
},
|
||||
type: 'keyword',
|
||||
type: runTimeType,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -9,9 +9,9 @@ import { useCallback, useRef } from 'react';
|
|||
import type { Subscription } from 'rxjs';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import memoizeOne from 'memoize-one';
|
||||
import type { BrowserField } from '@kbn/timelines-plugin/common';
|
||||
import type { BrowserField, BrowserFields } from '@kbn/timelines-plugin/common';
|
||||
import { getCategory } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { DataViewFieldBase } from '@kbn/es-query';
|
||||
import type { DataViewSpec } from '@kbn/data-views-plugin/public';
|
||||
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
import { sourcererActions } from '../../store/sourcerer';
|
||||
|
@ -50,34 +50,31 @@ interface DataViewInfo {
|
|||
export const getDataViewStateFromIndexFields = memoizeOne(
|
||||
(
|
||||
_title: string,
|
||||
fields: DataViewFieldBase[],
|
||||
fields: DataViewSpec['fields'],
|
||||
_includeUnmapped: boolean = false
|
||||
): DataViewInfo => {
|
||||
// Adds two dangerous casts to allow for mutations within this function
|
||||
type DangerCastForMutation = Record<string, {}>;
|
||||
|
||||
return fields.reduce<DataViewInfo>(
|
||||
(acc, field) => {
|
||||
// mutate browserFields
|
||||
const category = getCategory(field.name);
|
||||
if (acc.browserFields[category] == null) {
|
||||
(acc.browserFields as DangerCastForMutation)[category] = {};
|
||||
if (fields == null) {
|
||||
return { browserFields: {} };
|
||||
} else {
|
||||
const browserFields: BrowserFields = {};
|
||||
for (const [name, field] of Object.entries(fields)) {
|
||||
const category = getCategory(name);
|
||||
if (browserFields[category] == null) {
|
||||
(browserFields as DangerCastForMutation)[category] = { fields: {} };
|
||||
}
|
||||
if (acc.browserFields[category].fields == null) {
|
||||
acc.browserFields[category].fields = {};
|
||||
const categoryFields = browserFields[category].fields;
|
||||
if (categoryFields) {
|
||||
categoryFields[name] = field as BrowserField;
|
||||
}
|
||||
acc.browserFields[category].fields[field.name] = field as unknown as BrowserField;
|
||||
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
browserFields: {},
|
||||
}
|
||||
);
|
||||
return { browserFields: browserFields as DangerCastForBrowserFieldsMutation };
|
||||
}
|
||||
},
|
||||
(newArgs, lastArgs) =>
|
||||
newArgs[0] === lastArgs[0] &&
|
||||
newArgs[1].length === lastArgs[1].length &&
|
||||
newArgs[1]?.length === lastArgs[1]?.length &&
|
||||
newArgs[2] === lastArgs[2]
|
||||
);
|
||||
|
||||
|
@ -89,7 +86,6 @@ export const useDataView = (): {
|
|||
const searchSubscription$ = useRef<Record<string, Subscription>>({});
|
||||
const dispatch = useDispatch();
|
||||
const { addError } = useAppToasts();
|
||||
|
||||
const setLoading = useCallback(
|
||||
({ id, loading }: { id: string; loading: boolean }) => {
|
||||
dispatch(sourcererActions.setDataViewLoading({ id, loading }));
|
||||
|
@ -113,7 +109,6 @@ export const useDataView = (): {
|
|||
setLoading({ id: dataViewId, loading: true });
|
||||
|
||||
const dataView = await getSourcererDataView(dataViewId, data.dataViews, cleanCache);
|
||||
|
||||
if (needToBeInit && scopeId && !skipScopeUpdate) {
|
||||
dispatch(
|
||||
sourcererActions.setSelectedDataView({
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import type { DataViewsContract } from '@kbn/data-views-plugin/common';
|
||||
import { ensurePatternFormat } from '../../../../common/utils/sourcerer';
|
||||
import type { SourcererDataView } from '../../store/sourcerer/model';
|
||||
import type { SourcererDataView, RunTimeMappings } from '../../store/sourcerer/model';
|
||||
import { getDataViewStateFromIndexFields } from '../source/use_data_view';
|
||||
|
||||
export const getSourcererDataView = async (
|
||||
|
@ -15,8 +15,9 @@ export const getSourcererDataView = async (
|
|||
dataViewsService: DataViewsContract,
|
||||
refreshFields = false
|
||||
): Promise<SourcererDataView> => {
|
||||
const dataViewData = await dataViewsService.get(dataViewId, true, refreshFields);
|
||||
const defaultPatternsList = ensurePatternFormat(dataViewData.getIndexPattern().split(','));
|
||||
const dataView = await dataViewsService.get(dataViewId, true, refreshFields);
|
||||
const dataViewData = dataView.toSpec();
|
||||
const defaultPatternsList = ensurePatternFormat(dataView.getIndexPattern().split(','));
|
||||
|
||||
// typeguard used to assert that pattern is a string, otherwise
|
||||
// typescript expects patternList to be (string | null)[]
|
||||
|
@ -45,15 +46,13 @@ export const getSourcererDataView = async (
|
|||
return {
|
||||
loading: false,
|
||||
id: dataViewData.id ?? '',
|
||||
title: dataViewData.getIndexPattern(),
|
||||
indexFields: dataViewData.fields,
|
||||
title: dataView.getIndexPattern(),
|
||||
indexFields: dataView.fields,
|
||||
fields: dataViewData.fields,
|
||||
patternList,
|
||||
dataView: dataViewData,
|
||||
browserFields: getDataViewStateFromIndexFields(
|
||||
dataViewData.id ?? '',
|
||||
dataViewData.fields != null ? dataViewData.fields : []
|
||||
).browserFields,
|
||||
runtimeMappings: dataViewData.getRuntimeMappings(),
|
||||
browserFields: getDataViewStateFromIndexFields(dataViewData.id ?? '', dataViewData.fields)
|
||||
.browserFields,
|
||||
runtimeMappings: dataViewData.runtimeFieldMap as RunTimeMappings,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -245,7 +245,7 @@ describe('Sourcerer Hooks', () => {
|
|||
type: 'x-pack/security_solution/local/sourcerer/SET_SOURCERER_SCOPE_LOADING',
|
||||
payload: { loading: false },
|
||||
});
|
||||
expect(mockDispatch).toHaveBeenCalledTimes(9);
|
||||
expect(mockDispatch).toHaveBeenCalledTimes(7);
|
||||
expect(mockSearch).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
|||
SelectedDataView,
|
||||
SourcererDataView,
|
||||
SourcererUrlState,
|
||||
RunTimeMappings,
|
||||
} from '../../store/sourcerer/model';
|
||||
import { SourcererScopeName } from '../../store/sourcerer/model';
|
||||
import { useUserInfo } from '../../../detections/components/user_info';
|
||||
|
@ -395,14 +396,14 @@ export const useSourcererDataView = (
|
|||
() => ({
|
||||
...fetchIndexReturn,
|
||||
dataView: fetchIndexReturn.dataView,
|
||||
runtimeMappings: fetchIndexReturn.dataView?.getRuntimeMappings() ?? {},
|
||||
title: fetchIndexReturn.dataView?.getIndexPattern() ?? '',
|
||||
runtimeMappings: (fetchIndexReturn.dataView?.runtimeFieldMap as RunTimeMappings) ?? {},
|
||||
title: fetchIndexReturn.dataView?.title ?? '',
|
||||
id: fetchIndexReturn.dataView?.id ?? null,
|
||||
loading: indexPatternsLoading,
|
||||
patternList: fetchIndexReturn.indexes,
|
||||
indexFields: fetchIndexReturn.indexPatterns
|
||||
.fields as SelectedDataView['indexPattern']['fields'],
|
||||
fields: fetchIndexReturn.indexPatterns.fields,
|
||||
fields: fetchIndexReturn.dataView?.fields,
|
||||
}),
|
||||
[fetchIndexReturn, indexPatternsLoading]
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { TableId } from '@kbn/securitysolution-data-table';
|
||||
import type { DataViewSpec } from '@kbn/data-views-plugin/public';
|
||||
import { InputsModelId } from '../store/inputs/constants';
|
||||
import {
|
||||
Direction,
|
||||
|
@ -48,6 +49,10 @@ import { UsersFields } from '../../../common/search_strategy/security_solution/u
|
|||
import { initialGroupingState } from '../store/grouping/reducer';
|
||||
import type { SourcererState } from '../store/sourcerer';
|
||||
|
||||
const mockFieldMap: DataViewSpec['fields'] = Object.fromEntries(
|
||||
mockIndexFields.map((field) => [field.name, field])
|
||||
);
|
||||
|
||||
export const mockSourcererState: SourcererState = {
|
||||
...initialSourcererState,
|
||||
signalIndexName: `${DEFAULT_SIGNALS_INDEX}-spacename`,
|
||||
|
@ -56,7 +61,7 @@ export const mockSourcererState: SourcererState = {
|
|||
browserFields: mockBrowserFields,
|
||||
id: DEFAULT_DATA_VIEW_ID,
|
||||
indexFields: mockIndexFields,
|
||||
fields: mockIndexFields,
|
||||
fields: mockFieldMap,
|
||||
loading: false,
|
||||
patternList: [...DEFAULT_INDEX_PATTERN, `${DEFAULT_SIGNALS_INDEX}-spacename`],
|
||||
runtimeMappings: mockRuntimeMappings,
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import type { DataViewFieldBase } from '@kbn/es-query';
|
||||
import type { BrowserFields } from '@kbn/timelines-plugin/common';
|
||||
import { EMPTY_BROWSER_FIELDS, EMPTY_INDEX_FIELDS } from '@kbn/timelines-plugin/common';
|
||||
import type { DataViewSpec } from '@kbn/data-views-plugin/public';
|
||||
import type { RuntimeFieldSpec, RuntimePrimitiveTypes } from '@kbn/data-views-plugin/common';
|
||||
import type { SecuritySolutionDataViewBase } from '../../types';
|
||||
|
||||
/** Uniquely identifies a Sourcerer Scope */
|
||||
export enum SourcererScopeName {
|
||||
default = 'default',
|
||||
|
@ -52,6 +52,10 @@ export interface KibanaDataView {
|
|||
title: string;
|
||||
}
|
||||
|
||||
export type RunTimeMappings =
|
||||
| Record<string, Omit<RuntimeFieldSpec, 'type'> & { type: RuntimePrimitiveTypes }>
|
||||
| undefined;
|
||||
|
||||
/**
|
||||
* DataView from Kibana + timelines/index_fields enhanced field data
|
||||
*/
|
||||
|
@ -68,7 +72,7 @@ export interface SourcererDataView extends KibanaDataView {
|
|||
* @deprecated use sourcererDataView.fields
|
||||
* comes from dataView.fields.toSpec() */
|
||||
indexFields: SecuritySolutionDataViewBase['fields'];
|
||||
fields: DataViewFieldBase[];
|
||||
fields: DataViewSpec['fields'] | undefined;
|
||||
/** set when data view fields are fetched */
|
||||
loading: boolean;
|
||||
/**
|
||||
|
@ -76,11 +80,11 @@ export interface SourcererDataView extends KibanaDataView {
|
|||
* Needed to pass to search strategy
|
||||
* Remove once issue resolved: https://github.com/elastic/kibana/issues/111762
|
||||
*/
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
/**
|
||||
* @type DataView @kbn/data-views-plugin/common
|
||||
*/
|
||||
dataView: DataView | undefined;
|
||||
dataView: DataViewSpec | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,7 +129,7 @@ export interface SelectedDataView {
|
|||
* Easier to add this additional data rather than
|
||||
* try to extend the SelectedDataView type from DataView.
|
||||
*/
|
||||
sourcererDataView: DataView | undefined;
|
||||
sourcererDataView: DataViewSpec | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,11 +159,12 @@ export const initSourcererScope: Omit<SourcererScope, 'id'> = {
|
|||
selectedPatterns: [],
|
||||
missingPatterns: [],
|
||||
};
|
||||
|
||||
export const initDataView: SourcererDataView & { id: string; error?: unknown } = {
|
||||
browserFields: EMPTY_BROWSER_FIELDS,
|
||||
id: '',
|
||||
indexFields: EMPTY_INDEX_FIELDS,
|
||||
fields: EMPTY_INDEX_FIELDS,
|
||||
fields: undefined,
|
||||
loading: false,
|
||||
patternList: [],
|
||||
runtimeMappings: {},
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import type { Filter, Query } from '@kbn/es-query';
|
||||
import { isNoneGroup, useGrouping } from '@kbn/securitysolution-grouping';
|
||||
import { isEmpty, isEqual } from 'lodash/fp';
|
||||
import type { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import type { TableIdLiteral } from '@kbn/securitysolution-data-table';
|
||||
import { getDefaultGroupingOptions } from '../../../common/utils/alerts';
|
||||
import { groupIdSelector } from '../../../common/store/grouping/selectors';
|
||||
import { getDefaultGroupingOptions } from '../../../common/utils/alerts';
|
||||
import { useDeepEqualSelector } from '../../../common/hooks/use_selector';
|
||||
import { updateGroups } from '../../../common/store/grouping/actions';
|
||||
import type { Status } from '../../../../common/detection_engine/schemas/common';
|
||||
import { defaultUnit } from '../../../common/components/toolbar/unit';
|
||||
import { useSourcererDataView } from '../../../common/containers/sourcerer';
|
||||
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
|
||||
import type { RunTimeMappings } from '../../../common/store/sourcerer/model';
|
||||
import { renderGroupPanel, getStats } from './grouping_settings';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { GroupedSubLevel } from './alerts_sub_grouping';
|
||||
|
@ -36,7 +36,7 @@ export interface AlertsTableComponentProps {
|
|||
hasIndexWrite: boolean;
|
||||
loading: boolean;
|
||||
renderChildComponent: (groupingFilters: Filter[]) => React.ReactElement;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
signalIndexName: string | null;
|
||||
tableId: TableIdLiteral;
|
||||
to: string;
|
||||
|
|
|
@ -13,9 +13,9 @@ import type { GroupingAggregation } from '@kbn/securitysolution-grouping';
|
|||
import { isNoneGroup } from '@kbn/securitysolution-grouping';
|
||||
import { getEsQueryConfig } from '@kbn/data-plugin/common';
|
||||
import type { DynamicGroupingProps } from '@kbn/securitysolution-grouping/src';
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { TableIdLiteral } from '@kbn/securitysolution-data-table';
|
||||
import { parseGroupingQuery } from '@kbn/securitysolution-grouping/src';
|
||||
import type { RunTimeMappings } from '../../../common/store/sourcerer/model';
|
||||
import { combineQueries } from '../../../common/lib/kuery';
|
||||
import { SourcererScopeName } from '../../../common/store/sourcerer/model';
|
||||
import type { AlertsGroupingAggregation } from './grouping_settings/types';
|
||||
|
@ -53,7 +53,7 @@ interface OwnProps {
|
|||
pageSize: number;
|
||||
parentGroupingFilter?: string;
|
||||
renderChildComponent: (groupingFilters: Filter[]) => React.ReactElement;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
selectedGroup: string;
|
||||
setPageIndex: (newIndex: number) => void;
|
||||
setPageSize: (newSize: number) => void;
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/types';
|
||||
import type { BoolQuery } from '@kbn/es-query';
|
||||
import type { NamedAggregation } from '@kbn/securitysolution-grouping';
|
||||
import { isNoneGroup, getGroupingQuery } from '@kbn/securitysolution-grouping';
|
||||
import type { RunTimeMappings } from '../../../../common/store/sourcerer/model';
|
||||
|
||||
interface AlertsGroupingQueryParams {
|
||||
additionalFilters: Array<{
|
||||
|
@ -17,7 +17,7 @@ interface AlertsGroupingQueryParams {
|
|||
from: string;
|
||||
pageIndex: number;
|
||||
pageSize: number;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
selectedGroup: string;
|
||||
uniqueValue: string;
|
||||
to: string;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { Filter, Query } from '@kbn/es-query';
|
||||
import { EuiFlexItem, EuiSkeletonText } from '@elastic/eui';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
|
@ -19,6 +18,7 @@ import { ChartSelect } from './chart_select';
|
|||
import { ChartCollapse } from './chart_collapse';
|
||||
import * as i18n from './chart_select/translations';
|
||||
import { AlertsTreemapPanel } from '../../../../common/components/alerts_treemap_panel';
|
||||
import type { RunTimeMappings } from '../../../../common/store/sourcerer/model';
|
||||
import type { UpdateDateRange } from '../../../../common/components/charts/common';
|
||||
import { useEuiComboBoxReset } from '../../../../common/components/use_combo_box_reset';
|
||||
import { AlertsHistogramPanel } from '../../../components/alerts_kpis/alerts_histogram_panel';
|
||||
|
@ -51,7 +51,7 @@ export interface Props {
|
|||
alertsDefaultFilters: Filter[];
|
||||
isLoadingIndexPattern: boolean;
|
||||
query: Query;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
signalIndexName: string | null;
|
||||
updateDateRangeCallback: UpdateDateRange;
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@ import { EuiSpacer, EuiFlyoutBody } from '@elastic/eui';
|
|||
import React, { useMemo } from 'react';
|
||||
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { EntityType } from '@kbn/timelines-plugin/common';
|
||||
import type { BrowserFields } from '../../../../common/containers/source';
|
||||
import { ExpandableEvent, ExpandableEventTitle } from './expandable_event';
|
||||
import { useTimelineEventsDetails } from '../../../containers/details';
|
||||
import type { TimelineTabs } from '../../../../../common/types/timeline';
|
||||
import type { RunTimeMappings } from '../../../../common/store/sourcerer/model';
|
||||
import { useHostIsolationTools } from './use_host_isolation_tools';
|
||||
import { FlyoutBody, FlyoutHeader, FlyoutFooter } from './flyout';
|
||||
import { useBasicDataFromDetailsData, getAlertIndexAlias } from './helpers';
|
||||
|
@ -33,7 +33,7 @@ interface EventDetailsPanelProps {
|
|||
handleOnEventClosed: () => void;
|
||||
isDraggable?: boolean;
|
||||
isFlyoutView?: boolean;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
tabType: TimelineTabs;
|
||||
scopeId: string;
|
||||
isReadOnly?: boolean;
|
||||
|
|
|
@ -10,13 +10,13 @@ import { useDispatch } from 'react-redux';
|
|||
import type { EuiFlyoutProps } from '@elastic/eui';
|
||||
import { EuiFlyout } from '@elastic/eui';
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { EntityType } from '@kbn/timelines-plugin/common';
|
||||
import { dataTableActions, dataTableSelectors } from '@kbn/securitysolution-data-table';
|
||||
import { getScopedActions, isInTableScope, isTimelineScope } from '../../../helpers';
|
||||
import { timelineSelectors } from '../../store/timeline';
|
||||
import { timelineDefaults } from '../../store/timeline/defaults';
|
||||
import type { BrowserFields } from '../../../common/containers/source';
|
||||
import type { RunTimeMappings } from '../../../common/store/sourcerer/model';
|
||||
import { TimelineId, TimelineTabs } from '../../../../common/types/timeline';
|
||||
import { useDeepEqualSelector } from '../../../common/hooks/use_selector';
|
||||
import { EventDetailsPanel } from './event_details';
|
||||
|
@ -30,7 +30,7 @@ interface DetailsPanelProps {
|
|||
entityType?: EntityType;
|
||||
handleOnPanelClosed?: () => void;
|
||||
isFlyoutView?: boolean;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
tabType?: TimelineTabs;
|
||||
scopeId: string;
|
||||
isReadOnly?: boolean;
|
||||
|
|
|
@ -11,11 +11,11 @@ import ReactDOM from 'react-dom';
|
|||
import deepEqual from 'fast-deep-equal';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
|
||||
import { EntityType } from '@kbn/timelines-plugin/common';
|
||||
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import type { RunTimeMappings } from '../../../common/store/sourcerer/model';
|
||||
import type {
|
||||
SearchHit,
|
||||
TimelineEventsDetailsItem,
|
||||
|
@ -35,7 +35,7 @@ export interface UseTimelineEventsDetailsProps {
|
|||
entityType?: EntityType;
|
||||
indexName: string;
|
||||
eventId: string;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
skip: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { DataView } from '@kbn/data-plugin/common';
|
||||
import { isCompleteResponse, isErrorResponse } from '@kbn/data-plugin/common';
|
||||
import type { ESQuery } from '../../../common/typed_json';
|
||||
|
||||
import type { inputsModel } from '../../common/store';
|
||||
import type { RunTimeMappings } from '../../common/store/sourcerer/model';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
import { createFilter } from '../../common/containers/helpers';
|
||||
import { timelineActions } from '../store/timeline';
|
||||
|
@ -89,7 +89,7 @@ export interface UseTimelineEventsProps {
|
|||
indexNames: string[];
|
||||
language?: KueryFilterQueryKind;
|
||||
limit: number;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
skip?: boolean;
|
||||
sort?: TimelineRequestSortField[];
|
||||
startDate?: string;
|
||||
|
@ -356,7 +356,7 @@ export const useTimelineEventsHandler = ({
|
|||
querySize: prevRequest?.pagination.querySize ?? 0,
|
||||
sort: prevRequest?.sort ?? initSortDefault,
|
||||
timerange: prevRequest?.timerange ?? {},
|
||||
runtimeMappings: prevRequest?.runtimeMappings ?? {},
|
||||
runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as RunTimeMappings,
|
||||
...deStructureEqlOptions(prevEqlRequest),
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { BehaviorSubject, Observable } from 'rxjs';
|
|||
import type { AppLeaveHandler, CoreStart } from '@kbn/core/public';
|
||||
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { FieldFormatsStartCommon } from '@kbn/field-formats-plugin/common';
|
||||
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
|
||||
import type { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import type { NewsfeedPublicPluginStart } from '@kbn/newsfeed-plugin/public';
|
||||
|
@ -108,6 +109,7 @@ export interface StartPlugins {
|
|||
threatIntelligence: ThreatIntelligencePluginStart;
|
||||
cloudExperiments?: CloudExperimentsPluginStart;
|
||||
dataViews: DataViewsServicePublic;
|
||||
fieldFormats: FieldFormatsStartCommon;
|
||||
}
|
||||
|
||||
export interface StartPluginsDependencies extends StartPlugins {
|
||||
|
|
|
@ -157,6 +157,7 @@
|
|||
"@kbn/ecs",
|
||||
"@kbn/url-state",
|
||||
"@kbn/ml-anomaly-utils",
|
||||
"@kbn/field-formats-plugin",
|
||||
"@kbn/dev-proc-runner"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export interface BrowserField {
|
|||
category: string;
|
||||
description: string | null;
|
||||
example: string | number | null;
|
||||
fields: Readonly<Record<string, Partial<BrowserField>>>;
|
||||
fields: Record<string, Partial<BrowserField>>;
|
||||
format: string;
|
||||
indexes: string[];
|
||||
name: string;
|
||||
|
@ -97,7 +97,7 @@ export interface BrowserField {
|
|||
* you are working with? Or perhaps you need a description for a
|
||||
* particular field? Consider using the EcsFlat module from `@kbn/ecs`
|
||||
*/
|
||||
export type BrowserFields = Readonly<Record<string, Partial<BrowserField>>>;
|
||||
export type BrowserFields = Record<string, Partial<BrowserField>>;
|
||||
|
||||
export const EMPTY_BROWSER_FIELDS = {};
|
||||
export const EMPTY_INDEX_FIELDS: FieldSpec[] = [];
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
import { JsonObject } from '@kbn/utility-types';
|
||||
|
||||
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { IEsSearchResponse } from '@kbn/data-plugin/common';
|
||||
import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs';
|
||||
import type { CursorType, Inspect, Maybe, PaginationInputPaginated } from '../../../common';
|
||||
import type { TimelineRequestOptionsPaginated } from '../..';
|
||||
import type { RunTimeMappings } from '../eql';
|
||||
|
||||
export interface TimelineEdges {
|
||||
node: TimelineItem;
|
||||
|
@ -45,6 +45,6 @@ export interface TimelineEventsAllRequestOptions extends TimelineRequestOptionsP
|
|||
fieldRequested: string[];
|
||||
fields: string[] | Array<{ field: string; include_unmapped: boolean }>;
|
||||
language: 'eql' | 'kuery' | 'lucene';
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
filterStatus?: AlertWorkflowStatus;
|
||||
}
|
||||
|
|
|
@ -6,10 +6,20 @@
|
|||
*/
|
||||
|
||||
import { EuiComboBoxOptionOption } from '@elastic/eui';
|
||||
import type { EqlSearchStrategyRequest, EqlSearchStrategyResponse } from '@kbn/data-plugin/common';
|
||||
import type {
|
||||
EqlSearchStrategyRequest,
|
||||
EqlSearchStrategyResponse,
|
||||
EqlRequestParams,
|
||||
} from '@kbn/data-plugin/common';
|
||||
import type { RuntimeFieldSpec, RuntimePrimitiveTypes } from '@kbn/data-views-plugin/common';
|
||||
import { EqlSearchResponse, Inspect, Maybe, PaginationInputPaginated } from '../../..';
|
||||
import { TimelineEdges, TimelineEventsAllRequestOptions } from '../..';
|
||||
|
||||
type EqlBody = Pick<EqlRequestParams, 'body'>;
|
||||
|
||||
export type RunTimeMappings =
|
||||
| Record<string, Omit<RuntimeFieldSpec, 'type'> & { type: RuntimePrimitiveTypes }>
|
||||
| undefined;
|
||||
export interface TimelineEqlRequestOptions
|
||||
extends EqlSearchStrategyRequest,
|
||||
Omit<TimelineEventsAllRequestOptions, 'params'> {
|
||||
|
@ -17,6 +27,8 @@ export interface TimelineEqlRequestOptions
|
|||
tiebreakerField?: string;
|
||||
timestampField?: string;
|
||||
size?: number;
|
||||
runtime_mappings?: RunTimeMappings;
|
||||
body?: Omit<EqlRequestParams, 'body'> & EqlBody & { runtime_mappings?: RunTimeMappings };
|
||||
}
|
||||
|
||||
export interface TimelineEqlResponse extends EqlSearchStrategyResponse<EqlSearchResponse<unknown>> {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { IEsSearchRequest } from '@kbn/data-plugin/common';
|
||||
import { ESQuery } from '../../typed_json';
|
||||
import {
|
||||
|
@ -26,6 +25,7 @@ import {
|
|||
TimelineStatus,
|
||||
RowRendererId,
|
||||
} from '../../types/timeline';
|
||||
import type { RunTimeMappings } from './events/eql';
|
||||
|
||||
export * from './events';
|
||||
|
||||
|
@ -37,7 +37,7 @@ export interface TimelineRequestBasicOptions extends IEsSearchRequest {
|
|||
defaultIndex: string[];
|
||||
factoryQueryType?: TimelineFactoryQueryTypes;
|
||||
entityType?: EntityType;
|
||||
runtimeMappings: MappingRuntimeFields;
|
||||
runtimeMappings: RunTimeMappings;
|
||||
}
|
||||
|
||||
export interface TimelineRequestSortField<Field = string> extends SortField<Field> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue