From 5dd68dd7b392d6ae8089dbe8d4a00f5e98fb902e Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Tue, 27 Jul 2021 09:12:02 -0600 Subject: [PATCH] [Security Solutions] Removes deprecated types in kbn-securitysolution-* for newer kbn-es-query types (#106801) ## Summary Fixes https://github.com/elastic/kibana/issues/105731, by replacing these `any` types: ```json type IFieldType = any; type IIndexPattern = any; type Filter = any; ``` With the types from `es-query` which are: * IndexPatternFieldBase * IndexPatternBase * Filter Note: I had to do a few creative casting to avoid having to use `FieldSpec` since that is not within the package `es-query` and is not planned to be within that package or another package for at least a while if ever. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../BUILD.bazel | 1 + .../README.md | 2 +- .../src/check_empty_value/index.ts | 7 +- .../src/field/index.tsx | 38 +- .../src/field_value_lists/index.tsx | 7 +- .../src/field_value_match/index.test.tsx | 16 +- .../src/field_value_match/index.tsx | 11 +- .../src/field_value_match_any/index.test.tsx | 12 +- .../src/field_value_match_any/index.tsx | 10 +- .../src/fields/index.mock.ts | 9 +- .../src/filter_field_to_list/index.test.ts | 46 ++- .../src/filter_field_to_list/index.ts | 14 +- .../src/get_operators/index.test.ts | 5 - .../src/get_operators/index.ts | 8 +- .../index.test.ts | 8 +- .../use_field_value_autocomplete/index.ts | 14 +- .../src/operator/index.test.tsx | 5 - .../src/operator/index.tsx | 7 +- .../src/param_is_valid/index.ts | 7 +- .../BUILD.bazel | 1 + .../src/build_exception_filter/index.ts | 11 +- .../src/helpers/index.ts | 37 +- .../src/types/index.ts | 11 +- .../components/builder/builder.stories.tsx | 4 +- .../builder/entry_renderer.stories.tsx | 2 +- .../builder/entry_renderer.test.tsx | 51 +-- .../components/builder/entry_renderer.tsx | 10 +- .../builder/exception_item_renderer.tsx | 9 +- .../builder/exception_items_renderer.tsx | 9 +- .../components/builder/helpers.test.ts | 335 +++++++++--------- .../components/exceptions/helpers.test.tsx | 9 +- .../common/components/exceptions/helpers.tsx | 8 +- .../components/threat_match/entry_item.tsx | 7 +- .../components/threat_match/helpers.test.tsx | 14 +- .../components/threat_match/helpers.tsx | 7 +- .../common/components/threat_match/types.ts | 6 +- .../rules/autocomplete_field/index.tsx | 7 +- .../rules/risk_score_mapping/index.tsx | 16 +- .../rules/severity_mapping/index.tsx | 17 +- 39 files changed, 399 insertions(+), 399 deletions(-) diff --git a/packages/kbn-securitysolution-autocomplete/BUILD.bazel b/packages/kbn-securitysolution-autocomplete/BUILD.bazel index 8e403a215d81d8..c29f6d6badc6fe 100644 --- a/packages/kbn-securitysolution-autocomplete/BUILD.bazel +++ b/packages/kbn-securitysolution-autocomplete/BUILD.bazel @@ -36,6 +36,7 @@ SRC_DEPS = [ "//packages/kbn-i18n", "//packages/kbn-securitysolution-io-ts-list-types", "//packages/kbn-securitysolution-list-hooks", + "//packages/kbn-es-query", "@npm//@babel/core", "@npm//babel-loader", "@npm//@elastic/eui", diff --git a/packages/kbn-securitysolution-autocomplete/README.md b/packages/kbn-securitysolution-autocomplete/README.md index fb500ca0761e33..6212b9719679ea 100644 --- a/packages/kbn-securitysolution-autocomplete/README.md +++ b/packages/kbn-securitysolution-autocomplete/README.md @@ -12,7 +12,7 @@ This hook uses the kibana `services.data.autocomplete.getValueSuggestions()` ser This component can be used to display available indexPattern fields. It requires an indexPattern to be passed in and will show an error state if value is not one of the available indexPattern fields. Users will be able to select only one option. -The `onChange` handler is passed `IFieldType[]`. +The `onChange` handler is passed `IndexPatternFieldBase[]`. ```js { diff --git a/packages/kbn-securitysolution-autocomplete/src/field/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field/index.tsx index 43342079ef92b5..69408e919bb1e1 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field/index.tsx @@ -8,11 +8,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; - -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -type IFieldType = any; -type IIndexPattern = any; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { getGenericComboBoxProps, @@ -24,14 +20,14 @@ const AS_PLAIN_TEXT = { asPlainText: true }; interface OperatorProps { fieldInputWidth?: number; fieldTypeFilter?: string[]; - indexPattern: IIndexPattern | undefined; + indexPattern: IndexPatternBase | undefined; isClearable: boolean; isDisabled: boolean; isLoading: boolean; isRequired?: boolean; - onChange: (a: IFieldType[]) => void; + onChange: (a: IndexPatternFieldBase[]) => void; placeholder: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; } export const FieldComponent: React.FC = ({ @@ -60,7 +56,7 @@ export const FieldComponent: React.FC = ({ const handleValuesChange = useCallback( (newOptions: EuiComboBoxOptionOption[]): void => { - const newValues: IFieldType[] = newOptions.map( + const newValues: IndexPatternFieldBase[] = newOptions.map( ({ label }) => availableFields[labels.indexOf(label)] ); onChange(newValues); @@ -98,13 +94,13 @@ export const FieldComponent: React.FC = ({ FieldComponent.displayName = 'Field'; interface ComboBoxFields { - availableFields: IFieldType[]; - selectedFields: IFieldType[]; + availableFields: IndexPatternFieldBase[]; + selectedFields: IndexPatternFieldBase[]; } const getComboBoxFields = ( - indexPattern: IIndexPattern | undefined, - selectedField: IFieldType | undefined, + indexPattern: IndexPatternBase | undefined, + selectedField: IndexPatternFieldBase | undefined, fieldTypeFilter: string[] ): ComboBoxFields => { const existingFields = getExistingFields(indexPattern); @@ -117,27 +113,29 @@ const getComboBoxFields = ( const getComboBoxProps = (fields: ComboBoxFields): GetGenericComboBoxPropsReturn => { const { availableFields, selectedFields } = fields; - return getGenericComboBoxProps({ + return getGenericComboBoxProps({ getLabel: (field) => field.name, options: availableFields, selectedOptions: selectedFields, }); }; -const getExistingFields = (indexPattern: IIndexPattern | undefined): IFieldType[] => { +const getExistingFields = (indexPattern: IndexPatternBase | undefined): IndexPatternFieldBase[] => { return indexPattern != null ? indexPattern.fields : []; }; -const getSelectedFields = (selectedField: IFieldType | undefined): IFieldType[] => { +const getSelectedFields = ( + selectedField: IndexPatternFieldBase | undefined +): IndexPatternFieldBase[] => { return selectedField ? [selectedField] : []; }; const getAvailableFields = ( - existingFields: IFieldType[], - selectedFields: IFieldType[], + existingFields: IndexPatternFieldBase[], + selectedFields: IndexPatternFieldBase[], fieldTypeFilter: string[] -): IFieldType[] => { - const fieldsByName = new Map(); +): IndexPatternFieldBase[] => { + const fieldsByName = new Map(); existingFields.forEach((f) => fieldsByName.set(f.name, f)); selectedFields.forEach((f) => fieldsByName.set(f.name, f)); diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx index 4064ff11962bde..093643c3a54698 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_lists/index.tsx @@ -10,14 +10,11 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import type { ListSchema } from '@kbn/securitysolution-io-ts-list-types'; import { useFindLists } from '@kbn/securitysolution-list-hooks'; +import { IndexPatternFieldBase } from '@kbn/es-query'; import { filterFieldToList } from '../filter_field_to_list'; import { getGenericComboBoxProps } from '../get_generic_combo_box_props'; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType } from '../../../../../../../src/plugins/data/common'; -type IFieldType = any; - // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 // import { HttpStart } from 'kibana/public'; type HttpStart = any; @@ -34,7 +31,7 @@ interface AutocompleteFieldListsProps { onChange: (arg: ListSchema) => void; placeholder: string; rowLabel?: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; selectedValue: string | undefined; } diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.test.tsx index d695088245622f..c0690774965c30 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.test.tsx @@ -54,7 +54,7 @@ describe('AutocompleteFieldMatchComponent', () => { placeholder="Placeholder text" rowLabel={'Row Label'} selectedField={getField('ip')} - selectedValue="126.45.211.34" + selectedValue="127.0.0.1" /> ); @@ -79,7 +79,7 @@ describe('AutocompleteFieldMatchComponent', () => { onError={jest.fn()} placeholder="Placeholder text" selectedField={getField('ip')} - selectedValue="126.45.211.34" + selectedValue="127.0.0.1" /> ); @@ -104,7 +104,7 @@ describe('AutocompleteFieldMatchComponent', () => { onError={jest.fn()} placeholder="Placeholder text" selectedField={getField('ip')} - selectedValue="126.45.211.34" + selectedValue="127.0.0.1" /> ); wrapper.find('[data-test-subj="valuesAutocompleteMatch"] button').at(0).simulate('click'); @@ -131,7 +131,7 @@ describe('AutocompleteFieldMatchComponent', () => { onError={jest.fn()} placeholder="Placeholder text" selectedField={getField('ip')} - selectedValue="126.45.211.34" + selectedValue="127.0.0.1" /> ); @@ -158,13 +158,13 @@ describe('AutocompleteFieldMatchComponent', () => { onError={jest.fn()} placeholder="Placeholder text" selectedField={getField('ip')} - selectedValue="126.45.211.34" + selectedValue="127.0.0.1" /> ); expect( wrapper.find('[data-test-subj="valuesAutocompleteMatch"] EuiComboBoxPill').at(0).text() - ).toEqual('126.45.211.34'); + ).toEqual('127.0.0.1'); }); test('it invokes "onChange" when new value created', async () => { @@ -190,9 +190,9 @@ describe('AutocompleteFieldMatchComponent', () => { ((wrapper.find(EuiComboBox).props() as unknown) as { onCreateOption: (a: string) => void; - }).onCreateOption('126.45.211.34'); + }).onCreateOption('127.0.0.1'); - expect(mockOnChange).toHaveBeenCalledWith('126.45.211.34'); + expect(mockOnChange).toHaveBeenCalledWith('127.0.0.1'); }); test('it invokes "onChange" when new value selected', async () => { diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx index 8199967489515f..9088517adbe58c 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match/index.tsx @@ -14,6 +14,8 @@ import { EuiComboBoxOptionOption, EuiComboBox, } from '@elastic/eui'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; + import { uniq } from 'lodash'; import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; @@ -22,11 +24,6 @@ import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution- // import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; type AutocompleteStart = any; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -type IFieldType = any; -type IIndexPattern = any; - import * as i18n from '../translations'; import { useFieldValueAutocomplete } from '../hooks/use_field_value_autocomplete'; import { @@ -44,9 +41,9 @@ const SINGLE_SELECTION = { asPlainText: true }; interface AutocompleteFieldMatchProps { placeholder: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; selectedValue: string | undefined; - indexPattern: IIndexPattern | undefined; + indexPattern: IndexPatternBase | undefined; isLoading: boolean; isDisabled: boolean; isClearable: boolean; diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.test.tsx index a3ca97874908e1..389761c9a6dfc0 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.test.tsx @@ -64,7 +64,7 @@ describe('AutocompleteFieldMatchAnyComponent', () => { placeholder="Placeholder text" rowLabel={'Row Label'} selectedField={getField('ip')} - selectedValue={['126.45.211.34']} + selectedValue={['127.0.0.1']} /> ); @@ -124,7 +124,7 @@ describe('AutocompleteFieldMatchAnyComponent', () => { placeholder="Placeholder text" rowLabel={'Row Label'} selectedField={getField('ip')} - selectedValue={['126.45.211.34']} + selectedValue={['127.0.0.1']} /> ); @@ -155,13 +155,13 @@ describe('AutocompleteFieldMatchAnyComponent', () => { placeholder="Placeholder text" rowLabel={'Row Label'} selectedField={getField('ip')} - selectedValue={['126.45.211.34']} + selectedValue={['127.0.0.1']} /> ); expect( wrapper.find(`[data-test-subj="valuesAutocompleteMatchAny"] EuiComboBoxPill`).at(0).text() - ).toEqual('126.45.211.34'); + ).toEqual('127.0.0.1'); }); test('it invokes "onChange" when new value created', async () => { @@ -191,9 +191,9 @@ describe('AutocompleteFieldMatchAnyComponent', () => { ((wrapper.find(EuiComboBox).props() as unknown) as { onCreateOption: (a: string) => void; - }).onCreateOption('126.45.211.34'); + }).onCreateOption('127.0.0.1'); - expect(mockOnChange).toHaveBeenCalledWith(['126.45.211.34']); + expect(mockOnChange).toHaveBeenCalledWith(['127.0.0.1']); }); test('it invokes "onChange" when new value selected', async () => { diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx index 338c4baa8bc6fc..bfcafd199dc322 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_match_any/index.tsx @@ -10,16 +10,12 @@ import React, { useCallback, useMemo, useState } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { uniq } from 'lodash'; import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 // import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; type AutocompleteStart = any; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -type IFieldType = any; -type IIndexPattern = any; - import * as i18n from '../translations'; import { getGenericComboBoxProps, @@ -30,9 +26,9 @@ import { paramIsValid } from '../param_is_valid'; interface AutocompleteFieldMatchAnyProps { placeholder: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; selectedValue: string[]; - indexPattern: IIndexPattern | undefined; + indexPattern: IndexPatternBase | undefined; isLoading: boolean; isDisabled: boolean; isClearable: boolean; diff --git a/packages/kbn-securitysolution-autocomplete/src/fields/index.mock.ts b/packages/kbn-securitysolution-autocomplete/src/fields/index.mock.ts index 5938ed34547a1f..a79325e25343fc 100644 --- a/packages/kbn-securitysolution-autocomplete/src/fields/index.mock.ts +++ b/packages/kbn-securitysolution-autocomplete/src/fields/index.mock.ts @@ -6,11 +6,12 @@ * Side Public License, v 1. */ -// Copied from "src/plugins/data/common/index_patterns/fields/fields.mocks.ts" -// but without types. +import { IndexPatternFieldBase } from '@kbn/es-query'; + +// Copied from "src/plugins/data/common/index_patterns/fields/fields.mocks.ts" but with the types changed to "IndexPatternFieldBase" since that type is compatible. // TODO: This should move out once those mocks are directly useable or in their own package, https://github.com/elastic/kibana/issues/100715 -export const fields = [ +export const fields: IndexPatternFieldBase[] = ([ { name: 'bytes', type: 'number', @@ -308,6 +309,6 @@ export const fields = [ readFromDocValues: false, subType: { nested: { path: 'nestedField.nestedChild' } }, }, -]; +] as unknown) as IndexPatternFieldBase[]; export const getField = (name: string) => fields.find((field) => field.name === name); diff --git a/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.test.ts b/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.test.ts index 1022849ffda360..cb39adb9fde26d 100644 --- a/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.test.ts +++ b/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.test.ts @@ -10,10 +10,7 @@ import { filterFieldToList } from '.'; import type { ListSchema } from '@kbn/securitysolution-io-ts-list-types'; import { getListResponseMock } from '../list_schema/index.mock'; - -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType } from '../../../../../../../src/plugins/data/common'; -type IFieldType = any; +import { IndexPatternFieldBase } from '@kbn/es-query'; describe('#filterFieldToList', () => { test('it returns empty array if given a undefined for field', () => { @@ -22,13 +19,20 @@ describe('#filterFieldToList', () => { }); test('it returns empty array if filed does not contain esTypes', () => { - const field: IFieldType = { name: 'some-name', type: 'some-type' }; + const field: IndexPatternFieldBase = { + name: 'some-name', + type: 'some-type', + }; const filter = filterFieldToList([], field); expect(filter).toEqual([]); }); test('it returns single filtered list of ip_range -> ip', () => { - const field: IFieldType = { esTypes: ['ip'], name: 'some-name', type: 'ip' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['ip'], + name: 'some-name', + type: 'ip', + }; const listItem: ListSchema = { ...getListResponseMock(), type: 'ip_range' }; const filter = filterFieldToList([listItem], field); const expected: ListSchema[] = [listItem]; @@ -36,7 +40,11 @@ describe('#filterFieldToList', () => { }); test('it returns single filtered list of ip -> ip', () => { - const field: IFieldType = { esTypes: ['ip'], name: 'some-name', type: 'ip' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['ip'], + name: 'some-name', + type: 'ip', + }; const listItem: ListSchema = { ...getListResponseMock(), type: 'ip' }; const filter = filterFieldToList([listItem], field); const expected: ListSchema[] = [listItem]; @@ -44,7 +52,11 @@ describe('#filterFieldToList', () => { }); test('it returns single filtered list of keyword -> keyword', () => { - const field: IFieldType = { esTypes: ['keyword'], name: 'some-name', type: 'keyword' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['keyword'], + name: 'some-name', + type: 'keyword', + }; const listItem: ListSchema = { ...getListResponseMock(), type: 'keyword' }; const filter = filterFieldToList([listItem], field); const expected: ListSchema[] = [listItem]; @@ -52,7 +64,11 @@ describe('#filterFieldToList', () => { }); test('it returns single filtered list of text -> text', () => { - const field: IFieldType = { esTypes: ['text'], name: 'some-name', type: 'text' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['text'], + name: 'some-name', + type: 'text', + }; const listItem: ListSchema = { ...getListResponseMock(), type: 'text' }; const filter = filterFieldToList([listItem], field); const expected: ListSchema[] = [listItem]; @@ -60,7 +76,11 @@ describe('#filterFieldToList', () => { }); test('it returns 2 filtered lists of ip_range -> ip', () => { - const field: IFieldType = { esTypes: ['ip'], name: 'some-name', type: 'ip' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['ip'], + name: 'some-name', + type: 'ip', + }; const listItem1: ListSchema = { ...getListResponseMock(), type: 'ip_range' }; const listItem2: ListSchema = { ...getListResponseMock(), type: 'ip_range' }; const filter = filterFieldToList([listItem1, listItem2], field); @@ -69,7 +89,11 @@ describe('#filterFieldToList', () => { }); test('it returns 1 filtered lists of ip_range -> ip if the 2nd is not compatible type', () => { - const field: IFieldType = { esTypes: ['ip'], name: 'some-name', type: 'ip' }; + const field: IndexPatternFieldBase & { esTypes: string[] } = { + esTypes: ['ip'], + name: 'some-name', + type: 'ip', + }; const listItem1: ListSchema = { ...getListResponseMock(), type: 'ip_range' }; const listItem2: ListSchema = { ...getListResponseMock(), type: 'text' }; const filter = filterFieldToList([listItem1, listItem2], field); diff --git a/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts b/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts index b2e48c25f9b51f..51ce349fa39fdc 100644 --- a/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts +++ b/packages/kbn-securitysolution-autocomplete/src/filter_field_to_list/index.ts @@ -7,19 +7,23 @@ */ import { ListSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { IndexPatternFieldBase } from '@kbn/es-query'; import { typeMatch } from '../type_match'; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -type IFieldType = any; - /** * Given an array of lists and optionally a field this will return all * the lists that match against the field based on the types from the field + * + * NOTE: That we support one additional property from "FieldSpec" located here: + * src/plugins/data/common/index_patterns/fields/types.ts + * This type property is esTypes. If it exists and is on there we will read off the esTypes. * @param lists The lists to match against the field * @param field The field to check against the list to see if they are compatible */ -export const filterFieldToList = (lists: ListSchema[], field?: IFieldType): ListSchema[] => { +export const filterFieldToList = ( + lists: ListSchema[], + field?: IndexPatternFieldBase & { esTypes?: string[] } +): ListSchema[] => { if (field != null) { const { esTypes = [] } = field; return lists.filter(({ type }) => esTypes.some((esType: string) => typeMatch(type, esType))); diff --git a/packages/kbn-securitysolution-autocomplete/src/get_operators/index.test.ts b/packages/kbn-securitysolution-autocomplete/src/get_operators/index.test.ts index e473df104fa6a4..9ed9c6358c3971 100644 --- a/packages/kbn-securitysolution-autocomplete/src/get_operators/index.test.ts +++ b/packages/kbn-securitysolution-autocomplete/src/get_operators/index.test.ts @@ -31,13 +31,8 @@ describe('#getOperators', () => { test('it returns "isOperator" when field type is "nested"', () => { const operator = getOperators({ - aggregatable: false, - count: 0, - esTypes: ['text'], name: 'nestedField', - readFromDocValues: false, scripted: false, - searchable: true, subType: { nested: { path: 'nestedField' } }, type: 'nested', }); diff --git a/packages/kbn-securitysolution-autocomplete/src/get_operators/index.ts b/packages/kbn-securitysolution-autocomplete/src/get_operators/index.ts index 39d2779e2dc44f..b50bd57608e7ad 100644 --- a/packages/kbn-securitysolution-autocomplete/src/get_operators/index.ts +++ b/packages/kbn-securitysolution-autocomplete/src/get_operators/index.ts @@ -6,9 +6,7 @@ * Side Public License, v 1. */ -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType } from '../../../../../../../src/plugins/data/common'; -type IFieldType = any; +import { IndexPatternFieldBase } from '@kbn/es-query'; import { EXCEPTION_OPERATORS, @@ -22,10 +20,10 @@ import { /** * Returns the appropriate operators given a field type * - * @param field IFieldType selected field + * @param field IndexPatternFieldBase selected field * */ -export const getOperators = (field: IFieldType | undefined): OperatorOption[] => { +export const getOperators = (field: IndexPatternFieldBase | undefined): OperatorOption[] => { if (field == null) { return [isOperator]; } else if (field.type === 'boolean') { diff --git a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.test.ts b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.test.ts index 534daa021cf4a8..04b674758f952c 100644 --- a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.test.ts +++ b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.test.ts @@ -16,6 +16,7 @@ import { } from '.'; import { getField } from '../../fields/index.mock'; import { autocompleteStartMock } from '../../autocomplete/index.mock'; +import { IndexPatternFieldBase } from '@kbn/es-query'; // Copied from "src/plugins/data/common/index_patterns/index_pattern.stub.ts" // TODO: Remove this in favor of the above if/when it is ported, https://github.com/elastic/kibana/issues/100715 @@ -152,6 +153,11 @@ describe('use_field_value_autocomplete', () => { const suggestionsMock = jest.fn().mockResolvedValue([]); await act(async () => { + const selectedField: IndexPatternFieldBase | undefined = getField('nestedField.child'); + if (selectedField == null) { + throw new TypeError('selectedField for this test should always be defined'); + } + const { signal } = new AbortController(); const { waitForNextUpdate } = renderHook< UseFieldValueAutocompleteProps, @@ -166,7 +172,7 @@ describe('use_field_value_autocomplete', () => { indexPattern: stubIndexPatternWithFields, operatorType: OperatorTypeEnum.MATCH, query: '', - selectedField: { ...getField('nestedField.child'), name: 'child' }, + selectedField: { ...selectedField, name: 'child' }, }) ); // Note: initial `waitForNextUpdate` is hook initialization diff --git a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts index b4dec1615e3ed4..2b65051a6c67de 100644 --- a/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts +++ b/packages/kbn-securitysolution-autocomplete/src/hooks/use_field_value_autocomplete/index.ts @@ -9,19 +9,15 @@ import { useEffect, useRef, useState } from 'react'; import { debounce } from 'lodash'; import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; // TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715 // import { AutocompleteStart } from '../../../../../../../../src/plugins/data/public'; type AutocompleteStart = any; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -type IFieldType = any; -type IIndexPattern = any; - interface FuncArgs { - fieldSelected: IFieldType | undefined; - patterns: IIndexPattern | undefined; + fieldSelected: IndexPatternFieldBase | undefined; + patterns: IndexPatternBase | undefined; searchQuery: string; value: string | string[] | undefined; } @@ -33,10 +29,10 @@ export type UseFieldValueAutocompleteReturn = [boolean, boolean, string[], Func export interface UseFieldValueAutocompleteProps { autocompleteService: AutocompleteStart; fieldValue: string | string[] | undefined; - indexPattern: IIndexPattern | undefined; + indexPattern: IndexPatternBase | undefined; operatorType: OperatorTypeEnum; query: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; } /** * Hook for using the field value autocomplete service diff --git a/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx index fed7007b496361..e2af384215c258 100644 --- a/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx @@ -160,13 +160,8 @@ describe('operator', () => { operator={isOperator} placeholder="Placeholder text" selectedField={{ - aggregatable: false, - count: 0, - esTypes: ['text'], name: 'nestedField', - readFromDocValues: false, scripted: false, - searchable: true, subType: { nested: { path: 'nestedField' } }, type: 'nested', }} diff --git a/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx b/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx index 08f058fd578198..dc12de7c398c38 100644 --- a/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/operator/index.tsx @@ -9,10 +9,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { OperatorOption } from '@kbn/securitysolution-list-utils'; - -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType } from '../../../../../../../src/plugins/data/common'; -type IFieldType = any; +import { IndexPatternFieldBase } from '@kbn/es-query'; import { getOperators } from '../get_operators'; import { @@ -31,7 +28,7 @@ interface OperatorState { operatorInputWidth?: number; operatorOptions?: OperatorOption[]; placeholder: string; - selectedField: IFieldType | undefined; + selectedField: IndexPatternFieldBase | undefined; } export const OperatorComponent: React.FC = ({ diff --git a/packages/kbn-securitysolution-autocomplete/src/param_is_valid/index.ts b/packages/kbn-securitysolution-autocomplete/src/param_is_valid/index.ts index 5b596b4b624086..17de850e929846 100644 --- a/packages/kbn-securitysolution-autocomplete/src/param_is_valid/index.ts +++ b/packages/kbn-securitysolution-autocomplete/src/param_is_valid/index.ts @@ -7,12 +7,9 @@ */ import dateMath from '@elastic/datemath'; +import { IndexPatternFieldBase } from '@kbn/es-query'; import { checkEmptyValue } from '../check_empty_value'; -// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/105731 -// import { IFieldType } from '../../../../../../../src/plugins/data/common'; -type IFieldType = any; - import * as i18n from '../translations'; /** @@ -25,7 +22,7 @@ import * as i18n from '../translations'; */ export const paramIsValid = ( param: string | undefined, - field: IFieldType | undefined, + field: IndexPatternFieldBase | undefined, isRequired: boolean, touched: boolean ): string | undefined => { diff --git a/packages/kbn-securitysolution-list-utils/BUILD.bazel b/packages/kbn-securitysolution-list-utils/BUILD.bazel index 0d257a95f02593..cb6ddbd7f91d51 100644 --- a/packages/kbn-securitysolution-list-utils/BUILD.bazel +++ b/packages/kbn-securitysolution-list-utils/BUILD.bazel @@ -32,6 +32,7 @@ SRC_DEPS = [ "//packages/kbn-securitysolution-list-constants", "//packages/kbn-securitysolution-io-ts-list-types", "//packages/kbn-securitysolution-utils", + "//packages/kbn-es-query", "@npm//lodash", "@npm//tslib", ] diff --git a/packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts b/packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts index 72db4991a49a49..77e369dbcac74c 100644 --- a/packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts +++ b/packages/kbn-securitysolution-list-utils/src/build_exception_filter/index.ts @@ -21,17 +21,10 @@ import { entriesNested, OsTypeArray, } from '@kbn/securitysolution-io-ts-list-types'; +import { Filter } from '@kbn/es-query'; import { hasLargeValueList } from '../has_large_value_list'; -/** - * Originally this was an import type of: - * import type { Filter } from '../../../../../src/plugins/data/common'; - * TODO: Once we have the type for this within kbn packages, replace this with that one - * @deprecated - */ -type Filter = any; - type NonListEntry = EntryMatch | EntryMatchAny | EntryNested | EntryExists; interface ExceptionListItemNonLargeList extends ExceptionListItemSchema { entries: NonListEntry[]; @@ -190,7 +183,7 @@ export const buildExceptionFilter = ({ } else { const chunks = chunkExceptions(exceptionsWithoutLargeValueLists, chunkSize); - const filters = chunks.map((exceptionsChunk) => { + const filters = chunks.map((exceptionsChunk) => { const orClauses = createOrClauses(exceptionsChunk); return { diff --git a/packages/kbn-securitysolution-list-utils/src/helpers/index.ts b/packages/kbn-securitysolution-list-utils/src/helpers/index.ts index 38446b2a08ec0f..eeab05fadb126a 100644 --- a/packages/kbn-securitysolution-list-utils/src/helpers/index.ts +++ b/packages/kbn-securitysolution-list-utils/src/helpers/index.ts @@ -28,11 +28,7 @@ import { exceptionListItemSchema, nestedEntryItem, } from '@kbn/securitysolution-io-ts-list-types'; - -// TODO: I have to use any here for now, but once this is available below, we should use the correct types -// import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/public'; -type IFieldType = any; -type IIndexPattern = any; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { EXCEPTION_OPERATORS, @@ -282,17 +278,17 @@ export const getUpdatedEntriesOnDelete = ( * add nested entry, should only show nested fields, if item is the parent * field of a nested entry, we only display the parent field * - * @param patterns IIndexPattern containing available fields on rule index + * @param patterns IndexPatternBase containing available fields on rule index * @param item exception item entry * set to add a nested field */ export const getFilteredIndexPatterns = ( - patterns: IIndexPattern, + patterns: IndexPatternBase, item: FormattedBuilderEntry, type: ExceptionListType, - preFilter?: (i: IIndexPattern, t: ExceptionListType, o?: OsTypeArray) => IIndexPattern, + preFilter?: (i: IndexPatternBase, t: ExceptionListType, o?: OsTypeArray) => IndexPatternBase, osTypes?: OsTypeArray -): IIndexPattern => { +): IndexPatternBase => { const indexPatterns = preFilter != null ? preFilter(patterns, type, osTypes) : patterns; if (item.nested === 'child' && item.parent != null) { @@ -300,7 +296,6 @@ export const getFilteredIndexPatterns = ( return { ...indexPatterns, fields: indexPatterns.fields - // @ts-expect-error This will go away once we type IField from any .filter((indexField) => { const fieldHasCommonParentPath = indexField.subType != null && @@ -310,7 +305,6 @@ export const getFilteredIndexPatterns = ( return fieldHasCommonParentPath; }) - // @ts-expect-error This will go away once we type IField from any .map((f) => { const [fieldNameWithoutParentPath] = f.name.split('.').slice(-1); return { ...f, name: fieldNameWithoutParentPath }; @@ -324,7 +318,6 @@ export const getFilteredIndexPatterns = ( return { ...indexPatterns, fields: indexPatterns.fields.filter( - // @ts-expect-error This will go away once we type IField from any (field) => field.subType != null && field.subType.nested != null ), }; @@ -342,7 +335,7 @@ export const getFilteredIndexPatterns = ( */ export const getEntryOnFieldChange = ( item: FormattedBuilderEntry, - newField: IFieldType + newField: IndexPatternFieldBase ): { index: number; updatedEntry: BuilderEntry } => { const { parent, entryIndex, nested } = item; const newChildFieldValue = newField != null ? newField.name.split('.').slice(-1)[0] : ''; @@ -657,9 +650,9 @@ export const getCorrespondingKeywordField = ({ fields, selectedField, }: { - fields: IFieldType[]; + fields: IndexPatternFieldBase[]; selectedField: string | undefined; -}): IFieldType | undefined => { +}): IndexPatternFieldBase | undefined => { const selectedFieldBits = selectedField != null && selectedField !== '' ? selectedField.split('.') : []; const selectedFieldIsTextType = selectedFieldBits.slice(-1)[0] === 'text'; @@ -679,7 +672,7 @@ export const getCorrespondingKeywordField = ({ * Formats the entry into one that is easily usable for the UI, most of the * complexity was introduced with nested fields * - * @param patterns IIndexPattern containing available fields on rule index + * @param patterns IndexPatternBase containing available fields on rule index * @param item exception item entry * @param itemIndex entry index * @param parent nested entries hold copy of their parent for use in various logic @@ -687,7 +680,7 @@ export const getCorrespondingKeywordField = ({ * was added to ensure that nested items could be identified with their parent entry */ export const getFormattedBuilderEntry = ( - indexPattern: IIndexPattern, + indexPattern: IndexPatternBase, item: BuilderEntry, itemIndex: number, parent: EntryNested | undefined, @@ -695,7 +688,6 @@ export const getFormattedBuilderEntry = ( ): FormattedBuilderEntry => { const { fields } = indexPattern; const field = parent != null ? `${parent.field}.${item.field}` : item.field; - // @ts-expect-error This will go away once we type IField from any const [foundField] = fields.filter(({ name }) => field != null && field === name); const correspondingKeywordField = getCorrespondingKeywordField({ fields, @@ -734,7 +726,7 @@ export const getFormattedBuilderEntry = ( * Formats the entries to be easily usable for the UI, most of the * complexity was introduced with nested fields * - * @param patterns IIndexPattern containing available fields on rule index + * @param patterns IndexPatternBase containing available fields on rule index * @param entries exception item entries * @param addNested boolean noting whether or not UI is currently * set to add a nested field @@ -743,7 +735,7 @@ export const getFormattedBuilderEntry = ( * was added to ensure that nested items could be identified with their parent entry */ export const getFormattedBuilderEntries = ( - indexPattern: IIndexPattern, + indexPattern: IndexPatternBase, entries: BuilderEntry[], parent?: EntryNested, parentIndex?: number @@ -765,13 +757,14 @@ export const getFormattedBuilderEntries = ( entryIndex: index, field: isNewNestedEntry ? undefined - : { + : // This type below is really a FieldSpec type from "src/plugins/data/common/index_patterns/fields/types.ts", we cast it here to keep using the IndexPatternFieldBase interface + ({ aggregatable: false, esTypes: ['nested'], name: item.field != null ? item.field : '', searchable: false, type: 'string', - }, + } as IndexPatternFieldBase), id: item.id != null ? item.id : `${index}`, nested: 'parent', operator: isOperator, diff --git a/packages/kbn-securitysolution-list-utils/src/types/index.ts b/packages/kbn-securitysolution-list-utils/src/types/index.ts index 537ac06a49f34b..68896f1811472c 100644 --- a/packages/kbn-securitysolution-list-utils/src/types/index.ts +++ b/packages/kbn-securitysolution-list-utils/src/types/index.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { IndexPatternFieldBase } from '@kbn/es-query'; import type { CreateExceptionListItemSchema, Entry, @@ -30,21 +31,15 @@ export interface OperatorOption { type: OperatorTypeEnum; } -/** - * @deprecated Use the one from core once it is in its own package which will be from: - * Original import was // import { IFieldType } from '../../../../../../../src/plugins/data/common'; - */ -type IFieldType = any; - export interface FormattedBuilderEntry { id: string; - field: IFieldType | undefined; + field: IndexPatternFieldBase | undefined; operator: OperatorOption; value: string | string[] | undefined; nested: 'parent' | 'child' | undefined; entryIndex: number; parent: { parent: BuilderEntryNested; parentIndex: number } | undefined; - correspondingKeywordField: IFieldType | undefined; + correspondingKeywordField: IndexPatternFieldBase | undefined; } export interface EmptyEntry { diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx index 8eaba9e82d7247..267af602e2abf0 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx @@ -119,7 +119,7 @@ export default { }, indexPatterns: { description: - '`IIndexPattern` - index patterns used to populate field options and value autocomplete.', + '`IndexPatternBase` - index patterns used to populate field options and value autocomplete.', type: { required: true, }, @@ -201,7 +201,7 @@ export default { }, listTypeSpecificIndexPatternFilter: { description: - '`(pattern: IIndexPattern, type: ExceptionListType) => IIndexPattern` - callback invoked when index patterns filtered. Optional to be used if you would only like certain fields displayed.', + '`(pattern: IndexPatternBase, type: ExceptionListType) => IndexPatternBase` - callback invoked when index patterns filtered. Optional to be used if you would only like certain fields displayed.', type: { required: false, }, diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx index dd67381c30934b..9bf2ca0fc017a1 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx @@ -102,7 +102,7 @@ export default { }, indexPattern: { description: - '`IIndexPattern` - index patterns used to populate field options and value autocomplete.', + '`IndexPatternBase` - index patterns used to populate field options and value autocomplete.', type: { required: true, }, diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx index 4d22a883ad8463..f692ad96988cfe 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx @@ -20,6 +20,7 @@ import { isOperator, } from '@kbn/securitysolution-list-utils'; import { useFindLists } from '@kbn/securitysolution-list-hooks'; +import { FieldSpec } from 'src/plugins/data/common'; import { fields, @@ -374,31 +375,33 @@ describe('BuilderEntryItem', () => { }); test('it uses "correspondingKeywordField" if it exists', () => { + const correspondingKeywordField: FieldSpec = { + aggregatable: true, + count: 0, + esTypes: ['keyword'], + name: 'extension', + readFromDocValues: true, + scripted: false, + searchable: true, + type: 'string', + }; + const field: FieldSpec = { + aggregatable: false, + count: 0, + esTypes: ['text'], + name: 'extension.text', + readFromDocValues: true, + scripted: false, + searchable: false, + type: 'string', + }; wrapper = mount( { ((wrapper.find(EuiComboBox).at(2).props() as unknown) as { onCreateOption: (a: string) => void; - }).onCreateOption('126.45.211.34'); + }).onCreateOption('127.0.0.1'); expect(mockOnChange).toHaveBeenCalledWith( - { field: 'ip', id: '123', operator: 'excluded', type: 'match', value: '126.45.211.34' }, + { field: 'ip', id: '123', operator: 'excluded', type: 'match', value: '127.0.0.1' }, 0 ); }); @@ -576,10 +579,10 @@ describe('BuilderEntryItem', () => { ((wrapper.find(EuiComboBox).at(2).props() as unknown) as { onCreateOption: (a: string) => void; - }).onCreateOption('126.45.211.34'); + }).onCreateOption('127.0.0.1'); expect(mockOnChange).toHaveBeenCalledWith( - { field: 'ip', id: '123', operator: 'included', type: 'match_any', value: ['126.45.211.34'] }, + { field: 'ip', id: '123', operator: 'included', type: 'match_any', value: ['127.0.0.1'] }, 0 ); }); diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx index d7741b3fe0ff10..19349c4eff9b84 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.tsx @@ -35,9 +35,9 @@ import { FieldComponent, OperatorComponent, } from '@kbn/securitysolution-autocomplete'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; -import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { HttpStart } from '../../../../../../../src/core/public'; import { getEmptyValue } from '../../../common/empty_value'; @@ -52,15 +52,15 @@ export interface EntryItemProps { autocompleteService: AutocompleteStart; entry: FormattedBuilderEntry; httpService: HttpStart; - indexPattern: IIndexPattern; + indexPattern: IndexPatternBase; showLabel: boolean; osTypes?: OsTypeArray; listType: ExceptionListType; listTypeSpecificIndexPatternFilter?: ( - pattern: IIndexPattern, + pattern: IndexPatternBase, type: ExceptionListType, osTypes?: OsTypeArray - ) => IIndexPattern; + ) => IndexPatternBase; onChange: (arg: BuilderEntry, i: number) => void; onlyShowListOperators?: boolean; setErrorsExist: (arg: boolean) => void; @@ -90,7 +90,7 @@ export const BuilderEntryItem: React.FC = ({ ); const handleFieldChange = useCallback( - ([newField]: IFieldType[]): void => { + ([newField]: IndexPatternFieldBase[]): void => { const { updatedEntry, index } = getEntryOnFieldChange(entry, newField); onChange(updatedEntry, index); }, diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx index eee5b8b1e992d1..04d7606bda23e2 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.tsx @@ -18,8 +18,7 @@ import { getFormattedBuilderEntries, getUpdatedEntriesOnDelete, } from '@kbn/securitysolution-list-utils'; - -import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; +import { IndexPatternBase } from '@kbn/es-query'; import { BuilderAndBadgeComponent } from './and_badge'; import { BuilderEntryDeleteButtonComponent } from './entry_delete_button'; @@ -47,15 +46,15 @@ interface BuilderExceptionListItemProps { exceptionItem: ExceptionsBuilderExceptionItem; exceptionItemIndex: number; osTypes?: OsTypeArray; - indexPattern: IIndexPattern; + indexPattern: IndexPatternBase; andLogicIncluded: boolean; isOnlyItem: boolean; listType: ExceptionListType; listTypeSpecificIndexPatternFilter?: ( - pattern: IIndexPattern, + pattern: IndexPatternBase, type: ExceptionListType, osTypes?: OsTypeArray - ) => IIndexPattern; + ) => IndexPatternBase; onDeleteExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; onChangeExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; setErrorsExist: (arg: boolean) => void; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx index 1b68ef07657a85..14c3fbda31e22f 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx @@ -30,8 +30,9 @@ import { getDefaultNestedEmptyEntry, getNewExceptionItem, } from '@kbn/securitysolution-list-utils'; +import { IndexPatternBase } from '@kbn/es-query'; -import { AutocompleteStart, IIndexPattern } from '../../../../../../../src/plugins/data/public'; +import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; import { AndOrBadge } from '../and_or_badge'; import { BuilderExceptionListItemComponent } from './exception_item_renderer'; @@ -75,7 +76,7 @@ export interface ExceptionBuilderProps { exceptionListItems: ExceptionsBuilderExceptionItem[]; httpService: HttpStart; osTypes?: OsTypeArray; - indexPatterns: IIndexPattern; + indexPatterns: IndexPatternBase; isAndDisabled: boolean; isNestedDisabled: boolean; isOrDisabled: boolean; @@ -83,9 +84,9 @@ export interface ExceptionBuilderProps { listNamespaceType: NamespaceType; listType: ExceptionListType; listTypeSpecificIndexPatternFilter?: ( - pattern: IIndexPattern, + pattern: IndexPatternBase, type: ExceptionListType - ) => IIndexPattern; + ) => IndexPatternBase; onChange: (arg: OnChangeProps) => void; ruleName: string; isDisabled?: boolean; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts index afeac2d1bf4de3..8592408dde56ef 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts @@ -52,6 +52,7 @@ import { isOneOfOperator, isOperator, } from '@kbn/securitysolution-list-utils'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { ENTRIES_WITH_IDS } from '../../../../common/constants.mock'; import { getEntryExistsMock } from '../../../../common/schemas/types/entry_exists.mock'; @@ -60,7 +61,7 @@ import { fields, getField, } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; -import { IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/common'; +import { FieldSpec } from '../../../../../../../src/plugins/data/common'; import { getEntryNestedMock } from '../../../../common/schemas/types/entry_nested.mock'; import { getEntryMatchMock } from '../../../../common/schemas/types/entry_match.mock'; import { getEntryMatchAnyMock } from '../../../../common/schemas/types/entry_match_any.mock'; @@ -93,7 +94,7 @@ const getEntryMatchAnyWithIdMock = (): EntryMatchAny & { id: string } => ({ id: '123', }); -const getMockIndexPattern = (): IIndexPattern => ({ +const getMockIndexPattern = (): IndexPatternBase => ({ fields, id: '1234', title: 'logstash-*', @@ -131,7 +132,11 @@ const getMockNestedBuilderEntry = (): FormattedBuilderEntry => ({ const getMockNestedParentBuilderEntry = (): FormattedBuilderEntry => ({ correspondingKeywordField: undefined, entryIndex: 0, - field: { ...getField('nestedField.child'), esTypes: ['nested'], name: 'nestedField' }, + field: { + ...getField('nestedField.child'), + esTypes: ['nested'], + name: 'nestedField', + } as FieldSpec, id: '123', nested: 'parent', operator: isOperator, @@ -163,10 +168,13 @@ const mockEndpointFields = [ }, ]; -export const getEndpointField = (name: string): IFieldType => - mockEndpointFields.find((field) => field.name === name) as IFieldType; +export const getEndpointField = (name: string): IndexPatternFieldBase => + mockEndpointFields.find((field) => field.name === name) as IndexPatternFieldBase; -const filterIndexPatterns = (patterns: IIndexPattern, type: ExceptionListType): IIndexPattern => { +const filterIndexPatterns = ( + patterns: IndexPatternBase, + type: ExceptionListType +): IndexPatternBase => { return type === 'endpoint' ? { ...patterns, @@ -181,10 +189,10 @@ describe('Exception builder helpers', () => { describe('#getFilteredIndexPatterns', () => { describe('list type detections', () => { test('it returns nested fields that match parent value when "item.nested" is "child"', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: FormattedBuilderEntry = getMockNestedBuilderEntry(); const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'detection'); - const expected: IIndexPattern = { + const expected: IndexPatternBase = { fields: [{ ...getField('nestedField.child'), name: 'child' }], id: '1234', title: 'logstash-*', @@ -193,10 +201,10 @@ describe('Exception builder helpers', () => { }); test('it returns only parent nested field when "item.nested" is "parent" and nested parent field is not undefined', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: FormattedBuilderEntry = getMockNestedParentBuilderEntry(); const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'detection'); - const expected: IIndexPattern = { + const expected: IndexPatternBase & { fields: Array> } = { fields: [{ ...getField('nestedField.child'), esTypes: ['nested'], name: 'nestedField' }], id: '1234', title: 'logstash-*', @@ -205,13 +213,13 @@ describe('Exception builder helpers', () => { }); test('it returns only nested fields when "item.nested" is "parent" and nested parent field is undefined', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: FormattedBuilderEntry = { ...getMockNestedParentBuilderEntry(), field: undefined, }; const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'detection'); - const expected: IIndexPattern = { + const expected: IndexPatternBase = { fields: [ { ...getField('nestedField.child') }, { ...getField('nestedField.nestedChild.doublyNestedChild') }, @@ -223,10 +231,10 @@ describe('Exception builder helpers', () => { }); test('it returns all fields unfiletered if "item.nested" is not "child" or "parent"', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: FormattedBuilderEntry = getMockBuilderEntry(); const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'detection'); - const expected: IIndexPattern = { + const expected: IndexPatternBase = { fields: [...fields], id: '1234', title: 'logstash-*', @@ -236,7 +244,7 @@ describe('Exception builder helpers', () => { }); describe('list type endpoint', () => { - let payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + let payloadIndexPattern = getMockIndexPattern(); beforeAll(() => { payloadIndexPattern = { @@ -264,7 +272,7 @@ describe('Exception builder helpers', () => { value: 'some value', }; const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'endpoint'); - const expected: IIndexPattern = { + const expected: IndexPatternBase = { fields: [{ ...getEndpointField('file.Ext.code_signature.status'), name: 'status' }], id: '1234', title: 'logstash-*', @@ -273,33 +281,35 @@ describe('Exception builder helpers', () => { }); test('it returns only parent nested field when "item.nested" is "parent" and nested parent field is not undefined', () => { + const field: FieldSpec = { + ...getEndpointField('file.Ext.code_signature.status'), + esTypes: ['nested'], + name: 'file.Ext.code_signature', + } as FieldSpec; const payloadItem: FormattedBuilderEntry = { ...getMockNestedParentBuilderEntry(), - field: { - ...getEndpointField('file.Ext.code_signature.status'), - esTypes: ['nested'], - name: 'file.Ext.code_signature', - }, + field, }; const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem, 'endpoint'); - const expected: IIndexPattern = { - fields: [ - { - aggregatable: false, - count: 0, - esTypes: ['nested'], - name: 'file.Ext.code_signature', - readFromDocValues: false, - scripted: false, - searchable: true, - subType: { - nested: { - path: 'file.Ext.code_signature', - }, + const fieldsExpected: FieldSpec[] = [ + { + aggregatable: false, + count: 0, + esTypes: ['nested'], + name: 'file.Ext.code_signature', + readFromDocValues: false, + scripted: false, + searchable: true, + subType: { + nested: { + path: 'file.Ext.code_signature', }, - type: 'string', }, - ], + type: 'string', + }, + ]; + const expected: IndexPatternBase = { + fields: fieldsExpected, id: '1234', title: 'logstash-*', }; @@ -317,7 +327,7 @@ describe('Exception builder helpers', () => { 'endpoint', filterIndexPatterns ); - const expected: IIndexPattern = { + const expected: IndexPatternBase = { fields: [getEndpointField('file.Ext.code_signature.status')], id: '1234', title: 'logstash-*', @@ -333,30 +343,31 @@ describe('Exception builder helpers', () => { 'endpoint', filterIndexPatterns ); - const expected: IIndexPattern = { - fields: [ - { - aggregatable: false, - count: 0, - esTypes: ['keyword'], - name: 'file.path.caseless', - readFromDocValues: false, - scripted: false, - searchable: true, - type: 'string', - }, - { - aggregatable: false, - count: 0, - esTypes: ['text'], - name: 'file.Ext.code_signature.status', - readFromDocValues: false, - scripted: false, - searchable: true, - subType: { nested: { path: 'file.Ext.code_signature' } }, - type: 'string', - }, - ], + const fieldsExpected: FieldSpec[] = [ + { + aggregatable: false, + count: 0, + esTypes: ['keyword'], + name: 'file.path.caseless', + readFromDocValues: false, + scripted: false, + searchable: true, + type: 'string', + }, + { + aggregatable: false, + count: 0, + esTypes: ['text'], + name: 'file.Ext.code_signature.status', + readFromDocValues: false, + scripted: false, + searchable: true, + subType: { nested: { path: 'file.Ext.code_signature' } }, + type: 'string', + }, + ]; + const expected: IndexPatternBase = { + fields: fieldsExpected, id: '1234', title: 'logstash-*', }; @@ -626,7 +637,7 @@ describe('Exception builder helpers', () => { describe('#getEntryOnFieldChange', () => { test('it returns nested entry with single new subentry when "item.nested" is "parent"', () => { const payloadItem: FormattedBuilderEntry = getMockNestedParentBuilderEntry(); - const payloadIFieldType: IFieldType = getField('nestedField.child'); + const payloadIFieldType = getField('nestedField.child'); const output = getEntryOnFieldChange(payloadItem, payloadIFieldType); const expected: { updatedEntry: BuilderEntry & { id?: string }; index: number } = { index: 0, @@ -663,7 +674,7 @@ describe('Exception builder helpers', () => { parentIndex: 0, }, }; - const payloadIFieldType: IFieldType = getField('nestedField.child'); + const payloadIFieldType = getField('nestedField.child'); const output = getEntryOnFieldChange(payloadItem, payloadIFieldType); const expected: { updatedEntry: BuilderEntry & { id?: string }; index: number } = { index: 0, @@ -688,7 +699,7 @@ describe('Exception builder helpers', () => { test('it returns field of type "match" with updated field if not a nested entry', () => { const payloadItem: FormattedBuilderEntry = getMockBuilderEntry(); - const payloadIFieldType: IFieldType = getField('ip'); + const payloadIFieldType = getField('ip'); const output = getEntryOnFieldChange(payloadItem, payloadIFieldType); const expected: { updatedEntry: BuilderEntry & { id?: string }; index: number } = { index: 0, @@ -1023,7 +1034,7 @@ describe('Exception builder helpers', () => { describe('#getFormattedBuilderEntries', () => { test('it returns formatted entry with field undefined if it unable to find a matching index pattern field', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItems: BuilderEntry[] = [getEntryMatchWithIdMock()]; const output = getFormattedBuilderEntries(payloadIndexPattern, payloadItems); const expected: FormattedBuilderEntry[] = [ @@ -1042,26 +1053,37 @@ describe('Exception builder helpers', () => { }); test('it returns formatted entries when no nested entries exist', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItems: BuilderEntry[] = [ { ...getEntryMatchWithIdMock(), field: 'ip', value: 'some ip' }, { ...getEntryMatchAnyWithIdMock(), field: 'extension', value: ['some extension'] }, ]; const output = getFormattedBuilderEntries(payloadIndexPattern, payloadItems); + const field1: FieldSpec = { + aggregatable: true, + count: 0, + esTypes: ['ip'], + name: 'ip', + readFromDocValues: true, + scripted: false, + searchable: true, + type: 'ip', + }; + const field2: FieldSpec = { + aggregatable: true, + count: 0, + esTypes: ['keyword'], + name: 'extension', + readFromDocValues: true, + scripted: false, + searchable: true, + type: 'string', + }; const expected: FormattedBuilderEntry[] = [ { correspondingKeywordField: undefined, entryIndex: 0, - field: { - aggregatable: true, - count: 0, - esTypes: ['ip'], - name: 'ip', - readFromDocValues: true, - scripted: false, - searchable: true, - type: 'ip', - }, + field: field1, id: '123', nested: undefined, operator: isOperator, @@ -1071,16 +1093,7 @@ describe('Exception builder helpers', () => { { correspondingKeywordField: undefined, entryIndex: 1, - field: { - aggregatable: true, - count: 0, - esTypes: ['keyword'], - name: 'extension', - readFromDocValues: true, - scripted: false, - searchable: true, - type: 'string', - }, + field: field2, id: '123', nested: undefined, operator: isOneOfOperator, @@ -1092,7 +1105,7 @@ describe('Exception builder helpers', () => { }); test('it returns formatted entries when nested entries exist', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadParent: EntryNested = { ...getEntryNestedWithIdMock(), entries: [{ ...getEntryMatchWithIdMock(), field: 'child' }], @@ -1104,20 +1117,43 @@ describe('Exception builder helpers', () => { ]; const output = getFormattedBuilderEntries(payloadIndexPattern, payloadItems); + const field1: FieldSpec = { + aggregatable: true, + count: 0, + esTypes: ['ip'], + name: 'ip', + readFromDocValues: true, + scripted: false, + searchable: true, + type: 'ip', + }; + const field2: FieldSpec = { + aggregatable: false, + esTypes: ['nested'], + name: 'nestedField', + searchable: false, + type: 'string', + }; + const field3: FieldSpec = { + aggregatable: false, + count: 0, + esTypes: ['text'], + name: 'child', + readFromDocValues: false, + scripted: false, + searchable: true, + subType: { + nested: { + path: 'nestedField', + }, + }, + type: 'string', + }; const expected: FormattedBuilderEntry[] = [ { correspondingKeywordField: undefined, entryIndex: 0, - field: { - aggregatable: true, - count: 0, - esTypes: ['ip'], - name: 'ip', - readFromDocValues: true, - scripted: false, - searchable: true, - type: 'ip', - }, + field: field1, id: '123', nested: undefined, operator: isOperator, @@ -1127,13 +1163,7 @@ describe('Exception builder helpers', () => { { correspondingKeywordField: undefined, entryIndex: 1, - field: { - aggregatable: false, - esTypes: ['nested'], - name: 'nestedField', - searchable: false, - type: 'string', - }, + field: field2, id: '123', nested: 'parent', operator: isOperator, @@ -1143,21 +1173,7 @@ describe('Exception builder helpers', () => { { correspondingKeywordField: undefined, entryIndex: 0, - field: { - aggregatable: false, - count: 0, - esTypes: ['text'], - name: 'child', - readFromDocValues: false, - scripted: false, - searchable: true, - subType: { - nested: { - path: 'nestedField', - }, - }, - type: 'string', - }, + field: field3, id: '123', nested: 'child', operator: isOperator, @@ -1248,7 +1264,7 @@ describe('Exception builder helpers', () => { describe('#getFormattedBuilderEntry', () => { test('it returns entry with a value for "correspondingKeywordField" when "item.field" is of type "text" and matching keyword field exists', () => { - const payloadIndexPattern: IIndexPattern = { + const payloadIndexPattern: IndexPatternBase = { ...getMockIndexPattern(), fields: [ ...fields, @@ -1276,19 +1292,20 @@ describe('Exception builder helpers', () => { undefined, undefined ); + const field: FieldSpec = { + aggregatable: false, + count: 0, + esTypes: ['text'], + name: 'machine.os.raw.text', + readFromDocValues: true, + scripted: false, + searchable: false, + type: 'string', + }; const expected: FormattedBuilderEntry = { correspondingKeywordField: getField('machine.os.raw'), entryIndex: 0, - field: { - aggregatable: false, - count: 0, - esTypes: ['text'], - name: 'machine.os.raw.text', - readFromDocValues: true, - scripted: false, - searchable: false, - type: 'string', - }, + field, id: '123', nested: undefined, operator: isOperator, @@ -1299,7 +1316,7 @@ describe('Exception builder helpers', () => { }); test('it returns "FormattedBuilderEntry" with value "nested" of "child" when "parent" and "parentIndex" are defined', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: BuilderEntry = { ...getEntryMatchWithIdMock(), field: 'child' }; const payloadParent: EntryNested = { ...getEntryNestedWithIdMock(), @@ -1313,24 +1330,25 @@ describe('Exception builder helpers', () => { payloadParent, 1 ); + const field: FieldSpec = { + aggregatable: false, + count: 0, + esTypes: ['text'], + name: 'child', + readFromDocValues: false, + scripted: false, + searchable: true, + subType: { + nested: { + path: 'nestedField', + }, + }, + type: 'string', + }; const expected: FormattedBuilderEntry = { correspondingKeywordField: undefined, entryIndex: 0, - field: { - aggregatable: false, - count: 0, - esTypes: ['text'], - name: 'child', - readFromDocValues: false, - scripted: false, - searchable: true, - subType: { - nested: { - path: 'nestedField', - }, - }, - type: 'string', - }, + field, id: '123', nested: 'child', operator: isOperator, @@ -1349,7 +1367,7 @@ describe('Exception builder helpers', () => { }); test('it returns non nested "FormattedBuilderEntry" when "parent" and "parentIndex" are not defined', () => { - const payloadIndexPattern: IIndexPattern = getMockIndexPattern(); + const payloadIndexPattern = getMockIndexPattern(); const payloadItem: BuilderEntry = { ...getEntryMatchWithIdMock(), field: 'ip', @@ -1362,19 +1380,20 @@ describe('Exception builder helpers', () => { undefined, undefined ); + const field: FieldSpec = { + aggregatable: true, + count: 0, + esTypes: ['ip'], + name: 'ip', + readFromDocValues: true, + scripted: false, + searchable: true, + type: 'ip', + }; const expected: FormattedBuilderEntry = { correspondingKeywordField: undefined, entryIndex: 0, - field: { - aggregatable: true, - count: 0, - esTypes: ['ip'], - name: 'ip', - readFromDocValues: true, - scripted: false, - searchable: true, - type: 'ip', - }, + field, id: '123', nested: undefined, operator: isOperator, diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index af8058e25adc64..5347ee875181b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -41,14 +41,14 @@ import { getEntryMatchMock } from '../../../../../lists/common/schemas/types/ent import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comment.mock'; import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { ENTRIES, OLD_DATE_RELATIVE_TO_DATE_NOW } from '../../../../../lists/common/constants.mock'; -import { IFieldType, IIndexPattern } from 'src/plugins/data/common'; import { CodeSignature } from '../../../../common/ecs/file'; +import { IndexPatternBase } from '@kbn/es-query'; jest.mock('uuid', () => ({ v4: jest.fn().mockReturnValue('123'), })); -const getMockIndexPattern = (): IIndexPattern => ({ +const getMockIndexPattern = (): IndexPatternBase => ({ fields, id: '1234', title: 'logstash-*', @@ -91,9 +91,6 @@ const mockLinuxEndpointFields = [ }, ]; -export const getEndpointField = (name: string) => - mockEndpointFields.find((field) => field.name === name) as IFieldType; - describe('Exception helpers', () => { beforeEach(() => { moment.tz.setDefault('UTC'); @@ -367,7 +364,7 @@ describe('Exception helpers', () => { name: 'nested.field', }, ], - } as IIndexPattern; + } as IndexPatternBase; test('it should return false with an empty array', () => { const payload: ExceptionListItemSchema[] = []; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx index f8260062f69741..613d2955454619 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.tsx @@ -33,10 +33,10 @@ import { addIdToEntries, ExceptionsBuilderExceptionItem, } from '@kbn/securitysolution-list-utils'; +import { IndexPatternBase } from '@kbn/es-query'; import * as i18n from './translations'; import { AlertData, Flattened } from './types'; -import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { Ecs } from '../../../../common/ecs'; import { CodeSignature } from '../../../../common/ecs/file'; import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard'; @@ -46,10 +46,10 @@ import exceptionableEndpointFields from './exceptionable_endpoint_fields.json'; import exceptionableEndpointEventFields from './exceptionable_endpoint_event_fields.json'; export const filterIndexPatterns = ( - patterns: IIndexPattern, + patterns: IndexPatternBase, type: ExceptionListType, osTypes?: OsTypeArray -): IIndexPattern => { +): IndexPatternBase => { switch (type) { case 'endpoint': const osFilterForEndpoint: (name: string) => boolean = osTypes?.includes('linux') @@ -634,7 +634,7 @@ export const getPrepopulatedMemoryShellcodeException = ({ */ export const entryHasNonEcsType = ( exceptionItems: Array, - indexPatterns: IIndexPattern + indexPatterns: IndexPatternBase ): boolean => { const doesFieldNameExist = (exceptionEntry: Entry): boolean => { return indexPatterns.fields.some(({ name }) => name === exceptionEntry.field); diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx index 49bd7824d61008..99c5b37046505c 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx @@ -10,7 +10,8 @@ import { EuiFormRow, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; import { FieldComponent } from '@kbn/securitysolution-autocomplete'; -import { IFieldType, IndexPattern } from '../../../../../../../src/plugins/data/common'; +import { IndexPatternFieldBase } from '@kbn/es-query'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { FormattedEntry, Entry } from './types'; import * as i18n from './translations'; import { getEntryOnFieldChange, getEntryOnThreatFieldChange } from './helpers'; @@ -40,7 +41,7 @@ export const EntryItem: React.FC = ({ onChange, }): JSX.Element => { const handleFieldChange = useCallback( - ([newField]: IFieldType[]): void => { + ([newField]: IndexPatternFieldBase[]): void => { const { updatedEntry, index } = getEntryOnFieldChange(entry, newField); onChange(updatedEntry, index); }, @@ -48,7 +49,7 @@ export const EntryItem: React.FC = ({ ); const handleThreatFieldChange = useCallback( - ([newField]: IFieldType[]): void => { + ([newField]: IndexPatternFieldBase[]): void => { const { updatedEntry, index } = getEntryOnThreatFieldChange(entry, newField); onChange(updatedEntry, index); }, diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx index d3e1dea2dd93e5..24a0f94e05883d 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx @@ -10,7 +10,7 @@ import { getField, } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; import { Entry, EmptyEntry, ThreatMapEntries, FormattedEntry } from './types'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common'; +import { FieldSpec, IndexPattern } from '../../../../../../../src/plugins/data/common'; import moment from 'moment-timezone'; import { @@ -88,7 +88,7 @@ describe('Helpers', () => { searchable: false, aggregatable: false, readFromDocValues: true, - }, + } as FieldSpec, type: 'mapping', value: undefined, }; @@ -130,7 +130,7 @@ describe('Helpers', () => { searchable: true, aggregatable: true, readFromDocValues: false, - }, + } as FieldSpec, value: undefined, type: 'mapping', }, @@ -156,7 +156,7 @@ describe('Helpers', () => { searchable: true, aggregatable: true, readFromDocValues: false, - }, + } as FieldSpec, value: { name: 'machine.os', type: 'string', @@ -166,7 +166,7 @@ describe('Helpers', () => { searchable: true, aggregatable: true, readFromDocValues: false, - }, + } as FieldSpec, type: 'mapping', }, ]; @@ -192,7 +192,7 @@ describe('Helpers', () => { searchable: true, aggregatable: true, readFromDocValues: false, - }, + } as FieldSpec, type: 'mapping', value: { name: 'machine.os', @@ -203,7 +203,7 @@ describe('Helpers', () => { searchable: true, aggregatable: true, readFromDocValues: false, - }, + } as FieldSpec, entryIndex: 0, }, { diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx index 89ace117f1301a..3f8e5b1602db85 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx @@ -10,7 +10,8 @@ import { i18n } from '@kbn/i18n'; import { addIdToItem } from '@kbn/securitysolution-utils'; import { ThreatMap, threatMap, ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; -import { IndexPattern, IFieldType } from '../../../../../../../src/plugins/data/common'; +import { IndexPatternFieldBase } from '@kbn/es-query'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { Entry, FormattedEntry, ThreatMapEntries, EmptyEntry } from './types'; import { ValidationFunc } from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; import { ERROR_CODE } from '../../../../../../../src/plugins/es_ui_shared/static/forms/helpers/field_validators/types'; @@ -90,7 +91,7 @@ export const getUpdatedEntriesOnDelete = ( */ export const getEntryOnFieldChange = ( item: FormattedEntry, - newField: IFieldType + newField: IndexPatternFieldBase ): { updatedEntry: Entry; index: number } => { const { entryIndex } = item; return { @@ -113,7 +114,7 @@ export const getEntryOnFieldChange = ( */ export const getEntryOnThreatFieldChange = ( item: FormattedEntry, - newField: IFieldType + newField: IndexPatternFieldBase ): { updatedEntry: Entry; index: number } => { const { entryIndex } = item; return { diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/types.ts b/x-pack/plugins/security_solution/public/common/components/threat_match/types.ts index 3d4fa19ac57948..3d3a18b425e010 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/types.ts @@ -5,14 +5,14 @@ * 2.0. */ +import { IndexPatternFieldBase } from '@kbn/es-query'; import { ThreatMap, ThreatMapEntry } from '@kbn/securitysolution-io-ts-alerting-types'; -import { IFieldType } from '../../../../../../../src/plugins/data/common'; export interface FormattedEntry { id: string; - field: IFieldType | undefined; + field: IndexPatternFieldBase | undefined; type: 'mapping'; - value: IFieldType | undefined; + value: IndexPatternFieldBase | undefined; entryIndex: number; } diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/autocomplete_field/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/autocomplete_field/index.tsx index 16caed9086e611..22fabcd15b1946 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/autocomplete_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/autocomplete_field/index.tsx @@ -8,15 +8,14 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFormRow } from '@elastic/eui'; import { FieldComponent } from '@kbn/securitysolution-autocomplete'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { FieldHook } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; -import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; interface AutocompleteFieldProps { dataTestSubj: string; field: FieldHook; idAria: string; - indices: IIndexPattern; + indices: IndexPatternBase; isDisabled: boolean; fieldType: string; placeholder?: string; @@ -32,7 +31,7 @@ export const AutocompleteField = ({ placeholder, }: AutocompleteFieldProps) => { const handleFieldChange = useCallback( - ([newField]: IFieldType[]): void => { + ([newField]: IndexPatternFieldBase[]): void => { // TODO: Update onChange type in FieldComponent as newField can be undefined field.setValue(newField?.name ?? ''); }, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx index eef18a502c2704..e9cbcb6c38268a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx @@ -21,11 +21,10 @@ import styled from 'styled-components'; import { noop } from 'lodash/fp'; import { RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; import { FieldComponent } from '@kbn/securitysolution-autocomplete'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import * as i18n from './translations'; import { FieldHook } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; import { AboutStepRiskScore } from '../../../pages/detection_engine/rules/types'; -import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; const NestedContent = styled.div` margin-left: 24px; @@ -47,7 +46,7 @@ interface RiskScoreFieldProps { dataTestSubj: string; field: FieldHook; idAria: string; - indices: IIndexPattern; + indices: IndexPatternBase; isDisabled: boolean; placeholder?: string; } @@ -79,7 +78,7 @@ export const RiskScoreField = ({ ); const handleRiskScoreMappingChange = useCallback( - ([newField]: IFieldType[]): void => { + ([newField]: IndexPatternFieldBase[]): void => { setValue({ value, isMappingChecked, @@ -232,14 +231,17 @@ export const RiskScoreField = ({ }; /** - * Looks for field metadata (IFieldType) in existing index pattern. - * If specified field doesn't exist, returns a stub IFieldType created based on the mapping -- + * Looks for field metadata (IndexPatternFieldBase) in existing index pattern. + * If specified field doesn't exist, returns a stub IndexPatternFieldBase created based on the mapping -- * because the field might not have been indexed yet, but we still need to display the mapping. * * @param mapping Mapping of a specified field name to risk score. * @param pattern Existing index pattern. */ -const getFieldTypeByMapping = (mapping: RiskScoreMapping, pattern: IIndexPattern): IFieldType => { +const getFieldTypeByMapping = ( + mapping: RiskScoreMapping, + pattern: IndexPatternBase +): IndexPatternFieldBase => { const field = mapping?.[0]?.field ?? ''; const [knownFieldType] = pattern.fields.filter(({ name }) => field != null && field === name); return knownFieldType ?? { name: field, type: 'number' }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx index d4fbdc31fbcae9..4eca6f32d0c1fe 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx @@ -29,14 +29,11 @@ import { AutocompleteFieldMatchComponent, } from '@kbn/securitysolution-autocomplete'; +import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import * as i18n from './translations'; import { FieldHook } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; import { SeverityOptionItem } from '../step_about_rule/data'; import { AboutStepSeverity } from '../../../pages/detection_engine/rules/types'; -import { - IFieldType, - IIndexPattern, -} from '../../../../../../../../src/plugins/data/common/index_patterns'; import { useKibana } from '../../../../common/lib/kibana'; const NestedContent = styled.div` @@ -59,7 +56,7 @@ interface SeverityFieldProps { dataTestSubj: string; field: FieldHook; idAria: string; - indices: IIndexPattern; + indices: IndexPatternBase; isDisabled: boolean; options: SeverityOptionItem[]; } @@ -88,7 +85,7 @@ export const SeverityField = ({ ); const handleFieldChange = useCallback( - (index: number, severity: Severity, [newField]: IFieldType[]): void => { + (index: number, severity: Severity, [newField]: IndexPatternFieldBase[]): void => { const newMappingItems: SeverityMapping = [ { ...mapping[index], @@ -298,8 +295,8 @@ export const SeverityField = ({ }; /** - * Looks for field metadata (IFieldType) in existing index pattern. - * If specified field doesn't exist, returns a stub IFieldType created based on the mapping -- + * Looks for field metadata (IndexPatternFieldBase) in existing index pattern. + * If specified field doesn't exist, returns a stub IndexPatternFieldBase created based on the mapping -- * because the field might not have been indexed yet, but we still need to display the mapping. * * @param mapping Mapping of a specified field name + value to a certain severity value. @@ -307,8 +304,8 @@ export const SeverityField = ({ */ const getFieldTypeByMapping = ( mapping: SeverityMappingItem, - pattern: IIndexPattern -): IFieldType => { + pattern: IndexPatternBase +): IndexPatternFieldBase => { const { field } = mapping; const [knownFieldType] = pattern.fields.filter(({ name }) => field === name); return knownFieldType ?? { name: field, type: 'string' };