[Regression] Histogram aggregation always shows an error message (#63484) (#64211)

* WIP [Regression] Histogram aggregation always shows an error message

Closes: #62624

* make getInternalStartServices private

* fix ts issues

* remove createSearchSource from static contract

* fix some jest test

* move searh_source to static contract

* fix types

* fix function tests

* fix jest / add createStartServicesGetter

* fix comments: saved_object_management

* maps: fix PR comments

* maps: update types

* fix heck_published_api_changes

* move searchSource into runtime contract

* cleanup

* fix ts error

* cleanup

* remove extra dependencies

* fix Discover

* fix Discover JEST

* fix PR comments

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
# Conflicts:
#	src/plugins/data/public/public.api.md
This commit is contained in:
Alexey Antonov 2020-04-22 22:06:17 +03:00 committed by GitHub
parent fa509f1fd8
commit c4cff972d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
108 changed files with 1009 additions and 1295 deletions

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [createSearchSource](./kibana-plugin-plugins-data-public.createsearchsource.md)
## createSearchSource variable
Deserializes a json string and a set of referenced objects to a `SearchSource` instance. Use this method to re-create the search source serialized using `searchSource.serialize`<!-- -->.
This function is a factory function that returns the actual utility when calling it with the required service dependency (index patterns contract). A pre-wired version is also exposed in the start contract of the data plugin as part of the search service
<b>Signature:</b>
```typescript
createSearchSource: (indexPatterns: Pick<import("../../index_patterns/index_patterns").IndexPatternsService, "get" | "clearCache" | "getFieldsForTimePattern" | "getFieldsForWildcard" | "getIds" | "getTitles" | "getFields" | "getCache" | "getDefault" | "make">) => (searchSourceJson: string, references: SavedObjectReference[]) => Promise<SearchSource>
```

View file

@ -4,6 +4,8 @@
## ISearchSource type ## ISearchSource type
\*
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript

View file

@ -21,7 +21,6 @@
| [RequestTimeoutError](./kibana-plugin-plugins-data-public.requesttimeouterror.md) | Class used to signify that a request timed out. Useful for applications to conditionally handle this type of error differently than other errors. | | [RequestTimeoutError](./kibana-plugin-plugins-data-public.requesttimeouterror.md) | Class used to signify that a request timed out. Useful for applications to conditionally handle this type of error differently than other errors. |
| [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) | | | [SearchError](./kibana-plugin-plugins-data-public.searcherror.md) | |
| [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) | | | [SearchInterceptor](./kibana-plugin-plugins-data-public.searchinterceptor.md) | |
| [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) | |
| [TimeHistory](./kibana-plugin-plugins-data-public.timehistory.md) | | | [TimeHistory](./kibana-plugin-plugins-data-public.timehistory.md) | |
## Enumerations ## Enumerations
@ -101,7 +100,6 @@
| [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-public.castestokbnfieldtypename.md) | Get the KbnFieldType name for an esType string | | [castEsToKbnFieldTypeName](./kibana-plugin-plugins-data-public.castestokbnfieldtypename.md) | Get the KbnFieldType name for an esType string |
| [connectToQueryState](./kibana-plugin-plugins-data-public.connecttoquerystate.md) | Helper to setup two-way syncing of global data and a state container | | [connectToQueryState](./kibana-plugin-plugins-data-public.connecttoquerystate.md) | Helper to setup two-way syncing of global data and a state container |
| [createSavedQueryService](./kibana-plugin-plugins-data-public.createsavedqueryservice.md) | | | [createSavedQueryService](./kibana-plugin-plugins-data-public.createsavedqueryservice.md) | |
| [createSearchSource](./kibana-plugin-plugins-data-public.createsearchsource.md) | Deserializes a json string and a set of referenced objects to a <code>SearchSource</code> instance. Use this method to re-create the search source serialized using <code>searchSource.serialize</code>.<!-- -->This function is a factory function that returns the actual utility when calling it with the required service dependency (index patterns contract). A pre-wired version is also exposed in the start contract of the data plugin as part of the search service |
| [ES\_SEARCH\_STRATEGY](./kibana-plugin-plugins-data-public.es_search_strategy.md) | | | [ES\_SEARCH\_STRATEGY](./kibana-plugin-plugins-data-public.es_search_strategy.md) | |
| [esFilters](./kibana-plugin-plugins-data-public.esfilters.md) | | | [esFilters](./kibana-plugin-plugins-data-public.esfilters.md) | |
| [esKuery](./kibana-plugin-plugins-data-public.eskuery.md) | | | [esKuery](./kibana-plugin-plugins-data-public.eskuery.md) | |
@ -140,7 +138,7 @@
| [IpRangeKey](./kibana-plugin-plugins-data-public.iprangekey.md) | | | [IpRangeKey](./kibana-plugin-plugins-data-public.iprangekey.md) | |
| [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | | | [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | |
| [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | | | [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | |
| [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | | | [ISearchSource](./kibana-plugin-plugins-data-public.isearchsource.md) | \* |
| [MatchAllFilter](./kibana-plugin-plugins-data-public.matchallfilter.md) | | | [MatchAllFilter](./kibana-plugin-plugins-data-public.matchallfilter.md) | |
| [ParsedInterval](./kibana-plugin-plugins-data-public.parsedinterval.md) | | | [ParsedInterval](./kibana-plugin-plugins-data-public.parsedinterval.md) | |
| [PhraseFilter](./kibana-plugin-plugins-data-public.phrasefilter.md) | | | [PhraseFilter](./kibana-plugin-plugins-data-public.phrasefilter.md) | |

View file

@ -1,20 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [(constructor)](./kibana-plugin-plugins-data-public.searchsource._constructor_.md)
## SearchSource.(constructor)
Constructs a new instance of the `SearchSource` class
<b>Signature:</b>
```typescript
constructor(fields?: SearchSourceFields);
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| fields | <code>SearchSourceFields</code> | |

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [create](./kibana-plugin-plugins-data-public.searchsource.create.md)
## SearchSource.create() method
<b>Signature:</b>
```typescript
create(): SearchSource;
```
<b>Returns:</b>
`SearchSource`

View file

@ -1,22 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [createChild](./kibana-plugin-plugins-data-public.searchsource.createchild.md)
## SearchSource.createChild() method
<b>Signature:</b>
```typescript
createChild(options?: {}): SearchSource;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>{}</code> | |
<b>Returns:</b>
`SearchSource`

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [createCopy](./kibana-plugin-plugins-data-public.searchsource.createcopy.md)
## SearchSource.createCopy() method
<b>Signature:</b>
```typescript
createCopy(): SearchSource;
```
<b>Returns:</b>
`SearchSource`

View file

@ -1,17 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [destroy](./kibana-plugin-plugins-data-public.searchsource.destroy.md)
## SearchSource.destroy() method
Completely destroy the SearchSource. {<!-- -->undefined<!-- -->}
<b>Signature:</b>
```typescript
destroy(): void;
```
<b>Returns:</b>
`void`

View file

@ -1,25 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [fetch](./kibana-plugin-plugins-data-public.searchsource.fetch.md)
## SearchSource.fetch() method
Fetch this source and reject the returned Promise on error
<b>Signature:</b>
```typescript
fetch(options?: FetchOptions): Promise<any>;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>FetchOptions</code> | |
<b>Returns:</b>
`Promise<any>`

View file

@ -1,25 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getField](./kibana-plugin-plugins-data-public.searchsource.getfield.md)
## SearchSource.getField() method
Get fields from the fields
<b>Signature:</b>
```typescript
getField<K extends keyof SearchSourceFields>(field: K, recurse?: boolean): SearchSourceFields[K];
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| field | <code>K</code> | |
| recurse | <code>boolean</code> | |
<b>Returns:</b>
`SearchSourceFields[K]`

View file

@ -1,49 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getFields](./kibana-plugin-plugins-data-public.searchsource.getfields.md)
## SearchSource.getFields() method
<b>Signature:</b>
```typescript
getFields(): {
type?: string | undefined;
query?: import("../..").Query | undefined;
filter?: Filter | Filter[] | (() => Filter | Filter[] | undefined) | undefined;
sort?: Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric> | Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric>[] | undefined;
highlight?: any;
highlightAll?: boolean | undefined;
aggs?: any;
from?: number | undefined;
size?: number | undefined;
source?: string | boolean | string[] | undefined;
version?: boolean | undefined;
fields?: string | boolean | string[] | undefined;
index?: import("../..").IndexPattern | undefined;
searchAfter?: import("./types").EsQuerySearchAfter | undefined;
timeout?: string | undefined;
terminate_after?: number | undefined;
};
```
<b>Returns:</b>
`{
type?: string | undefined;
query?: import("../..").Query | undefined;
filter?: Filter | Filter[] | (() => Filter | Filter[] | undefined) | undefined;
sort?: Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric> | Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric>[] | undefined;
highlight?: any;
highlightAll?: boolean | undefined;
aggs?: any;
from?: number | undefined;
size?: number | undefined;
source?: string | boolean | string[] | undefined;
version?: boolean | undefined;
fields?: string | boolean | string[] | undefined;
index?: import("../..").IndexPattern | undefined;
searchAfter?: import("./types").EsQuerySearchAfter | undefined;
timeout?: string | undefined;
terminate_after?: number | undefined;
}`

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getId](./kibana-plugin-plugins-data-public.searchsource.getid.md)
## SearchSource.getId() method
<b>Signature:</b>
```typescript
getId(): string;
```
<b>Returns:</b>
`string`

View file

@ -1,24 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getOwnField](./kibana-plugin-plugins-data-public.searchsource.getownfield.md)
## SearchSource.getOwnField() method
Get the field from our own fields, don't traverse up the chain
<b>Signature:</b>
```typescript
getOwnField<K extends keyof SearchSourceFields>(field: K): SearchSourceFields[K];
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| field | <code>K</code> | |
<b>Returns:</b>
`SearchSourceFields[K]`

View file

@ -1,17 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getParent](./kibana-plugin-plugins-data-public.searchsource.getparent.md)
## SearchSource.getParent() method
Get the parent of this SearchSource {<!-- -->undefined\|searchSource<!-- -->}
<b>Signature:</b>
```typescript
getParent(): SearchSource | undefined;
```
<b>Returns:</b>
`SearchSource | undefined`

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [getSearchRequestBody](./kibana-plugin-plugins-data-public.searchsource.getsearchrequestbody.md)
## SearchSource.getSearchRequestBody() method
<b>Signature:</b>
```typescript
getSearchRequestBody(): Promise<any>;
```
<b>Returns:</b>
`Promise<any>`

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [history](./kibana-plugin-plugins-data-public.searchsource.history.md)
## SearchSource.history property
<b>Signature:</b>
```typescript
history: SearchRequest[];
```

View file

@ -1,46 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md)
## SearchSource class
<b>Signature:</b>
```typescript
export declare class SearchSource
```
## Constructors
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(fields)](./kibana-plugin-plugins-data-public.searchsource._constructor_.md) | | Constructs a new instance of the <code>SearchSource</code> class |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [history](./kibana-plugin-plugins-data-public.searchsource.history.md) | | <code>SearchRequest[]</code> | |
## Methods
| Method | Modifiers | Description |
| --- | --- | --- |
| [create()](./kibana-plugin-plugins-data-public.searchsource.create.md) | | |
| [createChild(options)](./kibana-plugin-plugins-data-public.searchsource.createchild.md) | | |
| [createCopy()](./kibana-plugin-plugins-data-public.searchsource.createcopy.md) | | |
| [destroy()](./kibana-plugin-plugins-data-public.searchsource.destroy.md) | | Completely destroy the SearchSource. {<!-- -->undefined<!-- -->} |
| [fetch(options)](./kibana-plugin-plugins-data-public.searchsource.fetch.md) | | Fetch this source and reject the returned Promise on error |
| [getField(field, recurse)](./kibana-plugin-plugins-data-public.searchsource.getfield.md) | | Get fields from the fields |
| [getFields()](./kibana-plugin-plugins-data-public.searchsource.getfields.md) | | |
| [getId()](./kibana-plugin-plugins-data-public.searchsource.getid.md) | | |
| [getOwnField(field)](./kibana-plugin-plugins-data-public.searchsource.getownfield.md) | | Get the field from our own fields, don't traverse up the chain |
| [getParent()](./kibana-plugin-plugins-data-public.searchsource.getparent.md) | | Get the parent of this SearchSource {<!-- -->undefined\|searchSource<!-- -->} |
| [getSearchRequestBody()](./kibana-plugin-plugins-data-public.searchsource.getsearchrequestbody.md) | | |
| [onRequestStart(handler)](./kibana-plugin-plugins-data-public.searchsource.onrequeststart.md) | | Add a handler that will be notified whenever requests start |
| [serialize()](./kibana-plugin-plugins-data-public.searchsource.serialize.md) | | Serializes the instance to a JSON string and a set of referenced objects. Use this method to get a representation of the search source which can be stored in a saved object.<!-- -->The references returned by this function can be mixed with other references in the same object, however make sure there are no name-collisions. The references will be named <code>kibanaSavedObjectMeta.searchSourceJSON.index</code> and <code>kibanaSavedObjectMeta.searchSourceJSON.filter[&lt;number&gt;].meta.index</code>.<!-- -->Using <code>createSearchSource</code>, the instance can be re-created. |
| [setField(field, value)](./kibana-plugin-plugins-data-public.searchsource.setfield.md) | | |
| [setFields(newFields)](./kibana-plugin-plugins-data-public.searchsource.setfields.md) | | |
| [setParent(parent, options)](./kibana-plugin-plugins-data-public.searchsource.setparent.md) | | Set a searchSource that this source should inherit from |
| [setPreferredSearchStrategyId(searchStrategyId)](./kibana-plugin-plugins-data-public.searchsource.setpreferredsearchstrategyid.md) | | \*\*\* PUBLIC API \*\*\* |

View file

@ -1,24 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [onRequestStart](./kibana-plugin-plugins-data-public.searchsource.onrequeststart.md)
## SearchSource.onRequestStart() method
Add a handler that will be notified whenever requests start
<b>Signature:</b>
```typescript
onRequestStart(handler: (searchSource: ISearchSource, options?: FetchOptions) => Promise<unknown>): void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| handler | <code>(searchSource: ISearchSource, options?: FetchOptions) =&gt; Promise&lt;unknown&gt;</code> | |
<b>Returns:</b>
`void`

View file

@ -1,27 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [serialize](./kibana-plugin-plugins-data-public.searchsource.serialize.md)
## SearchSource.serialize() method
Serializes the instance to a JSON string and a set of referenced objects. Use this method to get a representation of the search source which can be stored in a saved object.
The references returned by this function can be mixed with other references in the same object, however make sure there are no name-collisions. The references will be named `kibanaSavedObjectMeta.searchSourceJSON.index` and `kibanaSavedObjectMeta.searchSourceJSON.filter[<number>].meta.index`<!-- -->.
Using `createSearchSource`<!-- -->, the instance can be re-created.
<b>Signature:</b>
```typescript
serialize(): {
searchSourceJSON: string;
references: SavedObjectReference[];
};
```
<b>Returns:</b>
`{
searchSourceJSON: string;
references: SavedObjectReference[];
}`

View file

@ -1,23 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [setField](./kibana-plugin-plugins-data-public.searchsource.setfield.md)
## SearchSource.setField() method
<b>Signature:</b>
```typescript
setField<K extends keyof SearchSourceFields>(field: K, value: SearchSourceFields[K]): this;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| field | <code>K</code> | |
| value | <code>SearchSourceFields[K]</code> | |
<b>Returns:</b>
`this`

View file

@ -1,22 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [setFields](./kibana-plugin-plugins-data-public.searchsource.setfields.md)
## SearchSource.setFields() method
<b>Signature:</b>
```typescript
setFields(newFields: SearchSourceFields): this;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| newFields | <code>SearchSourceFields</code> | |
<b>Returns:</b>
`this`

View file

@ -1,25 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [setParent](./kibana-plugin-plugins-data-public.searchsource.setparent.md)
## SearchSource.setParent() method
Set a searchSource that this source should inherit from
<b>Signature:</b>
```typescript
setParent(parent?: ISearchSource, options?: SearchSourceOptions): this;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| parent | <code>ISearchSource</code> | |
| options | <code>SearchSourceOptions</code> | |
<b>Returns:</b>
`this`

View file

@ -1,24 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSource](./kibana-plugin-plugins-data-public.searchsource.md) &gt; [setPreferredSearchStrategyId](./kibana-plugin-plugins-data-public.searchsource.setpreferredsearchstrategyid.md)
## SearchSource.setPreferredSearchStrategyId() method
\*\*\* PUBLIC API \*\*\*
<b>Signature:</b>
```typescript
setPreferredSearchStrategyId(searchStrategyId: string): void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| searchStrategyId | <code>string</code> | |
<b>Returns:</b>
`void`

View file

@ -40,6 +40,11 @@ exports[`renders ControlsTab 1`] = `
"timefilter": Object {}, "timefilter": Object {},
}, },
}, },
"search": Object {
"searchSource": Object {
"create": [MockFunction],
},
},
}, },
} }
} }
@ -96,6 +101,11 @@ exports[`renders ControlsTab 1`] = `
"timefilter": Object {}, "timefilter": Object {},
}, },
}, },
"search": Object {
"searchSource": Object {
"create": [MockFunction],
},
},
}, },
} }
} }

View file

@ -21,7 +21,6 @@ import expect from '@kbn/expect';
import { Control } from './control'; import { Control } from './control';
import { ControlParams } from '../editor_utils'; import { ControlParams } from '../editor_utils';
import { FilterManager as BaseFilterManager } from './filter_manager/filter_manager'; import { FilterManager as BaseFilterManager } from './filter_manager/filter_manager';
import { SearchSource } from '../legacy_imports';
function createControlParams(id: string, label: string): ControlParams { function createControlParams(id: string, label: string): ControlParams {
return { return {
@ -51,18 +50,12 @@ class ControlMock extends Control<BaseFilterManager> {
destroy() {} destroy() {}
} }
const mockKbnApi: SearchSource = {} as SearchSource;
describe('hasChanged', () => { describe('hasChanged', () => {
let control: ControlMock; let control: ControlMock;
beforeEach(() => { beforeEach(() => {
control = new ControlMock( control = new ControlMock(createControlParams('3', 'control'), mockFilterManager, false);
createControlParams('3', 'control'),
mockFilterManager,
false,
mockKbnApi
);
}); });
afterEach(() => { afterEach(() => {
@ -93,20 +86,17 @@ describe('ancestors', () => {
grandParentControl = new ControlMock( grandParentControl = new ControlMock(
createControlParams('1', 'grandparent control'), createControlParams('1', 'grandparent control'),
mockFilterManager, mockFilterManager,
false, false
mockKbnApi
); );
parentControl = new ControlMock( parentControl = new ControlMock(
createControlParams('2', 'parent control'), createControlParams('2', 'parent control'),
mockFilterManager, mockFilterManager,
false, false
mockKbnApi
); );
childControl = new ControlMock( childControl = new ControlMock(
createControlParams('3', 'child control'), createControlParams('3', 'child control'),
mockFilterManager, mockFilterManager,
false, false
mockKbnApi
); );
}); });

View file

@ -23,7 +23,6 @@ import _ from 'lodash';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { Filter } from '../../../../../plugins/data/public'; import { Filter } from '../../../../../plugins/data/public';
import { SearchSource as SearchSourceClass } from '../legacy_imports';
import { ControlParams, ControlParamsOptions, CONTROL_TYPES } from '../editor_utils'; import { ControlParams, ControlParamsOptions, CONTROL_TYPES } from '../editor_utils';
import { RangeFilterManager } from './filter_manager/range_filter_manager'; import { RangeFilterManager } from './filter_manager/range_filter_manager';
import { PhraseFilterManager } from './filter_manager/phrase_filter_manager'; import { PhraseFilterManager } from './filter_manager/phrase_filter_manager';
@ -61,8 +60,7 @@ export abstract class Control<FilterManager extends BaseFilterManager> {
constructor( constructor(
public controlParams: ControlParams, public controlParams: ControlParams,
public filterManager: FilterManager, public filterManager: FilterManager,
public useTimeFilter: boolean, public useTimeFilter: boolean
public SearchSource: SearchSourceClass
) { ) {
this.id = controlParams.id; this.id = controlParams.id;
this.controlParams = controlParams; this.controlParams = controlParams;

View file

@ -17,11 +17,16 @@
* under the License. * under the License.
*/ */
import { PhraseFilter, IndexPattern, TimefilterContract } from '../../../../../plugins/data/public'; import {
import { SearchSource as SearchSourceClass, SearchSourceFields } from '../legacy_imports'; SearchSourceFields,
PhraseFilter,
IndexPattern,
TimefilterContract,
DataPublicPluginStart,
} from '../../../../../plugins/data/public';
export function createSearchSource( export function createSearchSource(
SearchSource: SearchSourceClass, { create }: DataPublicPluginStart['search']['searchSource'],
initialState: SearchSourceFields | null, initialState: SearchSourceFields | null,
indexPattern: IndexPattern, indexPattern: IndexPattern,
aggs: any, aggs: any,
@ -29,7 +34,8 @@ export function createSearchSource(
filters: PhraseFilter[] = [], filters: PhraseFilter[] = [],
timefilter: TimefilterContract timefilter: TimefilterContract
) { ) {
const searchSource = initialState ? new SearchSource(initialState) : new SearchSource(); const searchSource = create(initialState || {});
// Do not not inherit from rootSearchSource to avoid picking up time and globals // Do not not inherit from rootSearchSource to avoid picking up time and globals
searchSource.setParent(undefined); searchSource.setParent(undefined);
searchSource.setField('filter', () => { searchSource.setField('filter', () => {

View file

@ -21,12 +21,13 @@ import { listControlFactory, ListControl } from './list_control_factory';
import { ControlParams, CONTROL_TYPES } from '../editor_utils'; import { ControlParams, CONTROL_TYPES } from '../editor_utils';
import { getDepsMock, getSearchSourceMock } from '../test_utils'; import { getDepsMock, getSearchSourceMock } from '../test_utils';
const MockSearchSource = getSearchSourceMock(); describe('listControlFactory', () => {
const deps = getDepsMock(); const searchSourceMock = getSearchSourceMock();
const deps = getDepsMock({
jest.doMock('./create_search_source.ts', () => ({ searchSource: {
createSearchSource: MockSearchSource, create: searchSourceMock,
})); },
});
describe('hasValue', () => { describe('hasValue', () => {
const controlParams: ControlParams = { const controlParams: ControlParams = {
@ -42,7 +43,7 @@ describe('hasValue', () => {
let listControl: ListControl; let listControl: ListControl;
beforeEach(async () => { beforeEach(async () => {
listControl = await listControlFactory(controlParams, useTimeFilter, MockSearchSource, deps); listControl = await listControlFactory(controlParams, useTimeFilter, deps);
}); });
test('should be false when control has no value', () => { test('should be false when control has no value', () => {
@ -74,12 +75,12 @@ describe('fetch', () => {
let listControl: ListControl; let listControl: ListControl;
beforeEach(async () => { beforeEach(async () => {
listControl = await listControlFactory(controlParams, useTimeFilter, MockSearchSource, deps); listControl = await listControlFactory(controlParams, useTimeFilter, deps);
}); });
test('should pass in timeout parameters from injected vars', async () => { test('should pass in timeout parameters from injected vars', async () => {
await listControl.fetch(); await listControl.fetch();
expect(MockSearchSource).toHaveBeenCalledWith({ expect(searchSourceMock).toHaveBeenCalledWith({
timeout: `1000ms`, timeout: `1000ms`,
terminate_after: 100000, terminate_after: 100000,
}); });
@ -109,7 +110,7 @@ describe('fetch with ancestors', () => {
let listControl: ListControl; let listControl: ListControl;
let parentControl; let parentControl;
beforeEach(async () => { beforeEach(async () => {
listControl = await listControlFactory(controlParams, useTimeFilter, MockSearchSource, deps); listControl = await listControlFactory(controlParams, useTimeFilter, deps);
const parentControlParams: ControlParams = { const parentControlParams: ControlParams = {
id: 'parent', id: 'parent',
@ -120,12 +121,7 @@ describe('fetch with ancestors', () => {
indexPattern: {} as any, indexPattern: {} as any,
parent: 'parent', parent: 'parent',
}; };
parentControl = await listControlFactory( parentControl = await listControlFactory(parentControlParams, useTimeFilter, deps);
parentControlParams,
useTimeFilter,
MockSearchSource,
deps
);
parentControl.clear(); parentControl.clear();
listControl.setAncestors([parentControl]); listControl.setAncestors([parentControl]);
}); });
@ -143,3 +139,4 @@ describe('fetch with ancestors', () => {
}); });
}); });
}); });
});

View file

@ -19,14 +19,17 @@
import _ from 'lodash'; import _ from 'lodash';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { SearchSource as SearchSourceClass, SearchSourceFields } from '../legacy_imports';
import { Control, noValuesDisableMsg, noIndexPatternMsg } from './control'; import { Control, noValuesDisableMsg, noIndexPatternMsg } from './control';
import { PhraseFilterManager } from './filter_manager/phrase_filter_manager'; import { PhraseFilterManager } from './filter_manager/phrase_filter_manager';
import { createSearchSource } from './create_search_source'; import { createSearchSource } from './create_search_source';
import { ControlParams } from '../editor_utils'; import { ControlParams } from '../editor_utils';
import { InputControlVisDependencies } from '../plugin'; import { InputControlVisDependencies } from '../plugin';
import { IFieldType, TimefilterContract } from '../../../../../plugins/data/public'; import {
IFieldType,
TimefilterContract,
SearchSourceFields,
DataPublicPluginStart,
} from '../../../../../plugins/data/public';
function getEscapedQuery(query = '') { function getEscapedQuery(query = '') {
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html#_standard_operators // https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html#_standard_operators
@ -75,6 +78,7 @@ const termsAgg = ({ field, size, direction, query }: TermsAggArgs) => {
export class ListControl extends Control<PhraseFilterManager> { export class ListControl extends Control<PhraseFilterManager> {
private getInjectedVar: InputControlVisDependencies['core']['injectedMetadata']['getInjectedVar']; private getInjectedVar: InputControlVisDependencies['core']['injectedMetadata']['getInjectedVar'];
private timefilter: TimefilterContract; private timefilter: TimefilterContract;
private searchSource: DataPublicPluginStart['search']['searchSource'];
abortController?: AbortController; abortController?: AbortController;
lastAncestorValues: any; lastAncestorValues: any;
@ -86,12 +90,13 @@ export class ListControl extends Control<PhraseFilterManager> {
controlParams: ControlParams, controlParams: ControlParams,
filterManager: PhraseFilterManager, filterManager: PhraseFilterManager,
useTimeFilter: boolean, useTimeFilter: boolean,
SearchSource: SearchSourceClass, searchSource: DataPublicPluginStart['search']['searchSource'],
deps: InputControlVisDependencies deps: InputControlVisDependencies
) { ) {
super(controlParams, filterManager, useTimeFilter, SearchSource); super(controlParams, filterManager, useTimeFilter);
this.getInjectedVar = deps.core.injectedMetadata.getInjectedVar; this.getInjectedVar = deps.core.injectedMetadata.getInjectedVar;
this.timefilter = deps.data.query.timefilter.timefilter; this.timefilter = deps.data.query.timefilter.timefilter;
this.searchSource = searchSource;
} }
fetch = async (query?: string) => { fetch = async (query?: string) => {
@ -143,7 +148,7 @@ export class ListControl extends Control<PhraseFilterManager> {
query, query,
}); });
const searchSource = createSearchSource( const searchSource = createSearchSource(
this.SearchSource, this.searchSource,
initialSearchSourceState, initialSearchSourceState,
indexPattern, indexPattern,
aggs, aggs,
@ -202,7 +207,6 @@ export class ListControl extends Control<PhraseFilterManager> {
export async function listControlFactory( export async function listControlFactory(
controlParams: ControlParams, controlParams: ControlParams,
useTimeFilter: boolean, useTimeFilter: boolean,
SearchSource: SearchSourceClass,
deps: InputControlVisDependencies deps: InputControlVisDependencies
) { ) {
const [, { data: dataPluginStart }] = await deps.core.getStartServices(); const [, { data: dataPluginStart }] = await deps.core.getStartServices();
@ -225,7 +229,7 @@ export async function listControlFactory(
deps.data.query.filterManager deps.data.query.filterManager
), ),
useTimeFilter, useTimeFilter,
SearchSource, dataPluginStart.search.searchSource,
deps deps
); );
return listControl; return listControl;

View file

@ -21,8 +21,7 @@ import { rangeControlFactory } from './range_control_factory';
import { ControlParams, CONTROL_TYPES } from '../editor_utils'; import { ControlParams, CONTROL_TYPES } from '../editor_utils';
import { getDepsMock, getSearchSourceMock } from '../test_utils'; import { getDepsMock, getSearchSourceMock } from '../test_utils';
const deps = getDepsMock(); describe('rangeControlFactory', () => {
describe('fetch', () => { describe('fetch', () => {
const controlParams: ControlParams = { const controlParams: ControlParams = {
id: '1', id: '1',
@ -42,12 +41,14 @@ describe('fetch', () => {
minAgg: { value: 10 }, minAgg: { value: 10 },
}, },
}; };
const rangeControl = await rangeControlFactory( const searchSourceMock = getSearchSourceMock(esSearchResponse);
controlParams, const deps = getDepsMock({
useTimeFilter, searchSource: {
getSearchSourceMock(esSearchResponse), create: searchSourceMock,
deps },
); });
const rangeControl = await rangeControlFactory(controlParams, useTimeFilter, deps);
await rangeControl.fetch(); await rangeControl.fetch();
expect(rangeControl.isEnabled()).toBe(true); expect(rangeControl.isEnabled()).toBe(true);
@ -63,12 +64,14 @@ describe('fetch', () => {
minAgg: { value: null }, minAgg: { value: null },
}, },
}; };
const rangeControl = await rangeControlFactory( const searchSourceMock = getSearchSourceMock(esSearchResponse);
controlParams, const deps = getDepsMock({
useTimeFilter, searchSource: {
getSearchSourceMock(esSearchResponse), create: searchSourceMock,
deps },
); });
const rangeControl = await rangeControlFactory(controlParams, useTimeFilter, deps);
await rangeControl.fetch(); await rangeControl.fetch();
expect(rangeControl.isEnabled()).toBe(false); expect(rangeControl.isEnabled()).toBe(false);
@ -78,14 +81,17 @@ describe('fetch', () => {
// ES response for dashboardonly user who does not have read permissions on index is 200 (which is weird) // ES response for dashboardonly user who does not have read permissions on index is 200 (which is weird)
// and there is not aggregations key // and there is not aggregations key
const esSearchResponse = {}; const esSearchResponse = {};
const rangeControl = await rangeControlFactory( const searchSourceMock = getSearchSourceMock(esSearchResponse);
controlParams, const deps = getDepsMock({
useTimeFilter, searchSource: {
getSearchSourceMock(esSearchResponse), create: searchSourceMock,
deps },
); });
const rangeControl = await rangeControlFactory(controlParams, useTimeFilter, deps);
await rangeControl.fetch(); await rangeControl.fetch();
expect(rangeControl.isEnabled()).toBe(false); expect(rangeControl.isEnabled()).toBe(false);
}); });
}); });
});

View file

@ -20,13 +20,16 @@
import _ from 'lodash'; import _ from 'lodash';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { SearchSource as SearchSourceClass } from '../legacy_imports';
import { Control, noValuesDisableMsg, noIndexPatternMsg } from './control'; import { Control, noValuesDisableMsg, noIndexPatternMsg } from './control';
import { RangeFilterManager } from './filter_manager/range_filter_manager'; import { RangeFilterManager } from './filter_manager/range_filter_manager';
import { createSearchSource } from './create_search_source'; import { createSearchSource } from './create_search_source';
import { ControlParams } from '../editor_utils'; import { ControlParams } from '../editor_utils';
import { InputControlVisDependencies } from '../plugin'; import { InputControlVisDependencies } from '../plugin';
import { IFieldType, TimefilterContract } from '../.../../../../../../plugins/data/public'; import {
IFieldType,
TimefilterContract,
DataPublicPluginStart,
} from '../.../../../../../../plugins/data/public';
const minMaxAgg = (field?: IFieldType) => { const minMaxAgg = (field?: IFieldType) => {
const aggBody: any = {}; const aggBody: any = {};
@ -52,6 +55,8 @@ const minMaxAgg = (field?: IFieldType) => {
}; };
export class RangeControl extends Control<RangeFilterManager> { export class RangeControl extends Control<RangeFilterManager> {
private searchSource: DataPublicPluginStart['search']['searchSource'];
timefilter: TimefilterContract; timefilter: TimefilterContract;
abortController: any; abortController: any;
min: any; min: any;
@ -61,11 +66,12 @@ export class RangeControl extends Control<RangeFilterManager> {
controlParams: ControlParams, controlParams: ControlParams,
filterManager: RangeFilterManager, filterManager: RangeFilterManager,
useTimeFilter: boolean, useTimeFilter: boolean,
SearchSource: SearchSourceClass, searchSource: DataPublicPluginStart['search']['searchSource'],
deps: InputControlVisDependencies deps: InputControlVisDependencies
) { ) {
super(controlParams, filterManager, useTimeFilter, SearchSource); super(controlParams, filterManager, useTimeFilter);
this.timefilter = deps.data.query.timefilter.timefilter; this.timefilter = deps.data.query.timefilter.timefilter;
this.searchSource = searchSource;
} }
async fetch() { async fetch() {
@ -83,7 +89,7 @@ export class RangeControl extends Control<RangeFilterManager> {
const fieldName = this.filterManager.fieldName; const fieldName = this.filterManager.fieldName;
const aggs = minMaxAgg(indexPattern.fields.getByName(fieldName)); const aggs = minMaxAgg(indexPattern.fields.getByName(fieldName));
const searchSource = createSearchSource( const searchSource = createSearchSource(
this.SearchSource, this.searchSource,
null, null,
indexPattern, indexPattern,
aggs, aggs,
@ -129,7 +135,6 @@ export class RangeControl extends Control<RangeFilterManager> {
export async function rangeControlFactory( export async function rangeControlFactory(
controlParams: ControlParams, controlParams: ControlParams,
useTimeFilter: boolean, useTimeFilter: boolean,
SearchSource: SearchSourceClass,
deps: InputControlVisDependencies deps: InputControlVisDependencies
): Promise<RangeControl> { ): Promise<RangeControl> {
const [, { data: dataPluginStart }] = await deps.core.getStartServices(); const [, { data: dataPluginStart }] = await deps.core.getStartServices();
@ -144,7 +149,7 @@ export async function rangeControlFactory(
deps.data.query.filterManager deps.data.query.filterManager
), ),
useTimeFilter, useTimeFilter,
SearchSource, dataPluginStart.search.searchSource,
deps deps
); );
} }

View file

@ -22,8 +22,6 @@ import { createInputControlVisFn } from './input_control_fn';
// eslint-disable-next-line // eslint-disable-next-line
import { functionWrapper } from '../../../../plugins/expressions/common/expression_functions/specs/tests/utils'; import { functionWrapper } from '../../../../plugins/expressions/common/expression_functions/specs/tests/utils';
jest.mock('./legacy_imports.ts');
describe('interpreter/functions#input_control_vis', () => { describe('interpreter/functions#input_control_vis', () => {
const fn = functionWrapper(createInputControlVisFn()); const fn = functionWrapper(createInputControlVisFn());
const visConfig = { const visConfig = {
@ -48,8 +46,9 @@ describe('interpreter/functions#input_control_vis', () => {
pinFilters: false, pinFilters: false,
}; };
it('returns an object with the correct structure', async () => { test('returns an object with the correct structure', async () => {
const actual = await fn(null, { visConfig: JSON.stringify(visConfig) }); const actual = await fn(null, { visConfig: JSON.stringify(visConfig) });
expect(actual).toMatchSnapshot(); expect(actual).toMatchSnapshot();
}); });
}); });

View file

@ -1,26 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Class } from '@kbn/utility-types';
import { SearchSource as SearchSourceClass, ISearchSource } from '../../../../plugins/data/public';
export { SearchSourceFields } from '../../../../plugins/data/public';
export type SearchSource = Class<ISearchSource>;
export const SearchSource = SearchSourceClass;

View file

@ -19,6 +19,7 @@
import React from 'react'; import React from 'react';
import { InputControlVisDependencies } from '../plugin'; import { InputControlVisDependencies } from '../plugin';
import { getSearchSourceMock } from './get_search_service_mock';
const fields = [] as any; const fields = [] as any;
fields.push({ name: 'myField' } as any); fields.push({ name: 'myField' } as any);
@ -26,13 +27,20 @@ fields.getByName = (name: any) => {
return fields.find(({ name: n }: { name: string }) => n === name); return fields.find(({ name: n }: { name: string }) => n === name);
}; };
export const getDepsMock = (): InputControlVisDependencies => export const getDepsMock = ({
searchSource = {
create: getSearchSourceMock(),
},
} = {}): InputControlVisDependencies =>
({ ({
core: { core: {
getStartServices: jest.fn().mockReturnValue([ getStartServices: jest.fn().mockReturnValue([
null, null,
{ {
data: { data: {
search: {
searchSource,
},
ui: { ui: {
IndexPatternSelect: () => (<div />) as any, IndexPatternSelect: () => (<div />) as any,
}, },
@ -58,6 +66,11 @@ export const getDepsMock = (): InputControlVisDependencies =>
}, },
}, },
data: { data: {
search: {
searchSource: {
create: getSearchSourceMock(),
},
},
query: { query: {
filterManager: { filterManager: {
fieldName: 'myField', fieldName: 'myField',

View file

@ -17,9 +17,7 @@
* under the License. * under the License.
*/ */
import { SearchSource } from '../legacy_imports'; export const getSearchSourceMock = (esSearchResponse?: any) =>
export const getSearchSourceMock = (esSearchResponse?: any): SearchSource =>
jest.fn().mockImplementation(() => ({ jest.fn().mockImplementation(() => ({
setParent: jest.fn(), setParent: jest.fn(),
setField: jest.fn(), setField: jest.fn(),

View file

@ -21,8 +21,6 @@ import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom'; import { render, unmountComponentAtNode } from 'react-dom';
import { I18nStart } from 'kibana/public'; import { I18nStart } from 'kibana/public';
import { SearchSource } from './legacy_imports';
import { InputControlVis } from './components/vis/input_control_vis'; import { InputControlVis } from './components/vis/input_control_vis';
import { getControlFactory } from './control/control_factory'; import { getControlFactory } from './control/control_factory';
import { getLineageMap } from './lineage'; import { getLineageMap } from './lineage';
@ -102,7 +100,8 @@ export const createInputControlVisController = (deps: InputControlVisDependencie
const controlFactoryPromises = controlParamsList.map(controlParams => { const controlFactoryPromises = controlParamsList.map(controlParams => {
const factory = getControlFactory(controlParams); const factory = getControlFactory(controlParams);
return factory(controlParams, this.visParams?.useTimeFilter, SearchSource, deps);
return factory(controlParams, this.visParams?.useTimeFilter, deps);
}); });
const controls = await Promise.all<RangeControl | ListControl>(controlFactoryPromises); const controls = await Promise.all<RangeControl | ListControl>(controlFactoryPromises);

View file

@ -42,6 +42,7 @@ import {
DocViewerComponent, DocViewerComponent,
SavedSearch, SavedSearch,
} from '../../../../../plugins/discover/public'; } from '../../../../../plugins/discover/public';
import { SavedObjectKibanaServices } from '../../../../../plugins/saved_objects/public';
export interface DiscoverServices { export interface DiscoverServices {
addBasePath: (path: string) => string; addBasePath: (path: string) => string;
@ -65,12 +66,13 @@ export interface DiscoverServices {
uiSettings: IUiSettingsClient; uiSettings: IUiSettingsClient;
visualizations: VisualizationsStart; visualizations: VisualizationsStart;
} }
export async function buildServices( export async function buildServices(
core: CoreStart, core: CoreStart,
plugins: DiscoverStartPlugins, plugins: DiscoverStartPlugins,
getHistory: () => History getHistory: () => History
): Promise<DiscoverServices> { ): Promise<DiscoverServices> {
const services = { const services: SavedObjectKibanaServices = {
savedObjectsClient: core.savedObjects.client, savedObjectsClient: core.savedObjects.client,
indexPatterns: plugins.data.indexPatterns, indexPatterns: plugins.data.indexPatterns,
search: plugins.data.search, search: plugins.data.search,

View file

@ -77,7 +77,6 @@ export {
IndexPattern, IndexPattern,
indexPatterns, indexPatterns,
IFieldType, IFieldType,
SearchSource,
ISearchSource, ISearchSource,
EsQuerySortValue, EsQuerySortValue,
SortDirection, SortDirection,

View file

@ -19,7 +19,6 @@
import sinon from 'sinon'; import sinon from 'sinon';
import moment from 'moment'; import moment from 'moment';
import { SearchSource } from '../../../../../../../../../plugins/data/public';
export function createIndexPatternsStub() { export function createIndexPatternsStub() {
return { return {
@ -46,17 +45,15 @@ export function createSearchSourceStub(hits, timeField) {
}), }),
}; };
searchSourceStub.setParent = sinon searchSourceStub.setParent = sinon.spy(() => searchSourceStub);
.stub(SearchSource.prototype, 'setParent') searchSourceStub.setField = sinon.spy(() => searchSourceStub);
.returns(searchSourceStub);
searchSourceStub.setField = sinon searchSourceStub.getField = sinon.spy(key => {
.stub(SearchSource.prototype, 'setField')
.returns(searchSourceStub);
searchSourceStub.getField = sinon.stub(SearchSource.prototype, 'getField').callsFake(key => {
const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall; const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
return previousSetCall ? previousSetCall.args[1] : null; return previousSetCall ? previousSetCall.args[1] : null;
}); });
searchSourceStub.fetch = sinon.stub(SearchSource.prototype, 'fetch').callsFake(() =>
searchSourceStub.fetch = sinon.spy(() =>
Promise.resolve({ Promise.resolve({
hits: { hits: {
hits: searchSourceStub._stubHits, hits: searchSourceStub._stubHits,
@ -65,13 +62,6 @@ export function createSearchSourceStub(hits, timeField) {
}) })
); );
searchSourceStub._restore = () => {
searchSourceStub.setParent.restore();
searchSourceStub.setField.restore();
searchSourceStub.getField.restore();
searchSourceStub.fetch.restore();
};
return searchSourceStub; return searchSourceStub;
} }
@ -81,8 +71,7 @@ export function createSearchSourceStub(hits, timeField) {
export function createContextSearchSourceStub(hits, timeField = '@timestamp') { export function createContextSearchSourceStub(hits, timeField = '@timestamp') {
const searchSourceStub = createSearchSourceStub(hits, timeField); const searchSourceStub = createSearchSourceStub(hits, timeField);
searchSourceStub.fetch.restore(); searchSourceStub.fetch = sinon.spy(() => {
searchSourceStub.fetch = sinon.stub(SearchSource.prototype, 'fetch').callsFake(() => {
const timeField = searchSourceStub._stubTimeField; const timeField = searchSourceStub._stubTimeField;
const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1]; const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1];
const timeRange = lastQuery.query.constant_score.filter.range[timeField]; const timeRange = lastQuery.query.constant_score.filter.range[timeField];
@ -99,6 +88,7 @@ export function createContextSearchSourceStub(hits, timeField = '@timestamp') {
moment(hit[timeField]).isSameOrBefore(timeRange.lte) moment(hit[timeField]).isSameOrBefore(timeRange.lte)
) )
.sort(sortFunction); .sort(sortFunction);
return Promise.resolve({ return Promise.resolve({
hits: { hits: {
hits: filteredHits, hits: filteredHits,

View file

@ -31,10 +31,6 @@ describe('context app', function() {
fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub); fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub);
}); });
afterEach(() => {
searchSourceStub._restore();
});
it('should use the `fetch` method of the SearchSource', function() { it('should use the `fetch` method of the SearchSource', function() {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [ return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' }, { '@timestamp': 'desc' },

View file

@ -21,6 +21,7 @@ import moment from 'moment';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs'; import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs';
import { fetchContextProvider } from './context'; import { fetchContextProvider } from './context';
import { setServices } from '../../../../kibana_services';
const MS_PER_DAY = 24 * 60 * 60 * 1000; const MS_PER_DAY = 24 * 60 * 60 * 1000;
const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON(); const ANCHOR_TIMESTAMP = new Date(MS_PER_DAY).toJSON();
@ -31,10 +32,21 @@ const ANCHOR_TIMESTAMP_3000 = new Date(MS_PER_DAY * 3000).toJSON();
describe('context app', function() { describe('context app', function() {
describe('function fetchPredecessors', function() { describe('function fetchPredecessors', function() {
let fetchPredecessors; let fetchPredecessors;
let searchSourceStub; let mockSearchSource;
beforeEach(() => { beforeEach(() => {
searchSourceStub = createContextSearchSourceStub([], '@timestamp', MS_PER_DAY * 8); mockSearchSource = createContextSearchSourceStub([], '@timestamp', MS_PER_DAY * 8);
setServices({
data: {
search: {
searchSource: {
create: jest.fn().mockImplementation(() => mockSearchSource),
},
},
},
});
fetchPredecessors = ( fetchPredecessors = (
indexPatternId, indexPatternId,
timeField, timeField,
@ -65,17 +77,13 @@ describe('context app', function() {
}; };
}); });
afterEach(() => {
searchSourceStub._restore();
});
it('should perform exactly one query when enough hits are returned', function() { it('should perform exactly one query when enough hits are returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 3000 + 2), mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 2),
searchSourceStub._createStubHit(MS_PER_DAY * 3000 + 1), mockSearchSource._createStubHit(MS_PER_DAY * 3000 + 1),
searchSourceStub._createStubHit(MS_PER_DAY * 3000), mockSearchSource._createStubHit(MS_PER_DAY * 3000),
searchSourceStub._createStubHit(MS_PER_DAY * 2000), mockSearchSource._createStubHit(MS_PER_DAY * 2000),
searchSourceStub._createStubHit(MS_PER_DAY * 1000), mockSearchSource._createStubHit(MS_PER_DAY * 1000),
]; ];
return fetchPredecessors( return fetchPredecessors(
@ -89,18 +97,18 @@ describe('context app', function() {
3, 3,
[] []
).then(hits => { ).then(hits => {
expect(searchSourceStub.fetch.calledOnce).toBe(true); expect(mockSearchSource.fetch.calledOnce).toBe(true);
expect(hits).toEqual(searchSourceStub._stubHits.slice(0, 3)); expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 3));
}); });
}); });
it('should perform multiple queries with the last being unrestricted when too few hits are returned', function() { it('should perform multiple queries with the last being unrestricted when too few hits are returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 3010), mockSearchSource._createStubHit(MS_PER_DAY * 3010),
searchSourceStub._createStubHit(MS_PER_DAY * 3002), mockSearchSource._createStubHit(MS_PER_DAY * 3002),
searchSourceStub._createStubHit(MS_PER_DAY * 3000), mockSearchSource._createStubHit(MS_PER_DAY * 3000),
searchSourceStub._createStubHit(MS_PER_DAY * 2998), mockSearchSource._createStubHit(MS_PER_DAY * 2998),
searchSourceStub._createStubHit(MS_PER_DAY * 2990), mockSearchSource._createStubHit(MS_PER_DAY * 2990),
]; ];
return fetchPredecessors( return fetchPredecessors(
@ -114,7 +122,7 @@ describe('context app', function() {
6, 6,
[] []
).then(hits => { ).then(hits => {
const intervals = searchSourceStub.setField.args const intervals = mockSearchSource.setField.args
.filter(([property]) => property === 'query') .filter(([property]) => property === 'query')
.map(([, { query }]) => .map(([, { query }]) =>
_.get(query, ['constant_score', 'filter', 'range', '@timestamp']) _.get(query, ['constant_score', 'filter', 'range', '@timestamp'])
@ -129,16 +137,16 @@ describe('context app', function() {
expect(Object.keys(_.last(intervals))).toEqual(['format', 'gte']); expect(Object.keys(_.last(intervals))).toEqual(['format', 'gte']);
expect(intervals.length).toBeGreaterThan(1); expect(intervals.length).toBeGreaterThan(1);
expect(hits).toEqual(searchSourceStub._stubHits.slice(0, 3)); expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 3));
}); });
}); });
it('should perform multiple queries until the expected hit count is returned', function() { it('should perform multiple queries until the expected hit count is returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 1700), mockSearchSource._createStubHit(MS_PER_DAY * 1700),
searchSourceStub._createStubHit(MS_PER_DAY * 1200), mockSearchSource._createStubHit(MS_PER_DAY * 1200),
searchSourceStub._createStubHit(MS_PER_DAY * 1100), mockSearchSource._createStubHit(MS_PER_DAY * 1100),
searchSourceStub._createStubHit(MS_PER_DAY * 1000), mockSearchSource._createStubHit(MS_PER_DAY * 1000),
]; ];
return fetchPredecessors( return fetchPredecessors(
@ -152,7 +160,7 @@ describe('context app', function() {
3, 3,
[] []
).then(hits => { ).then(hits => {
const intervals = searchSourceStub.setField.args const intervals = mockSearchSource.setField.args
.filter(([property]) => property === 'query') .filter(([property]) => property === 'query')
.map(([, { query }]) => .map(([, { query }]) =>
_.get(query, ['constant_score', 'filter', 'range', '@timestamp']) _.get(query, ['constant_score', 'filter', 'range', '@timestamp'])
@ -163,7 +171,7 @@ describe('context app', function() {
// should have stopped before reaching MS_PER_DAY * 1700 // should have stopped before reaching MS_PER_DAY * 1700
expect(moment(_.last(intervals).lte).valueOf()).toBeLessThan(MS_PER_DAY * 1700); expect(moment(_.last(intervals).lte).valueOf()).toBeLessThan(MS_PER_DAY * 1700);
expect(intervals.length).toBeGreaterThan(1); expect(intervals.length).toBeGreaterThan(1);
expect(hits).toEqual(searchSourceStub._stubHits.slice(-3)); expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
}); });
}); });
@ -195,7 +203,7 @@ describe('context app', function() {
3, 3,
[] []
).then(() => { ).then(() => {
const setParentSpy = searchSourceStub.setParent; const setParentSpy = mockSearchSource.setParent;
expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true); expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true);
expect(setParentSpy.called).toBe(true); expect(setParentSpy.called).toBe(true);
}); });
@ -214,7 +222,7 @@ describe('context app', function() {
[] []
).then(() => { ).then(() => {
expect( expect(
searchSourceStub.setField.calledWith('sort', [{ '@timestamp': 'asc' }, { _doc: 'asc' }]) mockSearchSource.setField.calledWith('sort', [{ '@timestamp': 'asc' }, { _doc: 'asc' }])
).toBe(true); ).toBe(true);
}); });
}); });

View file

@ -21,6 +21,7 @@ import moment from 'moment';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs'; import { createIndexPatternsStub, createContextSearchSourceStub } from './_stubs';
import { setServices } from '../../../../kibana_services';
import { fetchContextProvider } from './context'; import { fetchContextProvider } from './context';
@ -32,10 +33,20 @@ const ANCHOR_TIMESTAMP_3000 = new Date(MS_PER_DAY * 3000).toJSON();
describe('context app', function() { describe('context app', function() {
describe('function fetchSuccessors', function() { describe('function fetchSuccessors', function() {
let fetchSuccessors; let fetchSuccessors;
let searchSourceStub; let mockSearchSource;
beforeEach(() => { beforeEach(() => {
searchSourceStub = createContextSearchSourceStub([], '@timestamp'); mockSearchSource = createContextSearchSourceStub([], '@timestamp');
setServices({
data: {
search: {
searchSource: {
create: jest.fn().mockImplementation(() => mockSearchSource),
},
},
},
});
fetchSuccessors = ( fetchSuccessors = (
indexPatternId, indexPatternId,
@ -67,17 +78,13 @@ describe('context app', function() {
}; };
}); });
afterEach(() => {
searchSourceStub._restore();
});
it('should perform exactly one query when enough hits are returned', function() { it('should perform exactly one query when enough hits are returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 5000), mockSearchSource._createStubHit(MS_PER_DAY * 5000),
searchSourceStub._createStubHit(MS_PER_DAY * 4000), mockSearchSource._createStubHit(MS_PER_DAY * 4000),
searchSourceStub._createStubHit(MS_PER_DAY * 3000), mockSearchSource._createStubHit(MS_PER_DAY * 3000),
searchSourceStub._createStubHit(MS_PER_DAY * 3000 - 1), mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 1),
searchSourceStub._createStubHit(MS_PER_DAY * 3000 - 2), mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 2),
]; ];
return fetchSuccessors( return fetchSuccessors(
@ -91,18 +98,18 @@ describe('context app', function() {
3, 3,
[] []
).then(hits => { ).then(hits => {
expect(searchSourceStub.fetch.calledOnce).toBe(true); expect(mockSearchSource.fetch.calledOnce).toBe(true);
expect(hits).toEqual(searchSourceStub._stubHits.slice(-3)); expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
}); });
}); });
it('should perform multiple queries with the last being unrestricted when too few hits are returned', function() { it('should perform multiple queries with the last being unrestricted when too few hits are returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 3010), mockSearchSource._createStubHit(MS_PER_DAY * 3010),
searchSourceStub._createStubHit(MS_PER_DAY * 3002), mockSearchSource._createStubHit(MS_PER_DAY * 3002),
searchSourceStub._createStubHit(MS_PER_DAY * 3000), mockSearchSource._createStubHit(MS_PER_DAY * 3000),
searchSourceStub._createStubHit(MS_PER_DAY * 2998), mockSearchSource._createStubHit(MS_PER_DAY * 2998),
searchSourceStub._createStubHit(MS_PER_DAY * 2990), mockSearchSource._createStubHit(MS_PER_DAY * 2990),
]; ];
return fetchSuccessors( return fetchSuccessors(
@ -116,7 +123,7 @@ describe('context app', function() {
6, 6,
[] []
).then(hits => { ).then(hits => {
const intervals = searchSourceStub.setField.args const intervals = mockSearchSource.setField.args
.filter(([property]) => property === 'query') .filter(([property]) => property === 'query')
.map(([, { query }]) => .map(([, { query }]) =>
_.get(query, ['constant_score', 'filter', 'range', '@timestamp']) _.get(query, ['constant_score', 'filter', 'range', '@timestamp'])
@ -131,18 +138,18 @@ describe('context app', function() {
expect(Object.keys(_.last(intervals))).toEqual(['format', 'lte']); expect(Object.keys(_.last(intervals))).toEqual(['format', 'lte']);
expect(intervals.length).toBeGreaterThan(1); expect(intervals.length).toBeGreaterThan(1);
expect(hits).toEqual(searchSourceStub._stubHits.slice(-3)); expect(hits).toEqual(mockSearchSource._stubHits.slice(-3));
}); });
}); });
it('should perform multiple queries until the expected hit count is returned', function() { it('should perform multiple queries until the expected hit count is returned', function() {
searchSourceStub._stubHits = [ mockSearchSource._stubHits = [
searchSourceStub._createStubHit(MS_PER_DAY * 3000), mockSearchSource._createStubHit(MS_PER_DAY * 3000),
searchSourceStub._createStubHit(MS_PER_DAY * 3000 - 1), mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 1),
searchSourceStub._createStubHit(MS_PER_DAY * 3000 - 2), mockSearchSource._createStubHit(MS_PER_DAY * 3000 - 2),
searchSourceStub._createStubHit(MS_PER_DAY * 2800), mockSearchSource._createStubHit(MS_PER_DAY * 2800),
searchSourceStub._createStubHit(MS_PER_DAY * 2200), mockSearchSource._createStubHit(MS_PER_DAY * 2200),
searchSourceStub._createStubHit(MS_PER_DAY * 1000), mockSearchSource._createStubHit(MS_PER_DAY * 1000),
]; ];
return fetchSuccessors( return fetchSuccessors(
@ -156,7 +163,7 @@ describe('context app', function() {
4, 4,
[] []
).then(hits => { ).then(hits => {
const intervals = searchSourceStub.setField.args const intervals = mockSearchSource.setField.args
.filter(([property]) => property === 'query') .filter(([property]) => property === 'query')
.map(([, { query }]) => .map(([, { query }]) =>
_.get(query, ['constant_score', 'filter', 'range', '@timestamp']) _.get(query, ['constant_score', 'filter', 'range', '@timestamp'])
@ -168,7 +175,7 @@ describe('context app', function() {
expect(moment(_.last(intervals).gte).valueOf()).toBeGreaterThan(MS_PER_DAY * 2200); expect(moment(_.last(intervals).gte).valueOf()).toBeGreaterThan(MS_PER_DAY * 2200);
expect(intervals.length).toBeGreaterThan(1); expect(intervals.length).toBeGreaterThan(1);
expect(hits).toEqual(searchSourceStub._stubHits.slice(0, 4)); expect(hits).toEqual(mockSearchSource._stubHits.slice(0, 4));
}); });
}); });
@ -200,7 +207,7 @@ describe('context app', function() {
3, 3,
[] []
).then(() => { ).then(() => {
const setParentSpy = searchSourceStub.setParent; const setParentSpy = mockSearchSource.setParent;
expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true); expect(setParentSpy.alwaysCalledWith(undefined)).toBe(true);
expect(setParentSpy.called).toBe(true); expect(setParentSpy.called).toBe(true);
}); });
@ -219,7 +226,7 @@ describe('context app', function() {
[] []
).then(() => { ).then(() => {
expect( expect(
searchSourceStub.setField.calledWith('sort', [{ '@timestamp': 'desc' }, { _doc: 'desc' }]) mockSearchSource.setField.calledWith('sort', [{ '@timestamp': 'desc' }, { _doc: 'desc' }])
).toBe(true); ).toBe(true);
}); });
}); });

View file

@ -27,8 +27,8 @@ import {
Filter, Filter,
IndexPatternsContract, IndexPatternsContract,
IndexPattern, IndexPattern,
SearchSource,
} from '../../../../../../../../../plugins/data/public'; } from '../../../../../../../../../plugins/data/public';
import { getServices } from '../../../../kibana_services';
export type SurrDocType = 'successors' | 'predecessors'; export type SurrDocType = 'successors' | 'predecessors';
export interface EsHitRecord { export interface EsHitRecord {
@ -115,7 +115,10 @@ function fetchContextProvider(indexPatterns: IndexPatternsContract) {
} }
async function createSearchSource(indexPattern: IndexPattern, filters: Filter[]) { async function createSearchSource(indexPattern: IndexPattern, filters: Filter[]) {
return new SearchSource() const { data } = getServices();
return data.search.searchSource
.create()
.setParent(undefined) .setParent(undefined)
.setField('index', indexPattern) .setField('index', indexPattern)
.setField('filter', filters); .setField('filter', filters);

View file

@ -20,7 +20,7 @@
import _ from 'lodash'; import _ from 'lodash';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import React from 'react'; import React from 'react';
import { getServices, SearchSource } from '../../../../kibana_services'; import { getServices } from '../../../../kibana_services';
import { fetchAnchorProvider } from '../api/anchor'; import { fetchAnchorProvider } from '../api/anchor';
import { fetchContextProvider } from '../api/context'; import { fetchContextProvider } from '../api/context';
@ -29,8 +29,8 @@ import { FAILURE_REASONS, LOADING_STATUS } from './constants';
import { MarkdownSimple } from '../../../../../../../../../plugins/kibana_react/public'; import { MarkdownSimple } from '../../../../../../../../../plugins/kibana_react/public';
export function QueryActionsProvider(Promise) { export function QueryActionsProvider(Promise) {
const { filterManager, indexPatterns } = getServices(); const { filterManager, indexPatterns, data } = getServices();
const fetchAnchor = fetchAnchorProvider(indexPatterns, new SearchSource()); const fetchAnchor = fetchAnchorProvider(indexPatterns, data.search.searchSource.create());
const { fetchSurroundingDocs } = fetchContextProvider(indexPatterns); const { fetchSurroundingDocs } = fetchContextProvider(indexPatterns);
const { setPredecessorCount, setQueryParameters, setSuccessorCount } = getQueryParameterActions( const { setPredecessorCount, setQueryParameters, setSuccessorCount } = getQueryParameterActions(
filterManager, filterManager,

View file

@ -17,17 +17,19 @@
* under the License. * under the License.
*/ */
import { searchSourceMock } from '../../../../data/public/mocks'; import { dataPluginMock } from '../../../../data/public/mocks';
import { SavedObjectDashboard } from '../../saved_dashboards'; import { SavedObjectDashboard } from '../../saved_dashboards';
export function getSavedDashboardMock( export function getSavedDashboardMock(
config?: Partial<SavedObjectDashboard> config?: Partial<SavedObjectDashboard>
): SavedObjectDashboard { ): SavedObjectDashboard {
const searchSource = dataPluginMock.createStartContract();
return { return {
id: '123', id: '123',
title: 'my dashboard', title: 'my dashboard',
panelsJSON: '[]', panelsJSON: '[]',
searchSource: searchSourceMock, searchSource: searchSource.search.searchSource.create(),
copyOnSave: false, copyOnSave: false,
timeRestore: false, timeRestore: false,
timeTo: 'now', timeTo: 'now',

View file

@ -366,8 +366,6 @@ export {
SearchResponse, SearchResponse,
SearchError, SearchError,
ISearchSource, ISearchSource,
SearchSource,
createSearchSource,
SearchSourceFields, SearchSourceFields,
EsQuerySortValue, EsQuerySortValue,
SortDirection, SortDirection,

View file

@ -67,7 +67,7 @@ const createStartContract = (): Start => {
}; };
}; };
export { searchSourceMock } from './search/mocks'; export { createSearchSourceMock } from './search/mocks';
export { getCalculateAutoTimeExpression } from './search/aggs'; export { getCalculateAutoTimeExpression } from './search/aggs';
export const dataPluginMock = { export const dataPluginMock = {

View file

@ -24,13 +24,13 @@ import {
Plugin, Plugin,
PackageInfo, PackageInfo,
} from 'src/core/public'; } from 'src/core/public';
import { Storage, IStorageWrapper } from '../../kibana_utils/public'; import { Storage, IStorageWrapper, createStartServicesGetter } from '../../kibana_utils/public';
import { import {
DataPublicPluginSetup, DataPublicPluginSetup,
DataPublicPluginStart, DataPublicPluginStart,
DataSetupDependencies, DataSetupDependencies,
DataStartDependencies, DataStartDependencies,
GetInternalStartServicesFn, InternalStartServices,
} from './types'; } from './types';
import { AutocompleteService } from './autocomplete'; import { AutocompleteService } from './autocomplete';
import { SearchService } from './search/search_service'; import { SearchService } from './search/search_service';
@ -48,8 +48,6 @@ import {
setQueryService, setQueryService,
setSearchService, setSearchService,
setUiSettings, setUiSettings,
getFieldFormats,
getNotifications,
} from './services'; } from './services';
import { createSearchBar } from './ui/search_bar/create_search_bar'; import { createSearchBar } from './ui/search_bar/create_search_bar';
import { esaggs } from './search/expressions'; import { esaggs } from './search/expressions';
@ -99,15 +97,21 @@ export class DataPublicPlugin implements Plugin<DataPublicPluginSetup, DataPubli
core: CoreSetup, core: CoreSetup,
{ expressions, uiActions }: DataSetupDependencies { expressions, uiActions }: DataSetupDependencies
): DataPublicPluginSetup { ): DataPublicPluginSetup {
setInjectedMetadata(core.injectedMetadata); const startServices = createStartServicesGetter(core.getStartServices);
const getInternalStartServices = (): InternalStartServices => {
const { core: coreStart, self }: any = startServices();
return {
fieldFormats: self.fieldFormats,
notifications: coreStart.notifications,
uiSettings: coreStart.uiSettings,
searchService: self.search,
injectedMetadata: coreStart.injectedMetadata,
};
};
expressions.registerFunction(esaggs); expressions.registerFunction(esaggs);
const getInternalStartServices: GetInternalStartServicesFn = () => ({
fieldFormats: getFieldFormats(),
notifications: getNotifications(),
});
const queryService = this.queryService.setup({ const queryService = this.queryService.setup({
uiSettings: core.uiSettings, uiSettings: core.uiSettings,
storage: this.storage, storage: this.storage,
@ -145,6 +149,7 @@ export class DataPublicPlugin implements Plugin<DataPublicPluginSetup, DataPubli
setNotifications(notifications); setNotifications(notifications);
setOverlays(overlays); setOverlays(overlays);
setUiSettings(uiSettings); setUiSettings(uiSettings);
setInjectedMetadata(core.injectedMetadata);
const fieldFormats = this.fieldFormatsService.start(); const fieldFormats = this.fieldFormatsService.start();
setFieldFormats(fieldFormats); setFieldFormats(fieldFormats);
@ -155,7 +160,10 @@ export class DataPublicPlugin implements Plugin<DataPublicPluginSetup, DataPubli
const query = this.queryService.start(savedObjects); const query = this.queryService.start(savedObjects);
setQueryService(query); setQueryService(query);
const search = this.searchService.start(core, { fieldFormats, indexPatterns }); const search = this.searchService.start(core, {
indexPatterns,
fieldFormats,
});
setSearchService(search); setSearchService(search);
uiActions.attachAction(APPLY_FILTER_TRIGGER, uiActions.getAction(ACTION_GLOBAL_APPLY_FILTER)); uiActions.attachAction(APPLY_FILTER_TRIGGER, uiActions.getAction(ACTION_GLOBAL_APPLY_FILTER));

View file

@ -12,8 +12,8 @@ import { Assign } from '@kbn/utility-types';
import { Breadcrumb } from '@elastic/eui'; import { Breadcrumb } from '@elastic/eui';
import { Component } from 'react'; import { Component } from 'react';
import { CoreSetup } from 'src/core/public'; import { CoreSetup } from 'src/core/public';
import { CoreStart } from 'src/core/public'; import { CoreStart } from 'kibana/public';
import { CoreStart as CoreStart_2 } from 'kibana/public'; import { CoreStart as CoreStart_2 } from 'src/core/public';
import { EuiButtonEmptyProps } from '@elastic/eui'; import { EuiButtonEmptyProps } from '@elastic/eui';
import { EuiComboBoxProps } from '@elastic/eui'; import { EuiComboBoxProps } from '@elastic/eui';
import { EuiConfirmModalProps } from '@elastic/eui'; import { EuiConfirmModalProps } from '@elastic/eui';
@ -210,9 +210,6 @@ export const connectToQueryState: <S extends QueryState>({ timefilter: { timefil
// @public (undocumented) // @public (undocumented)
export const createSavedQueryService: (savedObjectsClient: Pick<import("../../../../../core/public").SavedObjectsClient, "update" | "find" | "get" | "delete" | "create" | "bulkCreate" | "bulkGet" | "bulkUpdate">) => SavedQueryService; export const createSavedQueryService: (savedObjectsClient: Pick<import("../../../../../core/public").SavedObjectsClient, "update" | "find" | "get" | "delete" | "create" | "bulkCreate" | "bulkGet" | "bulkUpdate">) => SavedQueryService;
// @public
export const createSearchSource: (indexPatterns: Pick<import("../../index_patterns/index_patterns").IndexPatternsService, "get" | "clearCache" | "getFieldsForTimePattern" | "getFieldsForWildcard" | "getIds" | "getTitles" | "getFields" | "getCache" | "getDefault" | "make">) => (searchSourceJson: string, references: SavedObjectReference[]) => Promise<SearchSource>;
// Warning: (ae-missing-release-tag) "CustomFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "CustomFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// //
// @public (undocumented) // @public (undocumented)
@ -683,21 +680,21 @@ export type IAggType = AggType;
// Warning: (ae-missing-release-tag) "IDataPluginServices" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "IDataPluginServices" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// //
// @public (undocumented) // @public (undocumented)
export interface IDataPluginServices extends Partial<CoreStart> { export interface IDataPluginServices extends Partial<CoreStart_2> {
// (undocumented) // (undocumented)
appName: string; appName: string;
// (undocumented) // (undocumented)
data: DataPublicPluginStart; data: DataPublicPluginStart;
// (undocumented) // (undocumented)
http: CoreStart['http']; http: CoreStart_2['http'];
// (undocumented) // (undocumented)
notifications: CoreStart['notifications']; notifications: CoreStart_2['notifications'];
// (undocumented) // (undocumented)
savedObjects: CoreStart['savedObjects']; savedObjects: CoreStart_2['savedObjects'];
// (undocumented) // (undocumented)
storage: IStorageWrapper; storage: IStorageWrapper;
// (undocumented) // (undocumented)
uiSettings: CoreStart['uiSettings']; uiSettings: CoreStart_2['uiSettings'];
} }
// Warning: (ae-missing-release-tag) "IEsSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "IEsSearchRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
@ -1112,7 +1109,7 @@ export type ISearch<T extends TStrategyTypes = typeof DEFAULT_SEARCH_STRATEGY> =
// @public (undocumented) // @public (undocumented)
export interface ISearchContext { export interface ISearchContext {
// (undocumented) // (undocumented)
core: CoreStart_2; core: CoreStart;
// (undocumented) // (undocumented)
getSearchStrategy: <T extends TStrategyTypes>(name: T) => TSearchStrategyProvider<T>; getSearchStrategy: <T extends TStrategyTypes>(name: T) => TSearchStrategyProvider<T>;
} }
@ -1130,7 +1127,7 @@ export interface ISearchOptions {
signal?: AbortSignal; signal?: AbortSignal;
} }
// Warning: (ae-missing-release-tag) "ISearchSource" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-forgotten-export) The symbol "SearchSource" needs to be exported by the entry point index.d.ts
// //
// @public (undocumented) // @public (undocumented)
export type ISearchSource = Pick<SearchSource, keyof SearchSource>; export type ISearchSource = Pick<SearchSource, keyof SearchSource>;
@ -1325,7 +1322,7 @@ export class Plugin implements Plugin_2<DataPublicPluginSetup, DataPublicPluginS
// Warning: (ae-forgotten-export) The symbol "DataStartDependencies" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "DataStartDependencies" needs to be exported by the entry point index.d.ts
// //
// (undocumented) // (undocumented)
start(core: CoreStart, { uiActions }: DataStartDependencies): DataPublicPluginStart; start(core: CoreStart_2, { uiActions }: DataStartDependencies): DataPublicPluginStart;
// (undocumented) // (undocumented)
stop(): void; stop(): void;
} }
@ -1644,61 +1641,6 @@ export type SearchRequest = any;
// @public (undocumented) // @public (undocumented)
export type SearchResponse = any; export type SearchResponse = any;
// Warning: (ae-missing-release-tag) "SearchSource" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export class SearchSource {
constructor(fields?: SearchSourceFields);
// (undocumented)
create(): SearchSource;
// (undocumented)
createChild(options?: {}): SearchSource;
// (undocumented)
createCopy(): SearchSource;
destroy(): void;
fetch(options?: FetchOptions): Promise<any>;
getField<K extends keyof SearchSourceFields>(field: K, recurse?: boolean): SearchSourceFields[K];
// (undocumented)
getFields(): {
type?: string | undefined;
query?: import("../..").Query | undefined;
filter?: Filter | Filter[] | (() => Filter | Filter[] | undefined) | undefined;
sort?: Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric> | Record<string, import("./types").SortDirection | import("./types").SortDirectionNumeric>[] | undefined;
highlight?: any;
highlightAll?: boolean | undefined;
aggs?: any;
from?: number | undefined;
size?: number | undefined;
source?: string | boolean | string[] | undefined;
version?: boolean | undefined;
fields?: string | boolean | string[] | undefined;
index?: import("../..").IndexPattern | undefined;
searchAfter?: import("./types").EsQuerySearchAfter | undefined;
timeout?: string | undefined;
terminate_after?: number | undefined;
};
// (undocumented)
getId(): string;
getOwnField<K extends keyof SearchSourceFields>(field: K): SearchSourceFields[K];
getParent(): SearchSource | undefined;
// (undocumented)
getSearchRequestBody(): Promise<any>;
// (undocumented)
history: SearchRequest[];
onRequestStart(handler: (searchSource: ISearchSource, options?: FetchOptions) => Promise<unknown>): void;
serialize(): {
searchSourceJSON: string;
references: SavedObjectReference[];
};
// (undocumented)
setField<K extends keyof SearchSourceFields>(field: K, value: SearchSourceFields[K]): this;
// (undocumented)
setFields(newFields: SearchSourceFields): this;
// Warning: (ae-forgotten-export) The symbol "SearchSourceOptions" needs to be exported by the entry point index.d.ts
setParent(parent?: ISearchSource, options?: SearchSourceOptions): this;
setPreferredSearchStrategyId(searchStrategyId: string): void;
}
// Warning: (ae-missing-release-tag) "SearchSourceFields" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "SearchSourceFields" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// //
// @public (undocumented) // @public (undocumented)
@ -1889,21 +1831,21 @@ export type TSearchStrategyProvider<T extends TStrategyTypes> = (context: ISearc
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getRoutes" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "getRoutes" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:234:27 - (ae-forgotten-export) The symbol "formatHitProvider" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getRequestInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:384:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:382:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:389:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:387:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:388:1 - (ae-forgotten-export) The symbol "convertDateRangeToString" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:392:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:390:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:399:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:402:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:400:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:403:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:401:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:407:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:405:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:408:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:411:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:409:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:412:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:410:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:415:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:413:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:33:33 - (ae-forgotten-export) The symbol "FilterStateStore" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts // src/plugins/data/public/query/state_sync/connect_to_query_state.ts:37:1 - (ae-forgotten-export) The symbol "QueryStateChange" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromEvent" needs to be exported by the entry point index.d.ts // src/plugins/data/public/types.ts:52:5 - (ae-forgotten-export) The symbol "createFiltersFromEvent" needs to be exported by the entry point index.d.ts

View file

@ -25,13 +25,15 @@ import { AggParamType } from '../aggs/param_types/agg';
import { fieldFormatsServiceMock } from '../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../src/core/public/mocks';
import { AggTypeDependencies } from './agg_type'; import { AggTypeDependencies } from './agg_type';
import { InternalStartServices } from '../../types';
describe('AggParams class', () => { describe('AggParams class', () => {
const aggTypesDependencies: AggTypeDependencies = { const aggTypesDependencies: AggTypeDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
describe('constructor args', () => { describe('constructor args', () => {

View file

@ -21,19 +21,21 @@ import { AggType, AggTypeConfig, AggTypeDependencies } from './agg_type';
import { IAggConfig } from './agg_config'; import { IAggConfig } from './agg_config';
import { fieldFormatsServiceMock } from '../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../types';
describe('AggType Class', () => { describe('AggType Class', () => {
let dependencies: AggTypeDependencies; let dependencies: AggTypeDependencies;
beforeEach(() => { beforeEach(() => {
dependencies = { dependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: { fieldFormats: {
...fieldFormatsServiceMock.createStartContract(), ...fieldFormatsServiceMock.createStartContract(),
getDefaultInstance: jest.fn(() => 'default') as any, getDefaultInstance: jest.fn(() => 'default') as any,
}, },
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -32,6 +32,7 @@ import { RangeFilter } from '../../../../../common';
import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks'; import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks';
import { queryServiceMock } from '../../../../query/mocks'; import { queryServiceMock } from '../../../../query/mocks';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('date_histogram', () => { describe('date_histogram', () => {
@ -47,10 +48,11 @@ describe('AggConfig Filters', () => {
aggTypesDependencies = { aggTypesDependencies = {
uiSettings, uiSettings,
query: queryServiceMock.createSetupContract(), query: queryServiceMock.createSetupContract(),
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
mockDataServices(); mockDataServices();

View file

@ -28,6 +28,7 @@ import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../bucket_agg_type'; import { IBucketAggConfig } from '../bucket_agg_type';
import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks'; import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('Date range', () => { describe('Date range', () => {
@ -38,10 +39,11 @@ describe('AggConfig Filters', () => {
aggTypesDependencies = { aggTypesDependencies = {
uiSettings, uiSettings,
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -24,6 +24,7 @@ import { mockAggTypesRegistry } from '../../test_helpers';
import { IBucketAggConfig } from '../bucket_agg_type'; import { IBucketAggConfig } from '../bucket_agg_type';
import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks'; import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('filters', () => { describe('filters', () => {
@ -34,10 +35,11 @@ describe('AggConfig Filters', () => {
aggTypesDependencies = { aggTypesDependencies = {
uiSettings, uiSettings,
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -26,16 +26,18 @@ import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../bucket_agg_type'; import { IBucketAggConfig } from '../bucket_agg_type';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../core/public/mocks'; import { notificationServiceMock } from '../../../../../../../core/public/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('IP range', () => { describe('IP range', () => {
const fieldFormats = fieldFormatsServiceMock.createStartContract(); const fieldFormats = fieldFormatsServiceMock.createStartContract();
const typesRegistry = mockAggTypesRegistry([ const typesRegistry = mockAggTypesRegistry([
getIpRangeBucketAgg({ getIpRangeBucketAgg({
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats, fieldFormats,
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}), }),
]); ]);
const getAggConfigs = (aggs: CreateAggConfigParams[]) => { const getAggConfigs = (aggs: CreateAggConfigParams[]) => {

View file

@ -26,6 +26,7 @@ import { BUCKET_TYPES } from '../bucket_agg_types';
import { IBucketAggConfig } from '../bucket_agg_type'; import { IBucketAggConfig } from '../bucket_agg_type';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../core/public/mocks'; import { notificationServiceMock } from '../../../../../../../core/public/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('range', () => { describe('range', () => {
@ -33,10 +34,11 @@ describe('AggConfig Filters', () => {
beforeEach(() => { beforeEach(() => {
aggTypesDependencies = { aggTypesDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
mockDataServices(); mockDataServices();

View file

@ -27,6 +27,7 @@ import { Filter, ExistsFilter } from '../../../../../common';
import { RangeBucketAggDependencies } from '../range'; import { RangeBucketAggDependencies } from '../range';
import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../core/public/mocks'; import { notificationServiceMock } from '../../../../../../../core/public/mocks';
import { InternalStartServices } from '../../../../types';
describe('AggConfig Filters', () => { describe('AggConfig Filters', () => {
describe('terms', () => { describe('terms', () => {
@ -34,10 +35,11 @@ describe('AggConfig Filters', () => {
beforeEach(() => { beforeEach(() => {
aggTypesDependencies = { aggTypesDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -23,6 +23,7 @@ import { AggConfigs } from '../agg_configs';
import { mockAggTypesRegistry } from '../test_helpers'; import { mockAggTypesRegistry } from '../test_helpers';
import { BUCKET_TYPES } from './bucket_agg_types'; import { BUCKET_TYPES } from './bucket_agg_types';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { InternalStartServices } from '../../../types';
describe('date_range params', () => { describe('date_range params', () => {
let aggTypesDependencies: DateRangeBucketAggDependencies; let aggTypesDependencies: DateRangeBucketAggDependencies;
@ -32,10 +33,11 @@ describe('date_range params', () => {
aggTypesDependencies = { aggTypesDependencies = {
uiSettings, uiSettings,
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -24,6 +24,7 @@ import { BUCKET_TYPES } from './bucket_agg_types';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { BucketAggType, IBucketAggConfig } from './bucket_agg_type'; import { BucketAggType, IBucketAggConfig } from './bucket_agg_type';
import { InternalStartServices } from '../../../types';
describe('Geohash Agg', () => { describe('Geohash Agg', () => {
let aggTypesDependencies: GeoHashBucketAggDependencies; let aggTypesDependencies: GeoHashBucketAggDependencies;
@ -31,10 +32,11 @@ describe('Geohash Agg', () => {
beforeEach(() => { beforeEach(() => {
aggTypesDependencies = { aggTypesDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
geoHashBucketAgg = getGeoHashBucketAgg(aggTypesDependencies); geoHashBucketAgg = getGeoHashBucketAgg(aggTypesDependencies);

View file

@ -29,6 +29,7 @@ import {
} from './histogram'; } from './histogram';
import { BucketAggType } from './bucket_agg_type'; import { BucketAggType } from './bucket_agg_type';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { InternalStartServices } from '../../../types';
describe('Histogram Agg', () => { describe('Histogram Agg', () => {
let aggTypesDependencies: HistogramBucketAggDependencies; let aggTypesDependencies: HistogramBucketAggDependencies;
@ -38,10 +39,11 @@ describe('Histogram Agg', () => {
aggTypesDependencies = { aggTypesDependencies = {
uiSettings, uiSettings,
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -24,6 +24,7 @@ import { BUCKET_TYPES } from './bucket_agg_types';
import { FieldFormatsGetConfigFn, NumberFormat } from '../../../../common'; import { FieldFormatsGetConfigFn, NumberFormat } from '../../../../common';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
const buckets = [ const buckets = [
{ {
@ -50,10 +51,11 @@ describe('Range Agg', () => {
beforeEach(() => { beforeEach(() => {
aggTypesDependencies = { aggTypesDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
mockDataServices(); mockDataServices();

View file

@ -26,6 +26,7 @@ import {
} from './significant_terms'; } from './significant_terms';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('Significant Terms Agg', () => { describe('Significant Terms Agg', () => {
describe('order agg editor UI', () => { describe('order agg editor UI', () => {
@ -34,10 +35,11 @@ describe('Significant Terms Agg', () => {
beforeEach(() => { beforeEach(() => {
aggTypesDependencies = { aggTypesDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
}); });

View file

@ -24,6 +24,7 @@ import { isBucketAggType } from './buckets/bucket_agg_type';
import { isMetricAggType } from './metrics/metric_agg_type'; import { isMetricAggType } from './metrics/metric_agg_type';
import { QueryStart } from '../../query'; import { QueryStart } from '../../query';
import { FieldFormatsStart } from '../../field_formats'; import { FieldFormatsStart } from '../../field_formats';
import { InternalStartServices } from '../../types';
describe('AggTypesComponent', () => { describe('AggTypesComponent', () => {
const coreSetup = coreMock.createSetup(); const coreSetup = coreMock.createSetup();
@ -32,10 +33,11 @@ describe('AggTypesComponent', () => {
const aggTypes = getAggTypes({ const aggTypes = getAggTypes({
uiSettings: coreSetup.uiSettings, uiSettings: coreSetup.uiSettings,
query: {} as QueryStart, query: {} as QueryStart,
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
notifications: coreStart.notifications, notifications: coreStart.notifications,
fieldFormats: {} as FieldFormatsStart, fieldFormats: {} as FieldFormatsStart,
}), } as unknown) as InternalStartServices),
}); });
const { buckets, metrics } = aggTypes; const { buckets, metrics } = aggTypes;

View file

@ -23,14 +23,16 @@ import { mockAggTypesRegistry } from '../test_helpers';
import { METRIC_TYPES } from './metric_agg_types'; import { METRIC_TYPES } from './metric_agg_types';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('AggTypeMetricMedianProvider class', () => { describe('AggTypeMetricMedianProvider class', () => {
let aggConfigs: IAggConfigs; let aggConfigs: IAggConfigs;
const aggTypesDependencies: MedianMetricAggDependencies = { const aggTypesDependencies: MedianMetricAggDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
beforeEach(() => { beforeEach(() => {

View file

@ -25,14 +25,15 @@ import { AggConfigs } from '../agg_configs';
import { mockAggTypesRegistry } from '../test_helpers'; import { mockAggTypesRegistry } from '../test_helpers';
import { IMetricAggConfig, MetricAggType } from './metric_agg_type'; import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { GetInternalStartServicesFn } from '../../../types'; import { GetInternalStartServicesFn, InternalStartServices } from '../../../types';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
describe('parent pipeline aggs', function() { describe('parent pipeline aggs', function() {
const getInternalStartServices: GetInternalStartServicesFn = () => ({ const getInternalStartServices: GetInternalStartServicesFn = () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}); } as unknown) as InternalStartServices);
const typesRegistry = mockAggTypesRegistry(); const typesRegistry = mockAggTypesRegistry();

View file

@ -27,14 +27,16 @@ import { mockAggTypesRegistry } from '../test_helpers';
import { METRIC_TYPES } from './metric_agg_types'; import { METRIC_TYPES } from './metric_agg_types';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('AggTypesMetricsPercentileRanksProvider class', function() { describe('AggTypesMetricsPercentileRanksProvider class', function() {
let aggConfigs: IAggConfigs; let aggConfigs: IAggConfigs;
const aggTypesDependencies: PercentileRanksMetricAggDependencies = { const aggTypesDependencies: PercentileRanksMetricAggDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
beforeEach(() => { beforeEach(() => {

View file

@ -27,14 +27,16 @@ import { mockAggTypesRegistry } from '../test_helpers';
import { METRIC_TYPES } from './metric_agg_types'; import { METRIC_TYPES } from './metric_agg_types';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('AggTypesMetricsPercentilesProvider class', () => { describe('AggTypesMetricsPercentilesProvider class', () => {
let aggConfigs: IAggConfigs; let aggConfigs: IAggConfigs;
const aggTypesDependencies: PercentilesMetricAggDependencies = { const aggTypesDependencies: PercentilesMetricAggDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
beforeEach(() => { beforeEach(() => {

View file

@ -26,14 +26,15 @@ import { AggConfigs } from '../agg_configs';
import { IMetricAggConfig, MetricAggType } from './metric_agg_type'; import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
import { mockAggTypesRegistry } from '../test_helpers'; import { mockAggTypesRegistry } from '../test_helpers';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { GetInternalStartServicesFn } from '../../../types'; import { GetInternalStartServicesFn, InternalStartServices } from '../../../types';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
describe('sibling pipeline aggs', () => { describe('sibling pipeline aggs', () => {
const getInternalStartServices: GetInternalStartServicesFn = () => ({ const getInternalStartServices: GetInternalStartServicesFn = () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}); } as unknown) as InternalStartServices);
const typesRegistry = mockAggTypesRegistry(); const typesRegistry = mockAggTypesRegistry();

View file

@ -27,13 +27,15 @@ import { mockAggTypesRegistry } from '../test_helpers';
import { METRIC_TYPES } from './metric_agg_types'; import { METRIC_TYPES } from './metric_agg_types';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('AggTypeMetricStandardDeviationProvider class', () => { describe('AggTypeMetricStandardDeviationProvider class', () => {
const aggTypesDependencies: StdDeviationMetricAggDependencies = { const aggTypesDependencies: StdDeviationMetricAggDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
const typesRegistry = mockAggTypesRegistry([getStdDeviationMetricAgg(aggTypesDependencies)]); const typesRegistry = mockAggTypesRegistry([getStdDeviationMetricAgg(aggTypesDependencies)]);
const getAggConfigs = (customLabel?: string) => { const getAggConfigs = (customLabel?: string) => {

View file

@ -25,15 +25,17 @@ import { IMetricAggConfig } from './metric_agg_type';
import { KBN_FIELD_TYPES } from '../../../../common'; import { KBN_FIELD_TYPES } from '../../../../common';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('Top hit metric', () => { describe('Top hit metric', () => {
let aggDsl: Record<string, any>; let aggDsl: Record<string, any>;
let aggConfig: IMetricAggConfig; let aggConfig: IMetricAggConfig;
const aggTypesDependencies: TopHitMetricAggDependencies = { const aggTypesDependencies: TopHitMetricAggDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
const init = ({ const init = ({

View file

@ -23,13 +23,15 @@ import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../common';
import { IAggConfig } from '../agg_config'; import { IAggConfig } from '../agg_config';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { InternalStartServices } from '../../../types';
describe('Field', () => { describe('Field', () => {
const fieldParamTypeDependencies: FieldParamTypeDependencies = { const fieldParamTypeDependencies: FieldParamTypeDependencies = {
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), } as unknown) as InternalStartServices),
}; };
const indexPattern = { const indexPattern = {

View file

@ -17,7 +17,6 @@
* under the License. * under the License.
*/ */
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { coreMock, notificationServiceMock } from '../../../../../../../src/core/public/mocks'; import { coreMock, notificationServiceMock } from '../../../../../../../src/core/public/mocks';
import { AggTypesRegistry, AggTypesRegistryStart } from '../agg_types_registry'; import { AggTypesRegistry, AggTypesRegistryStart } from '../agg_types_registry';
import { getAggTypes } from '../agg_types'; import { getAggTypes } from '../agg_types';
@ -25,6 +24,7 @@ import { BucketAggType } from '../buckets/bucket_agg_type';
import { MetricAggType } from '../metrics/metric_agg_type'; import { MetricAggType } from '../metrics/metric_agg_type';
import { queryServiceMock } from '../../../query/mocks'; import { queryServiceMock } from '../../../query/mocks';
import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks';
import { InternalStartServices } from '../../../types';
/** /**
* Testing utility which creates a new instance of AggTypesRegistry, * Testing utility which creates a new instance of AggTypesRegistry,
@ -53,14 +53,19 @@ export function mockAggTypesRegistry<T extends BucketAggType<any> | MetricAggTyp
} }
}); });
} else { } else {
const core = coreMock.createSetup(); const coreSetup = coreMock.createSetup();
const coreStart = coreMock.createStart();
const aggTypes = getAggTypes({ const aggTypes = getAggTypes({
uiSettings: core.uiSettings, uiSettings: coreSetup.uiSettings,
query: queryServiceMock.createSetupContract(), query: queryServiceMock.createSetupContract(),
getInternalStartServices: () => ({ getInternalStartServices: () =>
(({
fieldFormats: fieldFormatsServiceMock.createStartContract(), fieldFormats: fieldFormatsServiceMock.createStartContract(),
notifications: notificationServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(),
}), uiSettings: coreStart.uiSettings,
injectedMetadata: coreStart.injectedMetadata,
} as unknown) as InternalStartServices),
}); });
aggTypes.buckets.forEach(type => registrySetup.registerBucket(type)); aggTypes.buckets.forEach(type => registrySetup.registerBucket(type));

View file

@ -30,7 +30,7 @@ import { PersistedState } from '../../../../../plugins/visualizations/public';
import { Adapters } from '../../../../../plugins/inspector/public'; import { Adapters } from '../../../../../plugins/inspector/public';
import { IAggConfigs } from '../aggs'; import { IAggConfigs } from '../aggs';
import { ISearchSource, SearchSource } from '../search_source'; import { ISearchSource } from '../search_source';
import { tabifyAggResponse } from '../tabify'; import { tabifyAggResponse } from '../tabify';
import { Filter, Query, serializeFieldFormat, TimeRange } from '../../../common'; import { Filter, Query, serializeFieldFormat, TimeRange } from '../../../common';
import { FilterManager, getTime } from '../../query'; import { FilterManager, getTime } from '../../query';
@ -253,7 +253,8 @@ export const esaggs = (): ExpressionFunctionDefinition<typeof name, Input, Argum
const aggs = searchService.aggs.createAggConfigs(indexPattern, aggConfigsState); const aggs = searchService.aggs.createAggConfigs(indexPattern, aggConfigsState);
// we should move searchSource creation inside courier request handler // we should move searchSource creation inside courier request handler
const searchSource = new SearchSource(); const searchSource = searchService.searchSource.create();
searchSource.setField('index', indexPattern); searchSource.setField('index', indexPattern);
searchSource.setField('size', 0); searchSource.setField('size', 0);

View file

@ -18,7 +18,7 @@
*/ */
import { IUiSettingsClient } from '../../../../../core/public'; import { IUiSettingsClient } from '../../../../../core/public';
import { ISearchStart } from '../types'; import { ISearchStartLegacy } from '../types';
export type SearchRequest = any; export type SearchRequest = any;
export type SearchResponse = any; export type SearchResponse = any;
@ -29,7 +29,7 @@ export interface FetchOptions {
} }
export interface FetchHandlers { export interface FetchHandlers {
searchService: ISearchStart; legacySearchService: ISearchStartLegacy;
config: IUiSettingsClient; config: IUiSettingsClient;
esShardTimeout: number; esShardTimeout: number;
} }

View file

@ -55,10 +55,10 @@ export {
export { export {
ISearchSource, ISearchSource,
SearchSource, SearchSource,
SearchSourceDependencies,
SearchSourceFields, SearchSourceFields,
EsQuerySortValue, EsQuerySortValue,
SortDirection, SortDirection,
createSearchSource,
} from './search_source'; } from './search_source';
export { SearchInterceptor } from './search_interceptor'; export { SearchInterceptor } from './search_interceptor';

View file

@ -54,7 +54,7 @@ describe('callClient', () => {
test('Passes the additional arguments it is given to the search strategy', () => { test('Passes the additional arguments it is given to the search strategy', () => {
const searchRequests = [{ _searchStrategyId: 0 }]; const searchRequests = [{ _searchStrategyId: 0 }];
const args = { searchService: {}, config: {}, esShardTimeout: 0 } as FetchHandlers; const args = { legacySearchService: {}, config: {}, esShardTimeout: 0 } as FetchHandlers;
callClient(searchRequests, [], args); callClient(searchRequests, [], args);

View file

@ -62,10 +62,10 @@ describe('defaultSearchStrategy', function() {
}, },
], ],
esShardTimeout: 0, esShardTimeout: 0,
searchService, legacySearchService: searchService.__LEGACY,
}; };
es = searchArgs.searchService.__LEGACY.esClient; es = searchArgs.legacySearchService.esClient;
}); });
test('does not send max_concurrent_shard_requests by default', async () => { test('does not send max_concurrent_shard_requests by default', async () => {

View file

@ -32,11 +32,11 @@ export const defaultSearchStrategy: SearchStrategyProvider = {
function msearch({ function msearch({
searchRequests, searchRequests,
searchService, legacySearchService,
config, config,
esShardTimeout, esShardTimeout,
}: SearchStrategySearchParams) { }: SearchStrategySearchParams) {
const es = searchService.__LEGACY.esClient; const es = legacySearchService.esClient;
const inlineRequests = searchRequests.map(({ index, body, search_type: searchType }) => { const inlineRequests = searchRequests.map(({ index, body, search_type: searchType }) => {
const inlineHeader = { const inlineHeader = {
index: index.title || index, index: index.title || index,

View file

@ -20,20 +20,19 @@
import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks'; import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks';
import { AggTypeFieldFilters } from './aggs/param_types/filter'; import { AggTypeFieldFilters } from './aggs/param_types/filter';
import { ISearchStart } from './types'; import { ISearchStart } from './types';
import { searchSourceMock, createSearchSourceMock } from './search_source/mocks';
export * from './search_source/mocks'; const searchSetupMock = {
export const searchSetupMock = {
aggs: searchAggsSetupMock(), aggs: searchAggsSetupMock(),
registerSearchStrategyContext: jest.fn(), registerSearchStrategyContext: jest.fn(),
registerSearchStrategyProvider: jest.fn(), registerSearchStrategyProvider: jest.fn(),
}; };
export const searchStartMock: jest.Mocked<ISearchStart> = { const searchStartMock: jest.Mocked<ISearchStart> = {
aggs: searchAggsStartMock(), aggs: searchAggsStartMock(),
setInterceptor: jest.fn(), setInterceptor: jest.fn(),
search: jest.fn(), search: jest.fn(),
createSearchSource: jest.fn(), searchSource: searchSourceMock,
__LEGACY: { __LEGACY: {
AggConfig: jest.fn() as any, AggConfig: jest.fn() as any,
AggType: jest.fn(), AggType: jest.fn(),
@ -48,3 +47,5 @@ export const searchStartMock: jest.Mocked<ISearchStart> = {
}, },
}, },
}; };
export { searchSetupMock, searchStartMock, createSearchSourceMock };

View file

@ -20,13 +20,18 @@
import { Plugin, CoreSetup, CoreStart, PackageInfo } from '../../../../core/public'; import { Plugin, CoreSetup, CoreStart, PackageInfo } from '../../../../core/public';
import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy'; import { SYNC_SEARCH_STRATEGY, syncSearchStrategyProvider } from './sync_search_strategy';
import {
createSearchSourceFromJSON,
SearchSource,
SearchSourceDependencies,
SearchSourceFields,
} from './search_source';
import { ISearchSetup, ISearchStart, TSearchStrategyProvider, TSearchStrategiesMap } from './types'; import { ISearchSetup, ISearchStart, TSearchStrategyProvider, TSearchStrategiesMap } from './types';
import { TStrategyTypes } from './strategy_types'; import { TStrategyTypes } from './strategy_types';
import { getEsClient, LegacyApiCaller } from './legacy'; import { getEsClient, LegacyApiCaller } from './legacy';
import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search'; import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search';
import { esSearchStrategyProvider } from './es_search'; import { esSearchStrategyProvider } from './es_search';
import { IndexPatternsContract } from '../index_patterns/index_patterns'; import { IndexPatternsContract } from '../index_patterns/index_patterns';
import { createSearchSource } from './search_source';
import { QuerySetup } from '../query'; import { QuerySetup } from '../query';
import { GetInternalStartServicesFn } from '../types'; import { GetInternalStartServicesFn } from '../types';
import { SearchInterceptor } from './search_interceptor'; import { SearchInterceptor } from './search_interceptor';
@ -43,8 +48,8 @@ import {
parentPipelineAggHelper, parentPipelineAggHelper,
siblingPipelineAggHelper, siblingPipelineAggHelper,
} from './aggs'; } from './aggs';
import { FieldFormatsStart } from '../field_formats'; import { FieldFormatsStart } from '../field_formats';
import { ISearchGeneric } from './i_search';
interface SearchServiceSetupDependencies { interface SearchServiceSetupDependencies {
packageInfo: PackageInfo; packageInfo: PackageInfo;
@ -52,9 +57,9 @@ interface SearchServiceSetupDependencies {
getInternalStartServices: GetInternalStartServicesFn; getInternalStartServices: GetInternalStartServicesFn;
} }
interface SearchStartDependencies { interface SearchServiceStartDependencies {
fieldFormats: FieldFormatsStart;
indexPatterns: IndexPatternsContract; indexPatterns: IndexPatternsContract;
fieldFormats: FieldFormatsStart;
} }
/** /**
@ -117,10 +122,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
}; };
} }
public start( public start(core: CoreStart, dependencies: SearchServiceStartDependencies): ISearchStart {
core: CoreStart,
{ fieldFormats, indexPatterns }: SearchStartDependencies
): ISearchStart {
/** /**
* A global object that intercepts all searches and provides convenience methods for cancelling * A global object that intercepts all searches and provides convenience methods for cancelling
* all pending search requests, as well as getting the number of pending search requests. * all pending search requests, as well as getting the number of pending search requests.
@ -135,31 +137,16 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
const aggTypesStart = this.aggTypesRegistry.start(); const aggTypesStart = this.aggTypesRegistry.start();
return { const search: ISearchGeneric = (request, options, strategyName) => {
aggs: {
calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings),
createAggConfigs: (indexPattern, configStates = [], schemas) => {
return new AggConfigs(indexPattern, configStates, {
typesRegistry: aggTypesStart,
fieldFormats,
});
},
types: aggTypesStart,
},
search: (request, options, strategyName) => {
const strategyProvider = this.getSearchStrategy(strategyName || DEFAULT_SEARCH_STRATEGY); const strategyProvider = this.getSearchStrategy(strategyName || DEFAULT_SEARCH_STRATEGY);
const { search } = strategyProvider({ const searchStrategy = strategyProvider({
core, core,
getSearchStrategy: this.getSearchStrategy, getSearchStrategy: this.getSearchStrategy,
}); });
return this.searchInterceptor.search(search as any, request, options); return this.searchInterceptor.search(searchStrategy.search as any, request, options);
}, };
setInterceptor: (searchInterceptor: SearchInterceptor) => {
// TODO: should an intercepror have a destroy method? const legacySearch = {
this.searchInterceptor = searchInterceptor;
},
createSearchSource: createSearchSource(indexPatterns),
__LEGACY: {
esClient: this.esClient!, esClient: this.esClient!,
AggConfig, AggConfig,
AggType, AggType,
@ -168,7 +155,36 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
MetricAggType, MetricAggType,
parentPipelineAggHelper, parentPipelineAggHelper,
siblingPipelineAggHelper, siblingPipelineAggHelper,
};
const searchSourceDependencies: SearchSourceDependencies = {
uiSettings: core.uiSettings,
injectedMetadata: core.injectedMetadata,
search,
legacySearch,
};
return {
aggs: {
calculateAutoTimeExpression: getCalculateAutoTimeExpression(core.uiSettings),
createAggConfigs: (indexPattern, configStates = [], schemas) => {
return new AggConfigs(indexPattern, configStates, {
fieldFormats: dependencies.fieldFormats,
typesRegistry: aggTypesStart,
});
}, },
types: aggTypesStart,
},
search,
searchSource: {
create: (fields?: SearchSourceFields) => new SearchSource(fields, searchSourceDependencies),
fromJSON: createSearchSourceFromJSON(dependencies.indexPatterns, searchSourceDependencies),
},
setInterceptor: (searchInterceptor: SearchInterceptor) => {
// TODO: should an intercepror have a destroy method?
this.searchInterceptor = searchInterceptor;
},
__LEGACY: legacySearch,
}; };
} }

View file

@ -16,30 +16,43 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { createSearchSource as createSearchSourceFactory } from './create_search_source'; import { createSearchSourceFromJSON } from './create_search_source';
import { IIndexPattern } from '../../../common/index_patterns'; import { IIndexPattern } from '../../../common/index_patterns';
import { IndexPatternsContract } from '../../index_patterns/index_patterns'; import { IndexPatternsContract } from '../../index_patterns/index_patterns';
import { Filter } from '../../../common/es_query/filters'; import { Filter } from '../../../common/es_query/filters';
import { coreMock } from '../../../../../core/public/mocks';
import { dataPluginMock } from '../../mocks';
describe('createSearchSource', function() { describe('createSearchSource', () => {
let createSearchSource: ReturnType<typeof createSearchSourceFactory>;
const indexPatternMock: IIndexPattern = {} as IIndexPattern; const indexPatternMock: IIndexPattern = {} as IIndexPattern;
let indexPatternContractMock: jest.Mocked<IndexPatternsContract>; let indexPatternContractMock: jest.Mocked<IndexPatternsContract>;
let dependencies: any;
let createSearchSource: ReturnType<typeof createSearchSourceFromJSON>;
beforeEach(() => { beforeEach(() => {
const core = coreMock.createStart();
const data = dataPluginMock.createStartContract();
dependencies = {
searchService: data.search,
uiSettings: core.uiSettings,
injectedMetadata: core.injectedMetadata,
};
indexPatternContractMock = ({ indexPatternContractMock = ({
get: jest.fn().mockReturnValue(Promise.resolve(indexPatternMock)), get: jest.fn().mockReturnValue(Promise.resolve(indexPatternMock)),
} as unknown) as jest.Mocked<IndexPatternsContract>; } as unknown) as jest.Mocked<IndexPatternsContract>;
createSearchSource = createSearchSourceFactory(indexPatternContractMock);
createSearchSource = createSearchSourceFromJSON(indexPatternContractMock, dependencies);
}); });
it('should fail if JSON is invalid', () => { test('should fail if JSON is invalid', () => {
expect(createSearchSource('{', [])).rejects.toThrow(); expect(createSearchSource('{', [])).rejects.toThrow();
expect(createSearchSource('0', [])).rejects.toThrow(); expect(createSearchSource('0', [])).rejects.toThrow();
expect(createSearchSource('"abcdefg"', [])).rejects.toThrow(); expect(createSearchSource('"abcdefg"', [])).rejects.toThrow();
}); });
it('should set fields', async () => { test('should set fields', async () => {
const searchSource = await createSearchSource( const searchSource = await createSearchSource(
JSON.stringify({ JSON.stringify({
highlightAll: true, highlightAll: true,
@ -50,6 +63,7 @@ describe('createSearchSource', function() {
}), }),
[] []
); );
expect(searchSource.getOwnField('highlightAll')).toBe(true); expect(searchSource.getOwnField('highlightAll')).toBe(true);
expect(searchSource.getOwnField('query')).toEqual({ expect(searchSource.getOwnField('query')).toEqual({
query: '', query: '',
@ -57,7 +71,7 @@ describe('createSearchSource', function() {
}); });
}); });
it('should resolve referenced index pattern', async () => { test('should resolve referenced index pattern', async () => {
const searchSource = await createSearchSource( const searchSource = await createSearchSource(
JSON.stringify({ JSON.stringify({
indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index',
@ -70,11 +84,12 @@ describe('createSearchSource', function() {
}, },
] ]
); );
expect(indexPatternContractMock.get).toHaveBeenCalledWith('123-456'); expect(indexPatternContractMock.get).toHaveBeenCalledWith('123-456');
expect(searchSource.getOwnField('index')).toBe(indexPatternMock); expect(searchSource.getOwnField('index')).toBe(indexPatternMock);
}); });
it('should set filters and resolve referenced index patterns', async () => { test('should set filters and resolve referenced index patterns', async () => {
const searchSource = await createSearchSource( const searchSource = await createSearchSource(
JSON.stringify({ JSON.stringify({
filter: [ filter: [
@ -110,6 +125,7 @@ describe('createSearchSource', function() {
] ]
); );
const filters = searchSource.getOwnField('filter') as Filter[]; const filters = searchSource.getOwnField('filter') as Filter[];
expect(filters[0]).toMatchInlineSnapshot(` expect(filters[0]).toMatchInlineSnapshot(`
Object { Object {
"$state": Object { "$state": Object {
@ -135,7 +151,7 @@ describe('createSearchSource', function() {
`); `);
}); });
it('should migrate legacy queries on the fly', async () => { test('should migrate legacy queries on the fly', async () => {
const searchSource = await createSearchSource( const searchSource = await createSearchSource(
JSON.stringify({ JSON.stringify({
highlightAll: true, highlightAll: true,
@ -143,6 +159,7 @@ describe('createSearchSource', function() {
}), }),
[] []
); );
expect(searchSource.getOwnField('query')).toEqual({ expect(searchSource.getOwnField('query')).toEqual({
query: 'a:b', query: 'a:b',
language: 'lucene', language: 'lucene',

View file

@ -16,11 +16,11 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import _ from 'lodash'; import { transform, defaults, isFunction } from 'lodash';
import { SavedObjectReference } from 'kibana/public'; import { SavedObjectReference } from 'kibana/public';
import { migrateLegacyQuery } from '../../../../kibana_legacy/public'; import { migrateLegacyQuery } from '../../../../kibana_legacy/public';
import { InvalidJSONProperty } from '../../../../kibana_utils/public'; import { InvalidJSONProperty } from '../../../../kibana_utils/public';
import { SearchSource } from './search_source'; import { SearchSourceDependencies, SearchSource, ISearchSource } from './search_source';
import { IndexPatternsContract } from '../../index_patterns/index_patterns'; import { IndexPatternsContract } from '../../index_patterns/index_patterns';
import { SearchSourceFields } from './types'; import { SearchSourceFields } from './types';
@ -38,12 +38,16 @@ import { SearchSourceFields } from './types';
* returned by `serializeSearchSource` and `references`, a list of references including the ones * returned by `serializeSearchSource` and `references`, a list of references including the ones
* returned by `serializeSearchSource`. * returned by `serializeSearchSource`.
* *
*
* @public */ * @public */
export const createSearchSource = (indexPatterns: IndexPatternsContract) => async ( export const createSearchSourceFromJSON = (
indexPatterns: IndexPatternsContract,
searchSourceDependencies: SearchSourceDependencies
) => async (
searchSourceJson: string, searchSourceJson: string,
references: SavedObjectReference[] references: SavedObjectReference[]
) => { ): Promise<ISearchSource> => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
// if we have a searchSource, set its values based on the searchSourceJson field // if we have a searchSource, set its values based on the searchSourceJson field
let searchSourceValues: Record<string, unknown>; let searchSourceValues: Record<string, unknown>;
@ -90,17 +94,17 @@ export const createSearchSource = (indexPatterns: IndexPatternsContract) => asyn
} }
const searchSourceFields = searchSource.getFields(); const searchSourceFields = searchSource.getFields();
const fnProps = _.transform( const fnProps = transform(
searchSourceFields, searchSourceFields,
function(dynamic, val, name) { function(dynamic, val, name) {
if (_.isFunction(val) && name) dynamic[name] = val; if (isFunction(val) && name) dynamic[name] = val;
}, },
{} {}
); );
// This assignment might hide problems because the type of values passed from the parsed JSON // This assignment might hide problems because the type of values passed from the parsed JSON
// might not fit the SearchSourceFields interface. // might not fit the SearchSourceFields interface.
const newFields: SearchSourceFields = _.defaults(searchSourceValues, fnProps); const newFields: SearchSourceFields = defaults(searchSourceValues, fnProps);
searchSource.setFields(newFields); searchSource.setFields(newFields);
const query = searchSource.getOwnField('query'); const query = searchSource.getOwnField('query');

View file

@ -17,6 +17,6 @@
* under the License. * under the License.
*/ */
export * from './search_source'; export { SearchSource, ISearchSource, SearchSourceDependencies } from './search_source';
export { createSearchSource } from './create_search_source'; export { createSearchSourceFromJSON } from './create_search_source';
export { SortDirection, EsQuerySortValue, SearchSourceFields } from './types'; export { SortDirection, EsQuerySortValue, SearchSourceFields } from './types';

View file

@ -17,9 +17,15 @@
* under the License. * under the License.
*/ */
import { ISearchSource } from './search_source'; import {
injectedMetadataServiceMock,
uiSettingsServiceMock,
} from '../../../../../core/public/mocks';
export const searchSourceMock: MockedKeys<ISearchSource> = { import { ISearchSource, SearchSource } from './search_source';
import { SearchSourceFields } from './types';
export const searchSourceInstanceMock: MockedKeys<ISearchSource> = {
setPreferredSearchStrategyId: jest.fn(), setPreferredSearchStrategyId: jest.fn(),
setFields: jest.fn().mockReturnThis(), setFields: jest.fn().mockReturnThis(),
setField: jest.fn().mockReturnThis(), setField: jest.fn().mockReturnThis(),
@ -39,3 +45,21 @@ export const searchSourceMock: MockedKeys<ISearchSource> = {
history: [], history: [],
serialize: jest.fn(), serialize: jest.fn(),
}; };
export const searchSourceMock = {
create: jest.fn().mockReturnValue(searchSourceInstanceMock),
fromJSON: jest.fn().mockReturnValue(searchSourceInstanceMock),
};
export const createSearchSourceMock = (fields?: SearchSourceFields) =>
new SearchSource(fields, {
search: jest.fn(),
legacySearch: {
esClient: {
search: jest.fn(),
msearch: jest.fn(),
},
},
uiSettings: uiSettingsServiceMock.createStartContract(),
injectedMetadata: injectedMetadataServiceMock.createStartContract(),
});

View file

@ -16,28 +16,13 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Observable } from 'rxjs';
import { SearchSource } from './search_source'; import { SearchSource } from './search_source';
import { IndexPattern, SortDirection } from '../..'; import { IndexPattern, SortDirection } from '../..';
import { mockDataServices } from '../aggs/test_helpers';
import { setSearchService } from '../../services';
import { searchStartMock } from '../mocks';
import { fetchSoon } from '../legacy'; import { fetchSoon } from '../legacy';
import { CoreStart } from 'kibana/public'; import { IUiSettingsClient } from '../../../../../core/public';
import { Observable } from 'rxjs'; import { dataPluginMock } from '../../../../data/public/mocks';
import { coreMock } from '../../../../../core/public/mocks';
// Setup search service mock
searchStartMock.search = jest.fn(() => {
return new Observable(subscriber => {
setTimeout(() => {
subscriber.next({
rawResponse: '',
});
subscriber.complete();
}, 100);
});
}) as any;
setSearchService(searchStartMock);
jest.mock('../legacy', () => ({ jest.mock('../legacy', () => ({
fetchSoon: jest.fn().mockResolvedValue({}), fetchSoon: jest.fn().mockResolvedValue({}),
@ -48,48 +33,70 @@ const getComputedFields = () => ({
scriptFields: [], scriptFields: [],
docvalueFields: [], docvalueFields: [],
}); });
const mockSource = { excludes: ['foo-*'] }; const mockSource = { excludes: ['foo-*'] };
const mockSource2 = { excludes: ['bar-*'] }; const mockSource2 = { excludes: ['bar-*'] };
const indexPattern = ({ const indexPattern = ({
title: 'foo', title: 'foo',
getComputedFields, getComputedFields,
getSourceFiltering: () => mockSource, getSourceFiltering: () => mockSource,
} as unknown) as IndexPattern; } as unknown) as IndexPattern;
const indexPattern2 = ({ const indexPattern2 = ({
title: 'foo', title: 'foo',
getComputedFields, getComputedFields,
getSourceFiltering: () => mockSource2, getSourceFiltering: () => mockSource2,
} as unknown) as IndexPattern; } as unknown) as IndexPattern;
describe('SearchSource', function() { describe('SearchSource', () => {
let uiSettingsMock: jest.Mocked<CoreStart['uiSettings']>; let mockSearchMethod: any;
let searchSourceDependencies: any;
beforeEach(() => { beforeEach(() => {
const { core } = mockDataServices(); const core = coreMock.createStart();
uiSettingsMock = core.uiSettings; const data = dataPluginMock.createStartContract();
jest.clearAllMocks();
mockSearchMethod = jest.fn(() => {
return new Observable(subscriber => {
setTimeout(() => {
subscriber.next({
rawResponse: '',
});
subscriber.complete();
}, 100);
});
}); });
describe('#setField()', function() { searchSourceDependencies = {
it('sets the value for the property', function() { search: mockSearchMethod,
const searchSource = new SearchSource(); legacySearch: data.search.__LEGACY,
injectedMetadata: core.injectedMetadata,
uiSettings: core.uiSettings,
};
});
describe('#setField()', () => {
test('sets the value for the property', () => {
const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('aggs', 5); searchSource.setField('aggs', 5);
expect(searchSource.getField('aggs')).toBe(5); expect(searchSource.getField('aggs')).toBe(5);
}); });
}); });
describe('#getField()', function() { describe('#getField()', () => {
it('gets the value for the property', function() { test('gets the value for the property', () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('aggs', 5); searchSource.setField('aggs', 5);
expect(searchSource.getField('aggs')).toBe(5); expect(searchSource.getField('aggs')).toBe(5);
}); });
}); });
describe(`#setField('index')`, function() { describe(`#setField('index')`, () => {
describe('auto-sourceFiltering', function() { describe('auto-sourceFiltering', () => {
describe('new index pattern assigned', function() { describe('new index pattern assigned', () => {
it('generates a searchSource filter', async function() { test('generates a searchSource filter', async () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
expect(searchSource.getField('index')).toBe(undefined); expect(searchSource.getField('index')).toBe(undefined);
expect(searchSource.getField('source')).toBe(undefined); expect(searchSource.getField('source')).toBe(undefined);
searchSource.setField('index', indexPattern); searchSource.setField('index', indexPattern);
@ -98,8 +105,8 @@ describe('SearchSource', function() {
expect(request._source).toBe(mockSource); expect(request._source).toBe(mockSource);
}); });
it('removes created searchSource filter on removal', async function() { test('removes created searchSource filter on removal', async () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('index', indexPattern); searchSource.setField('index', indexPattern);
searchSource.setField('index', undefined); searchSource.setField('index', undefined);
const request = await searchSource.getSearchRequestBody(); const request = await searchSource.getSearchRequestBody();
@ -107,9 +114,9 @@ describe('SearchSource', function() {
}); });
}); });
describe('new index pattern assigned over another', function() { describe('new index pattern assigned over another', () => {
it('replaces searchSource filter with new', async function() { test('replaces searchSource filter with new', async () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('index', indexPattern); searchSource.setField('index', indexPattern);
searchSource.setField('index', indexPattern2); searchSource.setField('index', indexPattern2);
expect(searchSource.getField('index')).toBe(indexPattern2); expect(searchSource.getField('index')).toBe(indexPattern2);
@ -117,8 +124,8 @@ describe('SearchSource', function() {
expect(request._source).toBe(mockSource2); expect(request._source).toBe(mockSource2);
}); });
it('removes created searchSource filter on removal', async function() { test('removes created searchSource filter on removal', async () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('index', indexPattern); searchSource.setField('index', indexPattern);
searchSource.setField('index', indexPattern2); searchSource.setField('index', indexPattern2);
searchSource.setField('index', undefined); searchSource.setField('index', undefined);
@ -130,8 +137,8 @@ describe('SearchSource', function() {
}); });
describe('#onRequestStart()', () => { describe('#onRequestStart()', () => {
it('should be called when starting a request', async () => { test('should be called when starting a request', async () => {
const searchSource = new SearchSource({ index: indexPattern }); const searchSource = new SearchSource({ index: indexPattern }, searchSourceDependencies);
const fn = jest.fn(); const fn = jest.fn();
searchSource.onRequestStart(fn); searchSource.onRequestStart(fn);
const options = {}; const options = {};
@ -139,9 +146,9 @@ describe('SearchSource', function() {
expect(fn).toBeCalledWith(searchSource, options); expect(fn).toBeCalledWith(searchSource, options);
}); });
it('should not be called on parent searchSource', async () => { test('should not be called on parent searchSource', async () => {
const parent = new SearchSource(); const parent = new SearchSource({}, searchSourceDependencies);
const searchSource = new SearchSource({ index: indexPattern }); const searchSource = new SearchSource({ index: indexPattern }, searchSourceDependencies);
const fn = jest.fn(); const fn = jest.fn();
searchSource.onRequestStart(fn); searchSource.onRequestStart(fn);
@ -154,9 +161,12 @@ describe('SearchSource', function() {
expect(parentFn).not.toBeCalled(); expect(parentFn).not.toBeCalled();
}); });
it('should be called on parent searchSource if callParentStartHandlers is true', async () => { test('should be called on parent searchSource if callParentStartHandlers is true', async () => {
const parent = new SearchSource(); const parent = new SearchSource({}, searchSourceDependencies);
const searchSource = new SearchSource({ index: indexPattern }).setParent(parent, { const searchSource = new SearchSource(
{ index: indexPattern },
searchSourceDependencies
).setParent(parent, {
callParentStartHandlers: true, callParentStartHandlers: true,
}); });
@ -174,19 +184,21 @@ describe('SearchSource', function() {
describe('#legacy fetch()', () => { describe('#legacy fetch()', () => {
beforeEach(() => { beforeEach(() => {
uiSettingsMock.get.mockImplementation(() => { const core = coreMock.createStart();
searchSourceDependencies = {
...searchSourceDependencies,
uiSettings: {
...core.uiSettings,
get: jest.fn(() => {
return true; // batchSearches = true return true; // batchSearches = true
}); }),
} as IUiSettingsClient,
};
}); });
afterEach(() => { test('should call msearch', async () => {
uiSettingsMock.get.mockImplementation(() => { const searchSource = new SearchSource({ index: indexPattern }, searchSourceDependencies);
return false; // batchSearches = false
});
});
it('should call msearch', async () => {
const searchSource = new SearchSource({ index: indexPattern });
const options = {}; const options = {};
await searchSource.fetch(options); await searchSource.fetch(options);
expect(fetchSoon).toBeCalledTimes(1); expect(fetchSoon).toBeCalledTimes(1);
@ -194,18 +206,19 @@ describe('SearchSource', function() {
}); });
describe('#search service fetch()', () => { describe('#search service fetch()', () => {
it('should call msearch', async () => { test('should call msearch', async () => {
const searchSource = new SearchSource({ index: indexPattern }); const searchSource = new SearchSource({ index: indexPattern }, searchSourceDependencies);
const options = {}; const options = {};
await searchSource.fetch(options); await searchSource.fetch(options);
expect(searchStartMock.search).toBeCalledTimes(1); expect(mockSearchMethod).toBeCalledTimes(1);
}); });
}); });
describe('#serialize', function() { describe('#serialize', () => {
it('should reference index patterns', () => { test('should reference index patterns', () => {
const indexPattern123 = { id: '123' } as IndexPattern; const indexPattern123 = { id: '123' } as IndexPattern;
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('index', indexPattern123); searchSource.setField('index', indexPattern123);
const { searchSourceJSON, references } = searchSource.serialize(); const { searchSourceJSON, references } = searchSource.serialize();
expect(references[0].id).toEqual('123'); expect(references[0].id).toEqual('123');
@ -213,8 +226,8 @@ describe('SearchSource', function() {
expect(JSON.parse(searchSourceJSON).indexRefName).toEqual(references[0].name); expect(JSON.parse(searchSourceJSON).indexRefName).toEqual(references[0].name);
}); });
it('should add other fields', () => { test('should add other fields', () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('highlightAll', true); searchSource.setField('highlightAll', true);
searchSource.setField('from', 123456); searchSource.setField('from', 123456);
const { searchSourceJSON } = searchSource.serialize(); const { searchSourceJSON } = searchSource.serialize();
@ -222,8 +235,8 @@ describe('SearchSource', function() {
expect(JSON.parse(searchSourceJSON).from).toEqual(123456); expect(JSON.parse(searchSourceJSON).from).toEqual(123456);
}); });
it('should omit sort and size', () => { test('should omit sort and size', () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
searchSource.setField('highlightAll', true); searchSource.setField('highlightAll', true);
searchSource.setField('from', 123456); searchSource.setField('from', 123456);
searchSource.setField('sort', { field: SortDirection.asc }); searchSource.setField('sort', { field: SortDirection.asc });
@ -232,8 +245,8 @@ describe('SearchSource', function() {
expect(Object.keys(JSON.parse(searchSourceJSON))).toEqual(['highlightAll', 'from']); expect(Object.keys(JSON.parse(searchSourceJSON))).toEqual(['highlightAll', 'from']);
}); });
it('should serialize filters', () => { test('should serialize filters', () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
const filter = [ const filter = [
{ {
query: 'query', query: 'query',
@ -249,8 +262,8 @@ describe('SearchSource', function() {
expect(JSON.parse(searchSourceJSON).filter).toEqual(filter); expect(JSON.parse(searchSourceJSON).filter).toEqual(filter);
}); });
it('should reference index patterns in filters separately from index field', () => { test('should reference index patterns in filters separately from index field', () => {
const searchSource = new SearchSource(); const searchSource = new SearchSource({}, searchSourceDependencies);
const indexPattern123 = { id: '123' } as IndexPattern; const indexPattern123 = { id: '123' } as IndexPattern;
searchSource.setField('index', indexPattern123); searchSource.setField('index', indexPattern123);
const filter = [ const filter = [

View file

@ -69,34 +69,45 @@
* `appSearchSource`. * `appSearchSource`.
*/ */
import _ from 'lodash'; import { uniqueId, uniq, extend, pick, difference, set, omit, keys, isFunction } from 'lodash';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { SavedObjectReference } from 'kibana/public'; import { CoreStart, SavedObjectReference } from 'kibana/public';
import { normalizeSortRequest } from './normalize_sort_request'; import { normalizeSortRequest } from './normalize_sort_request';
import { filterDocvalueFields } from './filter_docvalue_fields'; import { filterDocvalueFields } from './filter_docvalue_fields';
import { fieldWildcardFilter } from '../../../../kibana_utils/public'; import { fieldWildcardFilter } from '../../../../kibana_utils/public';
import { IIndexPattern, SearchRequest } from '../..'; import { IIndexPattern, ISearchGeneric, SearchRequest } from '../..';
import { SearchSourceOptions, SearchSourceFields } from './types'; import { SearchSourceOptions, SearchSourceFields } from './types';
import { FetchOptions, RequestFailure, getSearchParams, handleResponse } from '../fetch'; import { FetchOptions, RequestFailure, getSearchParams, handleResponse } from '../fetch';
import { getSearchService, getUiSettings, getInjectedMetadata } from '../../services';
import { getEsQueryConfig, buildEsQuery, Filter } from '../../../common'; import { getEsQueryConfig, buildEsQuery, Filter } from '../../../common';
import { getHighlightRequest } from '../../../common/field_formats'; import { getHighlightRequest } from '../../../common/field_formats';
import { fetchSoon } from '../legacy'; import { fetchSoon } from '../legacy';
import { ISearchStartLegacy } from '../types';
export type ISearchSource = Pick<SearchSource, keyof SearchSource>; export interface SearchSourceDependencies {
uiSettings: CoreStart['uiSettings'];
search: ISearchGeneric;
legacySearch: ISearchStartLegacy;
injectedMetadata: CoreStart['injectedMetadata'];
}
/** @public **/
export class SearchSource { export class SearchSource {
private id: string = _.uniqueId('data_source'); private id: string = uniqueId('data_source');
private searchStrategyId?: string; private searchStrategyId?: string;
private parent?: SearchSource; private parent?: SearchSource;
private requestStartHandlers: Array< private requestStartHandlers: Array<
(searchSource: ISearchSource, options?: FetchOptions) => Promise<unknown> (searchSource: SearchSource, options?: FetchOptions) => Promise<unknown>
> = []; > = [];
private inheritOptions: SearchSourceOptions = {}; private inheritOptions: SearchSourceOptions = {};
public history: SearchRequest[] = []; public history: SearchRequest[] = [];
private fields: SearchSourceFields;
private readonly dependencies: SearchSourceDependencies;
constructor(private fields: SearchSourceFields = {}) {} constructor(fields: SearchSourceFields = {}, dependencies: SearchSourceDependencies) {
this.fields = fields;
this.dependencies = dependencies;
}
/** *** /** ***
* PUBLIC API * PUBLIC API
@ -147,11 +158,11 @@ export class SearchSource {
} }
create() { create() {
return new SearchSource(); return new SearchSource({}, this.dependencies);
} }
createCopy() { createCopy() {
const newSearchSource = new SearchSource(); const newSearchSource = new SearchSource({}, this.dependencies);
newSearchSource.setFields({ ...this.fields }); newSearchSource.setFields({ ...this.fields });
// when serializing the internal fields we lose the internal classes used in the index // when serializing the internal fields we lose the internal classes used in the index
// pattern, so we have to set it again to workaround this behavior // pattern, so we have to set it again to workaround this behavior
@ -161,7 +172,7 @@ export class SearchSource {
} }
createChild(options = {}) { createChild(options = {}) {
const childSearchSource = new SearchSource(); const childSearchSource = new SearchSource({}, this.dependencies);
childSearchSource.setParent(this, options); childSearchSource.setParent(this, options);
return childSearchSource; return childSearchSource;
} }
@ -191,16 +202,17 @@ export class SearchSource {
* @return {Observable<SearchResponse<unknown>>} * @return {Observable<SearchResponse<unknown>>}
*/ */
private fetch$(searchRequest: SearchRequest, signal?: AbortSignal) { private fetch$(searchRequest: SearchRequest, signal?: AbortSignal) {
const esShardTimeout = getInjectedMetadata().getInjectedVar('esShardTimeout') as number; const { search, injectedMetadata, uiSettings } = this.dependencies;
const searchParams = getSearchParams(getUiSettings(), esShardTimeout); const esShardTimeout = injectedMetadata.getInjectedVar('esShardTimeout') as number;
const searchParams = getSearchParams(uiSettings, esShardTimeout);
const params = { const params = {
index: searchRequest.index.title || searchRequest.index, index: searchRequest.index.title || searchRequest.index,
body: searchRequest.body, body: searchRequest.body,
...searchParams, ...searchParams,
}; };
return getSearchService() return search({ params, indexType: searchRequest.indexType }, { signal }).pipe(
.search({ params, indexType: searchRequest.indexType }, { signal }) map(({ rawResponse }) => handleResponse(searchRequest, rawResponse))
.pipe(map(({ rawResponse }) => handleResponse(searchRequest, rawResponse))); );
} }
/** /**
@ -208,7 +220,9 @@ export class SearchSource {
* @return {Promise<SearchResponse<unknown>>} * @return {Promise<SearchResponse<unknown>>}
*/ */
private async legacyFetch(searchRequest: SearchRequest, options: FetchOptions) { private async legacyFetch(searchRequest: SearchRequest, options: FetchOptions) {
const esShardTimeout = getInjectedMetadata().getInjectedVar('esShardTimeout') as number; const { injectedMetadata, legacySearch, uiSettings } = this.dependencies;
const esShardTimeout = injectedMetadata.getInjectedVar('esShardTimeout') as number;
return await fetchSoon( return await fetchSoon(
searchRequest, searchRequest,
{ {
@ -216,8 +230,8 @@ export class SearchSource {
...options, ...options,
}, },
{ {
searchService: getSearchService(), legacySearchService: legacySearch,
config: getUiSettings(), config: uiSettings,
esShardTimeout, esShardTimeout,
} }
); );
@ -228,13 +242,14 @@ export class SearchSource {
* @async * @async
*/ */
async fetch(options: FetchOptions = {}) { async fetch(options: FetchOptions = {}) {
const { uiSettings } = this.dependencies;
await this.requestIsStarting(options); await this.requestIsStarting(options);
const searchRequest = await this.flatten(); const searchRequest = await this.flatten();
this.history = [searchRequest]; this.history = [searchRequest];
let response; let response;
if (getUiSettings().get('courier:batchSearches')) { if (uiSettings.get('courier:batchSearches')) {
response = await this.legacyFetch(searchRequest, options); response = await this.legacyFetch(searchRequest, options);
} else { } else {
response = this.fetch$(searchRequest, options.abortSignal).toPromise(); response = this.fetch$(searchRequest, options.abortSignal).toPromise();
@ -253,7 +268,7 @@ export class SearchSource {
* @return {undefined} * @return {undefined}
*/ */
onRequestStart( onRequestStart(
handler: (searchSource: ISearchSource, options?: FetchOptions) => Promise<unknown> handler: (searchSource: SearchSource, options?: FetchOptions) => Promise<unknown>
) { ) {
this.requestStartHandlers.push(handler); this.requestStartHandlers.push(handler);
} }
@ -326,13 +341,15 @@ export class SearchSource {
} }
}; };
const { uiSettings } = this.dependencies;
switch (key) { switch (key) {
case 'filter': case 'filter':
return addToRoot('filters', (data.filters || []).concat(val)); return addToRoot('filters', (data.filters || []).concat(val));
case 'query': case 'query':
return addToRoot(key, (data[key] || []).concat(val)); return addToRoot(key, (data[key] || []).concat(val));
case 'fields': case 'fields':
const fields = _.uniq((data[key] || []).concat(val)); const fields = uniq((data[key] || []).concat(val));
return addToRoot(key, fields); return addToRoot(key, fields);
case 'index': case 'index':
case 'type': case 'type':
@ -346,7 +363,7 @@ export class SearchSource {
const sort = normalizeSortRequest( const sort = normalizeSortRequest(
val, val,
this.getField('index'), this.getField('index'),
getUiSettings().get('sort:options') uiSettings.get('sort:options')
); );
return addToBody(key, sort); return addToBody(key, sort);
default: default:
@ -389,7 +406,7 @@ export class SearchSource {
body.stored_fields = computedFields.storedFields; body.stored_fields = computedFields.storedFields;
body.script_fields = body.script_fields || {}; body.script_fields = body.script_fields || {};
_.extend(body.script_fields, computedFields.scriptFields); extend(body.script_fields, computedFields.scriptFields);
const defaultDocValueFields = computedFields.docvalueFields const defaultDocValueFields = computedFields.docvalueFields
? computedFields.docvalueFields ? computedFields.docvalueFields
@ -400,9 +417,11 @@ export class SearchSource {
body._source = index.getSourceFiltering(); body._source = index.getSourceFiltering();
} }
const { uiSettings } = this.dependencies;
if (body._source) { if (body._source) {
// exclude source fields for this index pattern specified by the user // exclude source fields for this index pattern specified by the user
const filter = fieldWildcardFilter(body._source.excludes, getUiSettings().get('metaFields')); const filter = fieldWildcardFilter(body._source.excludes, uiSettings.get('metaFields'));
body.docvalue_fields = body.docvalue_fields.filter((docvalueField: any) => body.docvalue_fields = body.docvalue_fields.filter((docvalueField: any) =>
filter(docvalueField.field) filter(docvalueField.field)
); );
@ -412,19 +431,19 @@ export class SearchSource {
if (fields) { if (fields) {
// filter out the docvalue_fields, and script_fields to only include those that we are concerned with // filter out the docvalue_fields, and script_fields to only include those that we are concerned with
body.docvalue_fields = filterDocvalueFields(body.docvalue_fields, fields); body.docvalue_fields = filterDocvalueFields(body.docvalue_fields, fields);
body.script_fields = _.pick(body.script_fields, fields); body.script_fields = pick(body.script_fields, fields);
// request the remaining fields from both stored_fields and _source // request the remaining fields from both stored_fields and _source
const remainingFields = _.difference(fields, _.keys(body.script_fields)); const remainingFields = difference(fields, keys(body.script_fields));
body.stored_fields = remainingFields; body.stored_fields = remainingFields;
_.set(body, '_source.includes', remainingFields); set(body, '_source.includes', remainingFields);
} }
const esQueryConfigs = getEsQueryConfig(getUiSettings()); const esQueryConfigs = getEsQueryConfig(uiSettings);
body.query = buildEsQuery(index, query, filters, esQueryConfigs); body.query = buildEsQuery(index, query, filters, esQueryConfigs);
if (highlightAll && body.query) { if (highlightAll && body.query) {
body.highlight = getHighlightRequest(body.query, getUiSettings().get('doc_table:highlight')); body.highlight = getHighlightRequest(body.query, uiSettings.get('doc_table:highlight'));
delete searchRequest.highlightAll; delete searchRequest.highlightAll;
} }
@ -467,7 +486,7 @@ export class SearchSource {
const { const {
filter: originalFilters, filter: originalFilters,
...searchSourceFields ...searchSourceFields
}: Omit<SearchSourceFields, 'sort' | 'size'> = _.omit(this.getFields(), ['sort', 'size']); }: Omit<SearchSourceFields, 'sort' | 'size'> = omit(this.getFields(), ['sort', 'size']);
let serializedSearchSourceFields: Omit<SearchSourceFields, 'sort' | 'size' | 'filter'> & { let serializedSearchSourceFields: Omit<SearchSourceFields, 'sort' | 'size' | 'filter'> & {
indexRefName?: string; indexRefName?: string;
filter?: Array<Omit<Filter, 'meta'> & { meta: Filter['meta'] & { indexRefName?: string } }>; filter?: Array<Omit<Filter, 'meta'> & { meta: Filter['meta'] & { indexRefName?: string } }>;
@ -524,10 +543,13 @@ export class SearchSource {
return filterField; return filterField;
} }
if (_.isFunction(filterField)) { if (isFunction(filterField)) {
return this.getFilters(filterField()); return this.getFilters(filterField());
} }
return [filterField]; return [filterField];
} }
} }
/** @public **/
export type ISearchSource = Pick<SearchSource, keyof SearchSource>;

View file

@ -17,13 +17,13 @@
* under the License. * under the License.
*/ */
import { CoreStart } from 'kibana/public'; import { CoreStart, SavedObjectReference } from 'kibana/public';
import { createSearchSource } from './search_source';
import { SearchAggsSetup, SearchAggsStart, SearchAggsStartLegacy } from './aggs'; import { SearchAggsSetup, SearchAggsStart, SearchAggsStartLegacy } from './aggs';
import { ISearch, ISearchGeneric } from './i_search'; import { ISearch, ISearchGeneric } from './i_search';
import { TStrategyTypes } from './strategy_types'; import { TStrategyTypes } from './strategy_types';
import { LegacyApiCaller } from './legacy/es_client'; import { LegacyApiCaller } from './legacy/es_client';
import { SearchInterceptor } from './search_interceptor'; import { SearchInterceptor } from './search_interceptor';
import { ISearchSource, SearchSourceFields } from './search_source';
export interface ISearchContext { export interface ISearchContext {
core: CoreStart; core: CoreStart;
@ -60,7 +60,7 @@ export type TRegisterSearchStrategyProvider = <T extends TStrategyTypes>(
searchStrategyProvider: TSearchStrategyProvider<T> searchStrategyProvider: TSearchStrategyProvider<T>
) => void; ) => void;
interface ISearchStartLegacy { export interface ISearchStartLegacy {
esClient: LegacyApiCaller; esClient: LegacyApiCaller;
} }
@ -81,6 +81,12 @@ export interface ISearchStart {
aggs: SearchAggsStart; aggs: SearchAggsStart;
setInterceptor: (searchInterceptor: SearchInterceptor) => void; setInterceptor: (searchInterceptor: SearchInterceptor) => void;
search: ISearchGeneric; search: ISearchGeneric;
createSearchSource: ReturnType<typeof createSearchSource>; searchSource: {
create: (fields?: SearchSourceFields) => ISearchSource;
fromJSON: (
searchSourceJson: string,
references: SavedObjectReference[]
) => Promise<ISearchSource>;
};
__LEGACY: ISearchStartLegacy & SearchAggsStartLegacy; __LEGACY: ISearchStartLegacy & SearchAggsStartLegacy;
} }

View file

@ -17,7 +17,7 @@
* under the License. * under the License.
*/ */
import { NotificationsStart, CoreSetup, CoreStart } from 'src/core/public'; import { NotificationsStart, CoreStart } from 'src/core/public';
import { FieldFormatsStart } from './field_formats'; import { FieldFormatsStart } from './field_formats';
import { createGetterSetter } from '../../kibana_utils/public'; import { createGetterSetter } from '../../kibana_utils/public';
import { IndexPatternsContract } from './index_patterns'; import { IndexPatternsContract } from './index_patterns';
@ -48,7 +48,7 @@ export const [getQueryService, setQueryService] = createGetterSetter<
>('Query'); >('Query');
export const [getInjectedMetadata, setInjectedMetadata] = createGetterSetter< export const [getInjectedMetadata, setInjectedMetadata] = createGetterSetter<
CoreSetup['injectedMetadata'] CoreStart['injectedMetadata']
>('InjectedMetadata'); >('InjectedMetadata');
export const [getSearchService, setSearchService] = createGetterSetter< export const [getSearchService, setSearchService] = createGetterSetter<

View file

@ -74,8 +74,11 @@ export interface IDataPluginServices extends Partial<CoreStart> {
/** @internal **/ /** @internal **/
export interface InternalStartServices { export interface InternalStartServices {
fieldFormats: FieldFormatsStart; readonly fieldFormats: FieldFormatsStart;
notifications: CoreStart['notifications']; readonly notifications: CoreStart['notifications'];
readonly uiSettings: CoreStart['uiSettings'];
readonly searchService: DataPublicPluginStart['search'];
readonly injectedMetadata: CoreStart['injectedMetadata'];
} }
/** @internal **/ /** @internal **/

View file

@ -17,9 +17,9 @@
* under the License. * under the License.
*/ */
import _ from 'lodash'; import _ from 'lodash';
import { EsResponse, SavedObject, SavedObjectConfig } from '../../types'; import { EsResponse, SavedObject, SavedObjectConfig, SavedObjectKibanaServices } from '../../types';
import { expandShorthand, SavedObjectNotFound } from '../../../../kibana_utils/public'; import { expandShorthand, SavedObjectNotFound } from '../../../../kibana_utils/public';
import { DataPublicPluginStart, IndexPattern } from '../../../../data/public'; import { IndexPattern } from '../../../../data/public';
/** /**
* A given response of and ElasticSearch containing a plain saved object is applied to the given * A given response of and ElasticSearch containing a plain saved object is applied to the given
@ -29,7 +29,7 @@ export async function applyESResp(
resp: EsResponse, resp: EsResponse,
savedObject: SavedObject, savedObject: SavedObject,
config: SavedObjectConfig, config: SavedObjectConfig,
createSearchSource: DataPublicPluginStart['search']['createSearchSource'] dependencies: SavedObjectKibanaServices
) { ) {
const mapping = expandShorthand(config.mapping); const mapping = expandShorthand(config.mapping);
const esType = config.type || ''; const esType = config.type || '';
@ -65,7 +65,10 @@ export async function applyESResp(
if (config.searchSource) { if (config.searchSource) {
try { try {
savedObject.searchSource = await createSearchSource(meta.searchSourceJSON, resp.references); savedObject.searchSource = await dependencies.search.searchSource.fromJSON(
meta.searchSourceJSON,
resp.references
);
} catch (error) { } catch (error) {
if ( if (
error.constructor.name === 'SavedObjectNotFound' && error.constructor.name === 'SavedObjectNotFound' &&

View file

@ -16,8 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import _ from 'lodash'; import { once } from 'lodash';
import { SearchSource } from '../../../../data/public';
import { hydrateIndexPattern } from './hydrate_index_pattern'; import { hydrateIndexPattern } from './hydrate_index_pattern';
import { intializeSavedObject } from './initialize_saved_object'; import { intializeSavedObject } from './initialize_saved_object';
import { serializeSavedObject } from './serialize_saved_object'; import { serializeSavedObject } from './serialize_saved_object';
@ -55,7 +54,9 @@ export function buildSavedObject(
savedObject.isSaving = false; savedObject.isSaving = false;
savedObject.defaults = config.defaults || {}; savedObject.defaults = config.defaults || {};
// optional search source which this object configures // optional search source which this object configures
savedObject.searchSource = config.searchSource ? new SearchSource() : undefined; savedObject.searchSource = config.searchSource
? services.search.searchSource.create()
: undefined;
// the id of the document // the id of the document
savedObject.id = config.id || void 0; savedObject.id = config.id || void 0;
// the migration version of the document, should only be set on imports // the migration version of the document, should only be set on imports
@ -79,10 +80,9 @@ export function buildSavedObject(
* @return {Promise} * @return {Promise}
* @resolved {SavedObject} * @resolved {SavedObject}
*/ */
savedObject.init = _.once(() => intializeSavedObject(savedObject, savedObjectsClient, config)); savedObject.init = once(() => intializeSavedObject(savedObject, savedObjectsClient, config));
savedObject.applyESResp = (resp: EsResponse) => savedObject.applyESResp = (resp: EsResponse) => applyESResp(resp, savedObject, config, services);
applyESResp(resp, savedObject, config, services.search.createSearchSource);
/** /**
* Serialize this object * Serialize this object

View file

@ -28,9 +28,8 @@ import {
// @ts-ignore // @ts-ignore
import StubIndexPattern from 'test_utils/stub_index_pattern'; import StubIndexPattern from 'test_utils/stub_index_pattern';
import { InvalidJSONProperty } from '../../../kibana_utils/public';
import { coreMock } from '../../../../core/public/mocks'; import { coreMock } from '../../../../core/public/mocks';
import { dataPluginMock } from '../../../../plugins/data/public/mocks'; import { dataPluginMock, createSearchSourceMock } from '../../../../plugins/data/public/mocks';
import { SavedObjectAttributes, SimpleSavedObject } from 'kibana/public'; import { SavedObjectAttributes, SimpleSavedObject } from 'kibana/public';
import { IIndexPattern } from '../../../data/common/index_patterns'; import { IIndexPattern } from '../../../data/common/index_patterns';
@ -40,9 +39,9 @@ describe('Saved Object', () => {
const startMock = coreMock.createStart(); const startMock = coreMock.createStart();
const dataStartMock = dataPluginMock.createStartContract(); const dataStartMock = dataPluginMock.createStartContract();
const saveOptionsMock = {} as SavedObjectSaveOpts; const saveOptionsMock = {} as SavedObjectSaveOpts;
const savedObjectsClientStub = startMock.savedObjects.client;
let SavedObjectClass: new (config: SavedObjectConfig) => SavedObject; let SavedObjectClass: new (config: SavedObjectConfig) => SavedObject;
const savedObjectsClientStub = startMock.savedObjects.client;
/** /**
* Returns a fake doc response with the given index and id, of type dashboard * Returns a fake doc response with the given index and id, of type dashboard
@ -99,16 +98,22 @@ describe('Saved Object', () => {
function createInitializedSavedObject(config: SavedObjectConfig = {}) { function createInitializedSavedObject(config: SavedObjectConfig = {}) {
const savedObject = new SavedObjectClass(config); const savedObject = new SavedObjectClass(config);
savedObject.title = 'my saved object'; savedObject.title = 'my saved object';
return savedObject.init!(); return savedObject.init!();
} }
beforeEach(() => { beforeEach(() => {
(dataStartMock.search.createSearchSource as jest.Mock).mockReset(); SavedObjectClass = createSavedObjectClass(({
SavedObjectClass = createSavedObjectClass({
savedObjectsClient: savedObjectsClientStub, savedObjectsClient: savedObjectsClientStub,
indexPatterns: dataStartMock.indexPatterns, indexPatterns: dataStartMock.indexPatterns,
search: dataStartMock.search, search: {
} as SavedObjectKibanaServices); ...dataStartMock.search,
searchSource: {
...dataStartMock.search.searchSource,
create: createSearchSourceMock,
},
},
} as unknown) as SavedObjectKibanaServices);
}); });
describe('save', () => { describe('save', () => {
@ -411,27 +416,6 @@ describe('Saved Object', () => {
}); });
}); });
it('forwards thrown exceptions from createSearchSource', async () => {
(dataStartMock.search.createSearchSource as jest.Mock).mockImplementation(() => {
throw new InvalidJSONProperty('');
});
const savedObject = await createInitializedSavedObject({
type: 'dashboard',
searchSource: true,
});
const response = {
found: true,
_source: {},
};
try {
await savedObject.applyESResp(response);
throw new Error('applyESResp should have failed, but did not.');
} catch (err) {
expect(err instanceof InvalidJSONProperty).toBe(true);
}
});
it('preserves original defaults if not overridden', () => { it('preserves original defaults if not overridden', () => {
const id = 'anid'; const id = 'anid';
const preserveMeValue = 'here to stay!'; const preserveMeValue = 'here to stay!';
@ -589,7 +573,8 @@ describe('Saved Object', () => {
it('passes references to search source parsing function', async () => { it('passes references to search source parsing function', async () => {
const savedObject = new SavedObjectClass({ type: 'dashboard', searchSource: true }); const savedObject = new SavedObjectClass({ type: 'dashboard', searchSource: true });
return savedObject.init!().then(() => { await savedObject.init!();
const searchSourceJSON = JSON.stringify({ const searchSourceJSON = JSON.stringify({
indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index',
filter: [ filter: [
@ -620,11 +605,13 @@ describe('Saved Object', () => {
}, },
], ],
}; };
savedObject.applyESResp(response); const result = await savedObject.applyESResp(response);
expect(dataStartMock.search.createSearchSource).toBeCalledWith(
searchSourceJSON, expect(result._source).toEqual({
response.references kibanaSavedObjectMeta: {
); searchSourceJSON:
'{"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index","filter":[{"meta":{"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index"}}]}',
},
}); });
}); });
}); });

View file

@ -25,6 +25,7 @@ import {
} from './resolve_saved_objects'; } from './resolve_saved_objects';
import { SavedObject, SavedObjectLoader } from '../../../saved_objects/public'; import { SavedObject, SavedObjectLoader } from '../../../saved_objects/public';
import { IndexPatternsContract } from '../../../data/public'; import { IndexPatternsContract } from '../../../data/public';
import { dataPluginMock } from '../../../data/public/mocks';
class SavedObjectNotFound extends Error { class SavedObjectNotFound extends Error {
constructor(options: Record<string, any>) { constructor(options: Record<string, any>) {
@ -233,6 +234,19 @@ describe('resolveSavedObjects', () => {
}); });
describe('resolveIndexPatternConflicts', () => { describe('resolveIndexPatternConflicts', () => {
let dependencies: Parameters<typeof resolveIndexPatternConflicts>[3];
beforeEach(() => {
const search = dataPluginMock.createStartContract().search;
dependencies = {
indexPatterns: ({
get: (id: string) => Promise.resolve({ id }),
} as unknown) as IndexPatternsContract,
search,
};
});
it('should resave resolutions', async () => { it('should resave resolutions', async () => {
const save = jest.fn(); const save = jest.fn();
@ -284,11 +298,13 @@ describe('resolveSavedObjects', () => {
const overwriteAll = false; const overwriteAll = false;
await resolveIndexPatternConflicts(resolutions, conflictedIndexPatterns, overwriteAll, ({ await resolveIndexPatternConflicts(
get: (id: string) => Promise.resolve({ id }), resolutions,
} as unknown) as IndexPatternsContract); conflictedIndexPatterns,
expect(conflictedIndexPatterns[0].obj.searchSource!.getField('index')!.id).toEqual('2'); overwriteAll,
expect(conflictedIndexPatterns[1].obj.searchSource!.getField('index')!.id).toEqual('4'); dependencies
);
expect(save.mock.calls.length).toBe(2); expect(save.mock.calls.length).toBe(2);
expect(save).toHaveBeenCalledWith({ confirmOverwrite: !overwriteAll }); expect(save).toHaveBeenCalledWith({ confirmOverwrite: !overwriteAll });
}); });
@ -345,13 +361,13 @@ describe('resolveSavedObjects', () => {
const overwriteAll = false; const overwriteAll = false;
await resolveIndexPatternConflicts(resolutions, conflictedIndexPatterns, overwriteAll, ({ await resolveIndexPatternConflicts(
get: (id: string) => Promise.resolve({ id }), resolutions,
} as unknown) as IndexPatternsContract); conflictedIndexPatterns,
overwriteAll,
dependencies
);
expect(conflictedIndexPatterns[0].obj.searchSource!.getField('filter')).toEqual([
{ meta: { index: 'newFilterIndex' } },
]);
expect(save.mock.calls.length).toBe(2); expect(save.mock.calls.length).toBe(2);
}); });
}); });

View file

@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { OverlayStart, SavedObjectReference } from 'src/core/public'; import { OverlayStart, SavedObjectReference } from 'src/core/public';
import { SavedObject, SavedObjectLoader } from '../../../saved_objects/public'; import { SavedObject, SavedObjectLoader } from '../../../saved_objects/public';
import { IndexPatternsContract, IIndexPattern, createSearchSource } from '../../../data/public'; import { IndexPatternsContract, IIndexPattern, DataPublicPluginStart } from '../../../data/public';
type SavedObjectsRawDoc = Record<string, any>; type SavedObjectsRawDoc = Record<string, any>;
@ -162,7 +162,10 @@ export async function resolveIndexPatternConflicts(
resolutions: Array<{ oldId: string; newId: string }>, resolutions: Array<{ oldId: string; newId: string }>,
conflictedIndexPatterns: any[], conflictedIndexPatterns: any[],
overwriteAll: boolean, overwriteAll: boolean,
indexPatterns: IndexPatternsContract dependencies: {
indexPatterns: IndexPatternsContract;
search: DataPublicPluginStart['search'];
}
) { ) {
let importCount = 0; let importCount = 0;
@ -208,7 +211,7 @@ export async function resolveIndexPatternConflicts(
// The user decided to skip this conflict so do nothing // The user decided to skip this conflict so do nothing
return; return;
} }
obj.searchSource = await createSearchSource(indexPatterns)( obj.searchSource = await dependencies.search.searchSource.fromJSON(
JSON.stringify(serializedSearchSource), JSON.stringify(serializedSearchSource),
replacedReferences replacedReferences
); );

View file

@ -187,6 +187,7 @@ const SavedObjectsTablePage = ({
actionRegistry={actionRegistry} actionRegistry={actionRegistry}
savedObjectsClient={coreStart.savedObjects.client} savedObjectsClient={coreStart.savedObjects.client}
indexPatterns={dataStart.indexPatterns} indexPatterns={dataStart.indexPatterns}
search={dataStart.search}
http={coreStart.http} http={coreStart.http}
overlays={coreStart.overlays} overlays={coreStart.overlays}
notifications={coreStart.notifications} notifications={coreStart.notifications}

View file

@ -256,6 +256,41 @@ exports[`SavedObjectsTable import should show the flyout 1`] = `
"openModal": [MockFunction], "openModal": [MockFunction],
} }
} }
search={
Object {
"__LEGACY": Object {
"AggConfig": [MockFunction],
"AggType": [MockFunction],
"FieldParamType": [MockFunction],
"MetricAggType": [MockFunction],
"aggTypeFieldFilters": AggTypeFieldFilters {
"filters": Set {},
},
"esClient": Object {
"msearch": [MockFunction],
"search": [MockFunction],
},
"parentPipelineAggHelper": [MockFunction],
"siblingPipelineAggHelper": [MockFunction],
},
"aggs": Object {
"calculateAutoTimeExpression": [Function],
"createAggConfigs": [MockFunction],
"types": Object {
"get": [Function],
"getAll": [Function],
"getBuckets": [Function],
"getMetrics": [Function],
},
},
"search": [MockFunction],
"searchSource": Object {
"create": [MockFunction],
"fromJSON": [MockFunction],
},
"setInterceptor": [MockFunction],
}
}
serviceRegistry={ serviceRegistry={
Object { Object {
"all": [MockFunction], "all": [MockFunction],

View file

@ -33,6 +33,7 @@ import { coreMock } from '../../../../../../core/public/mocks';
import { serviceRegistryMock } from '../../../services/service_registry.mock'; import { serviceRegistryMock } from '../../../services/service_registry.mock';
import { Flyout, FlyoutProps, FlyoutState } from './flyout'; import { Flyout, FlyoutProps, FlyoutState } from './flyout';
import { ShallowWrapper } from 'enzyme'; import { ShallowWrapper } from 'enzyme';
import { dataPluginMock } from '../../../../../data/public/mocks';
const mockFile = ({ const mockFile = ({
name: 'foo.ndjson', name: 'foo.ndjson',
@ -56,6 +57,7 @@ describe('Flyout', () => {
beforeEach(() => { beforeEach(() => {
const { http, overlays } = coreMock.createStart(); const { http, overlays } = coreMock.createStart();
const search = dataPluginMock.createStartContract().search;
defaultProps = { defaultProps = {
close: jest.fn(), close: jest.fn(),
@ -68,6 +70,7 @@ describe('Flyout', () => {
http, http,
allowedTypes: ['search', 'index-pattern', 'visualization'], allowedTypes: ['search', 'index-pattern', 'visualization'],
serviceRegistry: serviceRegistryMock.create(), serviceRegistry: serviceRegistryMock.create(),
search,
}; };
}); });
@ -499,7 +502,10 @@ describe('Flyout', () => {
component.instance().resolutions, component.instance().resolutions,
mockConflictedIndexPatterns, mockConflictedIndexPatterns,
true, true,
defaultProps.indexPatterns {
search: defaultProps.search,
indexPatterns: defaultProps.indexPatterns,
}
); );
expect(saveObjectsMock).toHaveBeenCalledWith( expect(saveObjectsMock).toHaveBeenCalledWith(
mockConflictedSavedObjectsLinkedToSavedSearches, mockConflictedSavedObjectsLinkedToSavedSearches,

View file

@ -48,7 +48,11 @@ import {
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react'; import { FormattedMessage } from '@kbn/i18n/react';
import { OverlayStart, HttpStart } from 'src/core/public'; import { OverlayStart, HttpStart } from 'src/core/public';
import { IndexPatternsContract, IIndexPattern } from '../../../../../data/public'; import {
IndexPatternsContract,
IIndexPattern,
DataPublicPluginStart,
} from '../../../../../data/public';
import { import {
importFile, importFile,
importLegacyFile, importLegacyFile,
@ -75,6 +79,7 @@ export interface FlyoutProps {
indexPatterns: IndexPatternsContract; indexPatterns: IndexPatternsContract;
overlays: OverlayStart; overlays: OverlayStart;
http: HttpStart; http: HttpStart;
search: DataPublicPluginStart['search'];
} }
export interface FlyoutState { export interface FlyoutState {
@ -362,7 +367,7 @@ export class Flyout extends Component<FlyoutProps, FlyoutState> {
failedImports, failedImports,
} = this.state; } = this.state;
const { serviceRegistry, indexPatterns } = this.props; const { serviceRegistry, indexPatterns, search } = this.props;
this.setState({ this.setState({
error: undefined, error: undefined,
@ -388,7 +393,10 @@ export class Flyout extends Component<FlyoutProps, FlyoutState> {
resolutions, resolutions,
conflictedIndexPatterns!, conflictedIndexPatterns!,
isOverwriteAllChecked, isOverwriteAllChecked,
indexPatterns {
indexPatterns,
search,
}
); );
} }
this.setState({ this.setState({

View file

@ -88,6 +88,7 @@ describe('SavedObjectsTable', () => {
let overlays: ReturnType<typeof overlayServiceMock.createStartContract>; let overlays: ReturnType<typeof overlayServiceMock.createStartContract>;
let notifications: ReturnType<typeof notificationServiceMock.createStartContract>; let notifications: ReturnType<typeof notificationServiceMock.createStartContract>;
let savedObjects: ReturnType<typeof savedObjectsServiceMock.createStartContract>; let savedObjects: ReturnType<typeof savedObjectsServiceMock.createStartContract>;
let search: ReturnType<typeof dataPluginMock.createStartContract>['search'];
const shallowRender = (overrides: Partial<SavedObjectsTableProps> = {}) => { const shallowRender = (overrides: Partial<SavedObjectsTableProps> = {}) => {
return (shallowWithI18nProvider( return (shallowWithI18nProvider(
@ -106,6 +107,7 @@ describe('SavedObjectsTable', () => {
overlays = overlayServiceMock.createStartContract(); overlays = overlayServiceMock.createStartContract();
notifications = notificationServiceMock.createStartContract(); notifications = notificationServiceMock.createStartContract();
savedObjects = savedObjectsServiceMock.createStartContract(); savedObjects = savedObjectsServiceMock.createStartContract();
search = dataPluginMock.createStartContract().search;
const applications = applicationServiceMock.createStartContract(); const applications = applicationServiceMock.createStartContract();
applications.capabilities = { applications.capabilities = {
@ -141,6 +143,7 @@ describe('SavedObjectsTable', () => {
perPageConfig: 15, perPageConfig: 15,
goInspectObject: () => {}, goInspectObject: () => {},
canGoInApp: () => true, canGoInApp: () => true,
search,
}; };
findObjectsMock.mockImplementation(() => ({ findObjectsMock.mockImplementation(() => ({

View file

@ -73,6 +73,7 @@ import {
SavedObjectsManagementActionServiceStart, SavedObjectsManagementActionServiceStart,
} from '../../services'; } from '../../services';
import { Header, Table, Flyout, Relationships } from './components'; import { Header, Table, Flyout, Relationships } from './components';
import { DataPublicPluginStart } from '../../../../../plugins/data/public';
interface ExportAllOption { interface ExportAllOption {
id: string; id: string;
@ -86,6 +87,7 @@ export interface SavedObjectsTableProps {
savedObjectsClient: SavedObjectsClientContract; savedObjectsClient: SavedObjectsClientContract;
indexPatterns: IndexPatternsContract; indexPatterns: IndexPatternsContract;
http: HttpStart; http: HttpStart;
search: DataPublicPluginStart['search'];
overlays: OverlayStart; overlays: OverlayStart;
notifications: NotificationsStart; notifications: NotificationsStart;
applications: ApplicationStart; applications: ApplicationStart;
@ -467,6 +469,7 @@ export class SavedObjectsTable extends Component<SavedObjectsTableProps, SavedOb
newIndexPatternUrl={newIndexPatternUrl} newIndexPatternUrl={newIndexPatternUrl}
allowedTypes={this.props.allowedTypes} allowedTypes={this.props.allowedTypes}
overlays={this.props.overlays} overlays={this.props.overlays}
search={this.props.search}
/> />
); );
} }

Some files were not shown because too many files have changed in this diff Show more