Add more strict eslint rules for discover (#99241)

This commit is contained in:
Tim Roes 2021-05-05 10:54:15 +02:00 committed by GitHub
parent b2df82f0a9
commit 349b7e9f8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 217 additions and 132 deletions

View file

@ -1256,6 +1256,22 @@ module.exports = {
},
},
/**
* Discover overrides
*/
{
files: ['src/plugins/discover/**/*.{ts,tsx}'],
rules: {
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-expect-error': false,
},
],
},
},
/**
* Enterprise Search overrides
* NOTE: We also have a single rule at the bottom of the file that

View file

@ -83,7 +83,7 @@ const indexPattern = ({
indexPattern.flattenHit = indexPatterns.flattenHitWrapper(indexPattern, indexPattern.metaFields);
indexPattern.isTimeBased = () => !!indexPattern.timeFieldName;
indexPattern.formatField = (hit: Record<string, any>, fieldName: string) => {
indexPattern.formatField = (hit: Record<string, unknown>, fieldName: string) => {
return fieldName === '_source' ? hit._source : indexPattern.flattenHit(hit)[fieldName];
};

View file

@ -17,8 +17,10 @@ import { getServices } from '../../../../kibana_services';
export type SurrDocType = 'successors' | 'predecessors';
export interface EsHitRecord {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fields: Record<string, any>;
sort: number[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_source: Record<string, any>;
_id: string;
}

View file

@ -28,11 +28,11 @@ export function getEsQuerySearchAfter(
// already surrounding docs -> first or last record is used
const afterTimeRecIdx = type === 'successors' && documents.length ? documents.length - 1 : 0;
const afterTimeDoc = documents[afterTimeRecIdx];
let afterTimeValue = afterTimeDoc.sort[0];
let afterTimeValue: string | number = afterTimeDoc.sort[0];
if (nanoSeconds) {
afterTimeValue = useNewFieldsApi
? afterTimeDoc.fields[timeFieldName][0]
: afterTimeDoc._source[timeFieldName];
? (afterTimeDoc.fields[timeFieldName] as Array<string | number>)[0]
: (afterTimeDoc._source[timeFieldName] as string | number);
}
return [afterTimeValue, afterTimeDoc.sort[1]];
}
@ -42,8 +42,8 @@ export function getEsQuerySearchAfter(
searchAfter[0] = anchor.sort[0];
if (nanoSeconds) {
searchAfter[0] = useNewFieldsApi
? anchor.fields[timeFieldName][0]
: anchor._source[timeFieldName];
? (anchor.fields[timeFieldName] as Array<string | number>)[0]
: (anchor._source[timeFieldName] as string | number);
}
searchAfter[1] = anchor.sort[1];
return searchAfter;

View file

@ -27,7 +27,6 @@ export function getFirstSortableField(indexPattern: IndexPattern, fieldNames: st
const sortableFields = fieldNames.filter(
(fieldName) =>
META_FIELD_NAMES.includes(fieldName) ||
// @ts-ignore
(indexPattern.fields.getByName(fieldName) || { sortable: false }).sortable
);
return sortableFields[0];

View file

@ -9,6 +9,7 @@
import { getAngularModule } from '../../../../../kibana_services';
import { ActionBar } from './action_bar';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getAngularModule().directive('contextActionBar', function (reactDirective: any) {
return reactDirective(ActionBar);
});

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
// @ts-ignore
// @ts-expect-error
import { getQueryParameterActions } from './actions';
import { FilterManager } from '../../../../../../data/public';
import { coreMock } from '../../../../../../../core/public/mocks';

View file

@ -12,16 +12,17 @@ import { createBrowserHistory, History } from 'history';
import { FilterManager, Filter } from '../../../../data/public';
import { coreMock } from '../../../../../core/public/mocks';
import { SEARCH_FIELDS_FROM_SOURCE } from '../../../common';
const setupMock = coreMock.createSetup();
describe('Test Discover Context State', () => {
let history: History;
let state: any;
let state: ReturnType<typeof getState>;
const getCurrentUrl = () => history.createHref(history.location);
beforeEach(async () => {
history = createBrowserHistory();
history.push('/');
state = await getState({
state = getState({
defaultStepSize: '4',
timeFieldName: 'time',
history,

View file

@ -13,8 +13,8 @@ import {
createStateContainer,
createKbnUrlStateStorage,
syncStates,
BaseStateContainer,
withNotifyOnErrors,
ReduxLikeStateContainer,
} from '../../../../kibana_utils/public';
import { esFilters, FilterManager, Filter, Query } from '../../../../data/public';
import { handleSourceColumnState } from './helpers';
@ -85,11 +85,11 @@ interface GetStateReturn {
/**
* Global state, the _g part of the URL
*/
globalState: BaseStateContainer<GlobalState>;
globalState: ReduxLikeStateContainer<GlobalState>;
/**
* App state, the _a part of the URL
*/
appState: BaseStateContainer<AppState>;
appState: ReduxLikeStateContainer<AppState>;
/**
* Start sync between state and URL
*/

View file

@ -12,7 +12,7 @@ import 'angular-mocks';
import 'angular-sanitize';
import 'angular-route';
// @ts-ignore
// @ts-expect-error
import { createDebounceProviderTimeout } from './debounce';
import { coreMock } from '../../../../../../../core/public/mocks';
import { initializeInnerAngularModule } from '../../../../get_inner_angular';
@ -21,6 +21,7 @@ import { dataPluginMock } from '../../../../../../data/public/mocks';
import { initAngularBootstrap } from '../../../../../../kibana_legacy/public';
describe('debounce service', function () {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let debounce: (fn: () => void, timeout: number, options?: any) => any;
let $timeout: ITimeoutService;
let spy: SinonSpy;

View file

@ -7,17 +7,17 @@
*/
import { getAngularModule, getServices } from '../../kibana_services';
// @ts-ignore
import { getRootBreadcrumbs } from '../helpers/breadcrumbs';
import html from './doc.html';
import { Doc } from '../components/doc/doc';
interface LazyScope extends ng.IScope {
[key: string]: any;
[key: string]: unknown;
}
const { timefilter } = getServices();
const app = getAngularModule();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
app.directive('discoverDoc', function (reactDirective: any) {
return reactDirective(
Doc,
@ -31,6 +31,7 @@ app.directive('discoverDoc', function (reactDirective: any) {
);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
app.config(($routeProvider: any) => {
$routeProvider
.when('/doc/:indexPattern/:index/:type', {
@ -39,7 +40,7 @@ app.config(($routeProvider: any) => {
// the new route, es 7 deprecated types, es 8 removed them
.when('/doc/:indexPattern/:index', {
// have to be written as function expression, because it's not compiled in dev mode
// eslint-disable-next-line object-shorthand
// eslint-disable-next-line @typescript-eslint/no-explicit-any, object-shorthand
controller: function ($scope: LazyScope, $route: any) {
timefilter.disableAutoRefreshSelector();
timefilter.disableTimeRangeSelector();
@ -49,6 +50,7 @@ app.config(($routeProvider: any) => {
$scope.indexPatternService = getServices().indexPatterns;
},
template: html,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
k7Breadcrumbs: ($route: any) => [
...getRootBreadcrumbs(),
{

View file

@ -9,10 +9,12 @@
import { ToolBarPagerText } from './tool_bar_pager_text';
import { ToolBarPagerButtons } from './tool_bar_pager_buttons';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createToolBarPagerTextDirective(reactDirective: any) {
return reactDirective(ToolBarPagerText);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createToolBarPagerButtonsDirective(reactDirective: any) {
return reactDirective(ToolBarPagerButtons);
}

View file

@ -11,6 +11,7 @@ import { getServices } from '../../../../kibana_services';
import { SORT_DEFAULT_ORDER_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '../../../../../common';
import { UI_SETTINGS } from '../../../../../../data/public';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createTableHeaderDirective(reactDirective: any) {
const { uiSettings: config } = getServices();

View file

@ -8,7 +8,6 @@
import React from 'react';
import { IndexPattern } from '../../../../../kibana_services';
// @ts-ignore
import { TableHeaderColumn } from './table_header_column';
import { SortOrder, getDisplayedColumns } from './helpers';
import { getDefaultSort } from '../../lib/get_default_sort';

View file

@ -32,6 +32,7 @@ export function noWhiteSpace(html: string): string {
const MIN_LINE_LENGTH = 20;
interface LazyScope extends ng.IScope {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
@ -94,6 +95,7 @@ export function createTableRowDirective($compile: ng.ICompileService) {
createSummaryRow($scope.row);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
$scope.inlineFilter = function inlineFilter($event: any, type: string) {
const column = $($event.currentTarget).data().column;
const field = $scope.indexPattern.fields.getByName(column);
@ -119,6 +121,7 @@ export function createTableRowDirective($compile: ng.ICompileService) {
};
// create a tr element that lists the value for each *column*
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function createSummaryRow(row: any) {
const indexPattern = $scope.indexPattern;
$scope.flattenedRow = indexPattern.flattenHit(row);
@ -188,7 +191,7 @@ export function createTableRowDirective($compile: ng.ICompileService) {
const $cell = $cells.eq(i);
if ($cell.data('discover:html') === html) return;
const reuse = find($cells.slice(i + 1), function (cell: any) {
const reuse = find($cells.slice(i + 1), (cell) => {
return $.data(cell, 'discover:html') === html;
});
@ -222,6 +225,7 @@ export function createTableRowDirective($compile: ng.ICompileService) {
/**
* Fill an element with the value of a field
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function _displayField(row: any, fieldName: string, truncate = false) {
const indexPattern = $scope.indexPattern;
const text = indexPattern.formatField(row, fieldName);

View file

@ -45,6 +45,7 @@ export type AngularScope = IScope & { renderProps?: DocTableLegacyProps };
export async function injectAngularElement(
domNode: Element,
template: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
renderProps: any,
injector: auto.IInjectorService
) {
@ -64,6 +65,7 @@ export async function injectAngularElement(
return newScope;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getRenderFn(domNode: Element, props: any) {
const directive = {
template: `<doc-table

View file

@ -9,15 +9,17 @@
import html from './doc_table.html';
import { dispatchRenderComplete } from '../../../../../kibana_utils/public';
import { SAMPLE_SIZE_SETTING } from '../../../../common';
// @ts-ignore
// @ts-expect-error
import { getLimitedSearchResultsMessage } from './doc_table_strings';
import { getServices } from '../../../kibana_services';
import './index.scss';
export interface LazyScope extends ng.IScope {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createDocTableDirective(pagerFactory: any, $filter: any) {
return {
restrict: 'E',
@ -63,7 +65,7 @@ export function createDocTableDirective(pagerFactory: any, $filter: any) {
$scope.limit = Math.max(minimumVisibleRows || 50, $scope.limit || 50);
});
$scope.$watch('hits', (hits: any) => {
$scope.$watch('hits', (hits: unknown[]) => {
if (!hits) return;
// Reset infinite scroll limit

View file

@ -9,6 +9,7 @@
import $ from 'jquery';
interface LazyScope extends ng.IScope {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}
@ -19,6 +20,7 @@ export function createInfiniteScrollDirective() {
more: '=',
},
link: ($scope: LazyScope, $element: JQuery) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let checkTimer: any;
/**
* depending on which version of Discover is displayed, different elements are scrolling

View file

@ -7,7 +7,7 @@
*/
import { getDefaultSort } from './get_default_sort';
// @ts-ignore
// @ts-expect-error
import FixturesStubbedLogstashIndexPatternProvider from '../../../../__fixtures__/stubbed_logstash_index_pattern';
import { IndexPattern } from '../../../../kibana_services';

View file

@ -7,7 +7,7 @@
*/
import { getSort, getSortArray } from './get_sort';
// @ts-ignore
// @ts-expect-error
import FixturesStubbedLogstashIndexPatternProvider from '../../../../__fixtures__/stubbed_logstash_index_pattern';
import { IndexPattern } from '../../../../kibana_services';

View file

@ -7,7 +7,7 @@
*/
import { getSortForSearchSource } from './get_sort_for_search_source';
// @ts-ignore
// @ts-expect-error
import FixturesStubbedLogstashIndexPatternProvider from '../../../../__fixtures__/stubbed_logstash_index_pattern';
import { IndexPattern } from '../../../../kibana_services';
import { SortOrder } from '../components/table_header/helpers';

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
// @ts-ignore
// @ts-expect-error
import { Pager } from './pager';
export function createPagerFactory() {

View file

@ -9,9 +9,10 @@
import React from 'react';
import { DocViewer } from '../components/doc_viewer/doc_viewer';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createDocViewerDirective(reactDirective: any) {
return reactDirective(
(props: any) => {
(props: React.ComponentProps<typeof DocViewer>) => {
return <DocViewer {...props} />;
},
[

View file

@ -11,6 +11,7 @@ import { stubbedSavedObjectIndexPattern } from '../../../__mocks__/stubbed_saved
import { IndexPattern } from '../../../../../data/common/index_patterns/index_patterns';
import { fieldFormatsMock } from '../../../../../data/common/field_formats/mocks';
import { setServices } from '../../../kibana_services';
import { DiscoverServices } from '../../../build_services';
describe('Row formatter', () => {
const hit = {
@ -59,11 +60,11 @@ describe('Row formatter', () => {
beforeEach(() => {
// @ts-expect-error
indexPattern.formatHit = formatHitMock;
setServices({
setServices(({
uiSettings: {
get: () => 100,
},
});
} as unknown) as DiscoverServices);
});
it('formats document properly', () => {
@ -73,11 +74,11 @@ describe('Row formatter', () => {
});
it('limits number of rendered items', () => {
setServices({
setServices(({
uiSettings: {
get: () => 1,
},
});
} as unknown) as DiscoverServices);
expect(formatRow(hit, indexPattern).trim()).toMatchInlineSnapshot(
`"<dl class=\\"source truncate-by-height\\"><dt>also:</dt><dd>with \\\\&quot;quotes\\\\&quot; or &#39;single qoutes&#39;</dd> </dl>"`
);

View file

@ -30,6 +30,7 @@ const TemplateComponent = ({ defPairs }: Props) => {
);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const formatRow = (hit: Record<string, any>, indexPattern: IndexPattern) => {
const highlights = hit?.highlight ?? {};
// Keys are sorted in the hits object
@ -49,7 +50,9 @@ export const formatRow = (hit: Record<string, any>, indexPattern: IndexPattern)
};
export const formatTopLevelObject = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
row: Record<string, any>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fields: Record<string, any>,
indexPattern: IndexPattern
) => {

View file

@ -8,8 +8,10 @@
import { getAngularModule, getServices, getUrlTracker } from '../../kibana_services';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
getAngularModule().config(($routeProvider: any) => {
$routeProvider.otherwise({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
resolveRedirectTo: ($rootScope: any) => {
const path = window.location.hash.substr(1);
getUrlTracker().restorePreviousUrl();

View file

@ -8,6 +8,7 @@
import { ContextAppLegacy } from './context_app_legacy';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createContextAppLegacy(reactDirective: any) {
return reactDirective(ContextAppLegacy, [
['filter', { watchDepth: 'reference' }],

View file

@ -10,7 +10,7 @@ import React from 'react';
import { mountWithIntl } from '@kbn/test/jest';
import { ReactWrapper } from 'enzyme';
import { ContextErrorMessage } from './context_error_message';
// @ts-ignore
// @ts-expect-error
import { FAILURE_REASONS, LOADING_STATUS } from '../../angular/context/query';
import { findTestSubject } from '@elastic/eui/lib/test';

View file

@ -9,7 +9,7 @@
import React from 'react';
import { EuiCallOut, EuiText } from '@elastic/eui';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
// @ts-ignore
// @ts-expect-error
import { FAILURE_REASONS, LOADING_STATUS } from '../../angular/context/query';
export interface ContextErrorMessageProps {

View file

@ -7,6 +7,7 @@
*/
import { Discover } from './discover';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createDiscoverDirective(reactDirective: any) {
return reactDirective(Discover, [
['fetch', { watchDepth: 'reference' }],

View file

@ -33,6 +33,7 @@ export function DiscoverGridEmbeddable(props: DiscoverGridProps) {
/**
* this is just needed for the embeddable
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createDiscoverGridDirective(reactDirective: any) {
return reactDirective(DiscoverGridEmbeddable, [
['columns', { watchDepth: 'collection' }],

View file

@ -32,6 +32,7 @@ describe('Discover cell actions ', function () {
const component = mountWithIntl(
<DiscoverGridContext.Provider value={contextMock}>
<FilterInBtn
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Component={(props: any) => <EuiButton {...props} />}
rowIndex={1}
columnId={'extension'}
@ -59,6 +60,7 @@ describe('Discover cell actions ', function () {
const component = mountWithIntl(
<DiscoverGridContext.Provider value={contextMock}>
<FilterOutBtn
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Component={(props: any) => <EuiButton {...props} />}
rowIndex={1}
columnId={'extension'}

View file

@ -115,7 +115,7 @@ export const getRenderCellValueFn = (
if (typeof rowFlattened[columnId] === 'object' && isDetails) {
return (
<JsonCodeEditor
json={rowFlattened[columnId] as Record<string, any>}
json={rowFlattened[columnId] as Record<string, unknown>}
width={defaultMonacoEditorWidth}
/>
);
@ -123,7 +123,8 @@ export const getRenderCellValueFn = (
if (field && field.type === '_source') {
if (isDetails) {
return <JsonCodeEditor json={row} width={defaultMonacoEditorWidth} />;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return <JsonCodeEditor json={row as any} width={defaultMonacoEditorWidth} />;
}
const formatted = indexPattern.formatHit(row);

View file

@ -18,6 +18,7 @@ import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../.
const mockSearchApi = jest.fn();
jest.mock('../../../kibana_services', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let registry: any[] = [];
return {
@ -46,6 +47,7 @@ jest.mock('../../../kibana_services', () => {
},
}),
getDocViewsRegistry: () => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
addDocView(view: any) {
registry.push(view);
},
@ -72,12 +74,14 @@ const waitForPromises = async () =>
* this works but logs ugly error messages until we're using React 16.9
* should be adapted when we upgrade
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
async function mountDoc(update = false, indexPatternGetter: any = null) {
const indexPattern = {
getComputedFields: () => [],
};
const indexPatternService = {
get: indexPatternGetter ? indexPatternGetter : jest.fn(() => Promise.resolve(indexPattern)),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any;
const props = {

View file

@ -11,6 +11,7 @@ import { buildSearchBody, useEsDocSearch, ElasticRequestState } from './use_es_d
import { DocProps } from './doc';
import { Observable } from 'rxjs';
import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '../../../../common';
import { IndexPattern } from 'src/plugins/data/common';
const mockSearchResult = new Observable();
@ -35,9 +36,9 @@ jest.mock('../../../kibana_services', () => ({
describe('Test of <Doc /> helper / hook', () => {
test('buildSearchBody given useNewFieldsApi is false', () => {
const indexPattern = {
const indexPattern = ({
getComputedFields: () => ({ storedFields: [], scriptFields: [], docvalueFields: [] }),
} as any;
} as unknown) as IndexPattern;
const actual = buildSearchBody('1', indexPattern, false);
expect(actual).toMatchInlineSnapshot(`
Object {
@ -59,9 +60,9 @@ describe('Test of <Doc /> helper / hook', () => {
});
test('buildSearchBody useNewFieldsApi is true', () => {
const indexPattern = {
const indexPattern = ({
getComputedFields: () => ({ storedFields: [], scriptFields: [], docvalueFields: [] }),
} as any;
} as unknown) as IndexPattern;
const actual = buildSearchBody('1', indexPattern, true);
expect(actual).toMatchInlineSnapshot(`
Object {
@ -88,7 +89,7 @@ describe('Test of <Doc /> helper / hook', () => {
});
test('buildSearchBody with runtime fields', () => {
const indexPattern = {
const indexPattern = ({
getComputedFields: () => ({
storedFields: [],
scriptFields: [],
@ -102,7 +103,7 @@ describe('Test of <Doc /> helper / hook', () => {
},
},
}),
} as any;
} as unknown) as IndexPattern;
const actual = buildSearchBody('1', indexPattern, true);
expect(actual).toMatchInlineSnapshot(`
Object {
@ -139,21 +140,22 @@ describe('Test of <Doc /> helper / hook', () => {
const indexPattern = {
getComputedFields: () => [],
};
const indexPatternService = {
get: jest.fn(() => Promise.resolve(indexPattern)),
} as any;
const props = {
const getMock = jest.fn(() => Promise.resolve(indexPattern));
const indexPatternService = ({
get: getMock,
} as unknown) as IndexPattern;
const props = ({
id: '1',
index: 'index1',
indexPatternId: 'xyz',
indexPatternService,
} as DocProps;
let hook;
} as unknown) as DocProps;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let hook: any;
await act(async () => {
hook = renderHook((p: DocProps) => useEsDocSearch(p), { initialProps: props });
});
// @ts-ignore
expect(hook.result.current).toEqual([ElasticRequestState.Loading, null, indexPattern]);
expect(indexPatternService.get).toHaveBeenCalled();
expect(getMock).toHaveBeenCalled();
});
});

View file

@ -14,6 +14,7 @@ import { getDocViewsRegistry } from '../../../kibana_services';
import { DocViewRenderProps } from '../../doc_views/doc_views_types';
jest.mock('../../../kibana_services', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let registry: any[] = [];
return {
getServices: () => ({
@ -22,6 +23,7 @@ jest.mock('../../../kibana_services', () => {
},
}),
getDocViewsRegistry: () => ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
addDocView(view: any) {
registry.push(view);
},
@ -36,6 +38,7 @@ jest.mock('../../../kibana_services', () => {
});
beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(getDocViewsRegistry() as any).resetRegistry();
jest.clearAllMocks();
});
@ -44,6 +47,7 @@ test('Render <DocViewer/> with 3 different tabs', () => {
const registry = getDocViewsRegistry();
registry.addDocView({ order: 10, title: 'Render function', render: jest.fn() });
registry.addDocView({ order: 20, title: 'React component', component: () => <div>test</div> });
// @ts-expect-error This should be invalid and will throw an error when rendering
registry.addDocView({ order: 30, title: 'Invalid doc view' });
const renderProps = { hit: {} } as DocViewRenderProps;

View file

@ -16,11 +16,11 @@ import { getServices } from '../../../kibana_services';
import { KibanaContextProvider } from '../../../../../kibana_react/public';
interface Props {
component?: React.ComponentType<DocViewRenderProps>;
id: number;
render?: DocViewRenderFn;
renderProps: DocViewRenderProps;
title: string;
render?: DocViewRenderFn;
component?: React.ComponentType<DocViewRenderProps>;
}
interface State {
@ -53,17 +53,11 @@ export class DocViewerTab extends React.Component<Props, State> {
}
render() {
const { component, render, renderProps, title } = this.props;
const { component: Component, render, renderProps, title } = this.props;
const { hasError, error } = this.state;
if (hasError && error) {
return <DocViewerError error={error} />;
} else if (!render && !component) {
return (
<DocViewerError
error={`Invalid plugin ${title}, there is neither a (react) component nor a render function provided`}
/>
);
}
if (render) {
@ -72,14 +66,20 @@ export class DocViewerTab extends React.Component<Props, State> {
}
// doc view is provided by a react component
if (Component) {
return (
<I18nProvider>
<KibanaContextProvider services={{ uiSettings: getServices().uiSettings }}>
<Component {...renderProps} />
</KibanaContextProvider>
</I18nProvider>
);
}
const Component = component as any;
return (
<I18nProvider>
<KibanaContextProvider services={{ uiSettings: getServices().uiSettings }}>
<Component {...renderProps} />
</KibanaContextProvider>
</I18nProvider>
<DocViewerError
error={`Invalid plugin ${title}, there is neither a (react) component nor a render function provided`}
/>
);
}
}

View file

@ -22,7 +22,7 @@ const copyToClipboardLabel = i18n.translate('discover.json.copyToClipboardLabel'
});
interface JsonCodeEditorProps {
json: Record<string, any>;
json: Record<string, unknown>;
width?: string | number;
hasLineNumbers?: boolean;
}

View file

@ -8,7 +8,7 @@
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import { DiscoverField } from './discover_field';
@ -49,7 +49,7 @@ function getComponent({
}) {
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -8,7 +8,7 @@
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import { DiscoverFieldDetails } from './discover_field_details';
@ -18,7 +18,7 @@ import { getStubIndexPattern } from '../../../../../data/public/test_utils';
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -8,7 +8,7 @@
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import { coreMock } from '../../../../../../core/public/mocks';
@ -18,7 +18,7 @@ import { DiscoverFieldDetailsFooter } from './discover_field_details_footer';
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -47,7 +47,7 @@ describe('DiscoverFieldSearch', () => {
const aggregatableButtonGroup = findButtonGroup(component, 'aggregatable');
act(() => {
// @ts-ignore
// @ts-expect-error
(aggregatableButtonGroup.props() as EuiButtonGroupProps).onChange('aggregatable-true', null);
});
component.update();
@ -66,7 +66,7 @@ describe('DiscoverFieldSearch', () => {
// change value of aggregatable select
const aggregatableButtonGroup = findButtonGroup(component, 'aggregatable');
act(() => {
// @ts-ignore
// @ts-expect-error
(aggregatableButtonGroup.props() as EuiButtonGroupProps).onChange('aggregatable-true', null);
});
component.update();
@ -74,14 +74,14 @@ describe('DiscoverFieldSearch', () => {
// change value of searchable select
const searchableButtonGroup = findButtonGroup(component, 'searchable');
act(() => {
// @ts-ignore
// @ts-expect-error
(searchableButtonGroup.props() as EuiButtonGroupProps).onChange('searchable-true', null);
});
component.update();
expect(badge.text()).toEqual('2');
// change value of searchable select
act(() => {
// @ts-ignore
// @ts-expect-error
(searchableButtonGroup.props() as EuiButtonGroupProps).onChange('searchable-any', null);
});
component.update();
@ -114,7 +114,7 @@ describe('DiscoverFieldSearch', () => {
const aggregtableButtonGroup = findButtonGroup(component, 'aggregatable');
const missingSwitch = findTestSubject(component, 'missingSwitch');
act(() => {
// @ts-ignore
// @ts-expect-error
(aggregtableButtonGroup.props() as EuiButtonGroupProps).onChange('aggregatable-true', null);
});
missingSwitch.simulate('click');

View file

@ -14,7 +14,7 @@ import { ChangeIndexPattern } from './change_indexpattern';
import { SavedObject } from 'kibana/server';
import { DiscoverIndexPattern, DiscoverIndexPatternProps } from './discover_index_pattern';
import { EuiSelectable } from '@elastic/eui';
import { IndexPattern } from 'src/plugins/data/public';
import { IndexPattern, IndexPatternAttributes } from 'src/plugins/data/public';
import { configMock } from '../../../__mocks__/config';
import { indexPatternsMock } from '../../../__mocks__/index_patterns';
@ -28,14 +28,14 @@ const indexPattern1 = {
attributes: {
title: 'test1 title',
},
} as SavedObject<any>;
} as SavedObject<IndexPatternAttributes>;
const indexPattern2 = {
id: 'the-index-pattern-id',
attributes: {
title: 'test2 title',
},
} as SavedObject<any>;
} as SavedObject<IndexPatternAttributes>;
const defaultProps = {
config: configMock,
@ -58,6 +58,7 @@ function getIndexPatternPickerOptions(instance: ShallowWrapper) {
function selectIndexPatternPickerOption(instance: ShallowWrapper, selectedLabel: string) {
const options: Array<{ label: string; checked?: 'on' | 'off' }> = getIndexPatternPickerOptions(
instance
// eslint-disable-next-line @typescript-eslint/no-explicit-any
).map((option: any) =>
option.label === selectedLabel
? { ...option, checked: 'on' }
@ -79,6 +80,7 @@ describe('DiscoverIndexPattern', () => {
test('should list all index patterns', () => {
const instance = shallow(<DiscoverIndexPattern {...defaultProps} />);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
expect(getIndexPatternPickerOptions(instance)!.map((option: any) => option.label)).toEqual([
'test1 title',
'test2 title',

View file

@ -9,7 +9,7 @@
import { getStubIndexPattern } from '../../../../../data/public/index_patterns/index_pattern.stub';
import { coreMock } from '../../../../../../core/public/mocks';
import { DiscoverServices } from '../../../build_services';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import React from 'react';
@ -56,7 +56,7 @@ const mockServices = ({
describe('Discover IndexPattern Management', () => {
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -9,9 +9,9 @@
import { each, cloneDeep } from 'lodash';
import { ReactWrapper } from 'enzyme';
import { findTestSubject } from '@elastic/eui/lib/test';
// @ts-ignore
// @ts-expect-error
import realHits from '../../../__fixtures__/real_hits.js';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import React from 'react';
@ -67,7 +67,7 @@ jest.mock('./lib/get_index_pattern_field_list', () => ({
function getCompProps(): DiscoverSidebarProps {
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -9,9 +9,9 @@
import { each, cloneDeep } from 'lodash';
import { ReactWrapper } from 'enzyme';
import { findTestSubject } from '@elastic/eui/lib/test';
// @ts-ignore
// @ts-expect-error
import realHits from '../../../__fixtures__/real_hits.js';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../__fixtures__/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import React from 'react';
@ -63,7 +63,7 @@ jest.mock('./lib/get_index_pattern_field_list', () => ({
function getCompProps(): DiscoverSidebarResponsiveProps {
const indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -6,15 +6,17 @@
* Side Public License, v 1.
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import _ from 'lodash';
// @ts-ignore
// @ts-expect-error
import realHits from '../../../../__fixtures__/real_hits.js';
// @ts-ignore
// @ts-expect-error
import stubbedLogstashFields from '../../../../__fixtures__/logstash_fields';
import { coreMock } from '../../../../../../../core/public/mocks';
import { IndexPattern } from '../../../../../../data/public';
import { getStubIndexPattern } from '../../../../../../data/public/test_utils';
// @ts-ignore
// @ts-expect-error
import { fieldCalculator } from './field_calculator';
let indexPattern: IndexPattern;
@ -23,7 +25,7 @@ describe('fieldCalculator', function () {
beforeEach(function () {
indexPattern = getStubIndexPattern(
'logstash-*',
(cfg: any) => cfg,
(cfg: unknown) => cfg,
'time',
stubbedLogstashFields(),
coreMock.createSetup()

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
// @ts-ignore
// @ts-expect-error
import { fieldCalculator } from './field_calculator';
import { IndexPattern, IndexPatternField } from '../../../../../../data/public';
import { ElasticSearchHit } from '../../../doc_views/doc_views_types';

View file

@ -167,18 +167,11 @@ describe('group_fields', function () {
aggregatable: true,
readFromDocValues: false,
};
const fieldsToGroup = [category, currency, currencyKeyword];
const fieldsToGroup = [category, currency, currencyKeyword] as IndexPatternField[];
const fieldFilterState = getDefaultFieldFilter();
const actual = groupFields(
fieldsToGroup as any,
['currency'],
5,
fieldCounts,
fieldFilterState,
true
);
const actual = groupFields(fieldsToGroup, ['currency'], 5, fieldCounts, fieldFilterState, true);
expect(actual.popular).toEqual([category]);
expect(actual.selected).toEqual([currency]);

View file

@ -11,6 +11,7 @@ import { mount } from 'enzyme';
import { findTestSubject } from '@elastic/eui/lib/test';
import { DocViewTable } from './table';
import { indexPatterns, IndexPattern } from '../../../../../data/public';
import { ElasticSearchHit } from '../../doc_views/doc_views_types';
const indexPattern = ({
fields: {
@ -87,7 +88,7 @@ describe('DocViewTable at Discover', () => {
scripted: 123,
_underscore: 123,
},
} as any;
} as ElasticSearchHit;
const props = {
hit,
@ -185,7 +186,7 @@ describe('DocViewTable at Discover Context', () => {
Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. \
Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut',
},
} as any;
} as ElasticSearchHit;
const props = {
hit,
columns: ['extension'],
@ -312,7 +313,7 @@ describe('DocViewTable at Discover Doc with Fields API', () => {
},
metaFields: ['_index', '_type', '_score', '_id'],
flattenHit: jest.fn((hit) => {
const result = {} as Record<string, any>;
const result = {} as Record<string, unknown>;
Object.keys(hit).forEach((key) => {
if (key !== 'fields') {
result[key] = hit[key];
@ -325,7 +326,7 @@ describe('DocViewTable at Discover Doc with Fields API', () => {
return result;
}),
formatHit: jest.fn((hit) => {
const result = {} as Record<string, any>;
const result = {} as Record<string, unknown>;
Object.keys(hit).forEach((key) => {
if (key !== 'fields') {
result[key] = hit[key];
@ -347,7 +348,7 @@ describe('DocViewTable at Discover Doc with Fields API', () => {
_index: 'logstash-2014.09.09',
_type: 'doc',
_id: 'id123',
_score: null,
_score: 1.0,
fields: {
category: "Women's Clothing",
'category.keyword': "Women's Clothing",
@ -364,7 +365,6 @@ describe('DocViewTable at Discover Doc with Fields API', () => {
onAddColumn: jest.fn(),
onRemoveColumn: jest.fn(),
};
// @ts-ignore
const component = mount(<DocViewTable {...props} />);
it('renders multifield rows', () => {
const categoryMultifieldRow = findTestSubject(

View file

@ -79,10 +79,10 @@ describe('timechart header', function () {
component = mountWithIntl(<TimechartHeader {...props} />);
const dropdown = findTestSubject(component, 'discoverIntervalSelect');
expect(dropdown.length).toBe(1);
// @ts-ignore
// @ts-expect-error
const values = dropdown.find('option').map((option) => option.prop('value'));
expect(values).toEqual(['auto', 'ms', 's']);
// @ts-ignore
// @ts-expect-error
const labels = dropdown.find('option').map((option) => option.text());
expect(labels).toEqual(['Auto', 'Millisecond', 'Second']);
});

View file

@ -32,6 +32,7 @@ export async function injectAngularElement(
if (typeof Controller === 'function') {
// when a controller is defined, expose the value it produces to the view as `$ctrl`
// see: https://docs.angularjs.org/api/ng/provider/$compileProvider#component
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(newScope as any).$ctrl = $injector.instantiate(Controller, {
$scope: newScope,
});

View file

@ -25,7 +25,8 @@ export class DocViewsRegistry {
const docView = typeof docViewRaw === 'function' ? docViewRaw() : docViewRaw;
if (docView.directive) {
// convert angular directive to render function for backwards compatibility
docView.render = convertDirectiveToRenderFn(docView.directive, () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(docView.render as any) = convertDirectiveToRenderFn(docView.directive as any, () => {
if (!this.angularInjectorGetter) {
throw new Error('Angular was not initialized');
}

View file

@ -12,7 +12,7 @@ import type { estypes } from '@elastic/elasticsearch';
import { IndexPattern } from '../../../../data/public';
export interface AngularDirective {
controller: (...injectedServices: any[]) => void;
controller: (...injectedServices: unknown[]) => void;
template: string;
}
@ -49,17 +49,34 @@ export type DocViewRenderFn = (
renderProps: DocViewRenderProps
) => () => void;
export interface DocViewInput {
component?: DocViewerComponent;
directive?: AngularDirective;
export interface BaseDocViewInput {
order: number;
render?: DocViewRenderFn;
shouldShow?: (hit: ElasticSearchHit) => boolean;
title: string;
}
export interface DocView extends DocViewInput {
shouldShow: (hit: ElasticSearchHit) => boolean;
export interface RenderDocViewInput extends BaseDocViewInput {
render: DocViewRenderFn;
component?: undefined;
directive?: undefined;
}
interface ComponentDocViewInput extends BaseDocViewInput {
component: DocViewerComponent;
render?: undefined;
directive?: undefined;
}
interface DirectiveDocViewInput extends BaseDocViewInput {
component?: undefined;
render?: undefined;
directive: ng.IDirective;
}
export type DocViewInput = ComponentDocViewInput | RenderDocViewInput | DirectiveDocViewInput;
export type DocView = DocViewInput & {
shouldShow: NonNullable<DocViewInput['shouldShow']>;
};
export type DocViewInputFn = () => DocViewInput;

View file

@ -21,6 +21,7 @@ export function getRootBreadcrumbs() {
];
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getSavedSearchBreadcrumbs($route: any) {
return [
...getRootBreadcrumbs(),

View file

@ -14,7 +14,7 @@ import { IndexPattern } from '../../kibana_services';
*/
export function calcFieldCounts(
counts = {} as Record<string, number>,
rows: Array<Record<string, any>>,
rows: Array<Record<string, unknown>>,
indexPattern: IndexPattern
) {
for (const hit of rows) {

View file

@ -16,7 +16,7 @@ import { Query } from 'src/plugins/data/public';
* @return Object
*/
export function migrateLegacyQuery(query: Query | { [key: string]: any } | string): Query {
export function migrateLegacyQuery(query: Query | { [key: string]: unknown } | string): Query {
// Lucene was the only option before, so language-less queries are all lucene
if (!has(query, 'language')) {
return { query, language: 'lucene' };

View file

@ -8,6 +8,7 @@
import { History } from 'history';
import type { auto } from 'angular';
import {
Capabilities,
ChromeStart,
@ -57,7 +58,7 @@ export interface DiscoverServices {
toastNotifications: ToastsStart;
getSavedSearchById: (id: string) => Promise<SavedSearch>;
getSavedSearchUrlById: (id: string) => Promise<string>;
getEmbeddableInjector: any;
getEmbeddableInjector: () => Promise<auto.IInjectorService>;
uiSettings: IUiSettingsClient;
trackUiMetric?: (metricType: UiCounterMetricType, eventName: string | string[]) => void;
indexPatternFieldEditor: IndexPatternFieldEditorStart;
@ -67,7 +68,7 @@ export async function buildServices(
core: CoreStart,
plugins: DiscoverStartPlugins,
context: PluginInitializerContext,
getEmbeddableInjector: any
getEmbeddableInjector: () => Promise<auto.IInjectorService>
): Promise<DiscoverServices> {
const services = {
savedObjectsClient: core.savedObjects.client,

View file

@ -150,7 +150,7 @@ function createLocalStorageModule() {
}
const createLocalStorageService = function (type: string) {
return function ($window: any) {
return function ($window: ng.IWindowService) {
return new Storage($window[type]);
};
};

View file

@ -15,21 +15,24 @@ import { createGetterSetter } from '../../kibana_utils/public';
import { search } from '../../data/public';
import { DocViewsRegistry } from './application/doc_views/doc_views_registry';
let angularModule: any = null;
let angularModule: ng.IModule | null = null;
let services: DiscoverServices | null = null;
let uiActions: UiActionsStart;
/**
* set bootstrapped inner angular module
*/
export function setAngularModule(module: any) {
export function setAngularModule(module: ng.IModule) {
angularModule = module;
}
/**
* get boostrapped inner angular module
*/
export function getAngularModule() {
export function getAngularModule(): ng.IModule {
if (!angularModule) {
throw new Error('Discover angular module not yet available');
}
return angularModule;
}
@ -40,7 +43,7 @@ export function getServices(): DiscoverServices {
return services;
}
export function setServices(newServices: any) {
export function setServices(newServices: DiscoverServices) {
services = newServices;
}

View file

@ -22,10 +22,10 @@ const createSetupContract = (): Setup => {
const createStartContract = (): Start => {
const startContract: Start = {
savedSearchLoader: {} as any,
urlGenerator: {
savedSearchLoader: {} as DiscoverStart['savedSearchLoader'],
urlGenerator: ({
createUrl: jest.fn(),
} as any,
} as unknown) as DiscoverStart['urlGenerator'],
};
return startContract;
};

View file

@ -164,7 +164,10 @@ export class DiscoverPlugin
public initializeInnerAngular?: () => void;
public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>;
setup(core: CoreSetup<DiscoverStartPlugins, DiscoverStart>, plugins: DiscoverSetupPlugins) {
setup(
core: CoreSetup<DiscoverStartPlugins, DiscoverStart>,
plugins: DiscoverSetupPlugins
): DiscoverSetup {
const baseUrl = core.http.basePath.prepend('/app/discover');
if (plugins.share) {
@ -190,7 +193,8 @@ export class DiscoverPlugin
defaultMessage: 'JSON',
}),
order: 20,
component: ({ hit }) => <JsonCodeEditor json={hit} hasLineNumbers />,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
component: ({ hit }) => <JsonCodeEditor json={hit as any} hasLineNumbers />,
});
const {

View file

@ -31,7 +31,7 @@ const setup = async ({ useHash = false }: SetupParams = {}) => {
};
beforeEach(() => {
// @ts-ignore
// @ts-expect-error
hashedItemStore.storage = mockStorage;
});

View file

@ -47,5 +47,5 @@ export const searchSavedObjectType: SavedObjectsType = {
version: { type: 'integer' },
},
},
migrations: searchMigrations as any,
migrations: searchMigrations,
};

View file

@ -6,6 +6,9 @@
* Side Public License, v 1.
*/
// TODO: This needs to be removed and properly typed
/* eslint-disable @typescript-eslint/no-explicit-any */
import { flow, get } from 'lodash';
import { SavedObjectMigrationFn } from 'kibana/server';
import { DEFAULT_QUERY_LANGUAGE } from '../../../data/common';