From d7104aafd90112b9754bcc8258fa4c722bad1237 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 20 Feb 2026 13:07:08 -0700 Subject: [PATCH] [filters] type meta.value as string or object (#253537) Fixes https://github.com/elastic/kibana/issues/253480 `storedFilterMetaSchema.value` schema is too restrictive and needs to be broadened. This PR broadens `storedFilterMetaSchema.value` to any since `storedFilterMetaSchema.value` is a subset of `FilterMetaParams` and to prevent future issues like this. PR also updates `FilterMeta.value` type to more accurately reflect usage. [mapPhrases](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/data/public/query/filter_manager/lib/mappers/map_phrases.ts#L32) sets value to `PhraseFilterValue[]` ``` export const mapPhrases = (filter: Filter) => { if (!isPhrasesFilter(filter)) { throw filter; } const { type, key, params } = filter.meta; return { type, key, value: params, params, }; }; ``` [mapRange](https://github.com/elastic/kibana/blob/main/src/platform/plugins/shared/data/public/query/filter_manager/lib/mappers/map_range.ts#L54) sets value to `RangeFilterParams` ``` function getParams(filter: RangeFilter) { const isScriptedRange = isScriptedRangeFilter(filter); const key: string = (isScriptedRange ? filter.meta.field : getFirstRangeKey(filter)) || ''; const params: any = isScriptedRange ? get(filter.query, 'script.script.params') : getRangeByKey(filter, key); return { type: FILTERS.RANGE, key, value: params, params }; } export const mapRange = (filter: Filter) => { if (!isMapRangeFilter(filter)) { throw filter; } return getParams(filter); }; ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine (cherry picked from commit 64510c0529ccf2549e36b932a561ec335a1415e7) --- .../shared/kbn-es-query-server/src/stored_filter.ts | 3 ++- .../kbn-es-query/src/filters/build_filters/types.ts | 9 +++++++-- .../public/query/filter_manager/lib/get_display_value.ts | 2 +- .../plugins/shared/data/server/query/route_types.ts | 2 +- .../rules_client/lib/add_generated_action_values.ts | 3 ++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/platform/packages/shared/kbn-es-query-server/src/stored_filter.ts b/src/platform/packages/shared/kbn-es-query-server/src/stored_filter.ts index 892bdbcdf68da..15f93ee4e8f65 100644 --- a/src/platform/packages/shared/kbn-es-query-server/src/stored_filter.ts +++ b/src/platform/packages/shared/kbn-es-query-server/src/stored_filter.ts @@ -44,7 +44,8 @@ export const storedFilterMetaSchema = schema.object( // This would require a more complex schema definition that can handle recursive types. // For now, we use `schema.any()` to allow flexibility in the params field. params: schema.maybe(schema.any()), - value: schema.maybe(schema.string()), + // Typing as any since value is undocumented subset of FilterMetaParams + value: schema.maybe(schema.any()), }, { unknowns: 'allow' } ); diff --git a/src/platform/packages/shared/kbn-es-query/src/filters/build_filters/types.ts b/src/platform/packages/shared/kbn-es-query/src/filters/build_filters/types.ts index f67a51342333e..742730a33cb69 100644 --- a/src/platform/packages/shared/kbn-es-query/src/filters/build_filters/types.ts +++ b/src/platform/packages/shared/kbn-es-query/src/filters/build_filters/types.ts @@ -10,7 +10,12 @@ import type { FilterStateStore } from '@kbn/es-query-constants'; import type { ExistsFilter } from './exists_filter'; import type { PhrasesFilter, PhrasesFilterMeta } from './phrases_filter'; -import type { PhraseFilter, PhraseFilterMeta, PhraseFilterMetaParams } from './phrase_filter'; +import type { + PhraseFilter, + PhraseFilterMeta, + PhraseFilterMetaParams, + PhraseFilterValue, +} from './phrase_filter'; import type { RangeFilter, RangeFilterMeta, RangeFilterParams } from './range_filter'; import type { MatchAllFilter, MatchAllFilterMeta } from './match_all_filter'; @@ -73,7 +78,7 @@ export type FilterMeta = { type?: string; key?: string; params?: FilterMetaParams; - value?: string; + value?: string | RangeFilterParams | PhraseFilterValue[]; }; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions diff --git a/src/platform/plugins/shared/data/public/query/filter_manager/lib/get_display_value.ts b/src/platform/plugins/shared/data/public/query/filter_manager/lib/get_display_value.ts index 90278bad5fb73..f4a1da093ef1f 100644 --- a/src/platform/plugins/shared/data/public/query/filter_manager/lib/get_display_value.ts +++ b/src/platform/plugins/shared/data/public/query/filter_manager/lib/get_display_value.ts @@ -70,5 +70,5 @@ export function getDisplayValueFromFilter(filter: Filter, indexPatterns: DataVie return getPhrasesDisplayValue(filter, valueFormatter); } else if (isRangeFilter(filter) || isScriptedRangeFilter(filter)) { return getRangeDisplayValue(filter, valueFormatter); - } else return filter.meta.value ?? ''; + } else return String(filter.meta.value ?? ''); } diff --git a/src/platform/plugins/shared/data/server/query/route_types.ts b/src/platform/plugins/shared/data/server/query/route_types.ts index 646b0ee54f305..c60e8ce8707de 100644 --- a/src/platform/plugins/shared/data/server/query/route_types.ts +++ b/src/platform/plugins/shared/data/server/query/route_types.ts @@ -89,7 +89,7 @@ type FilterMetaRestResponse = { type?: string; key?: string; params?: FilterMetaParamsRestResponse; - value?: string; + value?: string | RangeFilterParamsRestResponse | PhraseFilterValue[]; }; type FilterStateStoreRestResponse = 'appState' | 'globalState'; diff --git a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/add_generated_action_values.ts b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/add_generated_action_values.ts index 77051c7330d7a..ad99855f0f112 100644 --- a/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/add_generated_action_values.ts +++ b/x-pack/platform/plugins/shared/alerting/server/rules_client/lib/add_generated_action_values.ts @@ -17,6 +17,7 @@ import type { RulesClientContext, } from '..'; import { getEsQueryConfig } from '../../lib/get_es_query_config'; +import type { RawRuleAlertsFilter } from '../../types'; export async function addGeneratedActionValues( actions: NormalizedAlertAction[] = [], @@ -55,7 +56,7 @@ export async function addGeneratedActionValues( dsl: generateDSL(alertsFilter.query.kql, alertsFilter.query.filters) ?? '', } : undefined, - }, + } as RawRuleAlertsFilter, } : {}), };