diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md
index 69cfb818561e5..7be45c6c173b4 100644
--- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md
+++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md
@@ -27,10 +27,10 @@ export interface SavedObjectsFindOptions
| [preference](./kibana-plugin-core-public.savedobjectsfindoptions.preference.md) | string | An optional ES preference value to be used for the query \* |
| [rootSearchFields](./kibana-plugin-core-public.savedobjectsfindoptions.rootsearchfields.md) | string[] | The fields to perform the parsed query against. Unlike the searchFields argument, these are expected to be root fields and will not be modified. If used in conjunction with searchFields, both are concatenated together. |
| [search](./kibana-plugin-core-public.savedobjectsfindoptions.search.md) | string | Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String query argument for more information |
-| [searchAfter](./kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md) | unknown[] | Use the sort values from the previous page to retrieve the next page of results. |
+| [searchAfter](./kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md) | estypes.Id[] | Use the sort values from the previous page to retrieve the next page of results. |
| [searchFields](./kibana-plugin-core-public.savedobjectsfindoptions.searchfields.md) | string[] | The fields to perform the parsed query against. See Elasticsearch Simple Query String fields argument for more information |
| [sortField](./kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md) | string | |
-| [sortOrder](./kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md) | string | |
+| [sortOrder](./kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md) | estypes.SortOrder | |
| [type](./kibana-plugin-core-public.savedobjectsfindoptions.type.md) | string | string[] | |
| [typeToNamespacesMap](./kibana-plugin-core-public.savedobjectsfindoptions.typetonamespacesmap.md) | Map<string, string[] | undefined> | This map defines each type to search for, and the namespace(s) to search for the type in; this is only intended to be used by a saved object client wrapper. If this is defined, it supersedes the type and namespaces fields when building the Elasticsearch query. Any types that are not included in this map will be excluded entirely. If a type is included but its value is undefined, the operation will search for that type in the Default namespace. |
diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md
index 99ca2c34e77be..7016e1f1b72de 100644
--- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md
+++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.searchafter.md
@@ -9,5 +9,5 @@ Use the sort values from the previous page to retrieve the next page of results.
Signature:
```typescript
-searchAfter?: unknown[];
+searchAfter?: estypes.Id[];
```
diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md
index 3834c802fa184..36f99e51ea8c6 100644
--- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md
+++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-sortOrder?: string;
+sortOrder?: estypes.SortOrder;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md
index 6f7c05ea469bc..a92b1f48d08eb 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md
@@ -27,10 +27,10 @@ export interface SavedObjectsFindOptions
| [preference](./kibana-plugin-core-server.savedobjectsfindoptions.preference.md) | string | An optional ES preference value to be used for the query \* |
| [rootSearchFields](./kibana-plugin-core-server.savedobjectsfindoptions.rootsearchfields.md) | string[] | The fields to perform the parsed query against. Unlike the searchFields argument, these are expected to be root fields and will not be modified. If used in conjunction with searchFields, both are concatenated together. |
| [search](./kibana-plugin-core-server.savedobjectsfindoptions.search.md) | string | Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String query argument for more information |
-| [searchAfter](./kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md) | unknown[] | Use the sort values from the previous page to retrieve the next page of results. |
+| [searchAfter](./kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md) | estypes.Id[] | Use the sort values from the previous page to retrieve the next page of results. |
| [searchFields](./kibana-plugin-core-server.savedobjectsfindoptions.searchfields.md) | string[] | The fields to perform the parsed query against. See Elasticsearch Simple Query String fields argument for more information |
| [sortField](./kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md) | string | |
-| [sortOrder](./kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md) | string | |
+| [sortOrder](./kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md) | estypes.SortOrder | |
| [type](./kibana-plugin-core-server.savedobjectsfindoptions.type.md) | string | string[] | |
| [typeToNamespacesMap](./kibana-plugin-core-server.savedobjectsfindoptions.typetonamespacesmap.md) | Map<string, string[] | undefined> | This map defines each type to search for, and the namespace(s) to search for the type in; this is only intended to be used by a saved object client wrapper. If this is defined, it supersedes the type and namespaces fields when building the Elasticsearch query. Any types that are not included in this map will be excluded entirely. If a type is included but its value is undefined, the operation will search for that type in the Default namespace. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md
index 6364370948976..9afd602259a78 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.searchafter.md
@@ -9,5 +9,5 @@ Use the sort values from the previous page to retrieve the next page of results.
Signature:
```typescript
-searchAfter?: unknown[];
+searchAfter?: estypes.Id[];
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md
index d247b9e38e448..e1c657e3a5171 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-sortOrder?: string;
+sortOrder?: estypes.SortOrder;
```
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.md
index 0f8e9c59236bb..a729ce32e1c80 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.md
@@ -16,5 +16,5 @@ export interface SavedObjectsFindResult extends SavedObject
| Property | Type | Description |
| --- | --- | --- |
| [score](./kibana-plugin-core-server.savedobjectsfindresult.score.md) | number | The Elasticsearch _score of this result. |
-| [sort](./kibana-plugin-core-server.savedobjectsfindresult.sort.md) | unknown[] | The Elasticsearch sort value of this result. |
+| [sort](./kibana-plugin-core-server.savedobjectsfindresult.sort.md) | string[] | The Elasticsearch sort value of this result. |
diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.sort.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.sort.md
index 17f5268724332..e73d6b4926d89 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.sort.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindresult.sort.md
@@ -9,7 +9,7 @@ The Elasticsearch `sort` value of this result.
Signature:
```typescript
-sort?: unknown[];
+sort?: string[];
```
## Remarks
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iessearchresponse.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iessearchresponse.md
index c8a372edbdb85..073b1d462986c 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iessearchresponse.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iessearchresponse.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-export declare type IEsSearchResponse = IKibanaSearchResponse>;
+export declare type IEsSearchResponse = IKibanaSearchResponse>;
```
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.fetch.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.fetch.md
index e96fe8b8e08dc..623d6366d4d13 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.fetch.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchsource.fetch.md
@@ -14,7 +14,7 @@ Fetch this source and reject the returned Promise on error
Signature:
```typescript
-fetch(options?: ISearchOptions): Promise>;
+fetch(options?: ISearchOptions): Promise>;
```
## Parameters
@@ -25,5 +25,5 @@ fetch(options?: ISearchOptions): PromiseReturns:
-`Promise>`
+`Promise>`
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iessearchresponse.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iessearchresponse.md
index d333af1b278c2..be208c0a51c81 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iessearchresponse.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.iessearchresponse.md
@@ -7,5 +7,5 @@
Signature:
```typescript
-export declare type IEsSearchResponse = IKibanaSearchResponse>;
+export declare type IEsSearchResponse = IKibanaSearchResponse>;
```
diff --git a/examples/search_examples/public/search/app.tsx b/examples/search_examples/public/search/app.tsx
index 8822be035a3d1..c87bf21e0e71c 100644
--- a/examples/search_examples/public/search/app.tsx
+++ b/examples/search_examples/public/search/app.tsx
@@ -145,7 +145,8 @@ export const SearchExamplesApp = ({
setResponse(res.rawResponse);
setTimeTook(res.rawResponse.took);
const avgResult: number | undefined = res.rawResponse.aggregations
- ? res.rawResponse.aggregations[1].value
+ ? // @ts-expect-error @elastic/elasticsearch no way to declare a type for aggregation in the search response
+ res.rawResponse.aggregations[1].value
: undefined;
const message = (
diff --git a/examples/search_examples/public/search_sessions/app.tsx b/examples/search_examples/public/search_sessions/app.tsx
index bf57964dc1f86..a768600db24ee 100644
--- a/examples/search_examples/public/search_sessions/app.tsx
+++ b/examples/search_examples/public/search_sessions/app.tsx
@@ -702,13 +702,15 @@ function doSearch(
const startTs = performance.now();
// Submit the search request using the `data.search` service.
+ // @ts-expect-error request.params is incompatible. Filter is not assignable to QueryContainer
return data.search
.search(req, { sessionId })
.pipe(
tap((res) => {
if (isCompleteResponse(res)) {
const avgResult: number | undefined = res.rawResponse.aggregations
- ? res.rawResponse.aggregations[1]?.value ?? res.rawResponse.aggregations[2]?.value
+ ? // @ts-expect-error @elastic/elasticsearch no way to declare a type for aggregation in the search response
+ res.rawResponse.aggregations[1]?.value ?? res.rawResponse.aggregations[2]?.value
: undefined;
const message = (
diff --git a/package.json b/package.json
index 7cb6a505eeafe..66a6ef1d4558b 100644
--- a/package.json
+++ b/package.json
@@ -96,7 +96,7 @@
},
"dependencies": {
"@elastic/datemath": "link:packages/elastic-datemath",
- "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.3",
+ "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.4",
"@elastic/ems-client": "7.12.0",
"@elastic/eui": "31.7.0",
"@elastic/filesaver": "1.1.2",
diff --git a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts
index 2c36e24453c62..dbc455bbd2f8f 100644
--- a/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts
+++ b/packages/kbn-es-archiver/src/actions/empty_kibana_index.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { KbnClient } from '@kbn/test';
@@ -17,7 +17,7 @@ export async function emptyKibanaIndexAction({
log,
kbnClient,
}: {
- client: Client;
+ client: KibanaClient;
log: ToolingLog;
kbnClient: KbnClient;
}) {
diff --git a/packages/kbn-es-archiver/src/actions/load.ts b/packages/kbn-es-archiver/src/actions/load.ts
index 68d5437336023..248c4a65cb20a 100644
--- a/packages/kbn-es-archiver/src/actions/load.ts
+++ b/packages/kbn-es-archiver/src/actions/load.ts
@@ -11,7 +11,7 @@ import { createReadStream } from 'fs';
import { Readable } from 'stream';
import { ToolingLog } from '@kbn/dev-utils';
import { KbnClient } from '@kbn/test';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { createPromiseFromStreams, concatStreamProviders } from '@kbn/utils';
import { ES_CLIENT_HEADERS } from '../client_headers';
@@ -48,7 +48,7 @@ export async function loadAction({
name: string;
skipExisting: boolean;
useCreate: boolean;
- client: Client;
+ client: KibanaClient;
dataDir: string;
log: ToolingLog;
kbnClient: KbnClient;
diff --git a/packages/kbn-es-archiver/src/actions/save.ts b/packages/kbn-es-archiver/src/actions/save.ts
index 3790e0f013ee0..c90f241a1c639 100644
--- a/packages/kbn-es-archiver/src/actions/save.ts
+++ b/packages/kbn-es-archiver/src/actions/save.ts
@@ -9,7 +9,7 @@
import { resolve } from 'path';
import { createWriteStream, mkdirSync } from 'fs';
import { Readable, Writable } from 'stream';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { createListStream, createPromiseFromStreams } from '@kbn/utils';
@@ -32,7 +32,7 @@ export async function saveAction({
}: {
name: string;
indices: string | string[];
- client: Client;
+ client: KibanaClient;
dataDir: string;
log: ToolingLog;
raw: boolean;
diff --git a/packages/kbn-es-archiver/src/actions/unload.ts b/packages/kbn-es-archiver/src/actions/unload.ts
index b5f259a1496bb..f4e37871a5337 100644
--- a/packages/kbn-es-archiver/src/actions/unload.ts
+++ b/packages/kbn-es-archiver/src/actions/unload.ts
@@ -9,7 +9,7 @@
import { resolve } from 'path';
import { createReadStream } from 'fs';
import { Readable, Writable } from 'stream';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { KbnClient } from '@kbn/test';
import { createPromiseFromStreams } from '@kbn/utils';
@@ -32,7 +32,7 @@ export async function unloadAction({
kbnClient,
}: {
name: string;
- client: Client;
+ client: KibanaClient;
dataDir: string;
log: ToolingLog;
kbnClient: KbnClient;
diff --git a/packages/kbn-es-archiver/src/client_headers.ts b/packages/kbn-es-archiver/src/client_headers.ts
index da240c3ad8318..5733eb9b97543 100644
--- a/packages/kbn-es-archiver/src/client_headers.ts
+++ b/packages/kbn-es-archiver/src/client_headers.ts
@@ -8,4 +8,4 @@
export const ES_CLIENT_HEADERS = {
'x-elastic-product-origin': 'kibana',
-};
+} as const;
diff --git a/packages/kbn-es-archiver/src/es_archiver.ts b/packages/kbn-es-archiver/src/es_archiver.ts
index 68eacb4f3caf2..93ce97efd4c84 100644
--- a/packages/kbn-es-archiver/src/es_archiver.ts
+++ b/packages/kbn-es-archiver/src/es_archiver.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { KbnClient } from '@kbn/test';
@@ -20,14 +20,14 @@ import {
} from './actions';
interface Options {
- client: Client;
+ client: KibanaClient;
dataDir: string;
log: ToolingLog;
kbnClient: KbnClient;
}
export class EsArchiver {
- private readonly client: Client;
+ private readonly client: KibanaClient;
private readonly dataDir: string;
private readonly log: ToolingLog;
private readonly kbnClient: KbnClient;
diff --git a/packages/kbn-es-archiver/src/lib/docs/generate_doc_records_stream.ts b/packages/kbn-es-archiver/src/lib/docs/generate_doc_records_stream.ts
index cacd224e71421..88e167b3705cb 100644
--- a/packages/kbn-es-archiver/src/lib/docs/generate_doc_records_stream.ts
+++ b/packages/kbn-es-archiver/src/lib/docs/generate_doc_records_stream.ts
@@ -7,7 +7,7 @@
*/
import { Transform } from 'stream';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { Stats } from '../stats';
import { Progress } from '../progress';
import { ES_CLIENT_HEADERS } from '../../client_headers';
@@ -21,7 +21,7 @@ export function createGenerateDocRecordsStream({
progress,
query,
}: {
- client: Client;
+ client: KibanaClient;
stats: Stats;
progress: Progress;
query?: Record;
diff --git a/packages/kbn-es-archiver/src/lib/docs/index_doc_records_stream.ts b/packages/kbn-es-archiver/src/lib/docs/index_doc_records_stream.ts
index e105a243cae76..028ff16c9afb2 100644
--- a/packages/kbn-es-archiver/src/lib/docs/index_doc_records_stream.ts
+++ b/packages/kbn-es-archiver/src/lib/docs/index_doc_records_stream.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import AggregateError from 'aggregate-error';
import { Writable } from 'stream';
import { Stats } from '../stats';
@@ -14,7 +14,7 @@ import { Progress } from '../progress';
import { ES_CLIENT_HEADERS } from '../../client_headers';
export function createIndexDocRecordsStream(
- client: Client,
+ client: KibanaClient,
stats: Stats,
progress: Progress,
useCreate: boolean = false
diff --git a/packages/kbn-es-archiver/src/lib/indices/__mocks__/stubs.ts b/packages/kbn-es-archiver/src/lib/indices/__mocks__/stubs.ts
index 59101f5490016..7dde4075dc3f2 100644
--- a/packages/kbn-es-archiver/src/lib/indices/__mocks__/stubs.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/__mocks__/stubs.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import sinon from 'sinon';
import { ToolingLog } from '@kbn/dev-utils';
import { Stats } from '../../stats';
@@ -67,7 +67,7 @@ const createEsClientError = (errorType: string) => {
const indexAlias = (aliases: Record, index: string) =>
Object.keys(aliases).find((k) => aliases[k] === index);
-type StubClient = Client;
+type StubClient = KibanaClient;
export const createStubClient = (
existingIndices: string[] = [],
diff --git a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.test.ts b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.test.ts
index 39e00ff0c72c0..28c8ccd1c28a8 100644
--- a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.test.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.test.ts
@@ -125,7 +125,6 @@ describe('esArchiver: createCreateIndexStream()', () => {
]);
sinon.assert.calledWith(client.indices.create as sinon.SinonSpy, {
- method: 'PUT',
index: 'index',
body: {
settings: undefined,
diff --git a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts
index ca89278305813..b45a8b18a5776 100644
--- a/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/create_index_stream.ts
@@ -9,7 +9,8 @@
import { Transform, Readable } from 'stream';
import { inspect } from 'util';
-import { Client } from '@elastic/elasticsearch';
+import { estypes } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { Stats } from '../stats';
@@ -18,12 +19,9 @@ import { deleteIndex } from './delete_index';
import { ES_CLIENT_HEADERS } from '../../client_headers';
interface DocRecord {
- value: {
+ value: estypes.IndexState & {
index: string;
type: string;
- settings: Record;
- mappings: Record;
- aliases: Record;
};
}
@@ -33,7 +31,7 @@ export function createCreateIndexStream({
skipExisting = false,
log,
}: {
- client: Client;
+ client: KibanaClient;
stats: Stats;
skipExisting?: boolean;
log: ToolingLog;
@@ -66,7 +64,6 @@ export function createCreateIndexStream({
await client.indices.create(
{
- method: 'PUT',
index,
body: {
settings,
diff --git a/packages/kbn-es-archiver/src/lib/indices/delete_index.ts b/packages/kbn-es-archiver/src/lib/indices/delete_index.ts
index b5641eec4b9da..2a42d52e2ca80 100644
--- a/packages/kbn-es-archiver/src/lib/indices/delete_index.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/delete_index.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { Stats } from '../stats';
import { ES_CLIENT_HEADERS } from '../../client_headers';
@@ -15,7 +15,7 @@ import { ES_CLIENT_HEADERS } from '../../client_headers';
const PENDING_SNAPSHOT_STATUSES = ['INIT', 'STARTED', 'WAITING'];
export async function deleteIndex(options: {
- client: Client;
+ client: KibanaClient;
stats: Stats;
index: string | string[];
log: ToolingLog;
@@ -84,7 +84,7 @@ export function isDeleteWhileSnapshotInProgressError(error: any) {
* snapshotting this index to complete.
*/
export async function waitForSnapshotCompletion(
- client: Client,
+ client: KibanaClient,
index: string | string[],
log: ToolingLog
) {
diff --git a/packages/kbn-es-archiver/src/lib/indices/delete_index_stream.ts b/packages/kbn-es-archiver/src/lib/indices/delete_index_stream.ts
index db065274a7b3b..e1552b5ed1e3b 100644
--- a/packages/kbn-es-archiver/src/lib/indices/delete_index_stream.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/delete_index_stream.ts
@@ -7,7 +7,7 @@
*/
import { Transform } from 'stream';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { Stats } from '../stats';
@@ -15,7 +15,7 @@ import { deleteIndex } from './delete_index';
import { cleanKibanaIndices } from './kibana_index';
export function createDeleteIndexStream(
- client: Client,
+ client: KibanaClient,
stats: Stats,
log: ToolingLog,
kibanaPluginIds: string[]
diff --git a/packages/kbn-es-archiver/src/lib/indices/generate_index_records_stream.ts b/packages/kbn-es-archiver/src/lib/indices/generate_index_records_stream.ts
index 4e0319c52264f..6619f1b3a601e 100644
--- a/packages/kbn-es-archiver/src/lib/indices/generate_index_records_stream.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/generate_index_records_stream.ts
@@ -7,11 +7,11 @@
*/
import { Transform } from 'stream';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { Stats } from '../stats';
import { ES_CLIENT_HEADERS } from '../../client_headers';
-export function createGenerateIndexRecordsStream(client: Client, stats: Stats) {
+export function createGenerateIndexRecordsStream(client: KibanaClient, stats: Stats) {
return new Transform({
writableObjectMode: true,
readableObjectMode: true,
diff --git a/packages/kbn-es-archiver/src/lib/indices/kibana_index.ts b/packages/kbn-es-archiver/src/lib/indices/kibana_index.ts
index dc49085cbd458..fbef255cd9ee5 100644
--- a/packages/kbn-es-archiver/src/lib/indices/kibana_index.ts
+++ b/packages/kbn-es-archiver/src/lib/indices/kibana_index.ts
@@ -8,7 +8,7 @@
import { inspect } from 'util';
-import { Client } from '@elastic/elasticsearch';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { ToolingLog } from '@kbn/dev-utils';
import { KbnClient } from '@kbn/test';
import { Stats } from '../stats';
@@ -23,7 +23,7 @@ export async function deleteKibanaIndices({
stats,
log,
}: {
- client: Client;
+ client: KibanaClient;
stats: Stats;
log: ToolingLog;
}) {
@@ -67,22 +67,27 @@ export async function migrateKibanaIndex(kbnClient: KbnClient) {
* with .kibana, then filters out any that aren't actually Kibana's core
* index (e.g. we don't want to remove .kibana_task_manager or the like).
*/
-async function fetchKibanaIndices(client: Client) {
- const resp = await client.cat.indices(
+function isKibanaIndex(index?: string): index is string {
+ return Boolean(
+ index &&
+ (/^\.kibana(:?_\d*)?$/.test(index) ||
+ /^\.kibana(_task_manager)?_(pre)?\d+\.\d+\.\d+/.test(index))
+ );
+}
+
+async function fetchKibanaIndices(client: KibanaClient) {
+ const resp = await client.cat.indices(
{ index: '.kibana*', format: 'json' },
{
headers: ES_CLIENT_HEADERS,
}
);
- const isKibanaIndex = (index: string) =>
- /^\.kibana(:?_\d*)?$/.test(index) ||
- /^\.kibana(_task_manager)?_(pre)?\d+\.\d+\.\d+/.test(index);
if (!Array.isArray(resp.body)) {
throw new Error(`expected response to be an array ${inspect(resp.body)}`);
}
- return resp.body.map((x: { index: string }) => x.index).filter(isKibanaIndex);
+ return resp.body.map((x: { index?: string }) => x.index).filter(isKibanaIndex);
}
const delay = (delayInMs: number) => new Promise((resolve) => setTimeout(resolve, delayInMs));
@@ -93,7 +98,7 @@ export async function cleanKibanaIndices({
log,
kibanaPluginIds,
}: {
- client: Client;
+ client: KibanaClient;
stats: Stats;
log: ToolingLog;
kibanaPluginIds: string[];
@@ -149,7 +154,13 @@ export async function cleanKibanaIndices({
stats.deletedIndex('.kibana');
}
-export async function createDefaultSpace({ index, client }: { index: string; client: Client }) {
+export async function createDefaultSpace({
+ index,
+ client,
+}: {
+ index: string;
+ client: KibanaClient;
+}) {
await client.create(
{
index,
diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md
index 396bf16cbdc6f..5c034e68a3736 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -11,6 +11,7 @@ import { ConfigDeprecationProvider } from '@kbn/config';
import { ConfigPath } from '@kbn/config';
import { DetailedPeerCertificate } from 'tls';
import { EnvironmentMode } from '@kbn/config';
+import { estypes } from '@elastic/elasticsearch';
import { EuiBreadcrumb } from '@elastic/eui';
import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui';
@@ -1225,12 +1226,12 @@ export interface SavedObjectsFindOptions {
preference?: string;
rootSearchFields?: string[];
search?: string;
- searchAfter?: unknown[];
+ searchAfter?: estypes.Id[];
searchFields?: string[];
// (undocumented)
sortField?: string;
// (undocumented)
- sortOrder?: string;
+ sortOrder?: estypes.SortOrder;
// (undocumented)
type: string | string[];
typeToNamespacesMap?: Map;
diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts
index dfd0a9efc90c1..1c28eca1f1dec 100644
--- a/src/core/server/core_usage_data/core_usage_data_service.test.ts
+++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts
@@ -120,10 +120,10 @@ describe('CoreUsageDataService', () => {
body: [
{
name: '.kibana_task_manager_1',
- 'docs.count': 10,
- 'docs.deleted': 10,
- 'store.size': 1000,
- 'pri.store.size': 2000,
+ 'docs.count': '10',
+ 'docs.deleted': '10',
+ 'store.size': '1000',
+ 'pri.store.size': '2000',
},
],
} as any);
@@ -131,10 +131,10 @@ describe('CoreUsageDataService', () => {
body: [
{
name: '.kibana_1',
- 'docs.count': 20,
- 'docs.deleted': 20,
- 'store.size': 2000,
- 'pri.store.size': 4000,
+ 'docs.count': '20',
+ 'docs.deleted': '20',
+ 'store.size': '2000',
+ 'pri.store.size': '4000',
},
],
} as any);
diff --git a/src/core/server/core_usage_data/core_usage_data_service.ts b/src/core/server/core_usage_data/core_usage_data_service.ts
index b9d8c9fc7e39f..dff68bf1c524f 100644
--- a/src/core/server/core_usage_data/core_usage_data_service.ts
+++ b/src/core/server/core_usage_data/core_usage_data_service.ts
@@ -118,10 +118,14 @@ export class CoreUsageDataService implements CoreService;
};
-function createApiResponse(opts: Partial = {}): ApiResponse {
+function createApiResponse>(
+ opts: Partial> = {}
+): ApiResponse {
return {
- body: {},
+ body: {} as any,
statusCode: 200,
headers: {},
warnings: [],
diff --git a/src/core/server/elasticsearch/client/retry_call_cluster.test.ts b/src/core/server/elasticsearch/client/retry_call_cluster.test.ts
index 7b442469838f6..636841316941b 100644
--- a/src/core/server/elasticsearch/client/retry_call_cluster.test.ts
+++ b/src/core/server/elasticsearch/client/retry_call_cluster.test.ts
@@ -11,7 +11,7 @@ import { elasticsearchClientMock } from './mocks';
import { loggingSystemMock } from '../../logging/logging_system.mock';
import { retryCallCluster, migrationRetryCallCluster } from './retry_call_cluster';
-const dummyBody = { foo: 'bar' };
+const dummyBody: any = { foo: 'bar' };
const createErrorReturn = (err: any) =>
elasticsearchClientMock.createErrorTransportRequestPromise(err);
@@ -29,7 +29,7 @@ describe('retryCallCluster', () => {
client.asyncSearch.get.mockReturnValue(successReturn);
- const result = await retryCallCluster(() => client.asyncSearch.get());
+ const result = await retryCallCluster(() => client.asyncSearch.get({} as any));
expect(result.body).toEqual(dummyBody);
});
@@ -44,7 +44,7 @@ describe('retryCallCluster', () => {
)
.mockImplementationOnce(() => successReturn);
- const result = await retryCallCluster(() => client.asyncSearch.get());
+ const result = await retryCallCluster(() => client.asyncSearch.get({} as any));
expect(result.body).toEqual(dummyBody);
});
diff --git a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts
index 22dcc8022858c..468a761781365 100644
--- a/src/core/server/saved_objects/export/saved_objects_exporter.test.ts
+++ b/src/core/server/saved_objects/export/saved_objects_exporter.test.ts
@@ -117,6 +117,7 @@ describe('getSortedObjectsForExport()', () => {
"keepAlive": "2m",
},
"search": undefined,
+ "searchAfter": undefined,
"sortField": "updated_at",
"sortOrder": "desc",
"type": Array [
@@ -145,7 +146,7 @@ describe('getSortedObjectsForExport()', () => {
type = 'index-pattern',
}: {
attributes?: Record;
- sort?: unknown[];
+ sort?: string[];
type?: string;
} = {}
) {
@@ -461,6 +462,7 @@ describe('getSortedObjectsForExport()', () => {
"keepAlive": "2m",
},
"search": undefined,
+ "searchAfter": undefined,
"sortField": "updated_at",
"sortOrder": "desc",
"type": Array [
@@ -617,6 +619,7 @@ describe('getSortedObjectsForExport()', () => {
"keepAlive": "2m",
},
"search": "foo",
+ "searchAfter": undefined,
"sortField": "updated_at",
"sortOrder": "desc",
"type": Array [
@@ -710,6 +713,7 @@ describe('getSortedObjectsForExport()', () => {
"keepAlive": "2m",
},
"search": undefined,
+ "searchAfter": undefined,
"sortField": "updated_at",
"sortOrder": "desc",
"type": Array [
@@ -808,6 +812,7 @@ describe('getSortedObjectsForExport()', () => {
"keepAlive": "2m",
},
"search": undefined,
+ "searchAfter": undefined,
"sortField": "updated_at",
"sortOrder": "desc",
"type": Array [
diff --git a/src/core/server/saved_objects/import/lib/check_origin_conflicts.ts b/src/core/server/saved_objects/import/lib/check_origin_conflicts.ts
index d35388ff94749..1952a04ab815c 100644
--- a/src/core/server/saved_objects/import/lib/check_origin_conflicts.ts
+++ b/src/core/server/saved_objects/import/lib/check_origin_conflicts.ts
@@ -95,7 +95,7 @@ const checkOriginConflict = async (
perPage: 10,
fields: ['title'],
sortField: 'updated_at',
- sortOrder: 'desc',
+ sortOrder: 'desc' as const,
...(namespace && { namespaces: [namespace] }),
};
const findResult = await savedObjectsClient.find<{ title?: string }>(findOptions);
diff --git a/src/core/server/saved_objects/mappings/types.ts b/src/core/server/saved_objects/mappings/types.ts
index fa7531392d122..25fb61de93518 100644
--- a/src/core/server/saved_objects/mappings/types.ts
+++ b/src/core/server/saved_objects/mappings/types.ts
@@ -102,7 +102,7 @@ export type SavedObjectsFieldMapping =
/** @internal */
export interface IndexMapping {
- dynamic?: string;
+ dynamic?: boolean | 'strict';
properties: SavedObjectsMappingProperties;
_meta?: IndexMappingMeta;
}
diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
index 63634bdb1754e..5465da2f620ad 100644
--- a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
+++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
@@ -164,6 +164,7 @@ describe('diffMappings', () => {
_meta: {
migrationMappingPropertyHashes: { foo: 'bar' },
},
+ // @ts-expect-error
dynamic: 'abcde',
properties: {},
};
diff --git a/src/core/server/saved_objects/migrations/core/call_cluster.ts b/src/core/server/saved_objects/migrations/core/call_cluster.ts
index bbf39549457d8..f37bbdd14a899 100644
--- a/src/core/server/saved_objects/migrations/core/call_cluster.ts
+++ b/src/core/server/saved_objects/migrations/core/call_cluster.ts
@@ -12,11 +12,12 @@
* funcationality contained here.
*/
+import type { estypes } from '@elastic/elasticsearch';
import { IndexMapping } from '../../mappings';
export interface CallCluster {
(path: 'bulk', opts: { body: object[] }): Promise;
- (path: 'count', opts: CountOpts): Promise<{ count: number; _shards: ShardsInfo }>;
+ (path: 'count', opts: CountOpts): Promise<{ count: number; _shards: estypes.ShardStatistics }>;
(path: 'clearScroll', opts: { scrollId: string }): Promise;
(path: 'indices.create', opts: IndexCreationOpts): Promise;
(path: 'indices.exists', opts: IndexOpts): Promise;
@@ -143,7 +144,7 @@ export interface IndexSettingsResult {
}
export interface RawDoc {
- _id: string;
+ _id: estypes.Id;
_source: any;
_type?: string;
}
@@ -153,14 +154,7 @@ export interface SearchResults {
hits: RawDoc[];
};
_scroll_id?: string;
- _shards: ShardsInfo;
-}
-
-export interface ShardsInfo {
- total: number;
- successful: number;
- skipped: number;
- failed: number;
+ _shards: estypes.ShardStatistics;
}
export interface ErrorResponse {
diff --git a/src/core/server/saved_objects/migrations/core/elastic_index.test.ts b/src/core/server/saved_objects/migrations/core/elastic_index.test.ts
index bfa686ac0cc47..5cb2a88c4733f 100644
--- a/src/core/server/saved_objects/migrations/core/elastic_index.test.ts
+++ b/src/core/server/saved_objects/migrations/core/elastic_index.test.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import type { estypes } from '@elastic/elasticsearch';
import _ from 'lodash';
import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks';
import * as Index from './elastic_index';
@@ -33,41 +34,6 @@ describe('ElasticIndex', () => {
expect(client.indices.get).toHaveBeenCalledWith({ index: '.kibana-test' }, { ignore: [404] });
});
- test('fails if the index doc type is unsupported', async () => {
- client.indices.get.mockImplementation((params) => {
- const index = params!.index as string;
- return elasticsearchClientMock.createSuccessTransportRequestPromise({
- [index]: {
- aliases: { foo: index },
- mappings: { spock: { dynamic: 'strict', properties: { a: 'b' } } },
- },
- });
- });
-
- await expect(Index.fetchInfo(client, '.baz')).rejects.toThrow(
- /cannot be automatically migrated/
- );
- });
-
- test('fails if there are multiple root types', async () => {
- client.indices.get.mockImplementation((params) => {
- const index = params!.index as string;
- return elasticsearchClientMock.createSuccessTransportRequestPromise({
- [index]: {
- aliases: { foo: index },
- mappings: {
- doc: { dynamic: 'strict', properties: { a: 'b' } },
- doctor: { dynamic: 'strict', properties: { a: 'b' } },
- },
- },
- });
- });
-
- await expect(Index.fetchInfo(client, '.baz')).rejects.toThrow(
- /cannot be automatically migrated/
- );
- });
-
test('decorates index info with exists and indexName', async () => {
client.indices.get.mockImplementation((params) => {
const index = params!.index as string;
@@ -75,8 +41,9 @@ describe('ElasticIndex', () => {
[index]: {
aliases: { foo: index },
mappings: { dynamic: 'strict', properties: { a: 'b' } },
+ settings: {},
},
- });
+ } as estypes.GetIndexResponse);
});
const info = await Index.fetchInfo(client, '.baz');
@@ -85,6 +52,7 @@ describe('ElasticIndex', () => {
mappings: { dynamic: 'strict', properties: { a: 'b' } },
exists: true,
indexName: '.baz',
+ settings: {},
});
});
});
@@ -134,7 +102,7 @@ describe('ElasticIndex', () => {
test('removes existing alias', async () => {
client.indices.getAlias.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
- '.my-fanci-index': '.muchacha',
+ '.my-fanci-index': { aliases: { '.muchacha': {} } },
})
);
@@ -157,7 +125,7 @@ describe('ElasticIndex', () => {
test('allows custom alias actions', async () => {
client.indices.getAlias.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
- '.my-fanci-index': '.muchacha',
+ '.my-fanci-index': { aliases: { '.muchacha': {} } },
})
);
@@ -185,14 +153,18 @@ describe('ElasticIndex', () => {
test('it creates the destination index, then reindexes to it', async () => {
client.indices.getAlias.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
- '.my-fanci-index': '.muchacha',
+ '.my-fanci-index': { aliases: { '.muchacha': {} } },
})
);
client.reindex.mockResolvedValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ task: 'abc',
+ } as estypes.ReindexResponse)
);
client.tasks.get.mockResolvedValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ completed: true })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ completed: true,
+ } as estypes.GetTaskResponse)
);
const info = {
@@ -200,7 +172,7 @@ describe('ElasticIndex', () => {
exists: true,
indexName: '.ze-index',
mappings: {
- dynamic: 'strict',
+ dynamic: 'strict' as const,
properties: { foo: { type: 'keyword' } },
},
};
@@ -259,13 +231,16 @@ describe('ElasticIndex', () => {
test('throws error if re-index task fails', async () => {
client.indices.getAlias.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
- '.my-fanci-index': '.muchacha',
+ '.my-fanci-index': { aliases: { '.muchacha': {} } },
})
);
client.reindex.mockResolvedValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ task: 'abc' })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ task: 'abc',
+ } as estypes.ReindexResponse)
);
client.tasks.get.mockResolvedValue(
+ // @ts-expect-error @elastic/elasticsearch GetTaskResponse requires a `task` property even on errors
elasticsearchClientMock.createSuccessTransportRequestPromise({
completed: true,
error: {
@@ -273,7 +248,7 @@ describe('ElasticIndex', () => {
reason: 'all shards failed',
failed_shards: [],
},
- })
+ } as estypes.GetTaskResponse)
);
const info = {
@@ -286,6 +261,7 @@ describe('ElasticIndex', () => {
},
};
+ // @ts-expect-error
await expect(Index.convertToAlias(client, info, '.muchacha', 10)).rejects.toThrow(
/Re-index failed \[search_phase_execution_exception\] all shards failed/
);
@@ -319,7 +295,9 @@ describe('ElasticIndex', () => {
describe('write', () => {
test('writes documents in bulk to the index', async () => {
client.bulk.mockResolvedValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ items: [] })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ items: [] as any[],
+ } as estypes.BulkResponse)
);
const index = '.myalias';
@@ -356,7 +334,7 @@ describe('ElasticIndex', () => {
client.bulk.mockResolvedValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
items: [{ index: { error: { type: 'shazm', reason: 'dern' } } }],
- })
+ } as estypes.BulkResponse)
);
const index = '.myalias';
diff --git a/src/core/server/saved_objects/migrations/core/elastic_index.ts b/src/core/server/saved_objects/migrations/core/elastic_index.ts
index e42643565eb4f..a5f3cb36e736b 100644
--- a/src/core/server/saved_objects/migrations/core/elastic_index.ts
+++ b/src/core/server/saved_objects/migrations/core/elastic_index.ts
@@ -12,11 +12,12 @@
*/
import _ from 'lodash';
+import { estypes } from '@elastic/elasticsearch';
import { MigrationEsClient } from './migration_es_client';
import { CountResponse, SearchResponse } from '../../../elasticsearch';
import { IndexMapping } from '../../mappings';
import { SavedObjectsMigrationVersion } from '../../types';
-import { AliasAction, RawDoc, ShardsInfo } from './call_cluster';
+import { AliasAction, RawDoc } from './call_cluster';
import { SavedObjectsRawDocSource } from '../../serialization';
const settings = { number_of_shards: 1, auto_expand_replicas: '0-1' };
@@ -46,6 +47,7 @@ export async function fetchInfo(client: MigrationEsClient, index: string): Promi
const [indexName, indexInfo] = Object.entries(body)[0];
+ // @ts-expect-error @elastic/elasticsearch IndexState.alias and IndexState.mappings should be required
return assertIsSupportedIndex({ ...indexInfo, exists: true, indexName });
}
@@ -142,7 +144,7 @@ export async function write(client: MigrationEsClient, index: string, docs: RawD
return;
}
- const exception: any = new Error(err.index.error!.reason);
+ const exception: any = new Error(err.index!.error!.reason);
exception.detail = err;
throw exception;
}
@@ -322,7 +324,7 @@ function assertIsSupportedIndex(indexInfo: FullIndexInfo) {
* Object indices should only ever have a single shard. This is more to handle
* instances where customers manually expand the shards of an index.
*/
-function assertResponseIncludeAllShards({ _shards }: { _shards: ShardsInfo }) {
+function assertResponseIncludeAllShards({ _shards }: { _shards: estypes.ShardStatistics }) {
if (!_.has(_shards, 'total') || !_.has(_shards, 'successful')) {
return;
}
@@ -375,11 +377,12 @@ async function reindex(
await new Promise((r) => setTimeout(r, pollInterval));
const { body } = await client.tasks.get({
- task_id: task,
+ task_id: String(task),
});
- if (body.error) {
- const e = body.error;
+ // @ts-expect-error @elastic/elasticsearch GetTaskResponse doesn't contain `error` property
+ const e = body.error;
+ if (e) {
throw new Error(`Re-index failed [${e.type}] ${e.reason} :: ${JSON.stringify(e)}`);
}
diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts
index 0d1939231ce6c..dd295efacf6b8 100644
--- a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts
+++ b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts
@@ -7,6 +7,7 @@
*/
import _ from 'lodash';
+import type { estypes } from '@elastic/elasticsearch';
import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks';
import { SavedObjectUnsanitizedDoc, SavedObjectsSerializer } from '../../serialization';
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
@@ -443,23 +444,28 @@ function withIndex(
elasticsearchClientMock.createSuccessTransportRequestPromise({
task: 'zeid',
_shards: { successful: 1, total: 1 },
- })
+ } as estypes.ReindexResponse)
);
client.tasks.get.mockReturnValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ completed: true })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ completed: true,
+ } as estypes.GetTaskResponse)
);
client.search.mockReturnValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise(searchResult(0))
+ elasticsearchClientMock.createSuccessTransportRequestPromise(searchResult(0) as any)
);
client.bulk.mockReturnValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ items: [] })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ items: [] as any[],
+ } as estypes.BulkResponse)
);
client.count.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
count: numOutOfDate,
_shards: { successful: 1, total: 1 },
- })
+ } as estypes.CountResponse)
);
+ // @ts-expect-error
client.scroll.mockImplementation(() => {
if (scrollCallCounter <= docs.length) {
const result = searchResult(scrollCallCounter);
diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.ts b/src/core/server/saved_objects/migrations/core/index_migrator.ts
index 52f155e5d2de2..5bf5ae26f6a0a 100644
--- a/src/core/server/saved_objects/migrations/core/index_migrator.ts
+++ b/src/core/server/saved_objects/migrations/core/index_migrator.ts
@@ -134,7 +134,7 @@ async function deleteIndexTemplates({ client, log, obsoleteIndexTemplatePattern
return;
}
- const { body: templates } = await client.cat.templates>({
+ const { body: templates } = await client.cat.templates({
format: 'json',
name: obsoleteIndexTemplatePattern,
});
@@ -147,7 +147,7 @@ async function deleteIndexTemplates({ client, log, obsoleteIndexTemplatePattern
log.info(`Removing index templates: ${templateNames}`);
- return Promise.all(templateNames.map((name) => client.indices.deleteTemplate({ name })));
+ return Promise.all(templateNames.map((name) => client.indices.deleteTemplate({ name: name! })));
}
/**
@@ -185,7 +185,13 @@ async function migrateSourceToDest(context: Context) {
await Index.write(
client,
dest.indexName,
- await migrateRawDocs(serializer, documentMigrator.migrateAndConvert, docs, log)
+ await migrateRawDocs(
+ serializer,
+ documentMigrator.migrateAndConvert,
+ // @ts-expect-error @elastic/elasticsearch `Hit._id` may be a string | number in ES, but we always expect strings in the SO index.
+ docs,
+ log
+ )
);
}
}
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
index b8accc462df9a..7ead37699980a 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
@@ -7,13 +7,13 @@
*/
import { take } from 'rxjs/operators';
+import { estypes, errors as esErrors } from '@elastic/elasticsearch';
import { elasticsearchClientMock } from '../../../elasticsearch/client/mocks';
import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator';
import { loggingSystemMock } from '../../../logging/logging_system.mock';
import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry';
import { SavedObjectsType } from '../../types';
-import { errors as esErrors } from '@elastic/elasticsearch';
import { DocumentMigrator } from '../core/document_migrator';
jest.mock('../core/document_migrator', () => {
return {
@@ -105,10 +105,7 @@ describe('KibanaMigrator', () => {
const options = mockOptions();
options.client.cat.templates.mockReturnValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise(
- { templates: [] },
- { statusCode: 404 }
- )
+ elasticsearchClientMock.createSuccessTransportRequestPromise([], { statusCode: 404 })
);
options.client.indices.get.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 })
@@ -129,7 +126,8 @@ describe('KibanaMigrator', () => {
options.client.cat.templates.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise(
- { templates: [] },
+ // @ts-expect-error
+ { templates: [] } as CatTemplatesResponse,
{ statusCode: 404 }
)
);
@@ -155,7 +153,8 @@ describe('KibanaMigrator', () => {
options.client.cat.templates.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise(
- { templates: [] },
+ // @ts-expect-error
+ { templates: [] } as CatTemplatesResponse,
{ statusCode: 404 }
)
);
@@ -193,7 +192,8 @@ describe('KibanaMigrator', () => {
options.client.cat.templates.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise(
- { templates: [] },
+ // @ts-expect-error
+ { templates: [] } as CatTemplatesResponse,
{ statusCode: 404 }
)
);
@@ -323,7 +323,7 @@ describe('KibanaMigrator', () => {
completed: true,
error: { type: 'elatsicsearch_exception', reason: 'task failed with an error' },
failures: [],
- task: { description: 'task description' },
+ task: { description: 'task description' } as any,
})
);
@@ -365,15 +365,17 @@ const mockV2MigrationOptions = () => {
elasticsearchClientMock.createSuccessTransportRequestPromise({ acknowledged: true })
);
options.client.reindex.mockReturnValue(
- elasticsearchClientMock.createSuccessTransportRequestPromise({ taskId: 'reindex_task_id' })
+ elasticsearchClientMock.createSuccessTransportRequestPromise({
+ taskId: 'reindex_task_id',
+ } as estypes.ReindexResponse)
);
options.client.tasks.get.mockReturnValue(
elasticsearchClientMock.createSuccessTransportRequestPromise({
completed: true,
error: undefined,
failures: [],
- task: { description: 'task description' },
- })
+ task: { description: 'task description' } as any,
+ } as estypes.GetTaskResponse)
);
return options;
diff --git a/src/core/server/saved_objects/migrationsv2/actions/index.ts b/src/core/server/saved_objects/migrationsv2/actions/index.ts
index d025f104c6e3f..22dfb03815052 100644
--- a/src/core/server/saved_objects/migrationsv2/actions/index.ts
+++ b/src/core/server/saved_objects/migrationsv2/actions/index.ts
@@ -13,9 +13,10 @@ import { ElasticsearchClientError } from '@elastic/elasticsearch/lib/errors';
import { pipe } from 'fp-ts/lib/pipeable';
import { errors as EsErrors } from '@elastic/elasticsearch';
import { flow } from 'fp-ts/lib/function';
+import type { estypes } from '@elastic/elasticsearch';
import { ElasticsearchClient } from '../../../elasticsearch';
import { IndexMapping } from '../../mappings';
-import { SavedObjectsRawDoc } from '../../serialization';
+import { SavedObjectsRawDoc, SavedObjectsRawDocSource } from '../../serialization';
import {
catchRetryableEsClientErrors,
RetryableEsClientError,
@@ -56,20 +57,22 @@ export type FetchIndexResponse = Record<
export const fetchIndices = (
client: ElasticsearchClient,
indicesToFetch: string[]
-): TaskEither.TaskEither => () => {
- return client.indices
- .get(
- {
- index: indicesToFetch,
- ignore_unavailable: true, // Don't return an error for missing indices. Note this *will* include closed indices, the docs are misleading https://github.com/elastic/elasticsearch/issues/63607
- },
- { ignore: [404], maxRetries: 0 }
- )
- .then(({ body }) => {
- return Either.right(body);
- })
- .catch(catchRetryableEsClientErrors);
-};
+): TaskEither.TaskEither =>
+ // @ts-expect-error @elastic/elasticsearch IndexState.alias and IndexState.mappings should be required
+ () => {
+ return client.indices
+ .get(
+ {
+ index: indicesToFetch,
+ ignore_unavailable: true, // Don't return an error for missing indices. Note this *will* include closed indices, the docs are misleading https://github.com/elastic/elasticsearch/issues/63607
+ },
+ { ignore: [404], maxRetries: 0 }
+ )
+ .then(({ body }) => {
+ return Either.right(body);
+ })
+ .catch(catchRetryableEsClientErrors);
+ };
/**
* Sets a write block in place for the given index. If the response includes
@@ -98,7 +101,7 @@ export const setWriteBlock = (
},
{ maxRetries: 0 /** handle retry ourselves for now */ }
)
- .then((res) => {
+ .then((res: any) => {
return res.body.acknowledged === true
? Either.right('set_write_block_succeeded' as const)
: Either.left({
@@ -134,7 +137,11 @@ export const removeWriteBlock = (
// Don't change any existing settings
preserve_existing: true,
body: {
- 'index.blocks.write': false,
+ index: {
+ blocks: {
+ write: false,
+ },
+ },
},
},
{ maxRetries: 0 /** handle retry ourselves for now */ }
@@ -285,7 +292,7 @@ interface WaitForTaskResponse {
error: Option.Option<{ type: string; reason: string; index: string }>;
completed: boolean;
failures: Option.Option;
- description: string;
+ description?: string;
}
/**
@@ -299,12 +306,7 @@ const waitForTask = (
timeout: string
): TaskEither.TaskEither => () => {
return client.tasks
- .get<{
- completed: boolean;
- response: { failures: any[] };
- task: { description: string };
- error: { type: string; reason: string; index: string };
- }>({
+ .get({
task_id: taskId,
wait_for_completion: true,
timeout,
@@ -314,6 +316,7 @@ const waitForTask = (
const failures = body.response?.failures ?? [];
return Either.right({
completed: body.completed,
+ // @ts-expect-error @elastic/elasticsearch GetTaskResponse doesn't declare `error` property
error: Option.fromNullable(body.error),
failures: failures.length > 0 ? Option.some(failures) : Option.none,
description: body.task.description,
@@ -359,7 +362,7 @@ export const pickupUpdatedMappings = (
wait_for_completion: false,
})
.then(({ body: { task: taskId } }) => {
- return Either.right({ taskId });
+ return Either.right({ taskId: String(taskId!) });
})
.catch(catchRetryableEsClientErrors);
};
@@ -387,7 +390,6 @@ export const reindex = (
.reindex({
// Require targetIndex to be an alias. Prevents a new index from being
// created if targetIndex doesn't exist.
- // @ts-expect-error This API isn't documented
require_alias: requireAlias,
body: {
// Ignore version conflicts from existing documents
@@ -416,7 +418,7 @@ export const reindex = (
wait_for_completion: false,
})
.then(({ body: { task: taskId } }) => {
- return Either.right({ taskId });
+ return Either.right({ taskId: String(taskId) });
})
.catch(catchRetryableEsClientErrors);
};
@@ -624,7 +626,7 @@ export const createIndex = (
const aliasesObject = (aliases ?? []).reduce((acc, alias) => {
acc[alias] = {};
return acc;
- }, {} as Record);
+ }, {} as Record);
return client.indices
.create(
@@ -727,7 +729,7 @@ export const updateAndPickupMappings = (
'update_mappings_succeeded'
> = () => {
return client.indices
- .putMapping, IndexMapping>({
+ .putMapping({
index,
timeout: DEFAULT_TIMEOUT,
body: mappings,
@@ -774,22 +776,16 @@ export const searchForOutdatedDocuments = (
query: Record
): TaskEither.TaskEither => () => {
return client
- .search<{
- // when `filter_path` is specified, ES doesn't return empty arrays, so if
- // there are no search results res.body.hits will be undefined.
- hits?: {
- hits?: SavedObjectsRawDoc[];
- };
- }>({
+ .search({
index,
- // Optimize search performance by sorting by the "natural" index order
- sort: ['_doc'],
// Return the _seq_no and _primary_term so we can use optimistic
// concurrency control for updates
seq_no_primary_term: true,
size: BATCH_SIZE,
body: {
query,
+ // Optimize search performance by sorting by the "natural" index order
+ sort: ['_doc'],
},
// Return an error when targeting missing or closed indices
allow_no_indices: false,
@@ -811,7 +807,9 @@ export const searchForOutdatedDocuments = (
'hits.hits._primary_term',
],
})
- .then((res) => Either.right({ outdatedDocuments: res.body.hits?.hits ?? [] }))
+ .then((res) =>
+ Either.right({ outdatedDocuments: (res.body.hits?.hits as SavedObjectsRawDoc[]) ?? [] })
+ )
.catch(catchRetryableEsClientErrors);
};
@@ -825,20 +823,7 @@ export const bulkOverwriteTransformedDocuments = (
transformedDocs: SavedObjectsRawDoc[]
): TaskEither.TaskEither => () => {
return client
- .bulk<{
- took: number;
- errors: boolean;
- items: [
- {
- index: {
- _id: string;
- status: number;
- // the filter_path ensures that only items with errors are returned
- error: { type: string; reason: string };
- };
- }
- ];
- }>({
+ .bulk({
// Because we only add aliases in the MARK_VERSION_INDEX_READY step we
// can't bulkIndex to an alias with require_alias=true. This means if
// users tamper during this operation (delete indices or restore a
@@ -880,7 +865,7 @@ export const bulkOverwriteTransformedDocuments = (
// Filter out version_conflict_engine_exception since these just mean
// that another instance already updated these documents
const errors = (res.body.items ?? []).filter(
- (item) => item.index.error.type !== 'version_conflict_engine_exception'
+ (item) => item.index?.error?.type !== 'version_conflict_engine_exception'
);
if (errors.length === 0) {
return Either.right('bulk_index_succeeded' as const);
diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts
index 46cfd935f429b..2c052a87d028b 100644
--- a/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts
+++ b/src/core/server/saved_objects/migrationsv2/integration_tests/actions.test.ts
@@ -258,7 +258,7 @@ describe('migration actions', () => {
index: 'clone_red_then_yellow_index',
body: {
// Enable all shard allocation so that the index status goes yellow
- 'index.routing.allocation.enable': 'all',
+ index: { routing: { allocation: { enable: 'all' } } },
},
});
indexYellow = true;
@@ -500,7 +500,7 @@ describe('migration actions', () => {
// Create an index with incompatible mappings
await createIndex(client, 'reindex_target_6', {
- dynamic: 'false',
+ dynamic: false,
properties: { title: { type: 'integer' } }, // integer is incompatible with string title
})();
@@ -926,7 +926,7 @@ describe('migration actions', () => {
index: 'red_then_yellow_index',
body: {
// Disable all shard allocation so that the index status is red
- 'index.routing.allocation.enable': 'all',
+ index: { routing: { allocation: { enable: 'all' } } },
},
});
indexYellow = true;
diff --git a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts
index 95a867934307a..fd62fd107648e 100644
--- a/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts
+++ b/src/core/server/saved_objects/migrationsv2/integration_tests/migration.test.ts
@@ -162,7 +162,9 @@ describe('migration v2', () => {
const expectedVersions = getExpectedVersionPerType();
const res = await esClient.search({
index: migratedIndex,
- sort: ['_doc'],
+ body: {
+ sort: ['_doc'],
+ },
size: 10000,
});
const allDocuments = res.body.hits.hits as SavedObjectsRawDoc[];
@@ -217,7 +219,9 @@ describe('migration v2', () => {
const expectedVersions = getExpectedVersionPerType();
const res = await esClient.search({
index: migratedIndex,
- sort: ['_doc'],
+ body: {
+ sort: ['_doc'],
+ },
size: 10000,
});
const allDocuments = res.body.hits.hits as SavedObjectsRawDoc[];
diff --git a/src/core/server/saved_objects/migrationsv2/model.ts b/src/core/server/saved_objects/migrationsv2/model.ts
index 6f915df9dd958..2e92f34429ea9 100644
--- a/src/core/server/saved_objects/migrationsv2/model.ts
+++ b/src/core/server/saved_objects/migrationsv2/model.ts
@@ -727,7 +727,6 @@ export const createInitialState = ({
};
const reindexTargetMappings: IndexMapping = {
- // @ts-expect-error we don't allow plugins to set `dynamic`
dynamic: false,
properties: {
type: { type: 'keyword' },
diff --git a/src/core/server/saved_objects/service/lib/included_fields.ts b/src/core/server/saved_objects/service/lib/included_fields.ts
index 16e27bcc12b8f..cef83f103ec53 100644
--- a/src/core/server/saved_objects/service/lib/included_fields.ts
+++ b/src/core/server/saved_objects/service/lib/included_fields.ts
@@ -12,7 +12,10 @@ function toArray(value: string | string[]): string[] {
/**
* Provides an array of paths for ES source filtering
*/
-export function includedFields(type: string | string[] = '*', fields?: string[] | string) {
+export function includedFields(
+ type: string | string[] = '*',
+ fields?: string[] | string
+): string[] | undefined {
if (!fields || fields.length === 0) {
return;
}
diff --git a/src/core/server/saved_objects/service/lib/point_in_time_finder.ts b/src/core/server/saved_objects/service/lib/point_in_time_finder.ts
index b8f459151e7b3..9a8dcceafebb2 100644
--- a/src/core/server/saved_objects/service/lib/point_in_time_finder.ts
+++ b/src/core/server/saved_objects/service/lib/point_in_time_finder.ts
@@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
-
+import type { estypes } from '@elastic/elasticsearch';
import type { Logger } from '../../../logging';
import type { SavedObjectsFindOptions, SavedObjectsClientContract } from '../../types';
import type { SavedObjectsFindResponse } from '../';
@@ -96,12 +96,12 @@ export class PointInTimeFinder implements ISavedObjectsPointInTimeFinder {
await this.open();
let lastResultsCount: number;
- let lastHitSortValue: unknown[] | undefined;
+ let lastHitSortValue: estypes.Id[] | undefined;
do {
const results = await this.findNext({
findOptions: this.#findOptions,
id: this.#pitId,
- ...(lastHitSortValue ? { searchAfter: lastHitSortValue } : {}),
+ searchAfter: lastHitSortValue,
});
this.#pitId = results.pit_id;
lastResultsCount = results.saved_objects.length;
@@ -159,7 +159,7 @@ export class PointInTimeFinder implements ISavedObjectsPointInTimeFinder {
}: {
findOptions: SavedObjectsFindOptions;
id?: string;
- searchAfter?: unknown[];
+ searchAfter?: estypes.Id[];
}) {
try {
return await this.#client.find({
@@ -168,8 +168,8 @@ export class PointInTimeFinder implements ISavedObjectsPointInTimeFinder {
sortOrder: 'desc',
// Bump keep_alive by 2m on every new request to allow for the ES client
// to make multiple retries in the event of a network failure.
- ...(id ? { pit: { id, keepAlive: '2m' } } : {}),
- ...(searchAfter ? { searchAfter } : {}),
+ pit: id ? { id, keepAlive: '2m' } : undefined,
+ searchAfter,
...findOptions,
});
} catch (e) {
@@ -181,7 +181,7 @@ export class PointInTimeFinder implements ISavedObjectsPointInTimeFinder {
}
}
- private getLastHitSortValue(res: SavedObjectsFindResponse): unknown[] | undefined {
+ private getLastHitSortValue(res: SavedObjectsFindResponse): estypes.Id[] | undefined {
if (res.saved_objects.length < 1) {
return undefined;
}
diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js
index bff23895fe459..37572c83e4c88 100644
--- a/src/core/server/saved_objects/service/lib/repository.test.js
+++ b/src/core/server/saved_objects/service/lib/repository.test.js
@@ -2782,18 +2782,20 @@ describe('SavedObjectsRepository', () => {
await findSuccess({ type, fields: ['title'] });
expect(client.search).toHaveBeenCalledWith(
expect.objectContaining({
- _source: [
- `${type}.title`,
- 'namespace',
- 'namespaces',
- 'type',
- 'references',
- 'migrationVersion',
- 'coreMigrationVersion',
- 'updated_at',
- 'originId',
- 'title',
- ],
+ body: expect.objectContaining({
+ _source: [
+ `${type}.title`,
+ 'namespace',
+ 'namespaces',
+ 'type',
+ 'references',
+ 'migrationVersion',
+ 'coreMigrationVersion',
+ 'updated_at',
+ 'originId',
+ 'title',
+ ],
+ }),
}),
expect.anything()
);
@@ -3837,6 +3839,7 @@ describe('SavedObjectsRepository', () => {
id: '6.0.0-alpha1',
...mockTimestampFields,
version: mockVersion,
+ references: [],
attributes: {
buildNum: 8468,
apiCallsCount: 100,
diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts
index a302cfe5a1e6f..aa1e62c1652ca 100644
--- a/src/core/server/saved_objects/service/lib/repository.ts
+++ b/src/core/server/saved_objects/service/lib/repository.ts
@@ -7,13 +7,9 @@
*/
import { omit, isObject } from 'lodash';
-import {
- ElasticsearchClient,
- DeleteDocumentResponse,
- GetResponse,
- SearchResponse,
-} from '../../../elasticsearch/';
-import { Logger } from '../../../logging';
+import type { estypes } from '@elastic/elasticsearch';
+import type { ElasticsearchClient } from '../../../elasticsearch/';
+import type { Logger } from '../../../logging';
import { getRootPropertiesObjects, IndexMapping } from '../../mappings';
import {
ISavedObjectsPointInTimeFinder,
@@ -397,7 +393,7 @@ export class SavedObjectsRepository {
_source: ['type', 'namespaces'],
}));
const bulkGetResponse = bulkGetDocs.length
- ? await this.client.mget(
+ ? await this.client.mget(
{
body: {
docs: bulkGetDocs,
@@ -425,8 +421,9 @@ export class SavedObjectsRepository {
if (esRequestIndex !== undefined) {
const indexFound = bulkGetResponse?.statusCode !== 404;
const actualResult = indexFound ? bulkGetResponse?.body.docs[esRequestIndex] : undefined;
- const docFound = indexFound && actualResult.found === true;
- if (docFound && !this.rawDocExistsInNamespace(actualResult, namespace)) {
+ const docFound = indexFound && actualResult?.found === true;
+ // @ts-expect-error MultiGetHit._source is optional
+ if (docFound && !this.rawDocExistsInNamespace(actualResult!, namespace)) {
const { id, type } = object;
return {
tag: 'Left' as 'Left',
@@ -441,7 +438,10 @@ export class SavedObjectsRepository {
};
}
savedObjectNamespaces =
- initialNamespaces || getSavedObjectNamespaces(namespace, docFound && actualResult);
+ initialNamespaces ||
+ // @ts-expect-error MultiGetHit._source is optional
+ getSavedObjectNamespaces(namespace, docFound ? actualResult : undefined);
+ // @ts-expect-error MultiGetHit._source is optional
versionProperties = getExpectedVersionProperties(version, actualResult);
} else {
if (this._registry.isSingleNamespace(object.type)) {
@@ -500,7 +500,7 @@ export class SavedObjectsRepository {
const { requestedId, rawMigratedDoc, esRequestIndex } = expectedResult.value;
const { error, ...rawResponse } = Object.values(
- bulkResponse?.body.items[esRequestIndex]
+ bulkResponse?.body.items[esRequestIndex] ?? {}
)[0] as any;
if (error) {
@@ -564,10 +564,10 @@ export class SavedObjectsRepository {
const bulkGetDocs = expectedBulkGetResults.filter(isRight).map(({ value: { type, id } }) => ({
_id: this._serializer.generateRawId(namespace, type, id),
_index: this.getIndexForType(type),
- _source: ['type', 'namespaces'],
+ _source: { includes: ['type', 'namespaces'] },
}));
const bulkGetResponse = bulkGetDocs.length
- ? await this.client.mget(
+ ? await this.client.mget(
{
body: {
docs: bulkGetDocs,
@@ -586,13 +586,14 @@ export class SavedObjectsRepository {
const { type, id, esRequestIndex } = expectedResult.value;
const doc = bulkGetResponse?.body.docs[esRequestIndex];
- if (doc.found) {
+ if (doc?.found) {
errors.push({
id,
type,
error: {
...errorContent(SavedObjectsErrorHelpers.createConflictError(type, id)),
- ...(!this.rawDocExistsInNamespace(doc, namespace) && {
+ // @ts-expect-error MultiGetHit._source is optional
+ ...(!this.rawDocExistsInNamespace(doc!, namespace) && {
metadata: { isNotOverwritable: true },
}),
},
@@ -636,7 +637,7 @@ export class SavedObjectsRepository {
}
}
- const { body, statusCode } = await this.client.delete(
+ const { body, statusCode } = await this.client.delete(
{
id: rawId,
index: this.getIndexForType(type),
@@ -652,6 +653,7 @@ export class SavedObjectsRepository {
}
const deleteDocNotFound = body.result === 'not_found';
+ // @ts-expect-error 'error' does not exist on type 'DeleteResponse'
const deleteIndexNotFound = body.error && body.error.type === 'index_not_found_exception';
if (deleteDocNotFound || deleteIndexNotFound) {
// see "404s from missing index" above
@@ -813,15 +815,18 @@ export class SavedObjectsRepository {
const esOptions = {
// If `pit` is provided, we drop the `index`, otherwise ES returns 400.
- ...(pit ? {} : { index: this.getIndicesForTypes(allowedTypes) }),
+ index: pit ? undefined : this.getIndicesForTypes(allowedTypes),
// If `searchAfter` is provided, we drop `from` as it will not be used for pagination.
- ...(searchAfter ? {} : { from: perPage * (page - 1) }),
+ from: searchAfter ? undefined : perPage * (page - 1),
_source: includedFields(type, fields),
preference,
rest_total_hits_as_int: true,
size: perPage,
body: {
+ size: perPage,
seq_no_primary_term: true,
+ from: perPage * (page - 1),
+ _source: includedFields(type, fields),
...getSearchDsl(this._mappings, this._registry, {
search,
defaultSearchOperator,
@@ -841,7 +846,7 @@ export class SavedObjectsRepository {
},
};
- const { body, statusCode } = await this.client.search>(esOptions, {
+ const { body, statusCode } = await this.client.search(esOptions, {
ignore: [404],
});
if (statusCode === 404) {
@@ -860,13 +865,15 @@ export class SavedObjectsRepository {
per_page: perPage,
total: body.hits.total,
saved_objects: body.hits.hits.map(
- (hit: SavedObjectsRawDoc): SavedObjectsFindResult => ({
+ (hit: estypes.Hit): SavedObjectsFindResult => ({
+ // @ts-expect-error @elastic/elasticsearch declared Id as string | number
...this._rawToSavedObject(hit),
- score: (hit as any)._score,
- ...((hit as any).sort && { sort: (hit as any).sort }),
+ score: hit._score!,
+ // @ts-expect-error @elastic/elasticsearch declared sort as string | number
+ sort: hit.sort,
})
),
- ...(body.pit_id && { pit_id: body.pit_id }),
+ pit_id: body.pit_id,
} as SavedObjectsFindResponse;
}
@@ -925,10 +932,10 @@ export class SavedObjectsRepository {
.map(({ value: { type, id, fields } }) => ({
_id: this._serializer.generateRawId(namespace, type, id),
_index: this.getIndexForType(type),
- _source: includedFields(type, fields),
+ _source: { includes: includedFields(type, fields) },
}));
const bulkGetResponse = bulkGetDocs.length
- ? await this.client.mget(
+ ? await this.client.mget(
{
body: {
docs: bulkGetDocs,
@@ -947,7 +954,8 @@ export class SavedObjectsRepository {
const { type, id, esRequestIndex } = expectedResult.value;
const doc = bulkGetResponse?.body.docs[esRequestIndex];
- if (!doc.found || !this.rawDocExistsInNamespace(doc, namespace)) {
+ // @ts-expect-error MultiGetHit._source is optional
+ if (!doc?.found || !this.rawDocExistsInNamespace(doc, namespace)) {
return ({
id,
type,
@@ -955,6 +963,7 @@ export class SavedObjectsRepository {
} as any) as SavedObject;
}
+ // @ts-expect-error MultiGetHit._source is optional
return this.getSavedObjectFromSource(type, id, doc);
}),
};
@@ -980,7 +989,7 @@ export class SavedObjectsRepository {
const namespace = normalizeNamespace(options.namespace);
- const { body, statusCode } = await this.client.get>(
+ const { body, statusCode } = await this.client.get(
{
id: this._serializer.generateRawId(namespace, type, id),
index: this.getIndexForType(type),
@@ -988,9 +997,13 @@ export class SavedObjectsRepository {
{ ignore: [404] }
);
- const docNotFound = body.found === false;
const indexNotFound = statusCode === 404;
- if (docNotFound || indexNotFound || !this.rawDocExistsInNamespace(body, namespace)) {
+
+ if (
+ !isFoundGetResponse(body) ||
+ indexNotFound ||
+ !this.rawDocExistsInNamespace(body, namespace)
+ ) {
// see "404s from missing index" above
throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id);
}
@@ -1026,7 +1039,7 @@ export class SavedObjectsRepository {
const time = this._getCurrentTime();
// retrieve the alias, and if it is not disabled, update it
- const aliasResponse = await this.client.update(
+ const aliasResponse = await this.client.update<{ 'legacy-url-alias': LegacyUrlAlias }>(
{
id: rawAliasId,
index: this.getIndexForType(LEGACY_URL_ALIAS_TYPE),
@@ -1059,15 +1072,16 @@ export class SavedObjectsRepository {
if (
aliasResponse.statusCode === 404 ||
- aliasResponse.body.get.found === false ||
- aliasResponse.body.get._source[LEGACY_URL_ALIAS_TYPE]?.disabled === true
+ aliasResponse.body.get?.found === false ||
+ aliasResponse.body.get?._source[LEGACY_URL_ALIAS_TYPE]?.disabled === true
) {
// no legacy URL alias exists, or one exists but it's disabled; just attempt to get the object
return this.resolveExactMatch(type, id, options);
}
- const legacyUrlAlias: LegacyUrlAlias = aliasResponse.body.get._source[LEGACY_URL_ALIAS_TYPE];
+
+ const legacyUrlAlias: LegacyUrlAlias = aliasResponse.body.get!._source[LEGACY_URL_ALIAS_TYPE];
const objectIndex = this.getIndexForType(type);
- const bulkGetResponse = await this.client.mget(
+ const bulkGetResponse = await this.client.mget(
{
body: {
docs: [
@@ -1090,23 +1104,28 @@ export class SavedObjectsRepository {
const exactMatchDoc = bulkGetResponse?.body.docs[0];
const aliasMatchDoc = bulkGetResponse?.body.docs[1];
const foundExactMatch =
+ // @ts-expect-error MultiGetHit._source is optional
exactMatchDoc.found && this.rawDocExistsInNamespace(exactMatchDoc, namespace);
const foundAliasMatch =
+ // @ts-expect-error MultiGetHit._source is optional
aliasMatchDoc.found && this.rawDocExistsInNamespace(aliasMatchDoc, namespace);
if (foundExactMatch && foundAliasMatch) {
return {
+ // @ts-expect-error MultiGetHit._source is optional
saved_object: this.getSavedObjectFromSource(type, id, exactMatchDoc),
outcome: 'conflict',
aliasTargetId: legacyUrlAlias.targetId,
};
} else if (foundExactMatch) {
return {
+ // @ts-expect-error MultiGetHit._source is optional
saved_object: this.getSavedObjectFromSource(type, id, exactMatchDoc),
outcome: 'exactMatch',
};
} else if (foundAliasMatch) {
return {
+ // @ts-expect-error MultiGetHit._source is optional
saved_object: this.getSavedObjectFromSource(type, legacyUrlAlias.targetId, aliasMatchDoc),
outcome: 'aliasMatch',
aliasTargetId: legacyUrlAlias.targetId,
@@ -1153,7 +1172,7 @@ export class SavedObjectsRepository {
};
const { body } = await this.client
- .update({
+ .update({
id: this._serializer.generateRawId(namespace, type, id),
index: this.getIndexForType(type),
...getExpectedVersionProperties(version, preflightResult),
@@ -1173,11 +1192,11 @@ export class SavedObjectsRepository {
throw err;
});
- const { originId } = body.get._source;
- let namespaces = [];
+ const { originId } = body.get?._source ?? {};
+ let namespaces: string[] = [];
if (!this._registry.isNamespaceAgnostic(type)) {
- namespaces = body.get._source.namespaces ?? [
- SavedObjectsUtils.namespaceIdToString(body.get._source.namespace),
+ namespaces = body.get?._source.namespaces ?? [
+ SavedObjectsUtils.namespaceIdToString(body.get?._source.namespace),
];
}
@@ -1185,7 +1204,6 @@ export class SavedObjectsRepository {
id,
type,
updated_at: time,
- // @ts-expect-error update doesn't have _seq_no, _primary_term as Record / any in LP
version: encodeHitVersion(body),
namespaces,
...(originId && { originId }),
@@ -1325,7 +1343,7 @@ export class SavedObjectsRepository {
return { namespaces: doc.namespaces };
} else {
// if there are no namespaces remaining, delete the saved object
- const { body, statusCode } = await this.client.delete(
+ const { body, statusCode } = await this.client.delete(
{
id: this._serializer.generateRawId(undefined, type, id),
refresh,
@@ -1343,6 +1361,7 @@ export class SavedObjectsRepository {
}
const deleteDocNotFound = body.result === 'not_found';
+ // @ts-expect-error
const deleteIndexNotFound = body.error && body.error.type === 'index_not_found_exception';
if (deleteDocNotFound || deleteIndexNotFound) {
// see "404s from missing index" above
@@ -1477,9 +1496,10 @@ export class SavedObjectsRepository {
if (esRequestIndex !== undefined) {
const indexFound = bulkGetResponse?.statusCode !== 404;
const actualResult = indexFound ? bulkGetResponse?.body.docs[esRequestIndex] : undefined;
- const docFound = indexFound && actualResult.found === true;
+ const docFound = indexFound && actualResult?.found === true;
if (
!docFound ||
+ // @ts-expect-error MultiGetHit is incorrectly missing _id, _source
!this.rawDocExistsInNamespace(actualResult, getNamespaceId(objectNamespace))
) {
return {
@@ -1491,10 +1511,13 @@ export class SavedObjectsRepository {
},
};
}
- namespaces = actualResult._source.namespaces ?? [
- SavedObjectsUtils.namespaceIdToString(actualResult._source.namespace),
+ // @ts-expect-error MultiGetHit is incorrectly missing _id, _source
+ namespaces = actualResult!._source.namespaces ?? [
+ // @ts-expect-error MultiGetHit is incorrectly missing _id, _source
+ SavedObjectsUtils.namespaceIdToString(actualResult!._source.namespace),
];
- versionProperties = getExpectedVersionProperties(version, actualResult);
+ // @ts-expect-error MultiGetHit is incorrectly missing _id, _source
+ versionProperties = getExpectedVersionProperties(version, actualResult!);
} else {
if (this._registry.isSingleNamespace(type)) {
// if `objectNamespace` is undefined, fall back to `options.namespace`
@@ -1543,7 +1566,7 @@ export class SavedObjectsRepository {
}
const { type, id, namespaces, documentToSave, esRequestIndex } = expectedResult.value;
- const response = bulkUpdateResponse?.body.items[esRequestIndex];
+ const response = bulkUpdateResponse?.body.items[esRequestIndex] ?? {};
// When a bulk update operation is completed, any fields specified in `_sourceIncludes` will be found in the "get" value of the
// returned object. We need to retrieve the `originId` if it exists so we can return it to the consumer.
const { error, _seq_no: seqNo, _primary_term: primaryTerm, get } = Object.values(
@@ -1636,7 +1659,7 @@ export class SavedObjectsRepository {
}
return {
- updated: body.updated,
+ updated: body.updated!,
};
}
@@ -1745,7 +1768,7 @@ export class SavedObjectsRepository {
const raw = this._serializer.savedObjectToRaw(migrated as SavedObjectSanitizedDoc);
- const { body } = await this.client.update({
+ const { body } = await this.client.update({
id: raw._id,
index: this.getIndexForType(type),
refresh,
@@ -1783,17 +1806,16 @@ export class SavedObjectsRepository {
},
});
- const { originId } = body.get._source;
+ const { originId } = body.get?._source ?? {};
return {
id,
type,
...(savedObjectNamespaces && { namespaces: savedObjectNamespaces }),
...(originId && { originId }),
updated_at: time,
- references: body.get._source.references,
- // @ts-expect-error
+ references: body.get?._source.references ?? [],
version: encodeHitVersion(body),
- attributes: body.get._source[type],
+ attributes: body.get?._source[type],
};
}
@@ -1852,9 +1874,13 @@ export class SavedObjectsRepository {
const {
body,
statusCode,
- } = await this.client.openPointInTime(esOptions, {
- ignore: [404],
- });
+ } = await this.client.openPointInTime(
+ // @ts-expect-error @elastic/elasticsearch OpenPointInTimeRequest.index expected to accept string[]
+ esOptions,
+ {
+ ignore: [404],
+ }
+ );
if (statusCode === 404) {
throw SavedObjectsErrorHelpers.createGenericNotFoundError();
}
@@ -1912,6 +1938,7 @@ export class SavedObjectsRepository {
const { body } = await this.client.closePointInTime({
body: { id },
});
+
return body;
}
@@ -2054,7 +2081,7 @@ export class SavedObjectsRepository {
throw new Error(`Cannot make preflight get request for non-multi-namespace type '${type}'.`);
}
- const { body, statusCode } = await this.client.get>(
+ const { body, statusCode } = await this.client.get(
{
id: this._serializer.generateRawId(undefined, type, id),
index: this.getIndexForType(type),
@@ -2065,8 +2092,7 @@ export class SavedObjectsRepository {
);
const indexFound = statusCode !== 404;
- const docFound = indexFound && body.found === true;
- if (docFound) {
+ if (indexFound && isFoundGetResponse(body)) {
if (!this.rawDocExistsInNamespace(body, namespace)) {
throw SavedObjectsErrorHelpers.createConflictError(type, id);
}
@@ -2091,7 +2117,7 @@ export class SavedObjectsRepository {
}
const rawId = this._serializer.generateRawId(undefined, type, id);
- const { body, statusCode } = await this.client.get>(
+ const { body, statusCode } = await this.client.get(
{
id: rawId,
index: this.getIndexForType(type),
@@ -2100,17 +2126,20 @@ export class SavedObjectsRepository {
);
const indexFound = statusCode !== 404;
- const docFound = indexFound && body.found === true;
- if (!docFound || !this.rawDocExistsInNamespace(body, namespace)) {
+ if (
+ !indexFound ||
+ !isFoundGetResponse(body) ||
+ !this.rawDocExistsInNamespace(body, namespace)
+ ) {
throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id);
}
- return body as SavedObjectsRawDoc;
+ return body;
}
private getSavedObjectFromSource(
type: string,
id: string,
- doc: { _seq_no: number; _primary_term: number; _source: SavedObjectsRawDocSource }
+ doc: { _seq_no?: number; _primary_term?: number; _source: SavedObjectsRawDocSource }
): SavedObject {
const { originId, updated_at: updatedAt } = doc._source;
@@ -2220,3 +2249,15 @@ const normalizeNamespace = (namespace?: string) => {
const errorContent = (error: DecoratedError) => error.output.payload;
const unique = (array: string[]) => [...new Set(array)];
+
+/**
+ * Type and type guard function for converting a possibly not existant doc to an existant doc.
+ */
+type GetResponseFound = estypes.GetResponse &
+ Required<
+ Pick, '_primary_term' | '_seq_no' | '_version' | '_source'>
+ >;
+
+const isFoundGetResponse = (
+ doc: estypes.GetResponse
+): doc is GetResponseFound => doc.found;
diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts
index 267d671361184..b15560b82ab31 100644
--- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts
+++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts
@@ -86,7 +86,7 @@ describe('getSearchDsl', () => {
const opts = {
type: 'foo',
sortField: 'bar',
- sortOrder: 'baz',
+ sortOrder: 'asc' as const,
pit: { id: 'abc123' },
};
@@ -109,10 +109,10 @@ describe('getSearchDsl', () => {
it('returns searchAfter if provided', () => {
getQueryParams.mockReturnValue({ a: 'a' });
getSortingParams.mockReturnValue({ b: 'b' });
- expect(getSearchDsl(mappings, registry, { type: 'foo', searchAfter: [1, 'bar'] })).toEqual({
+ expect(getSearchDsl(mappings, registry, { type: 'foo', searchAfter: ['1', 'bar'] })).toEqual({
a: 'a',
b: 'b',
- search_after: [1, 'bar'],
+ search_after: ['1', 'bar'],
});
});
@@ -123,14 +123,14 @@ describe('getSearchDsl', () => {
expect(
getSearchDsl(mappings, registry, {
type: 'foo',
- searchAfter: [1, 'bar'],
+ searchAfter: ['1', 'bar'],
pit: { id: 'abc123' },
})
).toEqual({
a: 'a',
b: 'b',
pit: { id: 'abc123' },
- search_after: [1, 'bar'],
+ search_after: ['1', 'bar'],
});
});
});
diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts
index 9820544f02bd1..64b3dd428fb8b 100644
--- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts
+++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts
@@ -8,6 +8,7 @@
import Boom from '@hapi/boom';
+import type { estypes } from '@elastic/elasticsearch';
import { IndexMapping } from '../../../mappings';
import { SavedObjectsPitParams } from '../../../types';
import { getQueryParams, HasReferenceQueryParams, SearchOperator } from './query_params';
@@ -23,9 +24,9 @@ interface GetSearchDslOptions {
defaultSearchOperator?: SearchOperator;
searchFields?: string[];
rootSearchFields?: string[];
- searchAfter?: unknown[];
+ searchAfter?: estypes.Id[];
sortField?: string;
- sortOrder?: string;
+ sortOrder?: estypes.SortOrder;
namespaces?: string[];
pit?: SavedObjectsPitParams;
typeToNamespacesMap?: Map;
@@ -80,6 +81,6 @@ export function getSearchDsl(
}),
...getSortingParams(mappings, type, sortField, sortOrder),
...(pit ? getPitParams(pit) : {}),
- ...(searchAfter ? { search_after: searchAfter } : {}),
+ search_after: searchAfter,
};
}
diff --git a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts
index e3bfba6a80f59..64849c308f3f0 100644
--- a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts
+++ b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import type { estypes } from '@elastic/elasticsearch';
import Boom from '@hapi/boom';
import { getProperty, IndexMapping } from '../../../mappings';
@@ -15,8 +16,8 @@ export function getSortingParams(
mappings: IndexMapping,
type: string | string[],
sortField?: string,
- sortOrder?: string
-) {
+ sortOrder?: estypes.SortOrder
+): { sort?: estypes.SortContainer[] } {
if (!sortField) {
return {};
}
diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts
index 9fa2896b7bbfe..9a0ccb88d3555 100644
--- a/src/core/server/saved_objects/service/saved_objects_client.ts
+++ b/src/core/server/saved_objects/service/saved_objects_client.ts
@@ -162,7 +162,7 @@ export interface SavedObjectsFindResult extends SavedObject {
* await savedObjectsClient.closePointInTime(page2.pit_id);
* ```
*/
- sort?: unknown[];
+ sort?: string[];
}
/**
diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts
index 11a694c72f29f..ecda120e025d8 100644
--- a/src/core/server/saved_objects/types.ts
+++ b/src/core/server/saved_objects/types.ts
@@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
+import type { estypes } from '@elastic/elasticsearch';
import { SavedObjectsClient } from './service/saved_objects_client';
import { SavedObjectsTypeMappingDefinition } from './mappings';
import { SavedObjectMigrationMap } from './migrations';
@@ -79,7 +80,7 @@ export interface SavedObjectsFindOptions {
page?: number;
perPage?: number;
sortField?: string;
- sortOrder?: string;
+ sortOrder?: estypes.SortOrder;
/**
* An array of fields to include in the results
* @example
@@ -93,7 +94,7 @@ export interface SavedObjectsFindOptions {
/**
* Use the sort values from the previous page to retrieve the next page of results.
*/
- searchAfter?: unknown[];
+ searchAfter?: estypes.Id[];
/**
* The fields to perform the parsed query against. Unlike the `searchFields` argument, these are expected to be root fields and will not
* be modified. If used in conjunction with `searchFields`, both are concatenated together.
diff --git a/src/core/server/saved_objects/version/encode_hit_version.ts b/src/core/server/saved_objects/version/encode_hit_version.ts
index 614666c6e1da6..979df93dc57b5 100644
--- a/src/core/server/saved_objects/version/encode_hit_version.ts
+++ b/src/core/server/saved_objects/version/encode_hit_version.ts
@@ -12,6 +12,6 @@ import { encodeVersion } from './encode_version';
* Helper for encoding a version from a "hit" (hits.hits[#] from _search) or
* "doc" (body from GET, update, etc) object
*/
-export function encodeHitVersion(response: { _seq_no: number; _primary_term: number }) {
+export function encodeHitVersion(response: { _seq_no?: number; _primary_term?: number }) {
return encodeVersion(response._seq_no, response._primary_term);
}
diff --git a/src/core/server/saved_objects/version/encode_version.ts b/src/core/server/saved_objects/version/encode_version.ts
index fa778ee931e41..9c0b0a7428f38 100644
--- a/src/core/server/saved_objects/version/encode_version.ts
+++ b/src/core/server/saved_objects/version/encode_version.ts
@@ -13,7 +13,7 @@ import { encodeBase64 } from './base64';
* that can be used in the saved object API in place of numeric
* version numbers
*/
-export function encodeVersion(seqNo: number, primaryTerm: number) {
+export function encodeVersion(seqNo?: number, primaryTerm?: number) {
if (!Number.isInteger(primaryTerm)) {
throw new TypeError('_primary_term from elasticsearch must be an integer');
}
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index 3d2023108c46a..73f8a44075162 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -50,6 +50,7 @@ import { DetailedPeerCertificate } from 'tls';
import { Duration } from 'moment';
import { Duration as Duration_2 } from 'moment-timezone';
import { EnvironmentMode } from '@kbn/config';
+import { estypes } from '@elastic/elasticsearch';
import { ExistsParams } from 'elasticsearch';
import { ExplainParams } from 'elasticsearch';
import { FieldStatsParams } from 'elasticsearch';
@@ -2507,12 +2508,12 @@ export interface SavedObjectsFindOptions {
preference?: string;
rootSearchFields?: string[];
search?: string;
- searchAfter?: unknown[];
+ searchAfter?: estypes.Id[];
searchFields?: string[];
// (undocumented)
sortField?: string;
// (undocumented)
- sortOrder?: string;
+ sortOrder?: estypes.SortOrder;
// (undocumented)
type: string | string[];
typeToNamespacesMap?: Map;
@@ -2543,7 +2544,7 @@ export interface SavedObjectsFindResponse {
// @public (undocumented)
export interface SavedObjectsFindResult extends SavedObject {
score: number;
- sort?: unknown[];
+ sort?: string[];
}
// @public
diff --git a/src/plugins/data/common/search/es_search/types.ts b/src/plugins/data/common/search/es_search/types.ts
index dc1de8d1338f1..12dc0c1b2599d 100644
--- a/src/plugins/data/common/search/es_search/types.ts
+++ b/src/plugins/data/common/search/es_search/types.ts
@@ -5,19 +5,18 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
+import type { estypes } from '@elastic/elasticsearch';
-import { SearchResponse } from 'elasticsearch';
-import { Search } from '@elastic/elasticsearch/api/requestParams';
import { IKibanaSearchRequest, IKibanaSearchResponse } from '../types';
export const ES_SEARCH_STRATEGY = 'es';
-export type ISearchRequestParams> = {
+export type ISearchRequestParams = {
trackTotalHits?: boolean;
-} & Search;
+} & estypes.SearchRequest;
export interface IEsSearchRequest extends IKibanaSearchRequest {
indexType?: string;
}
-export type IEsSearchResponse = IKibanaSearchResponse>;
+export type IEsSearchResponse = IKibanaSearchResponse>;
diff --git a/src/plugins/data/common/search/expressions/utils/courier_inspector_stats.ts b/src/plugins/data/common/search/expressions/utils/courier_inspector_stats.ts
index 6013b3d6c6f5f..99acbce8935c4 100644
--- a/src/plugins/data/common/search/expressions/utils/courier_inspector_stats.ts
+++ b/src/plugins/data/common/search/expressions/utils/courier_inspector_stats.ts
@@ -14,7 +14,7 @@
*/
import { i18n } from '@kbn/i18n';
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { ISearchSource } from 'src/plugins/data/public';
import { RequestStatistics } from 'src/plugins/inspector/common';
@@ -50,7 +50,7 @@ export function getRequestInspectorStats(searchSource: ISearchSource) {
/** @public */
export function getResponseInspectorStats(
- resp: SearchResponse,
+ resp: estypes.SearchResponse,
searchSource?: ISearchSource
) {
const lastRequest =
diff --git a/src/plugins/data/common/search/search_source/fetch/request_error.ts b/src/plugins/data/common/search/search_source/fetch/request_error.ts
index 14185d7d5afd3..d8c750d011b03 100644
--- a/src/plugins/data/common/search/search_source/fetch/request_error.ts
+++ b/src/plugins/data/common/search/search_source/fetch/request_error.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { KbnError } from '../../../../../kibana_utils/common';
import { SearchError } from './types';
@@ -16,8 +16,8 @@ import { SearchError } from './types';
* @param {Object} resp - optional HTTP response
*/
export class RequestFailure extends KbnError {
- public resp?: SearchResponse;
- constructor(err: SearchError | null = null, resp?: SearchResponse) {
+ public resp?: estypes.SearchResponse;
+ constructor(err: SearchError | null = null, resp?: estypes.SearchResponse) {
super(`Request to Elasticsearch failed: ${JSON.stringify(resp || err?.message)}`);
this.resp = resp;
diff --git a/src/plugins/data/common/search/search_source/fetch/types.ts b/src/plugins/data/common/search/search_source/fetch/types.ts
index 2387d9dbffa3a..8e8a9f1025b80 100644
--- a/src/plugins/data/common/search/search_source/fetch/types.ts
+++ b/src/plugins/data/common/search/search_source/fetch/types.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { LegacyFetchHandlers } from '../legacy/types';
import { GetConfigFn } from '../../../types';
@@ -25,7 +25,10 @@ export interface FetchHandlers {
* Callback which can be used to hook into responses, modify them, or perform
* side effects like displaying UI errors on the client.
*/
- onResponse: (request: SearchRequest, response: SearchResponse) => SearchResponse;
+ onResponse: (
+ request: SearchRequest,
+ response: estypes.SearchResponse
+ ) => estypes.SearchResponse;
/**
* These handlers are only used by the legacy defaultSearchStrategy and can be removed
* once that strategy has been deprecated.
diff --git a/src/plugins/data/common/search/search_source/legacy/call_client.ts b/src/plugins/data/common/search/search_source/legacy/call_client.ts
index a288cdc22c576..4c1156aac7015 100644
--- a/src/plugins/data/common/search/search_source/legacy/call_client.ts
+++ b/src/plugins/data/common/search/search_source/legacy/call_client.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { FetchHandlers, SearchRequest } from '../fetch';
import { defaultSearchStrategy } from './default_search_strategy';
import { ISearchOptions } from '../../index';
@@ -21,7 +21,7 @@ export function callClient(
[SearchRequest, ISearchOptions]
> = searchRequests.map((request, i) => [request, requestsOptions[i]]);
const requestOptionsMap = new Map(requestOptionEntries);
- const requestResponseMap = new Map>>();
+ const requestResponseMap = new Map>>();
const { searching, abort } = defaultSearchStrategy.search({
searchRequests,
diff --git a/src/plugins/data/common/search/search_source/legacy/fetch_soon.ts b/src/plugins/data/common/search/search_source/legacy/fetch_soon.ts
index e42ef6617594a..ff8ae2d19bd56 100644
--- a/src/plugins/data/common/search/search_source/legacy/fetch_soon.ts
+++ b/src/plugins/data/common/search/search_source/legacy/fetch_soon.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { UI_SETTINGS } from '../../../constants';
import { FetchHandlers, SearchRequest } from '../fetch';
import { ISearchOptions } from '../../index';
@@ -57,9 +57,11 @@ async function delayedFetch(
options: ISearchOptions,
fetchHandlers: FetchHandlers,
ms: number
-): Promise> {
+): Promise> {
if (ms === 0) {
- return callClient([request], [options], fetchHandlers)[0];
+ return callClient([request], [options], fetchHandlers)[0] as Promise<
+ estypes.SearchResponse
+ >;
}
const i = requestsToFetch.length;
diff --git a/src/plugins/data/common/search/search_source/legacy/types.ts b/src/plugins/data/common/search/search_source/legacy/types.ts
index 5a60d1082b0ed..a4328528fd662 100644
--- a/src/plugins/data/common/search/search_source/legacy/types.ts
+++ b/src/plugins/data/common/search/search_source/legacy/types.ts
@@ -7,8 +7,7 @@
*/
import { BehaviorSubject } from 'rxjs';
-import { ApiResponse } from '@elastic/elasticsearch';
-import { SearchResponse } from 'elasticsearch';
+import type { estypes, ApiResponse } from '@elastic/elasticsearch';
import { FetchHandlers, SearchRequest } from '../fetch';
interface MsearchHeaders {
@@ -28,7 +27,7 @@ export interface MsearchRequestBody {
// @internal
export interface MsearchResponse {
- body: ApiResponse<{ responses: Array> }>;
+ body: ApiResponse<{ responses: Array> }>;
}
// @internal
@@ -51,6 +50,6 @@ export interface SearchStrategyProvider {
}
export interface SearchStrategyResponse {
- searching: Promise>>;
+ searching: Promise>>;
abort: () => void;
}
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index 5dc5a8ab2ce93..4eae5629af3a6 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -28,6 +28,7 @@ import { DetailedPeerCertificate } from 'tls';
import { Ensure } from '@kbn/utility-types';
import { EnvironmentMode } from '@kbn/config';
import { ErrorToastOptions } from 'src/core/public/notifications';
+import { estypes } from '@elastic/elasticsearch';
import { EuiBreadcrumb } from '@elastic/eui';
import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiComboBoxProps } from '@elastic/eui';
@@ -92,8 +93,6 @@ import { SavedObjectsFindOptions } from 'kibana/public';
import { SavedObjectsFindResponse } from 'kibana/server';
import { SavedObjectsUpdateResponse } from 'kibana/server';
import { SchemaTypeError } from '@kbn/config-schema';
-import { Search } from '@elastic/elasticsearch/api/requestParams';
-import { SearchResponse } from 'elasticsearch';
import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/expressions/common';
import { StartServicesAccessor } from 'kibana/public';
import { ToastInputFields } from 'src/core/public/notifications';
@@ -1128,7 +1127,7 @@ export interface IEsSearchRequest extends IKibanaSearchRequest = IKibanaSearchResponse>;
+export type IEsSearchResponse = IKibanaSearchResponse>;
// Warning: (ae-missing-release-tag) "IFieldFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -2415,9 +2414,9 @@ export class SearchSource {
createChild(options?: {}): SearchSource;
createCopy(): SearchSource;
destroy(): void;
- fetch$(options?: ISearchOptions): import("rxjs").Observable>;
+ fetch$(options?: ISearchOptions): import("rxjs").Observable>;
// @deprecated
- fetch(options?: ISearchOptions): Promise>;
+ fetch(options?: ISearchOptions): Promise>;
getField(field: K, recurse?: boolean): SearchSourceFields[K];
getFields(): SearchSourceFields;
getId(): string;
diff --git a/src/plugins/data/public/search/expressions/es_raw_response.ts b/src/plugins/data/public/search/expressions/es_raw_response.ts
index 6b44a7afb6d67..2d12af017d88c 100644
--- a/src/plugins/data/public/search/expressions/es_raw_response.ts
+++ b/src/plugins/data/public/search/expressions/es_raw_response.ts
@@ -6,14 +6,14 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { ExpressionTypeDefinition } from '../../../../expressions/common';
const name = 'es_raw_response';
export interface EsRawResponse {
type: typeof name;
- body: SearchResponse;
+ body: estypes.SearchResponse;
}
// flattens elasticsearch object into table rows
@@ -46,11 +46,11 @@ function flatten(obj: any, keyPrefix = '') {
}
}
-const parseRawDocs = (hits: SearchResponse['hits']) => {
+const parseRawDocs = (hits: estypes.SearchResponse['hits']) => {
return hits.hits.map((hit) => hit.fields || hit._source).filter((hit) => hit);
};
-const convertResult = (body: SearchResponse) => {
+const convertResult = (body: estypes.SearchResponse) => {
return !body.aggregations ? parseRawDocs(body.hits) : flatten(body.aggregations);
};
diff --git a/src/plugins/data/public/search/fetch/handle_response.tsx b/src/plugins/data/public/search/fetch/handle_response.tsx
index 00d5b11089d62..57ee5737e50a2 100644
--- a/src/plugins/data/public/search/fetch/handle_response.tsx
+++ b/src/plugins/data/public/search/fetch/handle_response.tsx
@@ -9,13 +9,13 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
import { toMountPoint } from '../../../../kibana_react/public';
import { getNotifications } from '../../services';
import { SearchRequest } from '..';
-export function handleResponse(request: SearchRequest, response: SearchResponse) {
+export function handleResponse(request: SearchRequest, response: estypes.SearchResponse) {
if (response.timed_out) {
getNotifications().toasts.addWarning({
title: i18n.translate('data.search.searchSource.fetch.requestTimedOutNotificationMessage', {
diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx
index f510420cb30e8..8e6ad4bc92c8f 100644
--- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx
+++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_modal.tsx
@@ -21,14 +21,14 @@ import {
EuiButtonEmpty,
EuiCallOut,
} from '@elastic/eui';
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { ShardFailureTable } from './shard_failure_table';
import { ShardFailureRequest } from './shard_failure_types';
export interface Props {
onClose: () => void;
request: ShardFailureRequest;
- response: SearchResponse;
+ response: estypes.SearchResponse;
title: string;
}
diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
index 0907d6607579f..a230378d6c3d3 100644
--- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
+++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_open_modal_button.tsx
@@ -9,8 +9,8 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButton, EuiTextAlign } from '@elastic/eui';
+import type { estypes } from '@elastic/elasticsearch';
-import { SearchResponse } from 'elasticsearch';
import { getOverlays } from '../../services';
import { toMountPoint } from '../../../../kibana_react/public';
import { ShardFailureModal } from './shard_failure_modal';
@@ -19,7 +19,7 @@ import { ShardFailureRequest } from './shard_failure_types';
// @internal
export interface ShardFailureOpenModalButtonProps {
request: ShardFailureRequest;
- response: SearchResponse;
+ response: estypes.SearchResponse;
title: string;
}
diff --git a/src/plugins/data/server/autocomplete/value_suggestions_route.ts b/src/plugins/data/server/autocomplete/value_suggestions_route.ts
index 489a23eb83897..bdcc13ce4c061 100644
--- a/src/plugins/data/server/autocomplete/value_suggestions_route.ts
+++ b/src/plugins/data/server/autocomplete/value_suggestions_route.ts
@@ -12,7 +12,8 @@ import { IRouter, SharedGlobalConfig } from 'kibana/server';
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
-import { IFieldType, Filter } from '../index';
+import type { estypes } from '@elastic/elasticsearch';
+import type { IFieldType } from '../index';
import { findIndexPatternById, getFieldByName } from '../index_patterns';
import { getRequestAbortedSignal } from '../lib';
@@ -73,7 +74,7 @@ async function getBody(
{ timeout, terminate_after }: Record,
field: IFieldType | string,
query: string,
- filters: Filter[] = []
+ filters: estypes.QueryContainer[] = []
) {
const isFieldObject = (f: any): f is IFieldType => Boolean(f && f.name);
@@ -82,7 +83,7 @@ async function getBody(
q.replace(/[.?+*|{}[\]()"\\#@&<>~]/g, (match) => `\\${match}`);
// Helps ensure that the regex is not evaluated eagerly against the terms dictionary
- const executionHint = 'map';
+ const executionHint = 'map' as const;
// We don't care about the accuracy of the counts, just the content of the terms, so this reduces
// the amount of information that needs to be transmitted to the coordinating node
diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts b/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts
index db950e7aa48f9..69a9280dd93d8 100644
--- a/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts
+++ b/src/plugins/data/server/index_patterns/fetcher/lib/es_api.ts
@@ -8,17 +8,6 @@
import { ElasticsearchClient } from 'kibana/server';
import { convertEsError } from './errors';
-import { FieldCapsResponse } from './field_capabilities';
-
-export interface IndicesAliasResponse {
- [index: string]: IndexAliasResponse;
-}
-
-export interface IndexAliasResponse {
- aliases: {
- [aliasName: string]: Record;
- };
-}
/**
* Call the index.getAlias API for a list of indices.
@@ -67,7 +56,7 @@ export async function callFieldCapsApi(
fieldCapsOptions: { allow_no_indices: boolean } = { allow_no_indices: false }
) {
try {
- return await callCluster.fieldCaps({
+ return await callCluster.fieldCaps({
index: indices,
fields: '*',
ignore_unavailable: true,
diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts
index 31fd60b0382aa..c4c1ffa3cf9f9 100644
--- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts
+++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts
@@ -7,23 +7,11 @@
*/
import { uniq } from 'lodash';
+import type { estypes } from '@elastic/elasticsearch';
import { castEsToKbnFieldTypeName } from '../../../../../common';
import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values';
import { FieldDescriptor } from '../../../fetcher';
-interface FieldCapObject {
- type: string;
- searchable: boolean;
- aggregatable: boolean;
- indices?: string[];
- non_searchable_indices?: string[];
- non_aggregatable_indices?: string[];
-}
-
-export interface FieldCapsResponse {
- fields: Record>;
-}
-
/**
* Read the response from the _field_caps API to determine the type and
* "aggregatable"/"searchable" status of each field.
@@ -80,7 +68,9 @@ export interface FieldCapsResponse {
* @param {FieldCapsResponse} fieldCapsResponse
* @return {Array}
*/
-export function readFieldCapsResponse(fieldCapsResponse: FieldCapsResponse): FieldDescriptor[] {
+export function readFieldCapsResponse(
+ fieldCapsResponse: estypes.FieldCapabilitiesResponse
+): FieldDescriptor[] {
const capsByNameThenType = fieldCapsResponse.fields;
const kibanaFormattedCaps = Object.keys(capsByNameThenType).reduce<{
diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/index.ts b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/index.ts
index d7150d81e3803..773a615727ee5 100644
--- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/index.ts
+++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/index.ts
@@ -7,5 +7,4 @@
*/
export { getFieldCapabilities } from './field_capabilities';
-export { FieldCapsResponse } from './field_caps_response';
export { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values';
diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts b/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts
index d01f74429c3a5..32b9d8c7f893f 100644
--- a/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts
+++ b/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts
@@ -12,7 +12,7 @@ import moment from 'moment';
import { ElasticsearchClient } from 'kibana/server';
import { timePatternToWildcard } from './time_pattern_to_wildcard';
-import { callIndexAliasApi, IndicesAliasResponse } from './es_api';
+import { callIndexAliasApi } from './es_api';
/**
* Convert a time pattern into a list of indexes it could
@@ -28,7 +28,7 @@ import { callIndexAliasApi, IndicesAliasResponse } from './es_api';
export async function resolveTimePattern(callCluster: ElasticsearchClient, timePattern: string) {
const aliases = await callIndexAliasApi(callCluster, timePatternToWildcard(timePattern));
- const allIndexDetails = chain(aliases.body)
+ const allIndexDetails = chain(aliases.body)
.reduce(
(acc: string[], index: any, indexName: string) =>
acc.concat(indexName, Object.keys(index.aliases || {})),
diff --git a/src/plugins/data/server/search/collectors/fetch.ts b/src/plugins/data/server/search/collectors/fetch.ts
index 6dfc29e2cf2a6..aed35d73c7eb6 100644
--- a/src/plugins/data/server/search/collectors/fetch.ts
+++ b/src/plugins/data/server/search/collectors/fetch.ts
@@ -9,18 +9,16 @@
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { SharedGlobalConfig } from 'kibana/server';
-import { SearchResponse } from 'elasticsearch';
import { CollectorFetchContext } from 'src/plugins/usage_collection/server';
import { CollectedUsage, ReportedUsage } from './register';
interface SearchTelemetry {
'search-telemetry': CollectedUsage;
}
-type ESResponse = SearchResponse;
export function fetchProvider(config$: Observable) {
return async ({ esClient }: CollectorFetchContext): Promise => {
const config = await config$.pipe(first()).toPromise();
- const { body: esResponse } = await esClient.search(
+ const { body: esResponse } = await esClient.search(
{
index: config.kibana.index,
body: {
@@ -37,7 +35,7 @@ export function fetchProvider(config$: Observable) {
averageDuration: null,
};
}
- const { successCount, errorCount, totalDuration } = esResponse.hits.hits[0]._source[
+ const { successCount, errorCount, totalDuration } = esResponse.hits.hits[0]._source![
'search-telemetry'
];
const averageDuration = totalDuration / successCount;
diff --git a/src/plugins/data/server/search/es_search/es_search_strategy.ts b/src/plugins/data/server/search/es_search/es_search_strategy.ts
index cc81dce94c4ec..1afe627545248 100644
--- a/src/plugins/data/server/search/es_search/es_search_strategy.ts
+++ b/src/plugins/data/server/search/es_search/es_search_strategy.ts
@@ -8,7 +8,6 @@
import { from, Observable } from 'rxjs';
import { first, tap } from 'rxjs/operators';
-import type { SearchResponse } from 'elasticsearch';
import type { Logger, SharedGlobalConfig } from 'kibana/server';
import type { ISearchStrategy } from '../types';
import type { SearchUsage } from '../collectors';
@@ -44,7 +43,7 @@ export const esSearchStrategyProvider = (
...getShardTimeout(config),
...request.params,
};
- const promise = esClient.asCurrentUser.search>(params);
+ const promise = esClient.asCurrentUser.search(params);
const { body } = await shimAbortSignal(promise, abortSignal);
const response = shimHitsTotal(body, options);
return toKibanaSearchResponse(response);
diff --git a/src/plugins/data/server/search/es_search/response_utils.ts b/src/plugins/data/server/search/es_search/response_utils.ts
index 975ce392656b1..3bee63624ef67 100644
--- a/src/plugins/data/server/search/es_search/response_utils.ts
+++ b/src/plugins/data/server/search/es_search/response_utils.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { ISearchOptions } from '../../../common';
/**
@@ -14,7 +14,7 @@ import { ISearchOptions } from '../../../common';
* not included as it is already included in `successful`.
* @internal
*/
-export function getTotalLoaded(response: SearchResponse) {
+export function getTotalLoaded(response: estypes.SearchResponse) {
const { total, failed, successful } = response._shards;
const loaded = failed + successful;
return { total, loaded };
@@ -24,7 +24,7 @@ export function getTotalLoaded(response: SearchResponse) {
* Get the Kibana representation of this response (see `IKibanaSearchResponse`).
* @internal
*/
-export function toKibanaSearchResponse(rawResponse: SearchResponse) {
+export function toKibanaSearchResponse(rawResponse: estypes.SearchResponse) {
return {
rawResponse,
isPartial: false,
@@ -41,7 +41,7 @@ export function toKibanaSearchResponse(rawResponse: SearchResponse) {
* @internal
*/
export function shimHitsTotal(
- response: SearchResponse,
+ response: estypes.SearchResponse,
{ legacyHitsTotal = true }: ISearchOptions = {}
) {
if (!legacyHitsTotal) return response;
diff --git a/src/plugins/data/server/search/routes/call_msearch.ts b/src/plugins/data/server/search/routes/call_msearch.ts
index 8648d3f4526fe..0c238adf831bd 100644
--- a/src/plugins/data/server/search/routes/call_msearch.ts
+++ b/src/plugins/data/server/search/routes/call_msearch.ts
@@ -8,7 +8,6 @@
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
-import { SearchResponse } from 'elasticsearch';
import { IUiSettingsClient, IScopedClusterClient, SharedGlobalConfig } from 'src/core/server';
import type { MsearchRequestBody, MsearchResponse } from '../../../common/search/search_source';
@@ -66,6 +65,7 @@ export function getCallMsearch(dependencies: CallMsearchDependencies) {
try {
const promise = esClient.asCurrentUser.msearch(
{
+ // @ts-expect-error @elastic/elasticsearch client types don't support plain string bodies
body: convertRequestBody(params.body, timeout),
},
{
@@ -78,9 +78,7 @@ export function getCallMsearch(dependencies: CallMsearchDependencies) {
body: {
...response,
body: {
- responses: response.body.responses?.map((r: SearchResponse) =>
- shimHitsTotal(r)
- ),
+ responses: response.body.responses?.map((r) => shimHitsTotal(r)),
},
},
};
diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md
index e04fcdfa08f36..12458d7a74d9f 100644
--- a/src/plugins/data/server/server.api.md
+++ b/src/plugins/data/server/server.api.md
@@ -25,6 +25,7 @@ import { ElasticsearchClient as ElasticsearchClient_2 } from 'kibana/server';
import { Ensure } from '@kbn/utility-types';
import { EnvironmentMode } from '@kbn/config';
import { ErrorToastOptions } from 'src/core/public/notifications';
+import { estypes } from '@elastic/elasticsearch';
import { ExecutionContext } from 'src/plugins/expressions/common';
import { ExpressionAstExpression } from 'src/plugins/expressions/common';
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
@@ -64,7 +65,6 @@ import { SavedObjectsFindOptions } from 'kibana/server';
import { SavedObjectsFindResponse } from 'kibana/server';
import { SavedObjectsUpdateResponse } from 'kibana/server';
import { Search } from '@elastic/elasticsearch/api/requestParams';
-import { SearchResponse } from 'elasticsearch';
import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/expressions/common';
import { SharedGlobalConfig as SharedGlobalConfig_2 } from 'kibana/server';
import { ToastInputFields } from 'src/core/public/notifications';
@@ -596,7 +596,7 @@ export function getTime(indexPattern: IIndexPattern | undefined, timeRange: Time
}): import("../..").RangeFilter | undefined;
// @internal
-export function getTotalLoaded(response: SearchResponse): {
+export function getTotalLoaded(response: estypes.SearchResponse): {
total: number;
loaded: number;
};
@@ -631,7 +631,7 @@ export interface IEsSearchRequest extends IKibanaSearchRequest = IKibanaSearchResponse>;
+export type IEsSearchResponse = IKibanaSearchResponse>;
// Warning: (ae-missing-release-tag) "IFieldFormatsRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@@ -1384,30 +1384,26 @@ export function searchUsageObserver(logger: Logger_2, usage?: SearchUsage, { isR
export const shimAbortSignal: (promise: TransportRequestPromise, signal?: AbortSignal | undefined) => TransportRequestPromise;
// @internal
-export function shimHitsTotal(response: SearchResponse, { legacyHitsTotal }?: ISearchOptions): {
+export function shimHitsTotal(response: estypes.SearchResponse, { legacyHitsTotal }?: ISearchOptions): {
hits: {
total: any;
- max_score: number;
- hits: {
- _index: string;
- _type: string;
- _id: string;
- _score: number;
- _source: unknown;
- _version?: number | undefined;
- _explanation?: import("elasticsearch").Explanation | undefined;
- fields?: any;
- highlight?: any;
- inner_hits?: any;
- matched_queries?: string[] | undefined;
- sort?: string[] | undefined;
- }[];
+ hits: estypes.Hit[];
+ max_score?: number | undefined;
};
took: number;
timed_out: boolean;
+ _shards: estypes.ShardStatistics;
+ aggregations?: Record | undefined;
+ _clusters?: estypes.ClusterStatistics | undefined;
+ documents?: unknown[] | undefined;
+ fields?: Record | undefined;
+ max_score?: number | undefined;
+ num_reduce_phases?: number | undefined;
+ profile?: estypes.Profile | undefined;
+ pit_id?: string | undefined;
_scroll_id?: string | undefined;
- _shards: import("elasticsearch").ShardsResponse;
- aggregations?: any;
+ suggest?: Record[]> | undefined;
+ terminated_early?: boolean | undefined;
};
// Warning: (ae-missing-release-tag) "shouldReadFieldFromDocValues" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@@ -1425,10 +1421,10 @@ export type TimeRange = {
};
// @internal
-export function toKibanaSearchResponse(rawResponse: SearchResponse): {
+export function toKibanaSearchResponse(rawResponse: estypes.SearchResponse): {
total: number;
loaded: number;
- rawResponse: SearchResponse;
+ rawResponse: estypes.SearchResponse;
isPartial: boolean;
isRunning: boolean;
};
diff --git a/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx b/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx
index ba4d56b935512..0202f88e0e902 100644
--- a/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx
+++ b/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx
@@ -9,6 +9,7 @@
import angular, { auto, ICompileService, IScope } from 'angular';
import { render } from 'react-dom';
import React, { useRef, useEffect, useState, useCallback } from 'react';
+import type { estypes } from '@elastic/elasticsearch';
import { EuiButtonEmpty } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { getServices, IIndexPattern } from '../../../kibana_services';
@@ -20,7 +21,7 @@ export interface DocTableLegacyProps {
searchDescription?: string;
searchTitle?: string;
onFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
- rows: Array>;
+ rows: estypes.Hit[];
indexPattern: IIndexPattern;
minimumVisibleRows: number;
onAddColumn?: (column: string) => void;
diff --git a/src/plugins/discover/public/application/components/context_app/context_app_legacy.tsx b/src/plugins/discover/public/application/components/context_app/context_app_legacy.tsx
index 8dded3598c279..5031f78c49fcc 100644
--- a/src/plugins/discover/public/application/components/context_app/context_app_legacy.tsx
+++ b/src/plugins/discover/public/application/components/context_app/context_app_legacy.tsx
@@ -87,6 +87,7 @@ export function ContextAppLegacy(renderProps: ContextAppProps) {
minimumVisibleRows,
useNewFieldsApi,
} = renderProps;
+ // @ts-expect-error doesn't implement full DocTableLegacyProps interface
return {
columns,
indexPattern,
diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx
index 87b9c6243abd8..dbc94e5021294 100644
--- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx
+++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx
@@ -140,7 +140,7 @@ export function DiscoverGridFlyout({
iconType="documents"
flush="left"
href={getContextUrl(
- hit._id,
+ String(hit._id),
indexPattern.id,
columns,
services.filterManager,
diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
index f1025a0881d1f..74cf083d82653 100644
--- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
+++ b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.test.tsx
@@ -10,6 +10,7 @@ import React from 'react';
import { ReactWrapper, shallow } from 'enzyme';
import { getRenderCellValueFn } from './get_render_cell_value';
import { indexPatternMock } from '../../../__mocks__/index_pattern';
+import { ElasticSearchHit } from '../../doc_views/doc_views_types';
jest.mock('../../../../../kibana_react/public', () => ({
useUiSetting: () => true,
@@ -26,7 +27,7 @@ jest.mock('../../../kibana_services', () => ({
}),
}));
-const rowsSource = [
+const rowsSource: ElasticSearchHit[] = [
{
_id: '1',
_index: 'test',
@@ -34,12 +35,12 @@ const rowsSource = [
_score: 1,
_source: { bytes: 100, extension: '.gz' },
highlight: {
- extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ extension: ['@kibana-highlighted-field.gz@/kibana-highlighted-field'],
},
},
];
-const rowsFields = [
+const rowsFields: ElasticSearchHit[] = [
{
_id: '1',
_index: 'test',
@@ -48,12 +49,12 @@ const rowsFields = [
_source: undefined,
fields: { bytes: [100], extension: ['.gz'] },
highlight: {
- extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ extension: ['@kibana-highlighted-field.gz@/kibana-highlighted-field'],
},
},
];
-const rowsFieldsWithTopLevelObject = [
+const rowsFieldsWithTopLevelObject: ElasticSearchHit[] = [
{
_id: '1',
_index: 'test',
@@ -62,7 +63,7 @@ const rowsFieldsWithTopLevelObject = [
_source: undefined,
fields: { 'object.value': [100], extension: ['.gz'] },
highlight: {
- extension: '@kibana-highlighted-field.gz@/kibana-highlighted-field',
+ extension: ['@kibana-highlighted-field.gz@/kibana-highlighted-field'],
},
},
];
@@ -167,7 +168,9 @@ describe('Discover grid cell rendering', function () {
},
"_type": "test",
"highlight": Object {
- "extension": "@kibana-highlighted-field.gz@/kibana-highlighted-field",
+ "extension": Array [
+ "@kibana-highlighted-field.gz@/kibana-highlighted-field",
+ ],
},
}
}
@@ -264,7 +267,9 @@ describe('Discover grid cell rendering', function () {
],
},
"highlight": Object {
- "extension": "@kibana-highlighted-field.gz@/kibana-highlighted-field",
+ "extension": Array [
+ "@kibana-highlighted-field.gz@/kibana-highlighted-field",
+ ],
},
}
}
diff --git a/src/plugins/discover/public/application/components/table/table.test.tsx b/src/plugins/discover/public/application/components/table/table.test.tsx
index 6de41aa0643a5..8997c1d13a474 100644
--- a/src/plugins/discover/public/application/components/table/table.test.tsx
+++ b/src/plugins/discover/public/application/components/table/table.test.tsx
@@ -87,7 +87,7 @@ describe('DocViewTable at Discover', () => {
scripted: 123,
_underscore: 123,
},
- };
+ } as any;
const props = {
hit,
@@ -185,7 +185,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;
const props = {
hit,
columns: ['extension'],
diff --git a/src/plugins/discover/public/application/doc_views/doc_views_types.ts b/src/plugins/discover/public/application/doc_views/doc_views_types.ts
index b06b242ee9ea3..02ac951f7f57c 100644
--- a/src/plugins/discover/public/application/doc_views/doc_views_types.ts
+++ b/src/plugins/discover/public/application/doc_views/doc_views_types.ts
@@ -8,7 +8,7 @@
import { ComponentType } from 'react';
import { IScope } from 'angular';
-import { SearchResponse } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { IndexPattern } from '../../../../data/public';
export interface AngularDirective {
@@ -18,7 +18,7 @@ export interface AngularDirective {
export type AngularScope = IScope;
-export type ElasticSearchHit = SearchResponse['hits']['hits'][number];
+export type ElasticSearchHit = estypes.SearchResponse['hits']['hits'][number];
export interface FieldMapping {
filterable?: boolean;
diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts
index 829d23fa071fb..e7349ed22355a 100644
--- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts
+++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts
@@ -357,7 +357,7 @@ export class SearchEmbeddable
// Apply the changes to the angular scope
this.searchScope.$apply(() => {
this.searchScope!.hits = resp.hits.hits;
- this.searchScope!.totalHitCount = resp.hits.total;
+ this.searchScope!.totalHitCount = resp.hits.total as number;
this.searchScope!.isLoading = false;
});
} catch (error) {
diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md
index 189f71b85206b..b9719542adc81 100644
--- a/src/plugins/embeddable/public/public.api.md
+++ b/src/plugins/embeddable/public/public.api.md
@@ -15,6 +15,7 @@ import * as CSS from 'csstype';
import { DetailedPeerCertificate } from 'tls';
import { EmbeddableStart as EmbeddableStart_2 } from 'src/plugins/embeddable/public/plugin';
import { EnvironmentMode } from '@kbn/config';
+import { estypes } from '@elastic/elasticsearch';
import { EuiBreadcrumb } from '@elastic/eui';
import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui';
diff --git a/src/plugins/index_pattern_management/server/routes/preview_scripted_field.test.ts b/src/plugins/index_pattern_management/server/routes/preview_scripted_field.test.ts
index 385b4f04c40f1..1343b20365a44 100644
--- a/src/plugins/index_pattern_management/server/routes/preview_scripted_field.test.ts
+++ b/src/plugins/index_pattern_management/server/routes/preview_scripted_field.test.ts
@@ -46,8 +46,8 @@ describe('preview_scripted_field route', () => {
expect(mockClient.search.mock.calls[0][0]).toMatchInlineSnapshot(`
Object {
- "_source": undefined,
"body": Object {
+ "_source": undefined,
"query": Object {
"match_all": Object {},
},
@@ -59,10 +59,10 @@ describe('preview_scripted_field route', () => {
},
},
},
+ "size": 10,
+ "timeout": "30s",
},
"index": "kibana_sample_data_logs",
- "size": 10,
- "timeout": "30s",
}
`);
@@ -102,12 +102,12 @@ describe('preview_scripted_field route', () => {
expect(mockClient.search.mock.calls[0][0]).toMatchInlineSnapshot(`
Object {
- "_source": Array [
- "a",
- "b",
- "c",
- ],
"body": Object {
+ "_source": Array [
+ "a",
+ "b",
+ "c",
+ ],
"query": Object {
"bool": Object {
"some": "query",
@@ -121,10 +121,10 @@ describe('preview_scripted_field route', () => {
},
},
},
+ "size": 10,
+ "timeout": "30s",
},
"index": "kibana_sample_data_logs",
- "size": 10,
- "timeout": "30s",
}
`);
});
diff --git a/src/plugins/index_pattern_management/server/routes/preview_scripted_field.ts b/src/plugins/index_pattern_management/server/routes/preview_scripted_field.ts
index 276f6dc0db8bf..cc161859f4189 100644
--- a/src/plugins/index_pattern_management/server/routes/preview_scripted_field.ts
+++ b/src/plugins/index_pattern_management/server/routes/preview_scripted_field.ts
@@ -30,10 +30,10 @@ export function registerPreviewScriptedFieldRoute(router: IRouter): void {
try {
const response = await client.search({
index,
- _source: additionalFields && additionalFields.length > 0 ? additionalFields : undefined,
- size: 10,
- timeout: '30s',
body: {
+ _source: additionalFields && additionalFields.length > 0 ? additionalFields : undefined,
+ size: 10,
+ timeout: '30s',
query: query ?? { match_all: {} },
script_fields: {
[name]: {
diff --git a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
index 52ba793882a1d..42363f71ef87a 100644
--- a/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
+++ b/src/plugins/kibana_usage_collection/server/collectors/kibana/get_saved_object_counts.ts
@@ -58,6 +58,7 @@ export async function getSavedObjectsCounts(
};
const { body } = await esClient.search(savedObjectCountSearchParams);
const buckets: Array<{ key: string; doc_count: number }> =
+ // @ts-expect-error @elastic/elasticsearch Aggregate does not include `buckets`
body.aggregations?.types?.buckets || [];
// Initialise the object with all zeros for all the types
diff --git a/src/plugins/security_oss/server/check_cluster_data.test.ts b/src/plugins/security_oss/server/check_cluster_data.test.ts
index 0670eb3116b07..9e9459a68754c 100644
--- a/src/plugins/security_oss/server/check_cluster_data.test.ts
+++ b/src/plugins/security_oss/server/check_cluster_data.test.ts
@@ -27,6 +27,7 @@ describe('checkClusterForUserData', () => {
it('returns false if data only exists in system indices', async () => {
const esClient = elasticsearchServiceMock.createElasticsearchClient();
esClient.cat.indices.mockResolvedValue(
+ // @ts-expect-error @elastic/elasticsearch ES types don't support array response format
elasticsearchServiceMock.createApiResponse({
body: [
{
@@ -55,6 +56,7 @@ describe('checkClusterForUserData', () => {
it('returns true if data exists in non-system indices', async () => {
const esClient = elasticsearchServiceMock.createElasticsearchClient();
esClient.cat.indices.mockResolvedValue(
+ // @ts-expect-error @elastic/elasticsearch ES types don't support array response format
elasticsearchServiceMock.createApiResponse({
body: [
{
@@ -85,6 +87,7 @@ describe('checkClusterForUserData', () => {
)
.mockRejectedValueOnce(new Error('something terrible happened'))
.mockResolvedValueOnce(
+ // @ts-expect-error @elastic/elasticsearch ES types don't support array response format
elasticsearchServiceMock.createApiResponse({
body: [
{
@@ -95,6 +98,7 @@ describe('checkClusterForUserData', () => {
})
)
.mockResolvedValueOnce(
+ // @ts-expect-error @elastic/elasticsearch ES types don't support array response format
elasticsearchServiceMock.createApiResponse({
body: [
{
diff --git a/src/plugins/security_oss/server/check_cluster_data.ts b/src/plugins/security_oss/server/check_cluster_data.ts
index c8c30196b485c..19a4145333dd0 100644
--- a/src/plugins/security_oss/server/check_cluster_data.ts
+++ b/src/plugins/security_oss/server/check_cluster_data.ts
@@ -14,17 +14,15 @@ export const createClusterDataCheck = () => {
return async function doesClusterHaveUserData(esClient: ElasticsearchClient, log: Logger) {
if (!clusterHasUserData) {
try {
- const indices = await esClient.cat.indices<
- Array<{ index: string; ['docs.count']: string }>
- >({
+ const indices = await esClient.cat.indices({
format: 'json',
h: ['index', 'docs.count'],
});
clusterHasUserData = indices.body.some((indexCount) => {
const isInternalIndex =
- indexCount.index.startsWith('.') || indexCount.index.startsWith('kibana_sample_');
+ indexCount.index?.startsWith('.') || indexCount.index?.startsWith('kibana_sample_');
- return !isInternalIndex && parseInt(indexCount['docs.count'], 10) > 0;
+ return !isInternalIndex && parseInt(indexCount['docs.count']!, 10) > 0;
});
} catch (e) {
log.warn(`Error encountered while checking cluster for user data: ${e}`);
diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts
index 437d76fe7ccf2..3f93bde1e7e62 100644
--- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts
+++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts
@@ -8,22 +8,6 @@
import { ElasticsearchClient } from 'src/core/server';
-// This can be removed when the ES client improves the types
-export interface ESClusterInfo {
- cluster_uuid: string;
- cluster_name: string;
- version: {
- number: string;
- build_flavor?: string;
- build_type?: string;
- build_hash?: string;
- build_date?: string;
- build_snapshot?: boolean;
- lucene_version?: string;
- minimum_wire_compatibility_version?: string;
- minimum_index_compatibility_version?: string;
- };
-}
/**
* Get the cluster info from the connected cluster.
*
@@ -32,6 +16,6 @@ export interface ESClusterInfo {
* @param {function} esClient The asInternalUser handler (exposed for testing)
*/
export async function getClusterInfo(esClient: ElasticsearchClient) {
- const { body } = await esClient.info();
+ const { body } = await esClient.info();
return body;
}
diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts
index 42ccbcc46c462..c79c46072e11b 100644
--- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts
+++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts
@@ -261,14 +261,16 @@ export async function getDataTelemetry(esClient: ElasticsearchClient) {
const indices = indexNames.map((name) => {
const baseIndexInfo = {
name,
- isECS: !!indexMappings[name]?.mappings?.properties.ecs?.properties.version?.type,
+ isECS: !!indexMappings[name]?.mappings?.properties?.ecs?.properties?.version?.type,
shipper: indexMappings[name]?.mappings?._meta?.beat,
packageName: indexMappings[name]?.mappings?._meta?.package?.name,
managedBy: indexMappings[name]?.mappings?._meta?.managed_by,
dataStreamDataset:
- indexMappings[name]?.mappings?.properties.data_stream?.properties.dataset?.value,
+ // @ts-expect-error @elastic/elasticsearch PropertyBase doesn't decalre value
+ indexMappings[name]?.mappings?.properties?.data_stream?.properties?.dataset?.value,
dataStreamType:
- indexMappings[name]?.mappings?.properties.data_stream?.properties.type?.value,
+ // @ts-expect-error @elastic/elasticsearch PropertyBase doesn't decalre value
+ indexMappings[name]?.mappings?.properties?.data_stream?.properties?.type?.value,
};
const stats = (indexStats?.indices || {})[name];
diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts
index 47c6736ff9aea..edf8dbb30809b 100644
--- a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts
+++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts
@@ -7,6 +7,7 @@
*/
import { merge, omit } from 'lodash';
+import type { estypes } from '@elastic/elasticsearch';
import { getLocalStats, handleLocalStats } from './get_local_stats';
import {
@@ -34,35 +35,33 @@ function mockGetLocalStats(clusterInfo: any, clusterStats: any) {
esClient.cluster.stats
// @ts-expect-error we only care about the response body
.mockResolvedValue({ body: { ...clusterStats } });
- esClient.nodes.usage.mockResolvedValue(
+ esClient.nodes.usage.mockResolvedValue({
// @ts-expect-error we only care about the response body
- {
- body: {
- cluster_name: 'testCluster',
- nodes: {
- some_node_id: {
- timestamp: 1588617023177,
- since: 1588616945163,
- rest_actions: {
- nodes_usage_action: 1,
- create_index_action: 1,
- document_get_action: 1,
- search_action: 19,
- nodes_info_action: 36,
+ body: {
+ cluster_name: 'testCluster',
+ nodes: {
+ some_node_id: {
+ timestamp: 1588617023177,
+ since: 1588616945163,
+ rest_actions: {
+ nodes_usage_action: 1,
+ create_index_action: 1,
+ document_get_action: 1,
+ search_action: 19,
+ nodes_info_action: 36,
+ },
+ aggregations: {
+ scripted_metric: {
+ other: 7,
},
- aggregations: {
- terms: {
- bytes: 2,
- },
- scripted_metric: {
- other: 7,
- },
+ terms: {
+ bytes: 2,
},
},
},
},
- }
- );
+ },
+ });
// @ts-expect-error we only care about the response body
esClient.indices.getMapping.mockResolvedValue({ body: { mappings: {} } });
// @ts-expect-error we only care about the response body
@@ -188,7 +187,7 @@ describe('get_local_stats', () => {
describe('handleLocalStats', () => {
it('returns expected object without xpack or kibana data', () => {
const result = handleLocalStats(
- clusterInfo,
+ clusterInfo as estypes.RootNodeInfoResponse,
clusterStatsWithNodesUsage,
void 0,
void 0,
@@ -205,7 +204,7 @@ describe('get_local_stats', () => {
it('returns expected object with xpack', () => {
const result = handleLocalStats(
- clusterInfo,
+ clusterInfo as estypes.RootNodeInfoResponse,
clusterStatsWithNodesUsage,
void 0,
void 0,
diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts
index 710d836576d10..67f9ebb8ff3e4 100644
--- a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts
+++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts
@@ -6,11 +6,12 @@
* Side Public License, v 1.
*/
+import type { estypes } from '@elastic/elasticsearch';
import {
StatsGetter,
StatsCollectionContext,
} from 'src/plugins/telemetry_collection_manager/server';
-import { getClusterInfo, ESClusterInfo } from './get_cluster_info';
+import { getClusterInfo } from './get_cluster_info';
import { getClusterStats } from './get_cluster_stats';
import { getKibana, handleKibanaStats, KibanaUsageStats } from './get_kibana';
import { getNodesUsage } from './get_nodes_usage';
@@ -27,7 +28,7 @@ import { getDataTelemetry, DATA_TELEMETRY_ID, DataTelemetryPayload } from './get
*/
export function handleLocalStats(
// eslint-disable-next-line @typescript-eslint/naming-convention
- { cluster_name, cluster_uuid, version }: ESClusterInfo,
+ { cluster_name, cluster_uuid, version }: estypes.RootNodeInfoResponse,
{ _nodes, cluster_name: clusterName, ...clusterStats }: any,
kibana: KibanaUsageStats | undefined,
dataTelemetry: DataTelemetryPayload | undefined,
diff --git a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts
index 18c6d16447238..e46d4be540734 100644
--- a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts
+++ b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts
@@ -16,7 +16,7 @@ export interface NodeAggregation {
// we set aggregations as an optional type because it was only added in v7.8.0
export interface NodeObj {
node_id?: string;
- timestamp: number;
+ timestamp: number | string;
since: number;
rest_actions: {
[key: string]: number;
@@ -46,9 +46,10 @@ export type NodesUsageGetter = (
export async function fetchNodesUsage(
esClient: ElasticsearchClient
): Promise {
- const { body } = await esClient.nodes.usage({
+ const { body } = await esClient.nodes.usage({
timeout: TIMEOUT,
});
+ // @ts-expect-error TODO: Does the client parse `timestamp` to a Date object? Expected a number
return body;
}
diff --git a/src/plugins/vis_type_vega/public/data_model/types.ts b/src/plugins/vis_type_vega/public/data_model/types.ts
index 042ffac583e98..8590b51d3b5ff 100644
--- a/src/plugins/vis_type_vega/public/data_model/types.ts
+++ b/src/plugins/vis_type_vega/public/data_model/types.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { SearchResponse, SearchParams } from 'elasticsearch';
+import type { estypes } from '@elastic/elasticsearch';
import { Filter } from 'src/plugins/data/public';
import { DslQuery } from 'src/plugins/data/common';
@@ -17,7 +17,7 @@ import { EmsFileParser } from './ems_file_parser';
import { UrlParser } from './url_parser';
interface Body {
- aggs?: SearchParams['body']['aggs'];
+ aggs?: Record;
query?: Query;
timeout?: string;
}
@@ -76,7 +76,7 @@ interface Projection {
interface RequestDataObject {
name?: string;
url?: TUrlData;
- values: SearchResponse;
+ values: estypes.SearchResponse;
}
type ContextVarsObjectProps =
diff --git a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts
index 8d3512aa2138e..d5f8d978d5252 100644
--- a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts
+++ b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts
@@ -7,14 +7,12 @@
*/
import { parse } from 'hjson';
-import { SearchResponse } from 'elasticsearch';
import { ElasticsearchClient, SavedObject } from 'src/core/server';
import { VegaSavedObjectAttributes, VisTypeVegaPluginSetupDependencies } from '../types';
type UsageCollectorDependencies = Pick;
-type ESResponse = SearchResponse<{ visualization: { visState: string } }>;
type VegaType = 'vega' | 'vega-lite';
function isVegaType(attributes: any): attributes is VegaSavedObjectAttributes {
@@ -80,7 +78,9 @@ export const getStats = async (
},
};
- const { body: esResponse } = await esClient.search(searchParams);
+ const { body: esResponse } = await esClient.search<{ visualization: { visState: string } }>(
+ searchParams
+ );
const size = esResponse?.hits?.hits?.length ?? 0;
if (!size) {
diff --git a/src/plugins/visualizations/server/usage_collector/get_usage_collector.ts b/src/plugins/visualizations/server/usage_collector/get_usage_collector.ts
index 164d5b5fa72ac..89e1e7f03e149 100644
--- a/src/plugins/visualizations/server/usage_collector/get_usage_collector.ts
+++ b/src/plugins/visualizations/server/usage_collector/get_usage_collector.ts
@@ -61,7 +61,7 @@ export async function getStats(
// `map` to get the raw types
const visSummaries: VisSummary[] = esResponse.hits.hits.map((hit) => {
- const spacePhrases = hit._id.split(':');
+ const spacePhrases = hit._id.toString().split(':');
const lastUpdated: string = get(hit, '_source.updated_at');
const space = spacePhrases.length === 3 ? spacePhrases[0] : 'default'; // if in a custom space, the format of a saved object ID is space:type:id
const visualization = get(hit, '_source.visualization', { visState: '{}' });
diff --git a/test/api_integration/apis/home/sample_data.ts b/test/api_integration/apis/home/sample_data.ts
index b889b59fdaf32..99327901ec8c3 100644
--- a/test/api_integration/apis/home/sample_data.ts
+++ b/test/api_integration/apis/home/sample_data.ts
@@ -48,12 +48,12 @@ export default function ({ getService }: FtrProviderContext) {
});
it('should load elasticsearch index containing sample data with dates relative to current time', async () => {
- const { body: resp } = await es.search({
+ const { body: resp } = await es.search<{ timestamp: string }>({
index: 'kibana_sample_data_flights',
});
const doc = resp.hits.hits[0];
- const docMilliseconds = Date.parse(doc._source.timestamp);
+ const docMilliseconds = Date.parse(doc._source!.timestamp);
const nowMilliseconds = Date.now();
const delta = Math.abs(nowMilliseconds - docMilliseconds);
expect(delta).to.be.lessThan(MILLISECOND_IN_WEEK * 4);
@@ -66,12 +66,12 @@ export default function ({ getService }: FtrProviderContext) {
.post(`/api/sample_data/flights?now=${nowString}`)
.set('kbn-xsrf', 'kibana');
- const { body: resp } = await es.search({
+ const { body: resp } = await es.search<{ timestamp: string }>({
index: 'kibana_sample_data_flights',
});
const doc = resp.hits.hits[0];
- const docMilliseconds = Date.parse(doc._source.timestamp);
+ const docMilliseconds = Date.parse(doc._source!.timestamp);
const nowMilliseconds = Date.parse(nowString);
const delta = Math.abs(nowMilliseconds - docMilliseconds);
expect(delta).to.be.lessThan(MILLISECOND_IN_WEEK * 4);
diff --git a/test/api_integration/apis/saved_objects/migrations.ts b/test/api_integration/apis/saved_objects/migrations.ts
index 1f1f1a5c98cd6..87997ab4231a2 100644
--- a/test/api_integration/apis/saved_objects/migrations.ts
+++ b/test/api_integration/apis/saved_objects/migrations.ts
@@ -15,7 +15,7 @@ import { set } from '@elastic/safer-lodash-set';
import _ from 'lodash';
import expect from '@kbn/expect';
import { ElasticsearchClient, SavedObjectsType } from 'src/core/server';
-import { SearchResponse } from '../../../../src/core/server/elasticsearch/client';
+
import {
DocumentMigrator,
IndexMigrator,
@@ -113,7 +113,7 @@ export default ({ getService }: FtrProviderContext) => {
await esClient.indices.putTemplate({
name: 'migration_test_a_template',
body: {
- index_patterns: 'migration_test_a',
+ index_patterns: ['migration_test_a'],
mappings: {
dynamic: 'strict',
properties: { baz: { type: 'text' } },
@@ -125,7 +125,7 @@ export default ({ getService }: FtrProviderContext) => {
await esClient.indices.putTemplate({
name: 'migration_a_template',
body: {
- index_patterns: index,
+ index_patterns: [index],
mappings: {
dynamic: 'strict',
properties: { baz: { type: 'text' } },
@@ -744,7 +744,7 @@ async function migrateIndex({
}
async function fetchDocs(esClient: ElasticsearchClient, index: string) {
- const { body } = await esClient.search>({ index });
+ const { body } = await esClient.search({ index });
return body.hits.hits
.map((h) => ({
diff --git a/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts b/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts
index 2c58794c96eca..a76d09481eca1 100644
--- a/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts
+++ b/test/api_integration/apis/telemetry/telemetry_optin_notice_seen.ts
@@ -26,15 +26,13 @@ export default function optInTest({ getService }: FtrProviderContext) {
await supertest.put('/api/telemetry/v2/userHasSeenNotice').set('kbn-xsrf', 'xxx').expect(200);
const {
- body: {
- _source: { telemetry },
- },
- } = await client.get({
+ body: { _source },
+ } = await client.get<{ telemetry: { userHasSeenNotice: boolean } }>({
index: '.kibana',
id: 'telemetry:telemetry',
});
- expect(telemetry.userHasSeenNotice).to.be(true);
+ expect(_source?.telemetry.userHasSeenNotice).to.be(true);
});
});
}
diff --git a/test/api_integration/apis/ui_metric/ui_metric.ts b/test/api_integration/apis/ui_metric/ui_metric.ts
index 99007376e1ea4..47d10da9a1b29 100644
--- a/test/api_integration/apis/ui_metric/ui_metric.ts
+++ b/test/api_integration/apis/ui_metric/ui_metric.ts
@@ -102,12 +102,12 @@ export default function ({ getService }: FtrProviderContext) {
body: {
hits: { hits },
},
- } = await es.search({ index: '.kibana', q: 'type:ui-metric' });
+ } = await es.search({ index: '.kibana', q: 'type:ui-metric' });
const countTypeEvent = hits.find(
(hit: { _id: string }) => hit._id === `ui-metric:myApp:${uniqueEventName}`
);
- expect(countTypeEvent._source['ui-metric'].count).to.eql(3);
+ expect(countTypeEvent?._source['ui-metric'].count).to.eql(3);
});
});
}
diff --git a/test/common/services/elasticsearch.ts b/test/common/services/elasticsearch.ts
index 99335f8405828..7b8ff6bd6c8f4 100644
--- a/test/common/services/elasticsearch.ts
+++ b/test/common/services/elasticsearch.ts
@@ -10,10 +10,14 @@ import { format as formatUrl } from 'url';
import fs from 'fs';
import { Client } from '@elastic/elasticsearch';
import { CA_CERT_PATH } from '@kbn/dev-utils';
+import type { KibanaClient } from '@elastic/elasticsearch/api/kibana';
import { FtrProviderContext } from '../ftr_provider_context';
-export function ElasticsearchProvider({ getService }: FtrProviderContext) {
+/*
+ registers Kibana-specific @elastic/elasticsearch client instance.
+ */
+export function ElasticsearchProvider({ getService }: FtrProviderContext): KibanaClient {
const config = getService('config');
if (process.env.TEST_CLOUD) {
diff --git a/typings/elasticsearch/aggregations.d.ts b/typings/elasticsearch/aggregations.d.ts
deleted file mode 100644
index 2b501c94889f4..0000000000000
--- a/typings/elasticsearch/aggregations.d.ts
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { Unionize, UnionToIntersection } from 'utility-types';
-import { ESSearchHit, MaybeReadonlyArray, ESSourceOptions, ESHitsOf } from '.';
-
-export type SortOrder = 'asc' | 'desc';
-type SortInstruction = Record;
-export type SortOptions = SortOrder | SortInstruction | SortInstruction[];
-
-type Script =
- | string
- | {
- lang?: string;
- id?: string;
- source?: string;
- params?: Record;
- };
-
-type BucketsPath = string | Record;
-
-type AggregationSourceOptions =
- | {
- field: string;
- missing?: unknown;
- }
- | {
- script: Script;
- };
-
-interface MetricsAggregationResponsePart {
- value: number | null;
-}
-interface DateHistogramBucket {
- doc_count: number;
- key: number;
- key_as_string: string;
-}
-
-type GetCompositeKeys<
- TAggregationOptionsMap extends AggregationOptionsMap
-> = TAggregationOptionsMap extends {
- composite: { sources: Array };
-}
- ? keyof Source
- : never;
-
-type CompositeOptionsSource = Record<
- string,
- | {
- terms: ({ field: string } | { script: Script }) & {
- missing_bucket?: boolean;
- };
- }
- | undefined
->;
-
-export interface AggregationOptionsByType {
- terms: {
- size?: number;
- order?: SortOptions;
- execution_hint?: 'map' | 'global_ordinals';
- } & AggregationSourceOptions;
- date_histogram: {
- format?: string;
- min_doc_count?: number;
- extended_bounds?: {
- min: number;
- max: number;
- };
- } & ({ calendar_interval: string } | { fixed_interval: string }) &
- AggregationSourceOptions;
- histogram: {
- interval: number;
- min_doc_count?: number;
- extended_bounds?: {
- min?: number | string;
- max?: number | string;
- };
- } & AggregationSourceOptions;
- avg: AggregationSourceOptions;
- max: AggregationSourceOptions;
- min: AggregationSourceOptions;
- sum: AggregationSourceOptions;
- value_count: AggregationSourceOptions;
- cardinality: AggregationSourceOptions & {
- precision_threshold?: number;
- };
- percentiles: {
- percents?: number[];
- hdr?: { number_of_significant_value_digits: number };
- } & AggregationSourceOptions;
- stats: {
- field: string;
- };
- extended_stats: {
- field: string;
- };
- string_stats: { field: string };
- top_hits: {
- from?: number;
- size?: number;
- sort?: SortOptions;
- _source?: ESSourceOptions;
- fields?: MaybeReadonlyArray;
- docvalue_fields?: MaybeReadonlyArray;
- };
- filter: Record;
- filters: {
- filters: Record | any[];
- };
- sampler: {
- shard_size?: number;
- };
- derivative: {
- buckets_path: BucketsPath;
- };
- bucket_script: {
- buckets_path: BucketsPath;
- script?: Script;
- };
- composite: {
- size?: number;
- sources: CompositeOptionsSource[];
- after?: Record;
- };
- diversified_sampler: {
- shard_size?: number;
- max_docs_per_value?: number;
- } & ({ script: Script } | { field: string }); // TODO use MetricsAggregationOptions if possible
- scripted_metric: {
- params?: Record;
- init_script?: Script;
- map_script: Script;
- combine_script: Script;
- reduce_script: Script;
- };
- date_range: {
- format?: string;
- ranges: Array<
- | { from: string | number }
- | { to: string | number }
- | { from: string | number; to: string | number }
- >;
- keyed?: boolean;
- } & AggregationSourceOptions;
- range: {
- field: string;
- ranges: Array<
- | { key?: string; from: string | number }
- | { key?: string; to: string | number }
- | { key?: string; from: string | number; to: string | number }
- >;
- keyed?: boolean;
- };
- auto_date_histogram: {
- buckets: number;
- } & AggregationSourceOptions;
- percentile_ranks: {
- values: Array;
- keyed?: boolean;
- hdr?: { number_of_significant_value_digits: number };
- } & AggregationSourceOptions;
- bucket_sort: {
- sort?: SortOptions;
- from?: number;
- size?: number;
- };
- significant_terms: {
- size?: number;
- field?: string;
- background_filter?: Record;
- } & AggregationSourceOptions;
- bucket_selector: {
- buckets_path: {
- [x: string]: string;
- };
- script: string;
- };
- top_metrics: {
- metrics: { field: string } | MaybeReadonlyArray<{ field: string }>;
- sort: SortOptions;
- };
- avg_bucket: {
- buckets_path: string;
- gap_policy?: 'skip' | 'insert_zeros';
- format?: string;
- };
- rate: {
- unit: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
- } & (
- | {
- field: string;
- mode: 'sum' | 'value_count';
- }
- | {}
- );
-}
-
-type AggregationType = keyof AggregationOptionsByType;
-
-type AggregationOptionsMap = Unionize<
- {
- [TAggregationType in AggregationType]: AggregationOptionsByType[TAggregationType];
- }
-> & { aggs?: AggregationInputMap };
-
-interface DateRangeBucket {
- key: string;
- to?: number;
- from?: number;
- to_as_string?: string;
- from_as_string?: string;
- doc_count: number;
-}
-
-export interface AggregationInputMap {
- [key: string]: AggregationOptionsMap;
-}
-
-type SubAggregationResponseOf<
- TAggregationInputMap extends AggregationInputMap | undefined,
- TDocument
-> = TAggregationInputMap extends AggregationInputMap
- ? AggregationResponseMap
- : {};
-
-interface AggregationResponsePart {
- terms: {
- buckets: Array<
- {
- doc_count: number;
- key: string | number;
- } & SubAggregationResponseOf
- >;
- doc_count_error_upper_bound?: number;
- sum_other_doc_count?: number;
- };
- histogram: {
- buckets: Array<
- {
- doc_count: number;
- key: number;
- } & SubAggregationResponseOf
- >;
- };
- date_histogram: {
- buckets: Array<
- DateHistogramBucket & SubAggregationResponseOf
- >;
- };
- avg: MetricsAggregationResponsePart;
- sum: MetricsAggregationResponsePart;
- max: MetricsAggregationResponsePart;
- min: MetricsAggregationResponsePart;
- value_count: { value: number };
- cardinality: {
- value: number;
- };
- percentiles: {
- values: Record;
- };
- stats: {
- count: number;
- min: number | null;
- max: number | null;
- avg: number | null;
- sum: number | null;
- };
- extended_stats: {
- count: number;
- min: number | null;
- max: number | null;
- avg: number | null;
- sum: number | null;
- sum_of_squares: number | null;
- variance: number | null;
- std_deviation: number | null;
- std_deviation_bounds: {
- upper: number | null;
- lower: number | null;
- };
- };
- string_stats: {
- count: number;
- min_length: number;
- max_length: number;
- avg_length: number;
- entropy: number;
- };
- top_hits: {
- hits: {
- total: {
- value: number;
- relation: 'eq' | 'gte';
- };
- max_score: number | null;
- hits: TAggregationOptionsMap extends { top_hits: AggregationOptionsByType['top_hits'] }
- ? ESHitsOf
- : ESSearchHit[];
- };
- };
- filter: {
- doc_count: number;
- } & SubAggregationResponseOf;
- filters: TAggregationOptionsMap extends { filters: { filters: any[] } }
- ? Array<
- { doc_count: number } & AggregationResponseMap
- >
- : TAggregationOptionsMap extends {
- filters: {
- filters: Record;
- };
- }
- ? {
- buckets: {
- [key in keyof TAggregationOptionsMap['filters']['filters']]: {
- doc_count: number;
- } & SubAggregationResponseOf;
- };
- }
- : never;
- sampler: {
- doc_count: number;
- } & SubAggregationResponseOf;
- derivative:
- | {
- value: number;
- }
- | undefined;
- bucket_script:
- | {
- value: number | null;
- }
- | undefined;
- composite: {
- after_key: {
- [key in GetCompositeKeys]: TAggregationOptionsMap;
- };
- buckets: Array<
- {
- key: Record, string | number>;
- doc_count: number;
- } & SubAggregationResponseOf
- >;
- };
- diversified_sampler: {
- doc_count: number;
- } & AggregationResponseMap;
- scripted_metric: {
- value: unknown;
- };
- date_range: {
- buckets: TAggregationOptionsMap extends { date_range: { keyed: true } }
- ? Record
- : { buckets: DateRangeBucket[] };
- };
- range: {
- buckets: TAggregationOptionsMap extends { range: { keyed: true } }
- ? Record<
- string,
- DateRangeBucket & SubAggregationResponseOf
- >
- : Array<
- DateRangeBucket & SubAggregationResponseOf
- >;
- };
- auto_date_histogram: {
- buckets: Array<
- DateHistogramBucket & AggregationResponseMap
- >;
- interval: string;
- };
-
- percentile_ranks: {
- values: TAggregationOptionsMap extends {
- percentile_ranks: { keyed: false };
- }
- ? Array<{ key: number; value: number }>
- : Record;
- };
- significant_terms: {
- doc_count: number;
- bg_count: number;
- buckets: Array<
- {
- score: number;
- bg_count: number;
- doc_count: number;
- key: string | number;
- } & SubAggregationResponseOf
- >;
- };
- bucket_sort: undefined;
- bucket_selector: undefined;
- top_metrics: {
- top: [
- {
- sort: [string | number];
- metrics: UnionToIntersection<
- TAggregationOptionsMap extends {
- top_metrics: { metrics: { field: infer TFieldName } };
- }
- ? TopMetricsMap
- : TAggregationOptionsMap extends {
- top_metrics: { metrics: MaybeReadonlyArray<{ field: infer TFieldName }> };
- }
- ? TopMetricsMap
- : TopMetricsMap
- >;
- }
- ];
- };
- avg_bucket: {
- value: number | null;
- };
- rate: {
- value: number | null;
- };
-}
-
-type TopMetricsMap = TFieldName extends string
- ? Record
- : Record;
-
-// Type for debugging purposes. If you see an error in AggregationResponseMap
-// similar to "cannot be used to index type", uncomment the type below and hover
-// over it to see what aggregation response types are missing compared to the
-// input map.
-
-// type MissingAggregationResponseTypes = Exclude<
-// AggregationType,
-// keyof AggregationResponsePart<{}, unknown>
-// >;
-
-// ensures aggregations work with requests where aggregation options are a union type,
-// e.g. { transaction_groups: { composite: any } | { terms: any } }.
-// Union keys are not included in keyof. The type will fall back to keyof T if
-// UnionToIntersection fails, which happens when there are conflicts between the union
-// types, e.g. { foo: string; bar?: undefined } | { foo?: undefined; bar: string };
-export type ValidAggregationKeysOf<
- T extends Record
-> = keyof (UnionToIntersection extends never ? T : UnionToIntersection);
-
-export type AggregationResultOf<
- TAggregationOptionsMap extends AggregationOptionsMap,
- TDocument
-> = AggregationResponsePart[AggregationType &
- ValidAggregationKeysOf];
-
-export type AggregationResponseMap<
- TAggregationInputMap extends AggregationInputMap | undefined,
- TDocument
-> = TAggregationInputMap extends AggregationInputMap
- ? {
- [TName in keyof TAggregationInputMap]: AggregationResponsePart<
- TAggregationInputMap[TName],
- TDocument
- >[AggregationType & ValidAggregationKeysOf];
- }
- : undefined;
diff --git a/typings/elasticsearch/index.d.ts b/typings/elasticsearch/index.d.ts
index a84d4148f6fe7..7eaf762d353ac 100644
--- a/typings/elasticsearch/index.d.ts
+++ b/typings/elasticsearch/index.d.ts
@@ -5,136 +5,28 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
+import { estypes } from '@elastic/elasticsearch';
+import { InferSearchResponseOf, AggregateOf as AggregationResultOf, SearchHit } from './search';
-import { ValuesType } from 'utility-types';
-import { Explanation, SearchParams, SearchResponse } from 'elasticsearch';
-import { RequestParams } from '@elastic/elasticsearch';
-import { AggregationResponseMap, AggregationInputMap, SortOptions } from './aggregations';
-export {
- AggregationInputMap,
- AggregationOptionsByType,
- AggregationResponseMap,
- AggregationResultOf,
- SortOptions,
- ValidAggregationKeysOf,
-} from './aggregations';
+export type ESFilter = estypes.QueryContainer;
+export type ESSearchRequest = estypes.SearchRequest;
+export type AggregationOptionsByType = Required;
// Typings for Elasticsearch queries and aggregations. These are intended to be
// moved to the Elasticsearch JS client at some point (see #77720.)
export type MaybeReadonlyArray = T[] | readonly T[];
-interface CollapseQuery {
- field: string;
- inner_hits?: {
- name: string;
- size?: number;
- sort?: SortOptions;
- _source?:
- | string
- | string[]
- | {
- includes?: string | string[];
- excludes?: string | string[];
- };
- collapse?: {
- field: string;
- };
- };
- max_concurrent_group_searches?: number;
-}
-
export type ESSourceOptions = boolean | string | string[];
-export type ESHitsOf<
- TOptions extends
- | {
- size?: number;
- _source?: ESSourceOptions;
- docvalue_fields?: MaybeReadonlyArray;
- fields?: MaybeReadonlyArray;
- }
- | undefined,
- TDocument extends unknown
-> = Array<
- ESSearchHit<
- TOptions extends { _source: false } ? undefined : TDocument,
- TOptions extends { fields: MaybeReadonlyArray } ? TOptions['fields'] : undefined,
- TOptions extends { docvalue_fields: MaybeReadonlyArray }
- ? TOptions['docvalue_fields']
- : undefined
- >
->;
-
-export interface ESSearchBody {
- query?: any;
- size?: number;
- from?: number;
- aggs?: AggregationInputMap;
- track_total_hits?: boolean | number;
- collapse?: CollapseQuery;
- search_after?: Array;
- _source?: ESSourceOptions;
-}
-
-export type ESSearchRequest = RequestParams.Search;
-
export interface ESSearchOptions {
restTotalHitsAsInt: boolean;
}
-export type ESSearchHit<
- TSource extends any = unknown,
- TFields extends MaybeReadonlyArray | undefined = undefined,
- TDocValueFields extends MaybeReadonlyArray | undefined = undefined
-> = {
- _index: string;
- _type: string;
- _id: string;
- _score: number;
- _version?: number;
- _explanation?: Explanation;
- highlight?: any;
- inner_hits?: any;
- matched_queries?: string[];
- sort?: string[];
-} & (TSource extends false ? {} : { _source: TSource }) &
- (TFields extends MaybeReadonlyArray
- ? {
- fields: Partial, unknown[]>>;
- }
- : {}) &
- (TDocValueFields extends MaybeReadonlyArray
- ? {
- fields: Partial, unknown[]>>;
- }
- : {});
-
export type ESSearchResponse<
- TDocument,
- TSearchRequest extends ESSearchRequest,
- TOptions extends ESSearchOptions = { restTotalHitsAsInt: false }
-> = Omit, 'aggregations' | 'hits'> &
- (TSearchRequest extends { body: { aggs: AggregationInputMap } }
- ? {
- aggregations?: AggregationResponseMap;
- }
- : {}) & {
- hits: Omit['hits'], 'total' | 'hits'> &
- (TOptions['restTotalHitsAsInt'] extends true
- ? {
- total: number;
- }
- : {
- total: {
- value: number;
- relation: 'eq' | 'gte';
- };
- }) & { hits: ESHitsOf