diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/cti/event_enrichment.ts b/x-pack/plugins/security_solution/common/api/search_strategy/cti/event_enrichment.ts index 90ea7bbf6dd0b..ecf86bc742e6e 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/cti/event_enrichment.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/cti/event_enrichment.ts @@ -11,7 +11,7 @@ import { requestBasicOptionsSchema } from '../model/request_basic_options'; import { timerange } from '../model/timerange'; export const eventEnrichmentRequestOptionsSchema = requestBasicOptionsSchema.extend({ - eventFields: z.record(z.string()), + eventFields: z.record(z.unknown()), timerange, factoryQueryType: z.literal(CtiQueries.eventEnrichment), }); diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/index.ts b/x-pack/plugins/security_solution/common/api/search_strategy/index.ts index 839a84d08620c..54baa7c46ed2d 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/index.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/index.ts @@ -78,6 +78,8 @@ export * from './model/pagination'; export * from './model/factory_query_type'; +export * from './model/runtime_mappings'; + export const searchStrategyRequestSchema = z.discriminatedUnion('factoryQueryType', [ firstLastSeenRequestOptionsSchema, allHostsSchema, diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/matrix_histogram/matrix_histogram.ts b/x-pack/plugins/security_solution/common/api/search_strategy/matrix_histogram/matrix_histogram.ts index c8974a854b0c5..7ad60f8d8b6fc 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/matrix_histogram/matrix_histogram.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/matrix_histogram/matrix_histogram.ts @@ -9,6 +9,7 @@ import { z } from 'zod'; import { MatrixHistogramQuery } from '../model/factory_query_type'; import { inspect } from '../model/inspect'; import { requestBasicOptionsSchema } from '../model/request_basic_options'; +import { runtimeMappings } from '../model/runtime_mappings'; import { timerange } from '../model/timerange'; export enum MatrixHistogramType { @@ -45,8 +46,7 @@ export const matrixHistogramSchema = requestBasicOptionsSchema.extend({ inspect, isPtrIncluded: z.boolean().default(false), includeMissingData: z.boolean().default(true), - // TODO: add stricter type here - runtimeMappings: z.record(z.any()).optional(), + runtimeMappings, timerange, factoryQueryType: z.literal(MatrixHistogramQuery), }); diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/model/runtime_mappings.ts b/x-pack/plugins/security_solution/common/api/search_strategy/model/runtime_mappings.ts new file mode 100644 index 0000000000000..b3f16c1ed1236 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/search_strategy/model/runtime_mappings.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { z } from 'zod'; + +export type MappingRuntimeFieldType = + | 'boolean' + | 'date' + | 'double' + | 'geo_point' + | 'ip' + | 'keyword' + | 'long' + | 'lookup'; + +export const runtimeMappings = z + .record( + z.object({ + type: z.union([ + z.literal('boolean'), + z.literal('date'), + z.literal('double'), + z.literal('geo_point'), + z.literal('ip'), + z.literal('keyword'), + z.literal('long'), + z.literal('lookup'), + ]), + script: z + .union([ + z.string(), + z.object({ source: z.string() }), + z.object({ id: z.string(), params: z.record(z.any()) }), + ]) + .optional(), + fetch_fields: z.array(z.string()).optional(), + format: z.string().optional(), + input_field: z.string().optional(), + target_field: z.string().optional(), + target_index: z.string().optional(), + }) + ) + .optional(); + +export type RunTimeMappings = z.infer; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts index e85679e6c5dd8..3fdf2cc22de6c 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/all/index.ts @@ -10,5 +10,4 @@ export type { TimelineItem, TimelineNonEcsData, TimelineEventsAllStrategyResponse, - TimelineEventsAllRequestOptions, } from '@kbn/timelines-plugin/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts index b8994774a1887..3cb50c2869935 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/details/index.ts @@ -8,5 +8,4 @@ export type { TimelineEventsDetailsItem, TimelineEventsDetailsStrategyResponse, - TimelineEventsDetailsRequestOptions, } from '@kbn/timelines-plugin/common'; diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts index 38ebb27e0416a..10f993b468189 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/eql/index.ts @@ -6,7 +6,6 @@ */ export type { - TimelineEqlRequestOptions, TimelineEqlResponse, EqlOptionsData, EqlOptionsSelected, diff --git a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts index 924fff0230a14..9b95e7606d954 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/timeline/events/last_event_time/index.ts @@ -10,7 +10,7 @@ export { LastEventIndexKey } from '@kbn/timelines-plugin/common'; export type { LastTimeDetails, TimelineEventsLastEventTimeStrategyResponse, - TimelineKpiStrategyRequest, + TimelineKpiRequestOptionsInput, TimelineKpiStrategyResponse, - TimelineEventsLastEventTimeRequestOptions, + TimelineEventsLastEventTimeRequestOptionsInput, } from '@kbn/timelines-plugin/common'; diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/use_timelines_events.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/use_timelines_events.tsx index 2b234879ccc50..691d0e95cb924 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/use_timelines_events.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/use_timelines_events.tsx @@ -17,7 +17,8 @@ import type { Inspect, PaginationInputPaginated, TimelineEdges, - TimelineEventsAllRequestOptions, + TimelineEqlRequestOptionsInput, + TimelineEventsAllOptionsInput, TimelineEventsAllStrategyResponse, TimelineItem, } from '@kbn/timelines-plugin/common'; @@ -58,7 +59,7 @@ type TimelineEventsSearchHandler = (onNextResponse?: OnNextResponseHandler) => v type LoadPage = (newActivePage: number) => void; -type TimelineRequest = TimelineEventsAllRequestOptions; +type TimelineRequest = TimelineEventsAllOptionsInput | TimelineEqlRequestOptionsInput; type TimelineResponse = TimelineEventsAllStrategyResponse; @@ -161,11 +162,9 @@ export const useTimelineEventsHandler = ({ const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(true); const [activePage, setActivePage] = useState(0); - const [timelineRequest, setTimelineRequest] = useState | null>( - null - ); + const [timelineRequest, setTimelineRequest] = useState(null); const [prevFilterStatus, setFilterStatus] = useState(filterStatus); - const prevTimelineRequest = useRef | null>(null); + const prevTimelineRequest = useRef(null); const clearSignalsState = useCallback(() => { if (id != null && detectionsTimelineIds.some((timelineId) => timelineId === id)) { @@ -220,7 +219,7 @@ export const useTimelineEventsHandler = ({ }); const timelineSearch = useCallback( - (request: TimelineRequest | null, onNextHandler?: OnNextResponseHandler) => { + (request: TimelineRequest | null, onNextHandler?: OnNextResponseHandler) => { if (request == null || skip) { return; } @@ -233,7 +232,7 @@ export const useTimelineEventsHandler = ({ startTracking(); const abortSignal = abortCtrl.current.signal; searchSubscription$.current = data.search - .search, TimelineResponse>( + .search>( { ...request, entityType }, { strategy: @@ -296,12 +295,12 @@ export const useTimelineEventsHandler = ({ const prevSearchParameters = { defaultIndex: prevRequest?.defaultIndex ?? [], filterQuery: prevRequest?.filterQuery ?? '', - querySize: prevRequest?.pagination.querySize ?? 0, + querySize: prevRequest?.pagination?.querySize ?? 0, sort: prevRequest?.sort ?? initSortDefault, timerange: prevRequest?.timerange ?? {}, - runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as RunTimeMappings, + runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as unknown as RunTimeMappings, filterStatus: prevRequest?.filterStatus, - }; + } as const; const currentSearchParameters = { defaultIndex: indexNames, @@ -315,7 +314,7 @@ export const useTimelineEventsHandler = ({ to: endDate, }, filterStatus, - }; + } as const; const newActivePage = deepEqual(prevSearchParameters, currentSearchParameters) ? activePage @@ -333,7 +332,7 @@ export const useTimelineEventsHandler = ({ activePage: newActivePage, querySize: limit, }, - language, + language: language as TimelineRequest['language'], runtimeMappings, sort, timerange: { @@ -348,7 +347,7 @@ export const useTimelineEventsHandler = ({ setActivePage(newActivePage); } if (!deepEqual(prevRequest, currentRequest)) { - return currentRequest; + return currentRequest as TimelineRequest; } return prevRequest; }); diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts index 49ac62cb572e4..6d5df295dbc41 100644 --- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/types.ts @@ -8,8 +8,8 @@ import type React from 'react'; import type { EuiTitleSize } from '@elastic/eui'; import type { ScaleType, Position, TickFormatter } from '@elastic/charts'; -import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { ActionCreator } from 'redux'; +import type { RunTimeMappings } from '@kbn/timelines-plugin/common/api/search_strategy'; import type { ESQuery } from '../../../../common/typed_json'; import type { InputsModelId } from '../../store/inputs/constants'; import type { MatrixHistogramType } from '../../../../common/search_strategy/security_solution'; @@ -83,7 +83,7 @@ export interface MatrixHistogramQueryProps { skip?: boolean; isPtrIncluded?: boolean; includeMissingData?: boolean; - runtimeMappings?: MappingRuntimeFields; + runtimeMappings?: RunTimeMappings; } export interface MatrixHistogramProps extends MatrixHistogramBasicProps { diff --git a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts index 8904ccd5ad8bb..471d43c928458 100644 --- a/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts +++ b/x-pack/plugins/security_solution/public/common/containers/events/last_event_time/index.ts @@ -14,10 +14,10 @@ import { isCompleteResponse } from '@kbn/data-plugin/common'; import type { inputsModel } from '../../../store'; import { useKibana } from '../../../lib/kibana'; import type { - TimelineEventsLastEventTimeRequestOptions, TimelineEventsLastEventTimeStrategyResponse, LastTimeDetails, LastEventIndexKey, + TimelineEventsLastEventTimeRequestOptionsInput, } from '../../../../../common/search_strategy/timeline'; import { TimelineEventsQueries } from '../../../../../common/search_strategy/timeline'; import * as i18n from './translations'; @@ -46,7 +46,7 @@ export const useTimelineLastEventTime = ({ const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); const [TimelineLastEventTimeRequest, setTimelineLastEventTimeRequest] = - useState({ + useState({ defaultIndex: indexNames, factoryQueryType: TimelineEventsQueries.lastEventTime, indexKey, @@ -62,14 +62,14 @@ export const useTimelineLastEventTime = ({ const { addError } = useAppToasts(); const timelineLastEventTimeSearch = useCallback( - (request: TimelineEventsLastEventTimeRequestOptions) => { + (request: TimelineEventsLastEventTimeRequestOptionsInput) => { const asyncSearch = async () => { abortCtrl.current = new AbortController(); setLoading(true); searchSubscription$.current = data.search .search< - TimelineEventsLastEventTimeRequestOptions, + TimelineEventsLastEventTimeRequestOptionsInput, TimelineEventsLastEventTimeStrategyResponse >(request, { strategy: 'timelineSearchStrategy', diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx index 7ad0adcaccafd..a52446d389d7a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/actions.tsx @@ -33,6 +33,7 @@ import { import { lastValueFrom } from 'rxjs'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import type { DataTableModel } from '@kbn/securitysolution-data-table'; +import type { TimelineEventsDetailsRequestOptionsInput } from '@kbn/timelines-plugin/common'; import { ALERT_ORIGINAL_TIME, ALERT_GROUP_ID, @@ -54,7 +55,6 @@ import type { } from './types'; import type { TimelineEventsDetailsItem, - TimelineEventsDetailsRequestOptions, TimelineEventsDetailsStrategyResponse, } from '../../../../common/search_strategy/timeline'; import { TimelineEventsQueries } from '../../../../common/search_strategy/timeline'; @@ -956,7 +956,7 @@ export const sendAlertToTimelineAction = async ({ getTimelineTemplate(timelineId), lastValueFrom( searchStrategyClient.search< - TimelineEventsDetailsRequestOptions, + TimelineEventsDetailsRequestOptionsInput, TimelineEventsDetailsStrategyResponse >( { diff --git a/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx index df01e7f1b1450..8935ff132f246 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/alert_details/index.tsx @@ -11,6 +11,7 @@ import { Routes, Route } from '@kbn/shared-ux-router'; import { ALERT_RULE_NAME, TIMESTAMP } from '@kbn/rule-data-utils'; import { EuiSpacer } from '@elastic/eui'; import { useDispatch } from 'react-redux'; +import type { RunTimeMappings } from '../../../../common/api/search_strategy'; import { timelineActions } from '../../../timelines/store/timeline'; import { TimelineId } from '../../../../common/types/timeline'; import { useGetFieldsData } from '../../../common/hooks/use_get_fields_data'; @@ -42,7 +43,7 @@ export const AlertDetailsPage = memo(() => { const [loading, detailsData, searchHit, dataAsNestedObject] = useTimelineEventsDetails({ indexName, eventId, - runtimeMappings: sourcererDataView.runtimeMappings, + runtimeMappings: sourcererDataView.runtimeMappings as RunTimeMappings, skip: !eventID, }); const dataNotFound = !loading && !detailsData; diff --git a/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.ts b/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.ts index 0cdc66a95a99f..c291e2a123c3d 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.ts +++ b/x-pack/plugins/security_solution/public/flyout/left/hooks/use_threat_intelligence_details.ts @@ -6,6 +6,7 @@ */ import { useMemo } from 'react'; +import type { RunTimeMappings } from '../../../../common/api/search_strategy'; import type { CtiEnrichment, EventFields } from '../../../../common/search_strategy'; import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers'; import { @@ -53,7 +54,7 @@ export const useThreatIntelligenceDetails = (): ThreatIntelligenceDetailsValue = const [isEventDataLoading, eventData] = useTimelineEventsDetails({ indexName, eventId, - runtimeMappings: sourcererDataView.runtimeMappings, + runtimeMappings: sourcererDataView.runtimeMappings as RunTimeMappings, skip: !eventId, }); diff --git a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts index 91e371cd3b0b6..0f43743bcab28 100644 --- a/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts +++ b/x-pack/plugins/security_solution/public/flyout/shared/hooks/use_event_details.ts @@ -9,6 +9,7 @@ import type { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-pl import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { SecurityPageName } from '@kbn/security-solution-navigation'; import type { DataViewBase } from '@kbn/es-query'; +import type { RunTimeMappings } from '../../../../common/api/search_strategy'; import { useSpaceId } from '../../../common/hooks/use_space_id'; import { getAlertIndexAlias } from '../../../timelines/components/side_panel/event_details/helpers'; import { useRouteSpy } from '../../../common/utils/route/use_route_spy'; @@ -86,7 +87,7 @@ export const useEventDetails = ({ useTimelineEventsDetails({ indexName: eventIndex, eventId: eventId ?? '', - runtimeMappings: sourcererDataView.runtimeMappings, + runtimeMappings: sourcererDataView.runtimeMappings as RunTimeMappings, skip: !eventId, }); const getFieldsData = useGetFieldsData(searchHit?.fields); diff --git a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx index 360c95ec94019..b8592df20b3b5 100644 --- a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx @@ -14,6 +14,7 @@ import type { DataViewBase, Filter, Query } from '@kbn/es-query'; import styled from 'styled-components'; import { EuiButton } from '@elastic/eui'; import { getEsQueryConfig } from '@kbn/data-plugin/common'; +import type { RunTimeMappings } from '@kbn/timelines-plugin/common/api/search_strategy'; import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants'; import { SHOWING, UNIT } from '../../../common/components/events_viewer/translations'; import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts'; @@ -195,7 +196,7 @@ const EventsByDatasetComponent: React.FC = ({ headerChildren={headerContent} id={uniqueQueryId} indexNames={indexNames} - runtimeMappings={runtimeMappings} + runtimeMappings={runtimeMappings as RunTimeMappings} onError={toggleTopN} paddingSize={paddingSize} setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget} diff --git a/x-pack/plugins/security_solution/public/timelines/containers/active_timeline_context.ts b/x-pack/plugins/security_solution/public/timelines/containers/active_timeline_context.ts index 75a921cca12c2..383825da33038 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/active_timeline_context.ts +++ b/x-pack/plugins/security_solution/public/timelines/containers/active_timeline_context.ts @@ -5,12 +5,12 @@ * 2.0. */ +import type { + TimelineEventsAllOptionsInput, + TimelineEqlRequestOptionsInput, +} from '@kbn/timelines-plugin/common'; import type { ExpandedDetailTimeline, ExpandedDetailType } from '../../../common/types'; import { TimelineTabs } from '../../../common/types/timeline'; -import type { - TimelineEqlRequestOptions, - TimelineEventsAllRequestOptions, -} from '../../../common/search_strategy/timeline'; import type { TimelineArgs } from '.'; /* @@ -28,9 +28,9 @@ class ActiveTimelineEvents { private _activePage: number = 0; private _expandedDetail: ExpandedDetailTimeline = {}; private _pageName: string = ''; - private _request: TimelineEventsAllRequestOptions | null = null; + private _request: TimelineEventsAllOptionsInput | null = null; private _response: TimelineArgs | null = null; - private _eqlRequest: TimelineEqlRequestOptions | null = null; + private _eqlRequest: TimelineEqlRequestOptionsInput | null = null; private _eqlResponse: TimelineArgs | null = null; getActivePage() { @@ -89,7 +89,7 @@ class ActiveTimelineEvents { return this._request; } - setRequest(req: TimelineEventsAllRequestOptions) { + setRequest(req: TimelineEventsAllOptionsInput) { this._request = req; } @@ -105,7 +105,7 @@ class ActiveTimelineEvents { return this._eqlRequest; } - setEqlRequest(req: TimelineEqlRequestOptions) { + setEqlRequest(req: TimelineEqlRequestOptionsInput) { this._eqlRequest = req; } diff --git a/x-pack/plugins/security_solution/public/timelines/containers/details/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/details/index.tsx index 3b326e492d132..b35c2c86b9abe 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/details/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/details/index.tsx @@ -12,14 +12,13 @@ import deepEqual from 'fast-deep-equal'; import { Subscription } from 'rxjs'; import { isCompleteResponse } from '@kbn/data-plugin/common'; +import type { TimelineEventsDetailsRequestOptionsInput } from '@kbn/timelines-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, - TimelineEventsDetailsRequestOptions, TimelineEventsDetailsStrategyResponse, } from '../../../../common/search_strategy'; import { TimelineEventsQueries } from '../../../../common/search_strategy'; @@ -35,7 +34,7 @@ export interface UseTimelineEventsDetailsProps { entityType?: EntityType; indexName: string; eventId: string; - runtimeMappings: RunTimeMappings; + runtimeMappings: TimelineEventsDetailsRequestOptionsInput['runtimeMappings']; skip: boolean; } @@ -61,7 +60,7 @@ export const useTimelineEventsDetails = ({ // loading = false initial state causes flashes of empty tables const [loading, setLoading] = useState(true); const [timelineDetailsRequest, setTimelineDetailsRequest] = - useState(null); + useState(null); const { addError } = useAppToasts(); const [timelineDetailsResponse, setTimelineDetailsResponse] = @@ -70,7 +69,7 @@ export const useTimelineEventsDetails = ({ const [rawEventData, setRawEventData] = useState(undefined); const timelineDetailsSearch = useCallback( - (request: TimelineEventsDetailsRequestOptions | null) => { + (request: TimelineEventsDetailsRequestOptionsInput | null) => { if (request == null || skip || isEmpty(request.eventId)) { return; } @@ -80,7 +79,7 @@ export const useTimelineEventsDetails = ({ setLoading(true); searchSubscription$.current = data.search - .search( + .search( request, { strategy: 'timelineSearchStrategy', @@ -125,7 +124,7 @@ export const useTimelineEventsDetails = ({ eventId, factoryQueryType: TimelineEventsQueries.details, runtimeMappings, - }; + } as const; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } diff --git a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx index b65c7c7c51498..8d6e871f8354b 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/index.tsx @@ -13,6 +13,10 @@ import { Subscription } from 'rxjs'; import type { DataView } from '@kbn/data-plugin/common'; import { isCompleteResponse } from '@kbn/data-plugin/common'; +import type { + TimelineEqlRequestOptionsInput, + TimelineEventsAllOptionsInput, +} from '@kbn/timelines-plugin/common/api/search_strategy'; import type { ESQuery } from '../../../common/typed_json'; import type { inputsModel } from '../../common/store'; @@ -25,7 +29,6 @@ import { getInspectResponse } from '../../helpers'; import type { PaginationInputPaginated, TimelineEventsAllStrategyResponse, - TimelineEventsAllRequestOptions, TimelineEdges, TimelineItem, TimelineRequestSortField, @@ -38,7 +41,6 @@ import { useRouteSpy } from '../../common/utils/route/use_route_spy'; import { activeTimeline } from './active_timeline_context'; import type { EqlOptionsSelected, - TimelineEqlRequestOptions, TimelineEqlResponse, } from '../../../common/search_strategy/timeline/events/eql'; import { useTrackHttpRequest } from '../../common/lib/apm/use_track_http_request'; @@ -62,12 +64,12 @@ type TimelineEventsSearchHandler = (onNextResponse?: OnNextResponseHandler) => v type LoadPage = (newActivePage: number) => void; type TimelineRequest = T extends 'kuery' - ? TimelineEventsAllRequestOptions + ? TimelineEventsAllOptionsInput : T extends 'lucene' - ? TimelineEventsAllRequestOptions + ? TimelineEventsAllOptionsInput : T extends 'eql' - ? TimelineEqlRequestOptions - : TimelineEventsAllRequestOptions; + ? TimelineEqlRequestOptionsInput + : TimelineEventsAllOptionsInput; type TimelineResponse = T extends 'kuery' ? TimelineEventsAllStrategyResponse @@ -259,10 +261,9 @@ export const useTimelineEventsHandler = ({ activeTimeline.setExpandedDetail({}); activeTimeline.setPageName(pageName); if (request.language === 'eql') { - activeTimeline.setEqlRequest(request as TimelineEqlRequestOptions); + activeTimeline.setEqlRequest(request as TimelineEqlRequestOptionsInput); activeTimeline.setEqlResponse(newTimelineResponse); } else { - // @ts-expect-error EqlSearchRequest.query is not compatible with QueryDslQueryContainer activeTimeline.setRequest(request); activeTimeline.setResponse(newTimelineResponse); } @@ -335,14 +336,14 @@ export const useTimelineEventsHandler = ({ } setTimelineRequest((prevRequest) => { - const prevEqlRequest = prevRequest as TimelineEqlRequestOptions; + const prevEqlRequest = prevRequest as TimelineEqlRequestOptionsInput; const prevSearchParameters = { defaultIndex: prevRequest?.defaultIndex ?? [], filterQuery: prevRequest?.filterQuery ?? '', - querySize: prevRequest?.pagination.querySize ?? 0, + querySize: prevRequest?.pagination?.querySize ?? 0, sort: prevRequest?.sort ?? initSortDefault, timerange: prevRequest?.timerange ?? {}, - runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as RunTimeMappings, + runtimeMappings: (prevRequest?.runtimeMappings ?? {}) as unknown as RunTimeMappings, ...deStructureEqlOptions(prevEqlRequest), }; @@ -379,7 +380,7 @@ export const useTimelineEventsHandler = ({ sort, ...timerange, ...(eqlOptions ? eqlOptions : {}), - }; + } as const; if (activePage !== newActivePage) { setActivePage(newActivePage); diff --git a/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx b/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx index f2a1d81ec0294..898597830f49e 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/containers/kpis/index.tsx @@ -11,14 +11,14 @@ import deepEqual from 'fast-deep-equal'; import { Subscription } from 'rxjs'; import { isCompleteResponse } from '@kbn/data-plugin/public'; +import { TimelineEventsQueries } from '@kbn/timelines-plugin/common/api/search_strategy'; import type { inputsModel } from '../../../common/store'; import { useKibana } from '../../../common/lib/kibana'; import type { - TimelineKpiStrategyRequest, + TimelineKpiRequestOptionsInput, TimelineKpiStrategyResponse, TimerangeInput, } from '../../../../common/search_strategy'; -import { TimelineEventsQueries } from '../../../../common/search_strategy'; import type { ESQuery } from '../../../../common/typed_json'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import * as i18n from './translations'; @@ -41,15 +41,14 @@ export const useTimelineKpis = ({ const abortCtrl = useRef(new AbortController()); const searchSubscription$ = useRef(new Subscription()); const [loading, setLoading] = useState(false); - const [timelineKpiRequest, setTimelineKpiRequest] = useState( - null - ); + const [timelineKpiRequest, setTimelineKpiRequest] = + useState(null); const [timelineKpiResponse, setTimelineKpiResponse] = useState(null); const { addError } = useAppToasts(); const timelineKpiSearch = useCallback( - (request: TimelineKpiStrategyRequest | null) => { + (request: TimelineKpiRequestOptionsInput | null) => { if (request == null) { return; } @@ -58,7 +57,7 @@ export const useTimelineKpis = ({ setLoading(true); searchSubscription$.current = data.search - .search(request, { + .search(request, { strategy: 'timelineSearchStrategy', abortSignal: abortCtrl.current.signal, }) @@ -93,7 +92,7 @@ export const useTimelineKpis = ({ timerange, filterQuery, factoryQueryType: TimelineEventsQueries.kpi, - }; + } as const; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } diff --git a/x-pack/plugins/timelines/common/api/search_strategy/index.ts b/x-pack/plugins/timelines/common/api/search_strategy/index.ts index 9b93b53be8a85..4ff442c13f62a 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/index.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/index.ts @@ -13,6 +13,10 @@ import * as timelineSchemas from './timeline/timeline'; export * from './timeline/timeline'; +export * from './model/timeline_events_queries'; + +export * from './model/runtime_mappings'; + export const searchStrategyRequestSchema = z.discriminatedUnion('factoryQueryType', [ timelineSchemas.timelineEventsAllSchema, timelineSchemas.timelineEventsDetailsSchema, diff --git a/x-pack/plugins/timelines/common/api/search_strategy/model/language.ts b/x-pack/plugins/timelines/common/api/search_strategy/model/language.ts index d54571cc224ee..0301e2aa0581f 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/model/language.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/model/language.ts @@ -7,4 +7,4 @@ import { z } from 'zod'; -export const language = z.union([z.literal('eql'), z.literal('kuery'), z.literal('lucene')]); +export const language = z.union([z.literal('kuery'), z.literal('lucene')]); diff --git a/x-pack/plugins/timelines/common/api/search_strategy/model/runtime_mappings.ts b/x-pack/plugins/timelines/common/api/search_strategy/model/runtime_mappings.ts index 1954e83a3ee80..b3f16c1ed1236 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/model/runtime_mappings.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/model/runtime_mappings.ts @@ -30,7 +30,20 @@ export const runtimeMappings = z z.literal('long'), z.literal('lookup'), ]), - script: z.string(), + script: z + .union([ + z.string(), + z.object({ source: z.string() }), + z.object({ id: z.string(), params: z.record(z.any()) }), + ]) + .optional(), + fetch_fields: z.array(z.string()).optional(), + format: z.string().optional(), + input_field: z.string().optional(), + target_field: z.string().optional(), + target_index: z.string().optional(), }) ) .optional(); + +export type RunTimeMappings = z.infer; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/parse_options.ts b/x-pack/plugins/timelines/common/api/search_strategy/model/timeline_events_queries.ts similarity index 56% rename from x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/parse_options.ts rename to x-pack/plugins/timelines/common/api/search_strategy/model/timeline_events_queries.ts index 401482fa0a33e..96bd4a1090d3d 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/parse_options.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/model/timeline_events_queries.ts @@ -5,6 +5,9 @@ * 2.0. */ -import { timelineEventsAllSchema } from '../../../../../../common/api/search_strategy/timeline/events_all'; - -export const parseOptions = (options: unknown) => timelineEventsAllSchema.parse(options); +export enum TimelineEventsQueries { + all = 'eventsAll', + details = 'eventsDetails', + kpi = 'eventsKpi', + lastEventTime = 'eventsLastEventTime', +} diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/eql.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/eql.ts index 51905107cf3ab..c07aa3bf8c6cd 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/eql.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/eql.ts @@ -20,6 +20,7 @@ export const timelineEqlRequestOptionsSchema = requestPaginated.extend({ fieldRequested: z.array(z.string()), size: z.number().optional(), runTimeMappings: runtimeMappings.optional(), + language: z.literal('eql'), }); export type TimelineEqlRequestOptionsInput = z.input; diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_all.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_all.ts index 198ab2fc14294..84c046c348ab4 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_all.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_all.ts @@ -6,10 +6,10 @@ */ import { z } from 'zod'; -import { TimelineEventsQueries } from '../../../search_strategy'; import { language } from '../model/language'; import { runtimeMappings } from '../model/runtime_mappings'; import { sortItem } from '../model/sort'; +import { TimelineEventsQueries } from '../model/timeline_events_queries'; import { requestPaginated } from './request_paginated'; const extendedSortItem = sortItem.extend({ @@ -33,9 +33,6 @@ export const timelineEventsAllSchema = requestPaginated.extend({ }), ]) ), - filterStatus: z - .union([z.literal('open'), z.literal('closed'), z.literal('acknowledged')]) - .optional(), runtimeMappings, language, factoryQueryType: z.literal(TimelineEventsQueries.all), diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_details.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_details.ts index b39bd4dbbaa78..42444cf2d30e4 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_details.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_details.ts @@ -6,8 +6,8 @@ */ import { z } from 'zod'; -import { TimelineEventsQueries } from '../../../search_strategy'; import { runtimeMappings } from '../model/runtime_mappings'; +import { TimelineEventsQueries } from '../model/timeline_events_queries'; import { requestPaginated } from './request_paginated'; export const timelineEventsDetailsSchema = requestPaginated.partial().extend({ diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_last_event_time.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_last_event_time.ts index 03a9074f56aa2..6599c8e3fd91f 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_last_event_time.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/events_last_event_time.ts @@ -6,7 +6,7 @@ */ import { z } from 'zod'; -import { TimelineEventsQueries } from '../../../search_strategy'; +import { TimelineEventsQueries } from '../model/timeline_events_queries'; import { timelineRequestBasicOptionsSchema } from './request_basic'; export enum LastEventIndexKey { diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/kpi.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/kpi.ts index 24a166cd568f0..a0776ae6c8feb 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/kpi.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/kpi.ts @@ -6,7 +6,7 @@ */ import { z } from 'zod'; -import { TimelineEventsQueries } from '../../../search_strategy'; +import { TimelineEventsQueries } from '../model/timeline_events_queries'; import { timelineRequestBasicOptionsSchema } from './request_basic'; export const timelineKpiRequestOptionsSchema = timelineRequestBasicOptionsSchema.extend({ diff --git a/x-pack/plugins/timelines/common/api/search_strategy/timeline/request_basic.ts b/x-pack/plugins/timelines/common/api/search_strategy/timeline/request_basic.ts index 314bcdf530ce1..5e8ea1caaa0fb 100644 --- a/x-pack/plugins/timelines/common/api/search_strategy/timeline/request_basic.ts +++ b/x-pack/plugins/timelines/common/api/search_strategy/timeline/request_basic.ts @@ -18,4 +18,7 @@ export const timelineRequestBasicOptionsSchema = z.object({ entityType: z.enum(['events', 'sessions']).optional(), runtimeMappings, params: z.any().optional(), + filterStatus: z + .union([z.literal('open'), z.literal('closed'), z.literal('acknowledged')]) + .optional(), }); diff --git a/x-pack/plugins/timelines/common/index.ts b/x-pack/plugins/timelines/common/index.ts index f677c673f96f5..445297c8b12cc 100644 --- a/x-pack/plugins/timelines/common/index.ts +++ b/x-pack/plugins/timelines/common/index.ts @@ -5,7 +5,14 @@ * 2.0. */ -import { LastEventIndexKey } from './api/search_strategy'; +export { + LastEventIndexKey, + type TimelineEventsAllOptionsInput, + type TimelineEventsDetailsRequestOptionsInput, + type TimelineEventsLastEventTimeRequestOptionsInput, + type TimelineKpiRequestOptionsInput, + type TimelineEqlRequestOptionsInput, +} from './api/search_strategy'; // Careful of exporting anything from this file as any file(s) you export here will cause your page bundle size to increase. // If you're using functions/types/etc... internally or within integration tests it's best to import directly from their paths @@ -50,20 +57,13 @@ export type { TimelineEdges, TimelineItem, TimelineEventsAllStrategyResponse, - TimelineEventsAllRequestOptions, TimelineEventsDetailsItem, TimelineEventsDetailsStrategyResponse, - TimelineEventsDetailsRequestOptions, TimelineEventsLastEventTimeStrategyResponse, - TimelineEventsLastEventTimeRequestOptions, - TimelineEqlRequestOptions, TimelineEqlResponse, - TimelineKpiStrategyRequest, TimelineKpiStrategyResponse, TotalValue, PaginationInputPaginated, } from './search_strategy'; -export { LastEventIndexKey }; - export { Direction, EntityType, EMPTY_BROWSER_FIELDS, EMPTY_INDEX_FIELDS } from './search_strategy'; diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts index d03fa935c543f..ade162b367faf 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/all/index.ts @@ -5,13 +5,9 @@ * 2.0. */ -import { JsonObject } from '@kbn/utility-types'; - 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; @@ -37,15 +33,3 @@ export interface TimelineEventsAllStrategyResponse extends IEsSearchResponse { pageInfo: Pick; inspect?: Maybe; } - -type AlertWorkflowStatus = 'open' | 'closed' | 'acknowledged'; - -export interface TimelineEventsAllRequestOptions extends TimelineRequestOptionsPaginated { - authFilter?: JsonObject; - excludeEcsData?: boolean; - fieldRequested: string[]; - fields: string[] | Array<{ field: string; include_unmapped: boolean }>; - language: 'eql' | 'kuery' | 'lucene'; - runtimeMappings: RunTimeMappings; - filterStatus?: AlertWorkflowStatus; -} diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts index 036a7ddb8462f..ae95943139b9b 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/details/index.ts @@ -5,12 +5,9 @@ * 2.0. */ -import { JsonObject } from '@kbn/utility-types'; - import type { IEsSearchResponse } from '@kbn/data-plugin/common'; import { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { Inspect, Maybe } from '../../../common'; -import { TimelineRequestOptionsPaginated } from '../..'; export interface TimelineEventsDetailsItem { ariaRowindex?: Maybe; @@ -28,10 +25,3 @@ export interface TimelineEventsDetailsStrategyResponse extends IEsSearchResponse inspect?: Maybe; rawEventData?: Maybe; } - -export interface TimelineEventsDetailsRequestOptions - extends Partial { - indexName: string; - eventId: string; - authFilter?: JsonObject; -} diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts index 4c9419ccf802a..66758bbcb94d7 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/eql/index.ts @@ -6,30 +6,14 @@ */ import { EuiComboBoxOptionOption } from '@elastic/eui'; -import type { - EqlSearchStrategyRequest, - EqlSearchStrategyResponse, - EqlRequestParams, -} from '@kbn/data-plugin/common'; +import type { EqlSearchStrategyResponse } 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; +import { TimelineEdges } from '../..'; export type RunTimeMappings = | Record & { type: RuntimePrimitiveTypes }> | undefined; -export interface TimelineEqlRequestOptions - extends EqlSearchStrategyRequest, - Omit { - eventCategoryField?: string; - tiebreakerField?: string; - timestampField?: string; - size?: number; - runtime_mappings?: RunTimeMappings; - body?: Omit & EqlBody & { runtime_mappings?: RunTimeMappings }; -} export interface TimelineEqlResponse extends EqlSearchStrategyResponse> { edges: TimelineEdges[]; diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/index.ts index ef0a5d1af265e..96b74e4e42435 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/index.ts @@ -10,13 +10,6 @@ export * from './details'; export * from './last_event_time'; export * from './eql'; -export enum TimelineEventsQueries { - all = 'eventsAll', - details = 'eventsDetails', - kpi = 'eventsKpi', - lastEventTime = 'eventsLastEventTime', -} - export const EntityType = { EVENTS: 'events', SESSIONS: 'sessions', diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts index 24941fc827711..13e91cd0bca05 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/events/last_event_time/index.ts @@ -6,9 +6,7 @@ */ import type { IEsSearchResponse } from '@kbn/data-plugin/common'; -import { LastEventIndexKey } from '../../../../api/search_strategy/timeline/events_last_event_time'; import { Inspect, Maybe } from '../../../common'; -import { TimelineRequestBasicOptions } from '../..'; export interface LastTimeDetails { hostName?: Maybe; @@ -20,8 +18,6 @@ export interface TimelineEventsLastEventTimeStrategyResponse extends IEsSearchRe lastSeen: Maybe; inspect?: Maybe; } -export type TimelineKpiStrategyRequest = Omit; - export interface TimelineKpiStrategyResponse extends IEsSearchResponse { destinationIpCount: number; inspect?: Maybe; @@ -30,9 +26,3 @@ export interface TimelineKpiStrategyResponse extends IEsSearchResponse { sourceIpCount: number; userCount: number; } - -export interface TimelineEventsLastEventTimeRequestOptions - extends Omit { - indexKey: LastEventIndexKey; - details: LastTimeDetails; -} diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts index 5e5f7b34fb52c..aaa9696bb827d 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts @@ -5,22 +5,18 @@ * 2.0. */ -import type { IEsSearchRequest } from '@kbn/data-plugin/common'; -import { ESQuery } from '../../typed_json'; import { - TimelineEventsQueries, TimelineEventsAllStrategyResponse, TimelineEventsDetailsStrategyResponse, TimelineEventsLastEventTimeStrategyResponse, TimelineKpiStrategyResponse, - EntityType, } from './events'; -import { PaginationInputPaginated, TimerangeInput, SortField } from '../common'; -import type { RunTimeMappings } from './events/eql'; +import { SortField } from '../common'; import { TimelineEventsAllOptionsInput, TimelineEventsDetailsRequestOptionsInput, TimelineEventsLastEventTimeRequestOptionsInput, + TimelineEventsQueries, TimelineKpiRequestOptionsInput, } from '../../api/search_strategy'; @@ -28,26 +24,11 @@ export * from './events'; export type TimelineFactoryQueryTypes = TimelineEventsQueries; -export interface TimelineRequestBasicOptions extends IEsSearchRequest { - timerange?: TimerangeInput; - filterQuery: ESQuery | string | undefined; - defaultIndex: string[]; - factoryQueryType?: TimelineFactoryQueryTypes; - entityType?: EntityType; - runtimeMappings: RunTimeMappings; -} - export interface TimelineRequestSortField extends SortField { esTypes: string[]; type: string; } -export interface TimelineRequestOptionsPaginated - extends TimelineRequestBasicOptions { - pagination: Pick; - sort: Array>; -} - export type TimelineStrategyResponseType = T extends TimelineEventsQueries.all ? TimelineEventsAllStrategyResponse diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts index c73d36a15d40c..c0e145aa501f6 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/helpers.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { Direction, TimelineEqlRequestOptions } from '../../../../common/search_strategy'; +import { TimelineEqlRequestOptions } from '../../../../common/api/search_strategy'; +import { Direction } from '../../../../common/search_strategy'; import { buildEqlDsl, parseEqlResponse } from './helpers'; import { eventsResponse, sequenceResponse } from './__mocks__'; const defaultArgs = { diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts index e812284a13a1d..2f52dd9e224f2 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/eql/index.ts @@ -8,11 +8,9 @@ import { map, mergeMap } from 'rxjs/operators'; import { ISearchStrategy, PluginStart, shimHitsTotal } from '@kbn/data-plugin/server'; import { EqlSearchStrategyResponse, EQL_SEARCH_STRATEGY } from '@kbn/data-plugin/common'; +import { TimelineEqlRequestOptions } from '../../../../common/api/search_strategy'; import { EqlSearchResponse } from '../../../../common/search_strategy'; -import { - TimelineEqlRequestOptions, - TimelineEqlResponse, -} from '../../../../common/search_strategy/timeline/events/eql'; +import { TimelineEqlResponse } from '../../../../common/search_strategy/timeline/events/eql'; import { buildEqlDsl, parseEqlResponse } from './helpers'; import { parseOptions } from './parse_options'; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts index 4fda8dd1ba758..7dea40b3a6c1f 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/index.ts @@ -8,10 +8,10 @@ import { cloneDeep, getOr } from 'lodash/fp'; import type { IEsSearchResponse } from '@kbn/data-plugin/common'; import { buildAlertFieldsRequest as buildFieldsRequest } from '@kbn/alerts-as-data-utils'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../../../../common/constants'; import { EventHit, - TimelineEventsQueries, TimelineEventsAllStrategyResponse, TimelineEdges, } from '../../../../../../common/search_strategy'; @@ -20,12 +20,9 @@ import { buildTimelineEventsAllQuery } from './query.events_all.dsl'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import { formatTimelineData } from '../../helpers/format_timeline_data'; import { TIMELINE_EVENTS_FIELDS } from '../../helpers/constants'; -import { parseOptions } from './parse_options'; export const timelineEventsAll: TimelineFactory = { - buildDsl: (maybeOptions: unknown) => { - const { authFilter, ...options } = parseOptions(maybeOptions); - + buildDsl: ({ authFilter, ...options }) => { if (options.pagination && options.pagination.querySize >= DEFAULT_MAX_TABLE_QUERY_SIZE) { throw new Error(`No query size above ${DEFAULT_MAX_TABLE_QUERY_SIZE}`); } @@ -34,11 +31,9 @@ export const timelineEventsAll: TimelineFactory = { return buildTimelineEventsAllQuery({ ...queryOptions, authFilter }); }, parse: async ( - maybeOptions: unknown, + options, response: IEsSearchResponse ): Promise => { - const options = parseOptions(maybeOptions); - // eslint-disable-next-line prefer-const let { fieldRequested, ...queryOptions } = cloneDeep(options); queryOptions.fields = buildFieldsRequest(fieldRequested, queryOptions.excludeEcsData); diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.test.ts index c23920222c99f..9a3a4a0261002 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/all/query.events_all.dsl.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { Direction, TimelineEventsQueries } from '../../../../../../common/search_strategy'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; +import { Direction } from '../../../../../../common/search_strategy'; import { buildTimelineEventsAllQuery } from './query.events_all.dsl'; describe('buildTimelineEventsAllQuery', () => { @@ -16,7 +17,7 @@ describe('buildTimelineEventsAllQuery', () => { fields: [], defaultIndex, filterQuery: '', - language: 'eql', + language: 'kuery', pagination: { activePage: 0, querySize: 100, diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts index b523a3102abe1..da88bbb213e6b 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/index.ts @@ -8,9 +8,9 @@ import { merge } from 'lodash/fp'; import type { IEsSearchResponse } from '@kbn/data-plugin/common'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; import { EventHit, - TimelineEventsQueries, TimelineEventsDetailsStrategyResponse, TimelineEventsDetailsItem, } from '../../../../../../common/search_strategy'; @@ -22,11 +22,9 @@ import { getDataSafety, } from '../../../../../../common/utils/field_formatters'; import { buildEcsObjects } from '../../helpers/build_ecs_objects'; -import { parseOptions } from './parse_options'; export const timelineEventsDetails: TimelineFactory = { - buildDsl: (request: unknown) => { - const parsedRequest = parseOptions(request); + buildDsl: (parsedRequest) => { const { authFilter, ...options } = parsedRequest; const { indexName, eventId, runtimeMappings = {} } = options; return buildTimelineDetailsQuery({ @@ -37,11 +35,9 @@ export const timelineEventsDetails: TimelineFactory ): Promise => { - const options = parseOptions(maybeOptions); - const { indexName, eventId, runtimeMappings = {} } = options; const { fields, ...hitsData } = response.rawResponse.hits.hits[0] ?? {}; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/parse_options.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/parse_options.ts deleted file mode 100644 index 14e7f713416b1..0000000000000 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/parse_options.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { timelineEventsDetailsSchema } from '../../../../../../common/api/search_strategy/timeline/timeline'; - -export const parseOptions = (options: unknown) => timelineEventsDetailsSchema.parse(options); diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts index 33ec6d02d6a1a..3074cf006ef82 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/details/query.events_details.dsl.ts @@ -6,7 +6,7 @@ */ import { JsonObject } from '@kbn/utility-types'; -import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { RunTimeMappings } from '../../../../../../common/api/search_strategy/model/runtime_mappings'; export const buildTimelineDetailsQuery = ({ authFilter, @@ -17,7 +17,7 @@ export const buildTimelineDetailsQuery = ({ authFilter?: JsonObject; id: string; indexName: string; - runtimeMappings: MappingRuntimeFields; + runtimeMappings: RunTimeMappings; }) => { const basicFilter = { terms: { diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts index e140fa1038704..cb2935f04c354 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/index.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - TimelineFactoryQueryTypes, - TimelineEventsQueries, -} from '../../../../../common/search_strategy/timeline'; +import { TimelineEventsQueries } from '../../../../../common/api/search_strategy'; import { TimelineFactory } from '../types'; import { timelineEventsAll } from './all'; @@ -16,10 +13,9 @@ import { timelineEventsDetails } from './details'; import { timelineKpi } from './kpi'; import { timelineEventsLastEventTime } from './last_event_time'; -export const timelineEventsFactory: Record< - TimelineEventsQueries, - TimelineFactory -> = { +export const timelineEventsFactory: { + [K in TimelineEventsQueries]: TimelineFactory; +} = { [TimelineEventsQueries.all]: timelineEventsAll, [TimelineEventsQueries.details]: timelineEventsDetails, [TimelineEventsQueries.kpi]: timelineKpi, diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts index d61409eb011bd..e12782a85fb83 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/index.ts @@ -8,26 +8,20 @@ import { getOr } from 'lodash/fp'; import type { IEsSearchResponse } from '@kbn/data-plugin/common'; -import { - TimelineEventsQueries, - TimelineKpiStrategyResponse, -} from '../../../../../../common/search_strategy/timeline'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; +import { TimelineKpiStrategyResponse } from '../../../../../../common/search_strategy/timeline'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import { TimelineFactory } from '../../types'; import { buildTimelineKpiQuery } from './query.kpi.dsl'; -import { parseOptions } from './parse_options'; export const timelineKpi: TimelineFactory = { - buildDsl: (maybeOptions: unknown) => { - const options = parseOptions(maybeOptions); + buildDsl: (options) => { return buildTimelineKpiQuery(options); }, parse: async ( - maybeOptions: unknown, + options, response: IEsSearchResponse ): Promise => { - const options = parseOptions(maybeOptions); - const inspect = { dsl: [inspectStringifyObject(buildTimelineKpiQuery(options))], }; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/parse_options.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/parse_options.ts deleted file mode 100644 index f4d3fe3c2cdcf..0000000000000 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/kpi/parse_options.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { timelineKpiRequestOptionsSchema } from '../../../../../../common/api/search_strategy/timeline/kpi'; - -export const parseOptions = (options: unknown) => timelineKpiRequestOptionsSchema.parse(options); diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts index 67e580fd83d87..8bd21765f551e 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/index.ts @@ -8,26 +8,18 @@ import { getOr } from 'lodash/fp'; import type { IEsSearchResponse } from '@kbn/data-plugin/common'; -import { - TimelineEventsQueries, - TimelineEventsLastEventTimeStrategyResponse, -} from '../../../../../../common/search_strategy/timeline'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; +import { TimelineEventsLastEventTimeStrategyResponse } from '../../../../../../common/search_strategy/timeline'; import { inspectStringifyObject } from '../../../../../utils/build_query'; import { TimelineFactory } from '../../types'; import { buildLastEventTimeQuery } from './query.events_last_event_time.dsl'; -import { parseOptions } from './parse_options'; export const timelineEventsLastEventTime: TimelineFactory = { - buildDsl: (maybeOptions: unknown) => { - const options = parseOptions(maybeOptions); - return buildLastEventTimeQuery(options); - }, + buildDsl: (options) => buildLastEventTimeQuery(options), parse: async ( - maybeOptions: unknown, + options, response: IEsSearchResponse ): Promise => { - const options = parseOptions(maybeOptions); - const inspect = { dsl: [inspectStringifyObject(buildLastEventTimeQuery(options))], }; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/parse_options.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/parse_options.ts deleted file mode 100644 index ed11abac7584b..0000000000000 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/parse_options.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { timelineEventsLastEventTimeRequestSchema } from '../../../../../../common/api/search_strategy/timeline/events_last_event_time'; - -export const parseOptions = (options: unknown) => - timelineEventsLastEventTimeRequestSchema.parse(options); diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.test.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.test.ts index 65646c1b585e5..0a73089aaf321 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.test.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/events/last_event_time/query.events_last_event_time.dsl.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { TimelineEventsQueries } from '../../../../../../common/search_strategy'; +import { TimelineEventsQueries } from '../../../../../../common/api/search_strategy'; import { LastEventIndexKey } from '../../../../../../common/api/search_strategy/timeline/events_last_event_time'; import { buildLastEventTimeQuery } from './query.events_last_event_time.dsl'; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts index 2ac9c343c843a..4ab3ce6e176ce 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/index.ts @@ -5,13 +5,8 @@ * 2.0. */ -import { TimelineFactoryQueryTypes } from '../../../../common/search_strategy/timeline'; -import { TimelineFactory } from './types'; import { timelineEventsFactory } from './events'; -export const timelineFactory: Record< - TimelineFactoryQueryTypes, - TimelineFactory -> = { +export const timelineFactory = { ...timelineEventsFactory, -}; +} as const; diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts index 1697b8a2862d6..31bb37e077642 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/factory/types.ts @@ -8,13 +8,14 @@ import type { IEsSearchResponse, ISearchRequestParams } from '@kbn/data-plugin/common'; import { TimelineFactoryQueryTypes, + TimelineStrategyRequestType, TimelineStrategyResponseType, } from '../../../../common/search_strategy/timeline'; export interface TimelineFactory { - buildDsl: (options: unknown) => ISearchRequestParams; + buildDsl: (options: TimelineStrategyRequestType) => ISearchRequestParams; parse: ( - options: unknown, + options: TimelineStrategyRequestType, response: IEsSearchResponse ) => Promise>; } diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts index 070a917b38cb1..2281109863976 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts @@ -17,12 +17,16 @@ import { SecurityPluginSetup } from '@kbn/security-plugin/server'; import { Logger } from '@kbn/logging'; import { z } from 'zod'; import { searchStrategyRequestSchema } from '../../../common/api/search_strategy'; -import { TimelineFactoryQueryTypes, EntityType } from '../../../common/search_strategy/timeline'; +import { + TimelineFactoryQueryTypes, + EntityType, + TimelineStrategyRequestType, +} from '../../../common/search_strategy/timeline'; import { timelineFactory } from './factory'; import { TimelineFactory } from './factory/types'; import { isAggCardinalityAggregate } from './factory/helpers/is_agg_cardinality_aggregate'; -export const timelineSearchStrategyProvider = ( +export const timelineSearchStrategyProvider = ( data: PluginStart, logger: Logger, security?: SecurityPluginSetup @@ -35,13 +39,12 @@ export const timelineSearchStrategyProvider = = - timelineFactory[searchStrategyRequest.factoryQueryType]; + const queryFactory = timelineFactory[searchStrategyRequest.factoryQueryType]; if (entityType != null && entityType === EntityType.SESSIONS) { return timelineSessionsSearchStrategy({ es, - request, + request: searchStrategyRequest, options, deps, queryFactory, @@ -73,7 +76,7 @@ const timelineSearchStrategy = ({ queryFactory, }: { es: ISearchStrategy; - request: z.infer; + request: TimelineStrategyRequestType; options: ISearchOptions; deps: SearchStrategyDependencies; queryFactory: TimelineFactory; @@ -99,7 +102,7 @@ const timelineSessionsSearchStrategy = ({ queryFactory, }: { es: ISearchStrategy; - request: z.infer; + request: TimelineStrategyRequestType; options: ISearchOptions; deps: SearchStrategyDependencies; queryFactory: TimelineFactory; @@ -110,7 +113,7 @@ const timelineSessionsSearchStrategy = ({ ...request, defaultIndex: indices, indexName: indices, - }; + } as TimelineStrategyRequestType; const collapse = { field: 'process.entry_leader.entity_id',