From a2c3323162b21f0c5edc05cb2c203f69ad3a9861 Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Tue, 19 Jul 2022 13:28:21 -0700 Subject: [PATCH] [Data Views] Remove remaining "any" usage (#136343) * fix some any * remove some any * fix some any in saved_objects_client_wrapper * fix some any in common/types * remove some any from flattenHit and getFields* * fix more any * remove "any" in code comments * fix types * test commit * fix ts * fix types * remove more any * simplify / comment * more simplification * fix test * export public APIs * add fixme comment * cleanup * improve documentation and types for RollupIndexCapability * simplify shortenDottedString * fix jest test * use AggregationRestrictions * fix downstream types * simplify * add comments for public api items * add ts-expect-error in lens integration toJSON Co-authored-by: Joe Reuter --- src/plugins/data_view_editor/kibana.json | 2 +- .../preview/field_preview_context.tsx | 8 ++-- .../data_view_field_editor/public/types.ts | 14 +++---- .../data_view_field_editor/server/plugin.ts | 2 +- .../edit_index_pattern/edit_index_pattern.tsx | 4 +- .../source_filters_table.tsx | 2 +- .../field_editor/field_editor.test.tsx | 3 +- .../index_pattern_table/delete_modal_msg.tsx | 2 +- src/plugins/data_views/README.mdx | 2 +- src/plugins/data_views/common/constants.ts | 2 +- .../data_views/common/data_views/data_view.ts | 38 ++++++++++++------- .../common/data_views/data_views.ts | 19 +++++++--- .../common/data_views/flatten_hit.test.ts | 2 +- .../common/data_views/flatten_hit.ts | 33 +++++++++++----- .../data_views/common/fields/utils.test.ts | 6 +-- src/plugins/data_views/common/fields/utils.ts | 4 +- src/plugins/data_views/common/index.ts | 6 ++- src/plugins/data_views/common/types.ts | 28 +++++++------- .../data_views/data_views_api_client.ts | 12 +++--- .../data_views/public/debounce_by_key.ts | 14 +++++-- .../public/saved_objects_client_wrapper.ts | 20 ++++++---- .../data_views/public/services/has_data.ts | 2 +- .../data_views/public/ui_settings_wrapper.ts | 8 ++-- .../data_views/server/fetcher/index.ts | 5 ++- .../server/fetcher/index_patterns_fetcher.ts | 12 ++++-- .../data_views/server/fetcher/lib/errors.ts | 26 ++++++++----- .../field_capabilities/field_caps_response.ts | 2 +- .../server/fetcher/lib/jobs_compatibility.ts | 18 ++++++--- .../server/fetcher/lib/map_capabilities.ts | 20 ++++++++-- .../lib/merge_capabilities_with_fields.ts | 2 +- src/plugins/data_views/server/index.ts | 2 +- .../rest_api_routes/util/handle_errors.ts | 4 +- .../server/saved_objects/data_views.ts | 2 +- .../server/saved_objects_client_wrapper.ts | 15 ++++---- .../data_views/server/ui_settings_wrapper.ts | 6 +-- .../timeseries/common/fields_utils.ts | 3 +- .../indexpattern_datasource/field_item.tsx | 2 +- .../public/indexpattern_datasource/loader.ts | 1 + .../public/indexpattern_datasource/types.ts | 10 +---- .../es_search_source/es_search_source.tsx | 2 +- 40 files changed, 223 insertions(+), 142 deletions(-) diff --git a/src/plugins/data_view_editor/kibana.json b/src/plugins/data_view_editor/kibana.json index 8e83cb1be046b..26bff485037e2 100644 --- a/src/plugins/data_view_editor/kibana.json +++ b/src/plugins/data_view_editor/kibana.json @@ -9,5 +9,5 @@ "name": "App Services", "githubTeam": "kibana-app-services" }, - "description": "This plugin provides the ability to create data views via a modal flyout from any kibana app" + "description": "This plugin provides the ability to create data views via a modal flyout inside Kibana apps" } diff --git a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx index 6e21cc00e5dd5..127badffc826d 100644 --- a/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx +++ b/src/plugins/data_view_field_editor/public/components/preview/field_preview_context.tsx @@ -121,7 +121,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { // If no documents could be fetched from the cluster (and we are not trying to load // a custom doc ID) then we disable preview as the script field validation expect the result // of the preview to before resolving. If there are no documents we can't have a preview - // (the _execute API expects one) and thus the validation should not expect any value. + // (the _execute API expects one) and thus the validation should not expect a value. if (!isFetchingDocument && !isCustomDocId && documents.length === 0) { isPreviewAvailable = false; } @@ -341,7 +341,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { if (currentApiCall !== previewCount.current) { // Discard this response as there is another one inflight - // or we have called reset() and don't need the response anymore. + // or we have called reset() and no longer need the response. return; } @@ -410,7 +410,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { }, [currentIdx, totalDocs]); const reset = useCallback(() => { - // By resetting the previewCount we will discard any inflight + // By resetting the previewCount we will discard previous inflight // API call response coming in after calling reset() was called previewCount.current = 0; @@ -603,7 +603,7 @@ export const FieldPreviewProvider: FunctionComponent = ({ children }) => { }, [scriptEditorValidation, script?.source, setPreviewError, clearPreviewError]); /** - * Whenever updatePreview() changes (meaning whenever any of the params changes) + * Whenever updatePreview() changes (meaning whenever a param changes) * we call it to update the preview response with the field(s) value or possible error. */ useDebounce(updatePreview, 500, [updatePreview]); diff --git a/src/plugins/data_view_field_editor/public/types.ts b/src/plugins/data_view_field_editor/public/types.ts index 25f97e6737bf2..504a97eb7f329 100644 --- a/src/plugins/data_view_field_editor/public/types.ts +++ b/src/plugins/data_view_field_editor/public/types.ts @@ -6,20 +6,20 @@ * Side Public License, v 1. */ +import { SerializableRecord } from '@kbn/utility-types'; import { FunctionComponent } from 'react'; - +import { DeleteFieldProviderProps } from './components'; +import { OpenFieldDeleteModalOptions } from './open_delete_modal'; +import { OpenFieldEditorOptions } from './open_editor'; +import { FormatEditorServiceSetup, FormatEditorServiceStart } from './service'; import { DataPublicPluginStart, DataViewsPublicPluginStart, + FieldFormatsStart, RuntimeField, RuntimeType, UsageCollectionStart, - FieldFormatsStart, } from './shared_imports'; -import { OpenFieldEditorOptions } from './open_editor'; -import { OpenFieldDeleteModalOptions } from './open_delete_modal'; -import { FormatEditorServiceSetup, FormatEditorServiceStart } from './service'; -import { DeleteFieldProviderProps } from './components'; export interface PluginSetup { fieldFormatEditors: FormatEditorServiceSetup['fieldFormatEditors']; @@ -58,7 +58,7 @@ export interface Field { export interface FieldFormatConfig { id: string; - params?: { [key: string]: any }; + params?: SerializableRecord; } export interface EsRuntimeField { diff --git a/src/plugins/data_view_field_editor/server/plugin.ts b/src/plugins/data_view_field_editor/server/plugin.ts index c5bbe9bab7572..deb516ab25012 100644 --- a/src/plugins/data_view_field_editor/server/plugin.ts +++ b/src/plugins/data_view_field_editor/server/plugin.ts @@ -9,7 +9,7 @@ import { PluginInitializerContext, CoreSetup, Plugin, Logger } from '@kbn/core/s import { ApiRoutes } from './routes'; -export class IndexPatternPlugin implements Plugin { +export class IndexPatternPlugin implements Plugin { private readonly logger: Logger; private readonly apiRoutes: ApiRoutes; diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx index d502038a1018d..74e1eb77cf503 100644 --- a/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx +++ b/src/plugins/data_view_management/public/components/edit_index_pattern/edit_index_pattern.tsx @@ -70,7 +70,7 @@ export const EditIndexPattern = withRouter( indexPattern.fields.getAll().filter((field) => field.type === 'conflict') ); const [defaultIndex, setDefaultIndex] = useState(uiSettings.get('defaultIndex')); - const [tags, setTags] = useState([]); + const [tags, setTags] = useState>([]); const [showEditDialog, setShowEditDialog] = useState(false); const [relationships, setRelationships] = useState([]); const [allowedTypes, setAllowedTypes] = useState([]); @@ -220,7 +220,7 @@ export const EditIndexPattern = withRouter( {securityDataView} )} - {tags.map((tag: any) => ( + {tags.map((tag) => ( {tag.key === 'default' ? ( diff --git a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx index 455371d6c5e2b..f2fd9ce2d2140 100644 --- a/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx +++ b/src/plugins/data_view_management/public/components/edit_index_pattern/source_filters_table/source_filters_table.tsx @@ -33,7 +33,7 @@ export class SourceFiltersTable extends Component< SourceFiltersTableProps, SourceFiltersTableState > { - // Source filters do not have any unique ids, only the value is stored. + // Source filters do not have unique ids, only the value is stored. // To ensure we can create a consistent and expected UX when managing // source filters, we are assigning a unique id to each filter on the // client side only diff --git a/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx b/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx index 89f41e8b269ad..f3b533b7d8290 100644 --- a/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx +++ b/src/plugins/data_view_management/public/components/field_editor/field_editor.test.tsx @@ -85,6 +85,7 @@ class Format { params() {} } +// FIXME: which interface is this? const field = { scripted: true, type: 'number', @@ -190,7 +191,7 @@ describe('FieldEditor', () => { add: jest.fn(), }, }; - indexPattern.fieldFormatMap = { test: field }; + indexPattern.fieldFormatMap = { test: field } as {}; (indexPattern.deleteFieldFormat as any) = jest.fn(); const component = createComponentWithContext( diff --git a/src/plugins/data_view_management/public/components/index_pattern_table/delete_modal_msg.tsx b/src/plugins/data_view_management/public/components/index_pattern_table/delete_modal_msg.tsx index e675f4be59b45..080b3b8bd8ea0 100644 --- a/src/plugins/data_view_management/public/components/index_pattern_table/delete_modal_msg.tsx +++ b/src/plugins/data_view_management/public/components/index_pattern_table/delete_modal_msg.tsx @@ -32,7 +32,7 @@ const tableTitle = i18n.translate('indexPatternManagement.dataViewTable.tableTit }); export const deleteModalMsg = (views: RemoveDataViewProps[], hasSpaces: boolean) => { - const columns: Array> = [ + const columns: Array> = [ { field: 'name', name: dataViewColumnName, diff --git a/src/plugins/data_views/README.mdx b/src/plugins/data_views/README.mdx index 2d7bf08d78586..7fdd435db746e 100644 --- a/src/plugins/data_views/README.mdx +++ b/src/plugins/data_views/README.mdx @@ -20,5 +20,5 @@ and field lists across the various Kibana apps. Its typically used in conjunctio **hasData:** A standardized way to check the empty state for indices and data views. - `hasESData: () => Promise; // Check to see if ES data exists` -- `hasDataView: () => Promise; // Check to see if any data view exists (managed or user created)` +- `hasDataView: () => Promise; // Check to see if data view exists (managed or user created)` - `hasUserDataView: () => Promise; // Check to see if user created data views exists` diff --git a/src/plugins/data_views/common/constants.ts b/src/plugins/data_views/common/constants.ts index 81a424d291bec..b79eef45e7fc8 100644 --- a/src/plugins/data_views/common/constants.ts +++ b/src/plugins/data_views/common/constants.ts @@ -22,7 +22,7 @@ export const RUNTIME_FIELD_TYPES = [ ] as const; /** - * Used to determine if the instance has any user created index patterns by filtering index patterns + * Used to determine if the instance has some user created index patterns by filtering index patterns * that are created and backed only by Fleet server data * Should be revised after https://github.com/elastic/kibana/issues/82851 is fixed * For more background see: https://github.com/elastic/kibana/issues/107020 diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts index 6f01f61c98fe8..c8cafd36fb742 100644 --- a/src/plugins/data_views/common/data_views/data_view.ts +++ b/src/plugins/data_views/common/data_views/data_view.ts @@ -6,21 +6,31 @@ * Side Public License, v 1. */ -import _, { cloneDeep, each, reject } from 'lodash'; -import { castEsToKbnFieldTypeName, ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { CharacterNotAllowedInField } from '@kbn/kibana-utils-plugin/common'; -import { - FieldFormatsStartCommon, +import type { DataViewBase } from '@kbn/es-query'; +import type { FieldFormat, + FieldFormatsStartCommon, SerializedFieldFormat, } from '@kbn/field-formats-plugin/common'; -import type { DataViewBase } from '@kbn/es-query'; -import { FieldAttrs, FieldAttrSet, DataViewAttributes } from '..'; -import type { RuntimeField, RuntimeFieldSpec, RuntimeType, FieldConfiguration } from '../types'; -import { DataViewField, IIndexPatternFieldList, fieldList } from '../fields'; +import { castEsToKbnFieldTypeName, ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types'; +import { CharacterNotAllowedInField } from '@kbn/kibana-utils-plugin/common'; +import _, { cloneDeep, each, reject } from 'lodash'; +import type { DataViewAttributes, FieldAttrs, FieldAttrSet } from '..'; +import type { DataViewField, IIndexPatternFieldList } from '../fields'; +import { fieldList } from '../fields'; +import type { + DataViewFieldMap, + DataViewSpec, + FieldConfiguration, + FieldFormatMap, + RuntimeField, + RuntimeFieldSpec, + RuntimeType, + SourceFilter, + TypeMeta, +} from '../types'; import { flattenHitWrapper } from './flatten_hit'; -import { DataViewSpec, TypeMeta, SourceFilter, DataViewFieldMap } from '../types'; import { removeFieldAttrs } from './utils'; interface DataViewDeps { @@ -70,7 +80,7 @@ export class DataView implements DataViewBase { /** * Map of field formats by field name */ - public fieldFormatMap: Record; + public fieldFormatMap: FieldFormatMap; /** * Only used by rollup indices, used by rollup specific endpoint to load field list. */ @@ -90,7 +100,7 @@ export class DataView implements DataViewBase { /** * @deprecated Use `flattenHit` utility method exported from data plugin instead. */ - public flattenHit: (hit: Record, deep?: boolean) => Record; + public flattenHit: (hit: Record, deep?: boolean) => Record; /** * List of meta fields by name */ @@ -233,7 +243,7 @@ export class DataView implements DataViewBase { }; } - // Date value returned in "_source" could be in any number of formats + // Date value returned in "_source" could be in a number of formats // Use a docvalue for each date field to ensure standardized formats when working with date fields // dataView.flattenHit will override "_source" values when the same field is also defined in "fields" const docvalueFields = reject(this.fields.getByType('date'), 'scripted').map((dateField) => { @@ -296,7 +306,7 @@ export class DataView implements DataViewBase { name: this.name, }; - // Filter any undefined values from the spec + // Filter undefined values from the spec return Object.fromEntries(Object.entries(spec).filter(([, v]) => typeof v !== 'undefined')); } diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 85de6f2d5667e..8c98f7f18f0de 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -38,6 +38,10 @@ import { DuplicateDataViewError, DataViewInsufficientAccessError } from '../erro const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3; +/* + * Attributes of the data view saved object + * @public + */ export type DataViewSavedObjectAttrs = Pick< DataViewAttributes, 'title' | 'type' | 'typeMeta' | 'name' @@ -445,7 +449,7 @@ export class DataViewsService { * Get default index pattern id */ getDefaultId = async (): Promise => { - const defaultIndexPatternId = await this.config.get('defaultIndex'); + const defaultIndexPatternId = await this.config.get('defaultIndex'); return defaultIndexPatternId ?? null; }; @@ -473,7 +477,7 @@ export class DataViewsService { * @returns FieldSpec[] */ getFieldsForWildcard = async (options: GetFieldsOptions): Promise => { - const metaFields = await this.config.get(META_FIELDS); + const metaFields = await this.config.get(META_FIELDS); return this.apiClient.getFieldsForWildcard({ pattern: options.pattern, metaFields, @@ -786,8 +790,8 @@ export class DataViewsService { { id, name, title, ...restOfSpec }: DataViewSpec, skipFetchFields = false ): Promise { - const shortDotsEnable = await this.config.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); - const metaFields = await this.config.get(META_FIELDS); + const shortDotsEnable = await this.config.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); + const metaFields = await this.config.get(META_FIELDS); const spec = { id: id ?? uuid.v4(), @@ -886,7 +890,8 @@ export class DataViewsService { // get changed keys const originalChangedKeys: string[] = []; Object.entries(body).forEach(([key, value]) => { - if (value !== (originalBody as any)[key]) { + const realKey = key as keyof typeof originalBody; + if (value !== originalBody[realKey]) { originalChangedKeys.push(key); } }); @@ -913,7 +918,8 @@ export class DataViewsService { const serverChangedKeys: string[] = []; Object.entries(updatedBody).forEach(([key, value]) => { - if (value !== (body as any)[key] && value !== (originalBody as any)[key]) { + const realKey = key as keyof typeof originalBody; + if (value !== body[realKey] && value !== originalBody[realKey]) { serverChangedKeys.push(key); } }); @@ -946,6 +952,7 @@ export class DataViewsService { // Set the updated response on this object serverChangedKeys.forEach((key) => { + // FIXME: this overwrites read-only properties (indexPattern as any)[key] = (samePattern as any)[key]; }); indexPattern.version = samePattern.version; diff --git a/src/plugins/data_views/common/data_views/flatten_hit.test.ts b/src/plugins/data_views/common/data_views/flatten_hit.test.ts index 24d5ee12885d2..ab7e7d14df4ec 100644 --- a/src/plugins/data_views/common/data_views/flatten_hit.test.ts +++ b/src/plugins/data_views/common/data_views/flatten_hit.test.ts @@ -59,7 +59,7 @@ describe('flattenHit', () => { zzz: ['z'], _abc: ['a'], }, - }); + } as {}); const expectedOrder = ['_abc', 'date', 'name', 'zzz', '_id', '_routing', '_score', '_type']; expect(Object.keys(response)).toEqual(expectedOrder); expect(Object.entries(response).map(([key]) => key)).toEqual(expectedOrder); diff --git a/src/plugins/data_views/common/data_views/flatten_hit.ts b/src/plugins/data_views/common/data_views/flatten_hit.ts index 0a6388f0914b1..b9932c0de950d 100644 --- a/src/plugins/data_views/common/data_views/flatten_hit.ts +++ b/src/plugins/data_views/common/data_views/flatten_hit.ts @@ -14,11 +14,21 @@ import _ from 'lodash'; import { DataView } from './data_view'; -// Takes a hit, merges it with any stored/scripted fields, and with the metaFields -// returns a flattened version - -function flattenHit(indexPattern: DataView, hit: Record, deep: boolean) { - const flat = {} as Record; +/** + * Takes a hit, merges it with whatever stored/scripted fields, and with the metaFields + * returns a flattened version + * + * @param {DataView} indexPattern + * @param {Record} hit - userland data + * @param {boolean} deep - whether to look into objects within arrays + * @returns {Record} + */ +function flattenHit( + indexPattern: DataView, + hit: Record, + deep: boolean +): Record { + const flat = {} as Record; // recursively merge _source const fields = indexPattern.fields.getByName; @@ -61,8 +71,11 @@ function flattenHit(indexPattern: DataView, hit: Record, deep: bool return flat; } -function decorateFlattenedWrapper(hit: Record, metaFields: Record) { - return function (flattened: Record) { +function decorateFlattenedWrapper( + hit: Record, + metaFields: Record +) { + return function (flattened: Record) { // assign the meta fields _.each(metaFields, function (meta) { if (meta === '_source') return; @@ -70,7 +83,7 @@ function decorateFlattenedWrapper(hit: Record, metaFields: Record, metaFields: Record, deep = false) { +export function flattenHitWrapper(dataView: DataView, metaFields = {}, cache = new WeakMap()) { + return function cachedFlatten(hit: Record, deep = false) { const decorateFlattened = decorateFlattenedWrapper(hit, metaFields); const cached = cache.get(hit); const flattened = cached || flattenHit(dataView, hit, deep); diff --git a/src/plugins/data_views/common/fields/utils.test.ts b/src/plugins/data_views/common/fields/utils.test.ts index 0f2ff280eb61b..e7d84f4dc6f0a 100644 --- a/src/plugins/data_views/common/fields/utils.test.ts +++ b/src/plugins/data_views/common/fields/utils.test.ts @@ -16,8 +16,8 @@ describe('shortenDottedString', () => { test('should ignore non-string values', () => { const obj = { key: 'val' }; - expect(shortenDottedString(true)).toBe(true); - expect(shortenDottedString(123)).toBe(123); - expect(shortenDottedString(obj)).toBe(obj); + expect(shortenDottedString(true as unknown as string)).toBe(true); + expect(shortenDottedString(123 as unknown as string)).toBe(123); + expect(shortenDottedString(obj as unknown as string)).toBe(obj); }); }); diff --git a/src/plugins/data_views/common/fields/utils.ts b/src/plugins/data_views/common/fields/utils.ts index 1dc7e7f698995..a6418bec744f0 100644 --- a/src/plugins/data_views/common/fields/utils.ts +++ b/src/plugins/data_views/common/fields/utils.ts @@ -30,10 +30,8 @@ const DOT_PREFIX_RE = /(.).+?\./g; /** * Convert a dot.notated.string into a short * version (d.n.string) - * - * @return {any} */ -export function shortenDottedString(input: any) { +export function shortenDottedString(input: string): string { return typeof input !== 'string' ? input : input.replace(DOT_PREFIX_RE, '$1.'); } diff --git a/src/plugins/data_views/common/index.ts b/src/plugins/data_views/common/index.ts index aeaca476a8abd..ffeeb069d1912 100644 --- a/src/plugins/data_views/common/index.ts +++ b/src/plugins/data_views/common/index.ts @@ -55,7 +55,11 @@ export type { } from './types'; export { DataViewType } from './types'; -export type { DataViewsContract, DataViewsServiceDeps } from './data_views'; +export type { + DataViewsContract, + DataViewsServiceDeps, + DataViewSavedObjectAttrs, +} from './data_views'; export { DataViewsService, DataViewPersistableStateService } from './data_views'; export type { DataViewListItem, diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index 5319ee8b0301f..40a70e3c1f547 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -6,15 +6,19 @@ * Side Public License, v 1. */ +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { + SavedObject, + SavedObjectsCreateOptions, + SavedObjectsUpdateOptions, +} from '@kbn/core/public'; +import type { ErrorToastOptions, ToastInputFields } from '@kbn/core/public/notifications'; import type { DataViewFieldBase } from '@kbn/es-query'; -import { ToastInputFields, ErrorToastOptions } from '@kbn/core/public/notifications'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths,@kbn/imports/uniform_imports -import type { SavedObject } from 'src/core/server'; -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SerializedFieldFormat } from '@kbn/field-formats-plugin/common'; import { RUNTIME_FIELD_TYPES } from './constants'; export type { QueryDslQueryContainer }; +export type { SavedObject }; export type FieldFormatMap = Record; @@ -210,7 +214,7 @@ export interface UiSettingsCommon { * Get a setting value * @param key name of value */ - get: (key: string) => Promise; + get: (key: string) => Promise; /** * Get all settings values */ @@ -220,7 +224,7 @@ export interface UiSettingsCommon { * @param key name of value * @param value value to set */ - set: (key: string, value: T) => Promise; + set: (key: string, value: T) => Promise; /** * Remove a setting value * @param key name of value @@ -281,8 +285,8 @@ export interface SavedObjectsClientCommon { update: ( type: string, id: string, - attributes: Record, - options: Record + attributes: DataViewAttributes, + options: SavedObjectsUpdateOptions ) => Promise; /** * Create a saved object @@ -292,8 +296,8 @@ export interface SavedObjectsClientCommon { */ create: ( type: string, - attributes: Record, - options: Record + attributes: DataViewAttributes, + options: SavedObjectsCreateOptions ) => Promise; /** * Delete a saved object by id @@ -314,12 +318,10 @@ export interface GetFieldsOptions { } export interface IDataViewsApiClient { - getFieldsForWildcard: (options: GetFieldsOptions) => Promise; + getFieldsForWildcard: (options: GetFieldsOptions) => Promise; hasUserIndexPattern: () => Promise; } -export type { SavedObject }; - export type AggregationRestrictions = Record< string, { diff --git a/src/plugins/data_views/public/data_views/data_views_api_client.ts b/src/plugins/data_views/public/data_views/data_views_api_client.ts index e1b7ee1590acf..b02894d1afb63 100644 --- a/src/plugins/data_views/public/data_views/data_views_api_client.ts +++ b/src/plugins/data_views/public/data_views/data_views_api_client.ts @@ -8,7 +8,7 @@ import { HttpSetup } from '@kbn/core/public'; import { DataViewMissingIndices } from '../../common/lib'; -import { GetFieldsOptions, IDataViewsApiClient } from '../../common'; +import { FieldSpec, GetFieldsOptions, IDataViewsApiClient } from '../../common'; const API_BASE_URL: string = `/api/index_patterns/`; @@ -26,12 +26,12 @@ export class DataViewsApiClient implements IDataViewsApiClient { this.http = http; } - private _request(url: string, query?: any) { + private _request(url: string, query?: {}): Promise { return this.http .fetch(url, { query, }) - .catch((resp: any) => { + .catch((resp) => { if (resp.body.statusCode === 404 && resp.body.attributes?.code === 'no_matching_indices') { throw new DataViewMissingIndices(resp.body.message); } @@ -50,14 +50,14 @@ export class DataViewsApiClient implements IDataViewsApiClient { */ getFieldsForWildcard(options: GetFieldsOptions) { const { pattern, metaFields, type, rollupIndex, allowNoIndex, filter } = options; - return this._request(this._getUrl(['_fields_for_wildcard']), { + return this._request<{ fields: FieldSpec[] }>(this._getUrl(['_fields_for_wildcard']), { pattern, meta_fields: metaFields, type, rollup_index: rollupIndex, allow_no_index: allowNoIndex, filter, - }).then((resp: any) => resp.fields || []); + }).then((resp) => resp?.fields || []); } /** @@ -67,6 +67,6 @@ export class DataViewsApiClient implements IDataViewsApiClient { const response = await this._request<{ result: boolean }>( this._getUrl(['has_user_index_pattern']) ); - return response.result; + return response?.result ?? false; } } diff --git a/src/plugins/data_views/public/debounce_by_key.ts b/src/plugins/data_views/public/debounce_by_key.ts index c8ae7094a6437..402fd5baf9fc7 100644 --- a/src/plugins/data_views/public/debounce_by_key.ts +++ b/src/plugins/data_views/public/debounce_by_key.ts @@ -8,11 +8,19 @@ import { debounce } from 'lodash'; -export const debounceByKey = any>( +/** + * Uses a debouncer collector behind a debouncing factory to work on a set of functions + * + * @template F - function type + * @param {F} fn - function to debounce + * @param {number} waitInMs + * @returns {(key: string) => Function} + */ +export const debounceByKey = unknown>( fn: F, waitInMs: number -): ((key: string) => F) => { - const debouncerCollector: Record = {}; +): ((key: string) => Function) => { + const debouncerCollector: Record = {}; return (key: string) => { if (!debouncerCollector[key]) { debouncerCollector[key] = debounce(fn, waitInMs, { diff --git a/src/plugins/data_views/public/saved_objects_client_wrapper.ts b/src/plugins/data_views/public/saved_objects_client_wrapper.ts index 9dab5ec46f548..e8d008e130323 100644 --- a/src/plugins/data_views/public/saved_objects_client_wrapper.ts +++ b/src/plugins/data_views/public/saved_objects_client_wrapper.ts @@ -6,14 +6,20 @@ * Side Public License, v 1. */ +import { + SavedObjectsClientContract, + SavedObjectsCreateOptions, + SavedObjectsUpdateOptions, + SimpleSavedObject, +} from '@kbn/core/public'; import { omit } from 'lodash'; -import { SavedObjectsClientContract, SimpleSavedObject } from '@kbn/core/public'; +import { DataViewSavedObjectConflictError } from '../common/errors'; import { + DataViewAttributes, + SavedObject, SavedObjectsClientCommon, SavedObjectsClientCommonFindArgs, - SavedObject, } from '../common/types'; -import { DataViewSavedObjectConflictError } from '../common/errors'; type SOClient = Pick< SavedObjectsClientContract, @@ -24,7 +30,7 @@ const simpleSavedObjectToSavedObject = (simpleSavedObject: SimpleSavedObject) ({ version: simpleSavedObject._version, ...omit(simpleSavedObject, '_version'), - } as any); + } as SavedObject); export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommon { private savedObjectClient: SOClient; @@ -49,14 +55,14 @@ export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommo async update( type: string, id: string, - attributes: Record, - options: Record + attributes: DataViewAttributes, + options: SavedObjectsUpdateOptions ) { const response = await this.savedObjectClient.update(type, id, attributes, options); return simpleSavedObjectToSavedObject(response); } - async create(type: string, attributes: Record, options: Record) { + async create(type: string, attributes: DataViewAttributes, options?: SavedObjectsCreateOptions) { const response = await this.savedObjectClient.create(type, attributes, options); return simpleSavedObjectToSavedObject(response); } diff --git a/src/plugins/data_views/public/services/has_data.ts b/src/plugins/data_views/public/services/has_data.ts index 4c641e0e17f13..45f44e04e23a8 100644 --- a/src/plugins/data_views/public/services/has_data.ts +++ b/src/plugins/data_views/public/services/has_data.ts @@ -41,7 +41,7 @@ export class HasData { return hasLocalESData; }, /** - * Check to see if any data view exists + * Check to see if a data view exists */ hasDataView: async (): Promise => { const dataViewsCheck = await this.findDataViews(http); diff --git a/src/plugins/data_views/public/ui_settings_wrapper.ts b/src/plugins/data_views/public/ui_settings_wrapper.ts index 3474451ad720f..ad160ee39373e 100644 --- a/src/plugins/data_views/public/ui_settings_wrapper.ts +++ b/src/plugins/data_views/public/ui_settings_wrapper.ts @@ -14,15 +14,17 @@ export class UiSettingsPublicToCommon implements UiSettingsCommon { constructor(uiSettings: IUiSettingsClient) { this.uiSettings = uiSettings; } - get(key: string): Promise { + get(key: string): Promise { return Promise.resolve(this.uiSettings.get(key)); } - getAll(): Promise>> { + getAll(): Promise< + Record) | undefined> + > { return Promise.resolve(this.uiSettings.getAll()); } - set(key: string, value: any) { + set(key: string, value: unknown) { this.uiSettings.set(key, value); return Promise.resolve(); } diff --git a/src/plugins/data_views/server/fetcher/index.ts b/src/plugins/data_views/server/fetcher/index.ts index 8161f187a5e6a..2fbb7c8f3f3cb 100644 --- a/src/plugins/data_views/server/fetcher/index.ts +++ b/src/plugins/data_views/server/fetcher/index.ts @@ -8,7 +8,8 @@ export * from './index_patterns_fetcher'; export { - shouldReadFieldFromDocValues, - mergeCapabilitiesWithFields, getCapabilitiesForRollupIndices, + mergeCapabilitiesWithFields, + shouldReadFieldFromDocValues, } from './lib'; +export type { RollupIndexCapability } from './lib'; diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts index 9d3b8a180d91e..dd02c9b7f9a12 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts @@ -79,11 +79,17 @@ export class IndexPatternsFetcher { }); if (type === 'rollup' && rollupIndex) { const rollupFields: FieldDescriptor[] = []; - const rollupIndexCapabilities = getCapabilitiesForRollupIndices( + const capabilityCheck = getCapabilitiesForRollupIndices( await this.elasticsearchClient.rollup.getRollupIndexCaps({ index: rollupIndex, }) - )[rollupIndex].aggs; + )[rollupIndex]; + + if (capabilityCheck.error) { + throw new Error(capabilityCheck.error); + } + + const rollupIndexCapabilities = capabilityCheck.aggs; const fieldCapsResponseObj = keyBy(fieldCapsResponse, 'name'); // Keep meta fields metaFields!.forEach( @@ -91,7 +97,7 @@ export class IndexPatternsFetcher { fieldCapsResponseObj[field] && rollupFields.push(fieldCapsResponseObj[field]) ); return mergeCapabilitiesWithFields( - rollupIndexCapabilities, + rollupIndexCapabilities!, fieldCapsResponseObj, rollupFields ); diff --git a/src/plugins/data_views/server/fetcher/lib/errors.ts b/src/plugins/data_views/server/fetcher/lib/errors.ts index c69e177535b76..eb510798c759f 100644 --- a/src/plugins/data_views/server/fetcher/lib/errors.ts +++ b/src/plugins/data_views/server/fetcher/lib/errors.ts @@ -7,6 +7,7 @@ */ import Boom from '@hapi/boom'; +import { CustomHttpResponseOptions } from '@kbn/core/server'; import { get } from 'lodash'; const ERR_ES_INDEX_NOT_FOUND = 'index_not_found_exception'; @@ -15,10 +16,10 @@ const ERR_NO_MATCHING_INDICES = 'no_matching_indices'; /** * Determines if an error is an elasticsearch error that's * describing a failure caused by missing index/indices - * @param {Any} err + * @param err * @return {Boolean} */ -export function isEsIndexNotFoundError(err: any) { +export function isEsIndexNotFoundError(err: unknown) { return get(err, ['body', 'error', 'type']) === ERR_ES_INDEX_NOT_FOUND; } @@ -30,17 +31,17 @@ export function isEsIndexNotFoundError(err: any) { */ export function createNoMatchingIndicesError(pattern: string[] | string) { const err = Boom.notFound(`No indices match "${pattern}"`); - (err.output.payload as any).code = ERR_NO_MATCHING_INDICES; + (err as Boom.Boom).output.payload.code = ERR_NO_MATCHING_INDICES; return err; } /** * Determines if an error is produced by `createNoMatchingIndicesError()` * - * @param {Any} err + * @param err * @return {Boolean} */ -export function isNoMatchingIndicesError(err: any) { +export function isNoMatchingIndicesError(err: unknown) { return get(err, ['output', 'payload', 'code']) === ERR_NO_MATCHING_INDICES; } @@ -48,18 +49,23 @@ export function isNoMatchingIndicesError(err: any) { * Wrap "index_not_found_exception" errors in custom Boom errors * automatically * @param {Array|String} indices + * @param {Boom.Boom|CustomHttpResponseOptions} error * @return {Boom} */ -export function convertEsError(indices: string[] | string, error: any) { +export function convertEsError(indices: string[] | string, error: unknown) { if (isEsIndexNotFoundError(error)) { return createNoMatchingIndicesError(indices); } - if (error.isBoom) { + if ((error as Boom.Boom).isBoom) { return error; } - const statusCode = error.statusCode; - const message = error.body ? error.body.error : undefined; - return Boom.boomify(error, { statusCode, message }); + const custom = error as CustomHttpResponseOptions<{ error: string; message: string }>; + const options = { + statusCode: custom.statusCode, + message: custom.body?.error ?? undefined, + }; + + return Boom.boomify(error as Error, options); } diff --git a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts index 2581b2b78f5d8..c1bfc4c6c7e18 100644 --- a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts +++ b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts @@ -171,7 +171,7 @@ export function readFieldCapsResponse( subType = { ...subType, multi: { parent: firstParent.name } }; } - // We need to know if any parent field is nested + // We need to know if some parent field is nested const nestedParentCaps = parentFieldCapsAscending.find( (parentCaps) => parentCaps && parentCaps.type === 'nested' ); diff --git a/src/plugins/data_views/server/fetcher/lib/jobs_compatibility.ts b/src/plugins/data_views/server/fetcher/lib/jobs_compatibility.ts index adc60774fae37..2c104b03cf5c1 100644 --- a/src/plugins/data_views/server/fetcher/lib/jobs_compatibility.ts +++ b/src/plugins/data_views/server/fetcher/lib/jobs_compatibility.ts @@ -6,7 +6,10 @@ * Side Public License, v 1. */ +import { RollupGetRollupIndexCapsRollupJobSummary as RollupJobSummary } from '@elastic/elasticsearch/lib/api/types'; import { isEqual } from 'lodash'; +import { AggregationRestrictions } from '../../../common'; +import { RollupIndexCapability } from './map_capabilities'; /** * Checks if given job configs are compatible by attempting to merge them @@ -32,17 +35,19 @@ export function areJobsCompatible(jobs = []) { * by aggregation, then by field * * @param jobs - * @returns {{}} + * @returns {{ aggs: Dictionary }} */ -export function mergeJobConfigurations(jobs = []) { +export function mergeJobConfigurations( + jobs: RollupJobSummary[] = [] +): RollupIndexCapability[string] { if (!jobs || !Array.isArray(jobs) || !jobs.length) { throw new Error('No capabilities available'); } - const allAggs: { [key: string]: any } = {}; + const allAggs: RollupIndexCapability[string]['aggs'] = {}; // For each job, look through all of its fields - jobs.forEach((job: { fields: { [key: string]: any } }) => { + jobs.forEach((job) => { const fields = job.fields; const fieldNames = Object.keys(fields); @@ -51,7 +56,7 @@ export function mergeJobConfigurations(jobs = []) { const fieldAggs = fields[fieldName]; // Look through each field's capabilities (aggregations) - fieldAggs.forEach((agg: { agg: string; interval: string }) => { + fieldAggs.forEach((agg) => { const aggName = agg.agg; const aggDoesntExist = !allAggs[aggName]; const fieldDoesntExist = allAggs[aggName] && !allAggs[aggName][fieldName]; @@ -62,7 +67,7 @@ export function mergeJobConfigurations(jobs = []) { // date histogram field. if (aggDoesntExist || (fieldDoesntExist && !isDateHistogramAgg)) { allAggs[aggName] = allAggs[aggName] || {}; - allAggs[aggName][fieldName] = { ...agg }; + allAggs[aggName][fieldName] = { ...agg } as AggregationRestrictions[string]; } // If aggregation already exists, attempt to merge it else { @@ -73,6 +78,7 @@ export function mergeJobConfigurations(jobs = []) { // new interval and existing interval case 'histogram': // TODO: Fix this with LCD algorithm + // @ts-expect-error - Property 'interval' does not exist on type 'RollupGetRollupIndexCapsRollupJobSummaryField' const intervals = [fieldAgg.interval, agg.interval].sort((a, b) => a - b); const isMultiple = intervals[1] % intervals[0] === 0; fieldAgg.interval = isMultiple ? intervals[1] : intervals[0] * intervals[1]; diff --git a/src/plugins/data_views/server/fetcher/lib/map_capabilities.ts b/src/plugins/data_views/server/fetcher/lib/map_capabilities.ts index e2076a373d489..a5fdf98bd03e9 100644 --- a/src/plugins/data_views/server/fetcher/lib/map_capabilities.ts +++ b/src/plugins/data_views/server/fetcher/lib/map_capabilities.ts @@ -6,17 +6,31 @@ * Side Public License, v 1. */ +import { RollupGetRollupIndexCapsResponse } from '@elastic/elasticsearch/lib/api/types'; +import { Dictionary } from 'lodash'; +import { AggregationRestrictions } from '../../../common'; import { mergeJobConfigurations } from './jobs_compatibility'; +/** + * A record of capabilities (aggregations) for index rollup jobs + */ +export interface RollupIndexCapability { + /** + * A record of capabilities (aggregations) for an index rollup job + */ + [index: string]: { aggs?: Dictionary; error?: string }; +} + /** * Get rollup job capabilities * @public * @param indices rollup job index capabilites */ - -export function getCapabilitiesForRollupIndices(indices: Record) { +export function getCapabilitiesForRollupIndices( + indices: RollupGetRollupIndexCapsResponse +): RollupIndexCapability { const indexNames = Object.keys(indices); - const capabilities = {} as { [key: string]: any }; + const capabilities: RollupIndexCapability = {}; indexNames.forEach((index) => { try { diff --git a/src/plugins/data_views/server/fetcher/lib/merge_capabilities_with_fields.ts b/src/plugins/data_views/server/fetcher/lib/merge_capabilities_with_fields.ts index f80ae108fb681..922fde5347cfb 100644 --- a/src/plugins/data_views/server/fetcher/lib/merge_capabilities_with_fields.ts +++ b/src/plugins/data_views/server/fetcher/lib/merge_capabilities_with_fields.ts @@ -11,7 +11,7 @@ import { FieldDescriptor } from '../index_patterns_fetcher'; export const mergeCapabilitiesWithFields = ( - rollupIndexCapabilities: { [key: string]: any }, + rollupIndexCapabilities: Record, fieldsFromFieldCapsApi: Record, previousFields: FieldDescriptor[] = [] ) => { diff --git a/src/plugins/data_views/server/index.ts b/src/plugins/data_views/server/index.ts index e9eb7f0b50a3f..d7860e0bed473 100644 --- a/src/plugins/data_views/server/index.ts +++ b/src/plugins/data_views/server/index.ts @@ -7,7 +7,7 @@ */ export { getFieldByName, findIndexPatternById } from './utils'; -export type { FieldDescriptor } from './fetcher'; +export type { FieldDescriptor, RollupIndexCapability } from './fetcher'; export { IndexPatternsFetcher, getCapabilitiesForRollupIndices } from './fetcher'; export type { DataViewsServerPluginStart, diff --git a/src/plugins/data_views/server/rest_api_routes/util/handle_errors.ts b/src/plugins/data_views/server/rest_api_routes/util/handle_errors.ts index c828e064fce84..a01890c34a43d 100644 --- a/src/plugins/data_views/server/rest_api_routes/util/handle_errors.ts +++ b/src/plugins/data_views/server/rest_api_routes/util/handle_errors.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import Boom from '@hapi/boom'; import type { RequestHandler, RouteMethod, RequestHandlerContext } from '@kbn/core/server'; import { ErrorIndexPatternNotFound } from '../../error'; @@ -47,7 +48,8 @@ export const handleErrors = } const is404 = - (error as ErrorIndexPatternNotFound).is404 || (error as any)?.output?.statusCode === 404; + (error as ErrorIndexPatternNotFound).is404 || + (error as Boom.Boom)?.output?.statusCode === 404; if (is404) { return response.notFound({ diff --git a/src/plugins/data_views/server/saved_objects/data_views.ts b/src/plugins/data_views/server/saved_objects/data_views.ts index 064302e2b6fe6..3036efd5559d3 100644 --- a/src/plugins/data_views/server/saved_objects/data_views.ts +++ b/src/plugins/data_views/server/saved_objects/data_views.ts @@ -41,5 +41,5 @@ export const dataViewSavedObjectType: SavedObjectsType = { name: { type: 'text' }, }, }, - migrations: indexPatternSavedObjectTypeMigrations as any, + migrations: indexPatternSavedObjectTypeMigrations, }; diff --git a/src/plugins/data_views/server/saved_objects_client_wrapper.ts b/src/plugins/data_views/server/saved_objects_client_wrapper.ts index d8755b9ff1be1..9ac5e5203a10e 100644 --- a/src/plugins/data_views/server/saved_objects_client_wrapper.ts +++ b/src/plugins/data_views/server/saved_objects_client_wrapper.ts @@ -7,7 +7,11 @@ */ import { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; -import { SavedObjectsClientCommon, SavedObjectsClientCommonFindArgs } from '../common/types'; +import { + DataViewAttributes, + SavedObjectsClientCommon, + SavedObjectsClientCommonFindArgs, +} from '../common/types'; import { DataViewSavedObjectConflictError } from '../common/errors'; export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommon { @@ -27,15 +31,10 @@ export class SavedObjectsClientServerToCommon implements SavedObjectsClientCommo } return response.saved_object; } - async update( - type: string, - id: string, - attributes: Record, - options: Record - ) { + async update(type: string, id: string, attributes: DataViewAttributes, options: {}) { return (await this.savedObjectClient.update(type, id, attributes, options)) as SavedObject; } - async create(type: string, attributes: Record, options: Record) { + async create(type: string, attributes: DataViewAttributes, options: {}) { return await this.savedObjectClient.create(type, attributes, options); } delete(type: string, id: string) { diff --git a/src/plugins/data_views/server/ui_settings_wrapper.ts b/src/plugins/data_views/server/ui_settings_wrapper.ts index 51f23d7de4cd6..e9968d500fca8 100644 --- a/src/plugins/data_views/server/ui_settings_wrapper.ts +++ b/src/plugins/data_views/server/ui_settings_wrapper.ts @@ -14,15 +14,15 @@ export class UiSettingsServerToCommon implements UiSettingsCommon { constructor(uiSettings: IUiSettingsClient) { this.uiSettings = uiSettings; } - get(key: string): Promise { + get(key: string): Promise { return this.uiSettings.get(key); } - getAll(): Promise> { + getAll(): Promise> { return this.uiSettings.getAll(); } - set(key: string, value: any) { + set(key: string, value: unknown) { return this.uiSettings.set(key, value); } diff --git a/src/plugins/vis_types/timeseries/common/fields_utils.ts b/src/plugins/vis_types/timeseries/common/fields_utils.ts index 65125f616155e..d5c2dfdc68811 100644 --- a/src/plugins/vis_types/timeseries/common/fields_utils.ts +++ b/src/plugins/vis_types/timeseries/common/fields_utils.ts @@ -94,7 +94,8 @@ export const createCachedFieldValueFormatter = ( return convert(cachedFormatter); } - if (dataView && !excludedFieldFormatsIds.includes(dataView.fieldFormatMap?.[fieldName]?.id)) { + const formatId = dataView?.fieldFormatMap?.[fieldName]?.id as FIELD_FORMAT_IDS; + if (dataView && !excludedFieldFormatsIds.includes(formatId)) { const field = dataView.fields.getByName(fieldName); if (field) { const formatter = dataView.getFormatterForField(field); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index 27c774ed2963e..a0c2a182bee62 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -432,7 +432,7 @@ function FieldItemPopoverContents(props: State & FieldItemProps) { let formatter: { convert: (data: unknown) => string }; if (indexPattern.fieldFormatMap && indexPattern.fieldFormatMap[field.name]) { - const FormatType = fieldFormats.getType(indexPattern.fieldFormatMap[field.name].id); + const FormatType = fieldFormats.getType(indexPattern.fieldFormatMap[field.name].id as string); if (FormatType) { formatter = new FormatType( indexPattern.fieldFormatMap[field.name].params, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index ce162e5d2ff60..8ca21272a555e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -100,6 +100,7 @@ export function convertDataViewIntoLensIndexPattern(dataView: DataView): IndexPa Object.fromEntries( Object.entries(fieldFormatMap).map(([id, format]) => [ id, + // @ts-expect-error FIXME Property 'toJSON' does not exist on type 'SerializedFieldFormat' 'toJSON' in format ? format.toJSON() : format, ]) ), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts index d01415b460325..31aa7e3214d73 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/types.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/types.ts @@ -7,7 +7,7 @@ import type { IndexPatternAggRestrictions } from '@kbn/data-plugin/public'; import type { FieldSpec } from '@kbn/data-plugin/common'; -import type { FieldFormatParams } from '@kbn/field-formats-plugin/common'; +import type { FieldFormatMap } from '@kbn/data-views-plugin/common'; import type { DragDropIdentifier } from '../drag_drop/providers'; import type { IncompleteColumn, GenericIndexPatternColumn } from './operations'; import { DragDropOperation } from '../types'; @@ -57,13 +57,7 @@ export interface IndexPattern { title: string; name?: string; timeFieldName?: string; - fieldFormatMap?: Record< - string, - { - id: string; - params: FieldFormatParams; - } - >; + fieldFormatMap?: FieldFormatMap; hasRestrictions: boolean; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 078369ea3c32e..62c05c1e5c563 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -640,7 +640,7 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource ); } - const properties = indexPattern.flattenHit(hit); + const properties = indexPattern.flattenHit(hit) as Record; indexPattern.metaFields.forEach((metaField: string) => { if (!this._getTooltipPropertyNames().includes(metaField)) { delete properties[metaField];