;
```
Returns:
diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.md
index 7d9d47df544d0..c179e089d7cfd 100644
--- a/docs/development/core/public/kibana-plugin-core-public.chromestart.md
+++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.md
@@ -56,7 +56,7 @@ core.chrome.setHelpExtension(elem => {
| [getBrand$()](./kibana-plugin-core-public.chromestart.getbrand_.md) | Get an observable of the current brand information. |
| [getBreadcrumbs$()](./kibana-plugin-core-public.chromestart.getbreadcrumbs_.md) | Get an observable of the current list of breadcrumbs |
| [getHelpExtension$()](./kibana-plugin-core-public.chromestart.gethelpextension_.md) | Get an observable of the current custom help conttent |
-| [getIsCollapsed$()](./kibana-plugin-core-public.chromestart.getiscollapsed_.md) | Get an observable of the current collapsed state of the chrome. |
+| [getIsNavDrawerLocked$()](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) | Get an observable of the current locked state of the nav drawer. |
| [getIsVisible$()](./kibana-plugin-core-public.chromestart.getisvisible_.md) | Get an observable of the current visibility state of the chrome. |
| [removeApplicationClass(className)](./kibana-plugin-core-public.chromestart.removeapplicationclass.md) | Remove a className added with addApplicationClass()
. If className is unknown it is ignored. |
| [setAppTitle(appTitle)](./kibana-plugin-core-public.chromestart.setapptitle.md) | Sets the current app's title |
@@ -65,6 +65,5 @@ core.chrome.setHelpExtension(elem => {
| [setBreadcrumbs(newBreadcrumbs)](./kibana-plugin-core-public.chromestart.setbreadcrumbs.md) | Override the current set of breadcrumbs |
| [setHelpExtension(helpExtension)](./kibana-plugin-core-public.chromestart.sethelpextension.md) | Override the current set of custom help content |
| [setHelpSupportUrl(url)](./kibana-plugin-core-public.chromestart.sethelpsupporturl.md) | Override the default support URL shown in the help menu |
-| [setIsCollapsed(isCollapsed)](./kibana-plugin-core-public.chromestart.setiscollapsed.md) | Set the collapsed state of the chrome navigation. |
| [setIsVisible(isVisible)](./kibana-plugin-core-public.chromestart.setisvisible.md) | Set the temporary visibility for the chrome. This does nothing if the chrome is hidden by default and should be used to hide the chrome for things like full-screen modes with an exit button. |
diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md
deleted file mode 100644
index b1843ef326d96..0000000000000
--- a/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [setIsCollapsed](./kibana-plugin-core-public.chromestart.setiscollapsed.md)
-
-## ChromeStart.setIsCollapsed() method
-
-Set the collapsed state of the chrome navigation.
-
-Signature:
-
-```typescript
-setIsCollapsed(isCollapsed: boolean): void;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| isCollapsed | boolean
| |
-
-Returns:
-
-`void`
-
diff --git a/docs/development/core/server/kibana-plugin-core-server.routeconfig.validate.md b/docs/development/core/server/kibana-plugin-core-server.routeconfig.validate.md
index 204d8a786fede..3bbabc04f2500 100644
--- a/docs/development/core/server/kibana-plugin-core-server.routeconfig.validate.md
+++ b/docs/development/core/server/kibana-plugin-core-server.routeconfig.validate.md
@@ -14,7 +14,7 @@ validate: RouteValidatorFullConfig | false;
## Remarks
-You \*must\* specify a validation schema to be able to read: - url path segments - request query - request body To opt out of validating the request, specify `validate: false`. In this case request params, query, and body will be \*\*empty\*\* objects and have no access to raw values. In some cases you may want to use another validation library. To do this, you need to instruct the `@kbn/config-schema` library to output \*\*non-validated values\*\* with setting schema as `schema.object({}, { allowUnknowns: true })`;
+You \*must\* specify a validation schema to be able to read: - url path segments - request query - request body To opt out of validating the request, specify `validate: false`. In this case request params, query, and body will be \*\*empty\*\* objects and have no access to raw values. In some cases you may want to use another validation library. To do this, you need to instruct the `@kbn/config-schema` library to output \*\*non-validated values\*\* with setting schema as `schema.object({}, { unknowns: 'allow' })`;
## Example
@@ -49,7 +49,7 @@ router.get({
path: 'path/{id}',
validate: {
// handler has access to raw non-validated params in runtime
- params: schema.object({}, { allowUnknowns: true })
+ params: schema.object({}, { unknowns: 'allow' })
},
},
(context, req, res,) {
diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md
index e03072f9a41c3..7fd65e5db35f3 100644
--- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md
+++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md
@@ -44,8 +44,8 @@ esFilters: {
getPhraseFilterField: (filter: import("../common").PhraseFilter) => string;
getPhraseFilterValue: (filter: import("../common").PhraseFilter) => string | number | boolean;
getDisplayValueFromFilter: typeof getDisplayValueFromFilter;
- compareFilters: (first: import("../common").Filter | import("../common").Filter[], second: import("../common").Filter | import("../common").Filter[], comparatorOptions?: import("./query/filter_manager/lib/compare_filters").FilterCompareOptions) => boolean;
- COMPARE_ALL_OPTIONS: import("./query/filter_manager/lib/compare_filters").FilterCompareOptions;
+ compareFilters: (first: import("../common").Filter | import("../common").Filter[], second: import("../common").Filter | import("../common").Filter[], comparatorOptions?: import("../common").FilterCompareOptions) => boolean;
+ COMPARE_ALL_OPTIONS: import("../common").FilterCompareOptions;
generateFilters: typeof generateFilters;
onlyDisabledFiltersChanged: (newFilters?: import("../common").Filter[] | undefined, oldFilters?: import("../common").Filter[] | undefined) => boolean;
changeTimeFilter: typeof changeTimeFilter;
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md
deleted file mode 100644
index 27141c68ae1a7..0000000000000
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ICancel](./kibana-plugin-plugins-data-server.icancel.md)
-
-## ICancel type
-
-Signature:
-
-```typescript
-export declare type ICancel = (id: string) => Promise;
-```
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md
new file mode 100644
index 0000000000000..99c30515e8da6
--- /dev/null
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md)
+
+## ISearchCancel type
+
+Signature:
+
+```typescript
+export declare type ISearchCancel = (id: string) => Promise;
+```
diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
index 12d53f1a35ea0..d179b9d9dcd82 100644
--- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
+++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md
@@ -60,16 +60,14 @@
| [esQuery](./kibana-plugin-plugins-data-server.esquery.md) | |
| [fieldFormats](./kibana-plugin-plugins-data-server.fieldformats.md) | |
| [indexPatterns](./kibana-plugin-plugins-data-server.indexpatterns.md) | |
-| [search](./kibana-plugin-plugins-data-server.search.md) | |
## Type Aliases
| Type Alias | Description |
| --- | --- |
| [FieldFormatsGetConfigFn](./kibana-plugin-plugins-data-server.fieldformatsgetconfigfn.md) | |
-| [ICancel](./kibana-plugin-plugins-data-server.icancel.md) | |
| [IFieldFormatsRegistry](./kibana-plugin-plugins-data-server.ifieldformatsregistry.md) | |
| [ISearch](./kibana-plugin-plugins-data-server.isearch.md) | |
-| [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.md) | |
+| [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) | |
| [TSearchStrategyProvider](./kibana-plugin-plugins-data-server.tsearchstrategyprovider.md) | Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. |
diff --git a/docs/settings/monitoring-settings.asciidoc b/docs/settings/monitoring-settings.asciidoc
index 8586d26e9a07a..6645f49029a51 100644
--- a/docs/settings/monitoring-settings.asciidoc
+++ b/docs/settings/monitoring-settings.asciidoc
@@ -20,9 +20,7 @@ which support the same values as <>.
To control how data is collected from your {es} nodes, you configure
{ref}/monitoring-settings.html[`xpack.monitoring.collection`
settings] in `elasticsearch.yml`. To control how monitoring data is collected
-from Logstash, you configure
-{logstash-ref}/monitoring-internal-collection.html#monitoring-settings[`xpack.monitoring` settings]
-in `logstash.yml`.
+from Logstash, configure monitoring settings in `logstash.yml`.
For more information, see
{ref}/monitor-elasticsearch-cluster.html[Monitor a cluster].
diff --git a/examples/alerting_example/README.md b/examples/alerting_example/README.md
new file mode 100644
index 0000000000000..bf963c64586d3
--- /dev/null
+++ b/examples/alerting_example/README.md
@@ -0,0 +1,5 @@
+## Alerting Example
+
+This example plugin shows you how to create a custom Alert Type, create alerts based on that type and corresponding UI for viewing the details of all the alerts within the custom plugin.
+
+To run this example, use the command `yarn start --run-examples`.
\ No newline at end of file
diff --git a/examples/alerting_example/common/constants.ts b/examples/alerting_example/common/constants.ts
new file mode 100644
index 0000000000000..5884eb3220519
--- /dev/null
+++ b/examples/alerting_example/common/constants.ts
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+export const ALERTING_EXAMPLE_APP_ID = 'AlertingExample';
+
+// always firing
+export const DEFAULT_INSTANCES_TO_GENERATE = 5;
+
+// Astros
+export enum Craft {
+ OuterSpace = 'Outer Space',
+ ISS = 'ISS',
+}
+export enum Operator {
+ AreAbove = 'Are above',
+ AreBelow = 'Are below',
+ AreExactly = 'Are exactly',
+}
diff --git a/examples/alerting_example/kibana.json b/examples/alerting_example/kibana.json
new file mode 100644
index 0000000000000..bcdb7c2f14a9c
--- /dev/null
+++ b/examples/alerting_example/kibana.json
@@ -0,0 +1,10 @@
+{
+ "id": "alertingExample",
+ "version": "0.0.1",
+ "kibanaVersion": "kibana",
+ "configPath": ["alerting_example"],
+ "server": true,
+ "ui": true,
+ "requiredPlugins": ["triggers_actions_ui", "charts", "data", "alerting", "actions"],
+ "optionalPlugins": []
+}
diff --git a/examples/alerting_example/package.json b/examples/alerting_example/package.json
new file mode 100644
index 0000000000000..96187d847c1c4
--- /dev/null
+++ b/examples/alerting_example/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "alerting_example",
+ "version": "1.0.0",
+ "main": "target/examples/alerting_example",
+ "kibana": {
+ "version": "kibana",
+ "templateVersion": "1.0.0"
+ },
+ "license": "Apache-2.0",
+ "scripts": {
+ "kbn": "node ../../scripts/kbn.js",
+ "build": "rm -rf './target' && tsc"
+ },
+ "devDependencies": {
+ "typescript": "3.7.2"
+ }
+}
diff --git a/examples/alerting_example/public/alert_types/always_firing.tsx b/examples/alerting_example/public/alert_types/always_firing.tsx
new file mode 100644
index 0000000000000..a62a24365ea3f
--- /dev/null
+++ b/examples/alerting_example/public/alert_types/always_firing.tsx
@@ -0,0 +1,82 @@
+/*
+ * 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 React, { Fragment } from 'react';
+import { EuiFlexGroup, EuiFlexItem, EuiFieldNumber, EuiFormRow } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { AlertTypeModel } from '../../../../x-pack/plugins/triggers_actions_ui/public';
+import { DEFAULT_INSTANCES_TO_GENERATE } from '../../common/constants';
+
+interface AlwaysFiringParamsProps {
+ alertParams: { instances?: number };
+ setAlertParams: (property: string, value: any) => void;
+ errors: { [key: string]: string[] };
+}
+
+export function getAlertType(): AlertTypeModel {
+ return {
+ id: 'example.always-firing',
+ name: 'Always Fires',
+ iconClass: 'bolt',
+ alertParamsExpression: AlwaysFiringExpression,
+ validate: (alertParams: AlwaysFiringParamsProps['alertParams']) => {
+ const { instances } = alertParams;
+ const validationResult = {
+ errors: {
+ instances: new Array(),
+ },
+ };
+ if (instances && instances < 0) {
+ validationResult.errors.instances.push(
+ i18n.translate('AlertingExample.addAlert.error.invalidRandomInstances', {
+ defaultMessage: 'instances must be equal or greater than zero.',
+ })
+ );
+ }
+ return validationResult;
+ },
+ };
+}
+
+export const AlwaysFiringExpression: React.FunctionComponent = ({
+ alertParams,
+ setAlertParams,
+}) => {
+ const { instances = DEFAULT_INSTANCES_TO_GENERATE } = alertParams;
+ return (
+
+
+
+
+ {
+ setAlertParams('instances', event.target.valueAsNumber);
+ }}
+ />
+
+
+
+
+ );
+};
diff --git a/examples/alerting_example/public/alert_types/astros.tsx b/examples/alerting_example/public/alert_types/astros.tsx
new file mode 100644
index 0000000000000..9bda7da6f140d
--- /dev/null
+++ b/examples/alerting_example/public/alert_types/astros.tsx
@@ -0,0 +1,277 @@
+/*
+ * 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 React, { useState, useEffect, Fragment } from 'react';
+import {
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPopover,
+ EuiFieldNumber,
+ EuiPopoverTitle,
+ EuiSelect,
+ EuiCallOut,
+ EuiExpression,
+ EuiTextColor,
+} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { flatten } from 'lodash';
+import { ALERTING_EXAMPLE_APP_ID, Craft, Operator } from '../../common/constants';
+import { SanitizedAlert } from '../../../../x-pack/plugins/alerting/common';
+import { PluginSetupContract as AlertingSetup } from '../../../../x-pack/plugins/alerting/public';
+import { AlertTypeModel } from '../../../../x-pack/plugins/triggers_actions_ui/public';
+
+export function registerNavigation(alerting: AlertingSetup) {
+ alerting.registerNavigation(
+ ALERTING_EXAMPLE_APP_ID,
+ 'example.people-in-space',
+ (alert: SanitizedAlert) => `/astros/${alert.id}`
+ );
+}
+
+interface PeopleinSpaceParamsProps {
+ alertParams: { outerSpaceCapacity?: number; craft?: string; op?: string };
+ setAlertParams: (property: string, value: any) => void;
+ errors: { [key: string]: string[] };
+}
+
+function isValueInEnum(enumeratin: Record, value: any): boolean {
+ return !!Object.values(enumeratin).find(enumVal => enumVal === value);
+}
+
+export function getAlertType(): AlertTypeModel {
+ return {
+ id: 'example.people-in-space',
+ name: 'People Are In Space Right Now',
+ iconClass: 'globe',
+ alertParamsExpression: PeopleinSpaceExpression,
+ validate: (alertParams: PeopleinSpaceParamsProps['alertParams']) => {
+ const { outerSpaceCapacity, craft, op } = alertParams;
+
+ const validationResult = {
+ errors: {
+ outerSpaceCapacity: new Array(),
+ craft: new Array(),
+ },
+ };
+ if (!isValueInEnum(Craft, craft)) {
+ validationResult.errors.craft.push(
+ i18n.translate('AlertingExample.addAlert.error.invalidCraft', {
+ defaultMessage: 'You must choose one of the following Craft: {crafts}',
+ values: {
+ crafts: Object.values(Craft).join(', '),
+ },
+ })
+ );
+ }
+ if (!(typeof outerSpaceCapacity === 'number' && outerSpaceCapacity >= 0)) {
+ validationResult.errors.outerSpaceCapacity.push(
+ i18n.translate('AlertingExample.addAlert.error.invalidOuterSpaceCapacity', {
+ defaultMessage: 'outerSpaceCapacity must be a number greater than or equal to zero.',
+ })
+ );
+ }
+ if (!isValueInEnum(Operator, op)) {
+ validationResult.errors.outerSpaceCapacity.push(
+ i18n.translate('AlertingExample.addAlert.error.invalidCraft', {
+ defaultMessage: 'You must choose one of the following Operator: {crafts}',
+ values: {
+ crafts: Object.values(Operator).join(', '),
+ },
+ })
+ );
+ }
+
+ return validationResult;
+ },
+ };
+}
+
+export const PeopleinSpaceExpression: React.FunctionComponent = ({
+ alertParams,
+ setAlertParams,
+ errors,
+}) => {
+ const { outerSpaceCapacity = 0, craft = Craft.OuterSpace, op = Operator.AreAbove } = alertParams;
+
+ // store defaults
+ useEffect(() => {
+ if (outerSpaceCapacity !== alertParams.outerSpaceCapacity) {
+ setAlertParams('outerSpaceCapacity', outerSpaceCapacity);
+ }
+ if (craft !== alertParams.craft) {
+ setAlertParams('craft', craft);
+ }
+ if (op !== alertParams.op) {
+ setAlertParams('op', op);
+ }
+ }, [alertParams, craft, op, outerSpaceCapacity, setAlertParams]);
+
+ const [craftTrigger, setCraftTrigger] = useState<{ craft: string; isOpen: boolean }>({
+ craft,
+ isOpen: false,
+ });
+ const [outerSpaceCapacityTrigger, setOuterSpaceCapacity] = useState<{
+ outerSpaceCapacity: number;
+ op: string;
+ isOpen: boolean;
+ }>({
+ outerSpaceCapacity,
+ op,
+ isOpen: false,
+ });
+
+ const errorsCallout = flatten(
+ Object.entries(errors).map(([field, errs]: [string, string[]]) =>
+ errs.map(e => (
+
+ {field}: `: ${errs}`
+
+ ))
+ )
+ );
+
+ return (
+
+ {errorsCallout.length ? (
+
+ {errorsCallout}
+
+ ) : (
+
+ )}
+
+
+ {
+ setCraftTrigger({
+ ...craftTrigger,
+ isOpen: true,
+ });
+ }}
+ />
+ }
+ isOpen={craftTrigger.isOpen}
+ closePopover={() => {
+ setCraftTrigger({
+ ...craftTrigger,
+ isOpen: false,
+ });
+ }}
+ ownFocus
+ panelPaddingSize="s"
+ anchorPosition="downLeft"
+ >
+
+ When the People in
+ {
+ setAlertParams('craft', event.target.value);
+ setCraftTrigger({
+ craft: event.target.value,
+ isOpen: false,
+ });
+ }}
+ options={[
+ { value: Craft.OuterSpace, text: 'Outer Space' },
+ { value: Craft.ISS, text: 'the International Space Station' },
+ ]}
+ />
+
+
+
+
+
+ {
+ setOuterSpaceCapacity({
+ ...outerSpaceCapacityTrigger,
+ isOpen: true,
+ });
+ }}
+ />
+ }
+ isOpen={outerSpaceCapacityTrigger.isOpen}
+ closePopover={() => {
+ setOuterSpaceCapacity({
+ ...outerSpaceCapacityTrigger,
+ isOpen: false,
+ });
+ }}
+ ownFocus
+ panelPaddingSize="s"
+ anchorPosition="downLeft"
+ >
+
+
+
+ {
+ setAlertParams('op', event.target.value);
+ setOuterSpaceCapacity({
+ ...outerSpaceCapacityTrigger,
+ op: event.target.value,
+ isOpen: false,
+ });
+ }}
+ options={[
+ { value: Operator.AreAbove, text: 'Are above' },
+ { value: Operator.AreBelow, text: 'Are below' },
+ { value: Operator.AreExactly, text: 'Are exactly' },
+ ]}
+ />
+
+
+
+ {
+ setAlertParams('outerSpaceCapacity', event.target.valueAsNumber);
+ setOuterSpaceCapacity({
+ ...outerSpaceCapacityTrigger,
+ outerSpaceCapacity: event.target.valueAsNumber,
+ isOpen: false,
+ });
+ }}
+ />
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js b/examples/alerting_example/public/alert_types/index.ts
similarity index 57%
rename from src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js
rename to examples/alerting_example/public/alert_types/index.ts
index 267ca74c7c42a..96d9c09d15836 100644
--- a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js
+++ b/examples/alerting_example/public/alert_types/index.ts
@@ -17,18 +17,17 @@
* under the License.
*/
-import expect from '@kbn/expect';
-import { shortenDottedString } from '../shorten_dotted_string';
+import { registerNavigation as registerPeopleInSpaceNavigation } from './astros';
+import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
+import { SanitizedAlert } from '../../../../x-pack/plugins/alerting/common';
+import { PluginSetupContract as AlertingSetup } from '../../../../x-pack/plugins/alerting/public';
-describe('shortenDottedString', () => {
- it('Convert a dot.notated.string into a short string', () => {
- expect(shortenDottedString('dot.notated.string')).to.equal('d.n.string');
- });
+export function registerNavigation(alerting: AlertingSetup) {
+ // register default navigation
+ alerting.registerDefaultNavigation(
+ ALERTING_EXAMPLE_APP_ID,
+ (alert: SanitizedAlert) => `/alert/${alert.id}`
+ );
- it('Ignores non-string values', () => {
- expect(shortenDottedString(true)).to.equal(true);
- expect(shortenDottedString(123)).to.equal(123);
- const obj = { key: 'val' };
- expect(shortenDottedString(obj)).to.equal(obj);
- });
-});
+ registerPeopleInSpaceNavigation(alerting);
+}
diff --git a/examples/alerting_example/public/application.tsx b/examples/alerting_example/public/application.tsx
new file mode 100644
index 0000000000000..d71db92d3d421
--- /dev/null
+++ b/examples/alerting_example/public/application.tsx
@@ -0,0 +1,108 @@
+/*
+ * 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 React from 'react';
+import ReactDOM from 'react-dom';
+import { BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom';
+import { EuiPage } from '@elastic/eui';
+import {
+ AppMountParameters,
+ CoreStart,
+ IUiSettingsClient,
+ ToastsSetup,
+} from '../../../src/core/public';
+import { DataPublicPluginStart } from '../../../src/plugins/data/public';
+import { ChartsPluginStart } from '../../../src/plugins/charts/public';
+
+import { Page } from './components/page';
+import { DocumentationPage } from './components/documentation';
+import { ViewAlertPage } from './components/view_alert';
+import { TriggersAndActionsUIPublicPluginStart } from '../../../x-pack/plugins/triggers_actions_ui/public';
+import { AlertingExamplePublicStartDeps } from './plugin';
+import { ViewPeopleInSpaceAlertPage } from './components/view_astros_alert';
+
+export interface AlertingExampleComponentParams {
+ application: CoreStart['application'];
+ http: CoreStart['http'];
+ basename: string;
+ triggers_actions_ui: TriggersAndActionsUIPublicPluginStart;
+ data: DataPublicPluginStart;
+ charts: ChartsPluginStart;
+ uiSettings: IUiSettingsClient;
+ toastNotifications: ToastsSetup;
+}
+
+const AlertingExampleApp = (deps: AlertingExampleComponentParams) => {
+ const { basename, http } = deps;
+ return (
+
+
+ (
+
+
+
+ )}
+ />
+ ) => {
+ return (
+
+
+
+ );
+ }}
+ />
+ ) => {
+ return (
+
+
+
+ );
+ }}
+ />
+
+
+ );
+};
+
+export const renderApp = (
+ { application, notifications, http, uiSettings }: CoreStart,
+ deps: AlertingExamplePublicStartDeps,
+ { appBasePath, element }: AppMountParameters
+) => {
+ ReactDOM.render(
+ ,
+ element
+ );
+
+ return () => ReactDOM.unmountComponentAtNode(element);
+};
diff --git a/examples/alerting_example/public/components/create_alert.tsx b/examples/alerting_example/public/components/create_alert.tsx
new file mode 100644
index 0000000000000..65b8a9412dcda
--- /dev/null
+++ b/examples/alerting_example/public/components/create_alert.tsx
@@ -0,0 +1,72 @@
+/*
+ * 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 React, { useState } from 'react';
+
+import { EuiIcon, EuiFlexItem, EuiCard, EuiFlexGroup } from '@elastic/eui';
+
+import {
+ AlertsContextProvider,
+ AlertAdd,
+} from '../../../../x-pack/plugins/triggers_actions_ui/public';
+import { AlertingExampleComponentParams } from '../application';
+import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
+
+export const CreateAlert = ({
+ http,
+ triggers_actions_ui,
+ charts,
+ uiSettings,
+ data,
+ toastNotifications,
+}: AlertingExampleComponentParams) => {
+ const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false);
+
+ return (
+
+
+ }
+ title={`Create Alert`}
+ description="Create an new Alert based on one of our example Alert Types ."
+ onClick={() => setAlertFlyoutVisibility(true)}
+ />
+
+
+
+
+
+
+
+ );
+};
diff --git a/examples/alerting_example/public/components/documentation.tsx b/examples/alerting_example/public/components/documentation.tsx
new file mode 100644
index 0000000000000..17cc34959b010
--- /dev/null
+++ b/examples/alerting_example/public/components/documentation.tsx
@@ -0,0 +1,67 @@
+/*
+ * 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 React from 'react';
+
+import {
+ EuiText,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiTitle,
+ EuiSpacer,
+} from '@elastic/eui';
+import { CreateAlert } from './create_alert';
+import { AlertingExampleComponentParams } from '../application';
+
+export const DocumentationPage = (deps: AlertingExampleComponentParams) => (
+
+
+
+
+ Welcome to the Alerting plugin example
+
+
+
+
+
+
+
+ Documentation links
+
+
+
+
+
+ Plugin Structure
+
+ This example solution has both `server` and a `public` plugins. The `server` handles
+ registration of example the AlertTypes, while the `public` handles creation of, and
+ navigation for, these alert types.
+
+
+
+
+
+
+
+);
diff --git a/examples/alerting_example/public/components/page.tsx b/examples/alerting_example/public/components/page.tsx
new file mode 100644
index 0000000000000..99076c7ddcedf
--- /dev/null
+++ b/examples/alerting_example/public/components/page.tsx
@@ -0,0 +1,74 @@
+/*
+ * 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 React from 'react';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
+
+import {
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiTitle,
+ EuiBreadcrumbs,
+ EuiSpacer,
+} from '@elastic/eui';
+
+type PageProps = RouteComponentProps & {
+ title: string;
+ children: React.ReactNode;
+ crumb?: string;
+ isHome?: boolean;
+};
+
+export const Page = withRouter(({ title, crumb, children, isHome = false, history }: PageProps) => {
+ const breadcrumbs: Array<{
+ text: string;
+ onClick?: () => void;
+ }> = [
+ {
+ text: crumb ?? title,
+ },
+ ];
+ if (!isHome) {
+ breadcrumbs.splice(0, 0, {
+ text: 'Home',
+ onClick: () => {
+ history.push(`/`);
+ },
+ });
+ }
+ return (
+
+
+
+
+ {title}
+
+
+
+
+
+
+ {children}
+
+
+ );
+});
diff --git a/examples/alerting_example/public/components/view_alert.tsx b/examples/alerting_example/public/components/view_alert.tsx
new file mode 100644
index 0000000000000..c1b65eb92edc5
--- /dev/null
+++ b/examples/alerting_example/public/components/view_alert.tsx
@@ -0,0 +1,116 @@
+/*
+ * 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 React, { useState, useEffect, Fragment } from 'react';
+
+import {
+ EuiText,
+ EuiLoadingKibana,
+ EuiCallOut,
+ EuiTextColor,
+ EuiDescriptionList,
+ EuiDescriptionListTitle,
+ EuiDescriptionListDescription,
+ EuiCodeBlock,
+ EuiSpacer,
+} from '@elastic/eui';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
+import { CoreStart } from 'kibana/public';
+import { isEmpty } from 'lodash';
+import { Alert, AlertTaskState } from '../../../../x-pack/plugins/alerting/common';
+import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
+
+type Props = RouteComponentProps & {
+ http: CoreStart['http'];
+ id: string;
+};
+export const ViewAlertPage = withRouter(({ http, id }: Props) => {
+ const [alert, setAlert] = useState(null);
+ const [alertState, setAlertState] = useState(null);
+
+ useEffect(() => {
+ if (!alert) {
+ http.get(`/api/alert/${id}`).then(setAlert);
+ }
+ if (!alertState) {
+ http.get(`/api/alert/${id}/state`).then(setAlertState);
+ }
+ }, [alert, alertState, http, id]);
+
+ return alert && alertState ? (
+
+
+
+ This is a generic view for all Alerts created by the
+ {ALERTING_EXAMPLE_APP_ID}
+ plugin.
+
+
+ You are now viewing the {`${alert.name}`}
+ Alert, whose ID is {`${alert.id}`} .
+
+
+ Its AlertType is {`${alert.alertTypeId}`} and
+ its scheduled to run at an interval of
+ {`${alert.schedule.interval}`} .
+
+
+
+
+ Alert Instances
+
+ {isEmpty(alertState.alertInstances) ? (
+
+ This Alert doesn't have any active alert instances at the moment.
+
+ ) : (
+
+
+
+ Bellow are the active Alert Instances which were activated on the alerts last run.
+
+ For each instance id you can see its current state in JSON format.
+
+
+
+
+ {Object.entries(alertState.alertInstances ?? {}).map(([instance, { state }]) => (
+
+ {instance}
+
+
+ {`${JSON.stringify(state)}`}
+
+
+
+ ))}
+
+
+ )}
+
+ ) : (
+
+ );
+});
diff --git a/examples/alerting_example/public/components/view_astros_alert.tsx b/examples/alerting_example/public/components/view_astros_alert.tsx
new file mode 100644
index 0000000000000..db93d8f54924d
--- /dev/null
+++ b/examples/alerting_example/public/components/view_astros_alert.tsx
@@ -0,0 +1,123 @@
+/*
+ * 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 React, { useState, useEffect, Fragment } from 'react';
+
+import {
+ EuiText,
+ EuiLoadingKibana,
+ EuiCallOut,
+ EuiTextColor,
+ EuiDescriptionList,
+ EuiDescriptionListTitle,
+ EuiDescriptionListDescription,
+ EuiSpacer,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiStat,
+} from '@elastic/eui';
+import { withRouter, RouteComponentProps } from 'react-router-dom';
+import { CoreStart } from 'kibana/public';
+import { isEmpty } from 'lodash';
+import { Alert, AlertTaskState } from '../../../../x-pack/plugins/alerting/common';
+import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
+
+type Props = RouteComponentProps & {
+ http: CoreStart['http'];
+ id: string;
+};
+
+function hasCraft(state: any): state is { craft: string } {
+ return state && state.craft;
+}
+export const ViewPeopleInSpaceAlertPage = withRouter(({ http, id }: Props) => {
+ const [alert, setAlert] = useState(null);
+ const [alertState, setAlertState] = useState(null);
+
+ useEffect(() => {
+ if (!alert) {
+ http.get(`/api/alert/${id}`).then(setAlert);
+ }
+ if (!alertState) {
+ http.get(`/api/alert/${id}/state`).then(setAlertState);
+ }
+ }, [alert, alertState, http, id]);
+
+ return alert && alertState ? (
+
+
+
+ This is a specific view for all
+ example.people-in-space Alerts created by
+ the
+ {ALERTING_EXAMPLE_APP_ID}
+ plugin.
+
+
+
+
+ Alert Instances
+
+ {isEmpty(alertState.alertInstances) ? (
+
+
+ The people in {alert.params.craft} at the moment are not {alert.params.op}{' '}
+ {alert.params.outerSpaceCapacity}
+
+
+ ) : (
+
+
+
+ The alert has been triggered because the people in {alert.params.craft} at the moment{' '}
+ {alert.params.op} {alert.params.outerSpaceCapacity}
+
+
+
+
+
+
+
+
+
+
+ {Object.entries(alertState.alertInstances ?? {}).map(
+ ([instance, { state }], index) => (
+
+ {instance}
+
+ {hasCraft(state) ? state.craft : 'Unknown Craft'}
+
+
+ )
+ )}
+
+
+
+
+
+ )}
+
+ ) : (
+
+ );
+});
diff --git a/src/legacy/ui/public/indices/index.js b/examples/alerting_example/public/index.ts
similarity index 81%
rename from src/legacy/ui/public/indices/index.js
rename to examples/alerting_example/public/index.ts
index c1646bd66e367..4a2bfc79903c3 100644
--- a/src/legacy/ui/public/indices/index.js
+++ b/examples/alerting_example/public/index.ts
@@ -17,10 +17,6 @@
* under the License.
*/
-export { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from './constants';
+import { AlertingExamplePlugin } from './plugin';
-export {
- indexNameBeginsWithPeriod,
- findIllegalCharactersInIndexName,
- indexNameContainsSpaces,
-} from './validate';
+export const plugin = () => new AlertingExamplePlugin();
diff --git a/examples/alerting_example/public/plugin.tsx b/examples/alerting_example/public/plugin.tsx
new file mode 100644
index 0000000000000..299806d393446
--- /dev/null
+++ b/examples/alerting_example/public/plugin.tsx
@@ -0,0 +1,70 @@
+/*
+ * 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 { Plugin, CoreSetup, AppMountParameters, CoreStart } from 'kibana/public';
+import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerting/public';
+import { ChartsPluginStart } from '../../../src/plugins/charts/public';
+import { TriggersAndActionsUIPublicPluginSetup } from '../../../x-pack/plugins/triggers_actions_ui/public';
+import { DataPublicPluginStart } from '../../../src/plugins/data/public';
+import { getAlertType as getAlwaysFiringAlertType } from './alert_types/always_firing';
+import { getAlertType as getPeopleInSpaceAlertType } from './alert_types/astros';
+import { registerNavigation } from './alert_types';
+
+export type Setup = void;
+export type Start = void;
+
+export interface AlertingExamplePublicSetupDeps {
+ alerting: AlertingSetup;
+ triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
+}
+
+export interface AlertingExamplePublicStartDeps {
+ alerting: AlertingSetup;
+ triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup;
+ charts: ChartsPluginStart;
+ data: DataPublicPluginStart;
+}
+
+export class AlertingExamplePlugin implements Plugin {
+ public setup(
+ core: CoreSetup,
+ { alerting, triggers_actions_ui }: AlertingExamplePublicSetupDeps
+ ) {
+ core.application.register({
+ id: 'AlertingExample',
+ title: 'Alerting Example',
+ async mount(params: AppMountParameters) {
+ const [coreStart, depsStart]: [
+ CoreStart,
+ AlertingExamplePublicStartDeps
+ ] = await core.getStartServices();
+ const { renderApp } = await import('./application');
+ return renderApp(coreStart, depsStart, params);
+ },
+ });
+
+ triggers_actions_ui.alertTypeRegistry.register(getAlwaysFiringAlertType());
+ triggers_actions_ui.alertTypeRegistry.register(getPeopleInSpaceAlertType());
+
+ registerNavigation(alerting);
+ }
+
+ public start() {}
+ public stop() {}
+}
diff --git a/examples/alerting_example/server/alert_types/always_firing.ts b/examples/alerting_example/server/alert_types/always_firing.ts
new file mode 100644
index 0000000000000..f0553ad5ebebd
--- /dev/null
+++ b/examples/alerting_example/server/alert_types/always_firing.ts
@@ -0,0 +1,46 @@
+/*
+ * 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 uuid from 'uuid';
+import { range } from 'lodash';
+import { AlertType } from '../../../../x-pack/plugins/alerting/server';
+import { DEFAULT_INSTANCES_TO_GENERATE } from '../../common/constants';
+
+export const alertType: AlertType = {
+ id: 'example.always-firing',
+ name: 'Always firing',
+ actionGroups: [{ id: 'default', name: 'default' }],
+ defaultActionGroupId: 'default',
+ async executor({ services, params: { instances = DEFAULT_INSTANCES_TO_GENERATE }, state }) {
+ const count = (state.count ?? 0) + 1;
+
+ range(instances)
+ .map(() => ({ id: uuid.v4() }))
+ .forEach((instance: { id: string }) => {
+ services
+ .alertInstanceFactory(instance.id)
+ .replaceState({ triggerdOnCycle: count })
+ .scheduleActions('default');
+ });
+
+ return {
+ count,
+ };
+ },
+};
diff --git a/examples/alerting_example/server/alert_types/astros.ts b/examples/alerting_example/server/alert_types/astros.ts
new file mode 100644
index 0000000000000..3a53f85e6a266
--- /dev/null
+++ b/examples/alerting_example/server/alert_types/astros.ts
@@ -0,0 +1,82 @@
+/*
+ * 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 axios from 'axios';
+import { AlertType } from '../../../../x-pack/plugins/alerting/server';
+import { Operator, Craft } from '../../common/constants';
+
+interface PeopleInSpace {
+ people: Array<{
+ craft: string;
+ name: string;
+ }>;
+ number: number;
+}
+
+function getOperator(op: string) {
+ switch (op) {
+ case Operator.AreAbove:
+ return (left: number, right: number) => left > right;
+ case Operator.AreBelow:
+ return (left: number, right: number) => left < right;
+ case Operator.AreExactly:
+ return (left: number, right: number) => left === right;
+ default:
+ return () => {
+ throw new Error(
+ `Invalid Operator "${op}" [${Operator.AreAbove},${Operator.AreBelow},${Operator.AreExactly}]`
+ );
+ };
+ }
+}
+
+function getCraftFilter(craft: string) {
+ return (person: { craft: string; name: string }) =>
+ craft === Craft.OuterSpace ? true : craft === person.craft;
+}
+
+export const alertType: AlertType = {
+ id: 'example.people-in-space',
+ name: 'People In Space Right Now',
+ actionGroups: [{ id: 'default', name: 'default' }],
+ defaultActionGroupId: 'default',
+ async executor({ services, params }) {
+ const { outerSpaceCapacity, craft: craftToTriggerBy, op } = params;
+
+ const response = await axios.get('http://api.open-notify.org/astros.json');
+ const {
+ data: { number: peopleInSpace, people = [] },
+ } = response;
+
+ const peopleInCraft = people.filter(getCraftFilter(craftToTriggerBy));
+
+ if (getOperator(op)(peopleInCraft.length, outerSpaceCapacity)) {
+ peopleInCraft.forEach(({ craft, name }) => {
+ services
+ .alertInstanceFactory(name)
+ .replaceState({ craft })
+ .scheduleActions('default');
+ });
+ }
+
+ return {
+ peopleInSpace,
+ };
+ },
+};
diff --git a/examples/alerting_example/server/index.ts b/examples/alerting_example/server/index.ts
new file mode 100644
index 0000000000000..32e9b181ebb54
--- /dev/null
+++ b/examples/alerting_example/server/index.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 { PluginInitializer } from 'kibana/server';
+import { AlertingExamplePlugin } from './plugin';
+
+export const plugin: PluginInitializer = () => new AlertingExamplePlugin();
diff --git a/src/legacy/ui/public/chrome/services/global_nav_state.js b/examples/alerting_example/server/plugin.ts
similarity index 53%
rename from src/legacy/ui/public/chrome/services/global_nav_state.js
rename to examples/alerting_example/server/plugin.ts
index 5a67806852fe8..b5dabe51e8685 100644
--- a/src/legacy/ui/public/chrome/services/global_nav_state.js
+++ b/examples/alerting_example/server/plugin.ts
@@ -17,29 +17,23 @@
* under the License.
*/
-import { distinctUntilChanged } from 'rxjs/operators';
-import { npStart } from 'ui/new_platform';
-import { uiModules } from '../../modules';
+import { Plugin, CoreSetup } from 'kibana/server';
+import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerting/server';
-const newPlatformChrome = npStart.core.chrome;
+import { alertType as alwaysFiringAlert } from './alert_types/always_firing';
+import { alertType as peopleInSpaceAlert } from './alert_types/astros';
-uiModules.get('kibana').service('globalNavState', $rootScope => {
- let isOpen = false;
- newPlatformChrome
- .getIsCollapsed$()
- .pipe(distinctUntilChanged())
- .subscribe(isCollapsed => {
- $rootScope.$evalAsync(() => {
- isOpen = !isCollapsed;
- $rootScope.$broadcast('globalNavState:change');
- });
- });
+// this plugin's dependendencies
+export interface AlertingExampleDeps {
+ alerting: AlertingSetup;
+}
- return {
- isOpen: () => isOpen,
+export class AlertingExamplePlugin implements Plugin {
+ public setup(core: CoreSetup, { alerting }: AlertingExampleDeps) {
+ alerting.registerType(alwaysFiringAlert);
+ alerting.registerType(peopleInSpaceAlert);
+ }
- setOpen: newValue => {
- newPlatformChrome.setIsCollapsed(!newValue);
- },
- };
-});
+ public start() {}
+ public stop() {}
+}
diff --git a/examples/alerting_example/tsconfig.json b/examples/alerting_example/tsconfig.json
new file mode 100644
index 0000000000000..078522b36cb12
--- /dev/null
+++ b/examples/alerting_example/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./target",
+ "skipLibCheck": true,
+ "resolveJsonModule": true
+ },
+ "include": [
+ "index.ts",
+ "public/**/*.ts",
+ "public/**/*.tsx",
+ "server/**/*.ts",
+ "common/**/*.ts",
+ "../../typings/**/*",
+ ],
+ "exclude": []
+}
diff --git a/package.json b/package.json
index b3dcfb2aa3b0a..70d064fa2a8eb 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,7 @@
"url": "https://github.com/elastic/kibana.git"
},
"resolutions": {
- "**/@types/node": "10.12.27",
+ "**/@types/node": ">=10.17.17 <10.20.0",
"**/@types/react": "^16.9.19",
"**/@types/react-router": "^5.1.3",
"**/@types/hapi": "^17.0.18",
@@ -103,7 +103,8 @@
"x-pack/legacy/plugins/*",
"examples/*",
"test/plugin_functional/plugins/*",
- "test/interpreter_functional/plugins/*"
+ "test/interpreter_functional/plugins/*",
+ "x-pack/test/functional_with_es_ssl/fixtures/plugins/*"
],
"nohoist": [
"**/@types/*",
@@ -119,7 +120,7 @@
"@elastic/apm-rum": "^4.6.0",
"@elastic/charts": "^17.1.1",
"@elastic/datemath": "5.0.2",
- "@elastic/ems-client": "7.6.0",
+ "@elastic/ems-client": "7.7.0",
"@elastic/eui": "20.0.2",
"@elastic/filesaver": "1.1.2",
"@elastic/good": "8.1.1-kibana2",
@@ -171,7 +172,7 @@
"elastic-apm-node": "^3.2.0",
"elasticsearch": "^16.5.0",
"elasticsearch-browser": "^16.5.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"expiry-js": "0.1.7",
"fast-deep-equal": "^3.1.1",
"file-loader": "4.2.0",
@@ -239,7 +240,7 @@
"react-resize-detector": "^4.2.0",
"react-router-dom": "^5.1.2",
"react-sizeme": "^2.3.6",
- "react-use": "^13.13.0",
+ "react-use": "^13.27.0",
"reactcss": "1.2.3",
"redux": "^4.0.5",
"redux-actions": "^2.6.5",
@@ -314,6 +315,7 @@
"@types/cheerio": "^0.22.10",
"@types/chromedriver": "^2.38.0",
"@types/classnames": "^2.2.9",
+ "@types/color": "^3.0.0",
"@types/d3": "^3.5.43",
"@types/dedent": "^0.7.0",
"@types/deep-freeze-strict": "^1.1.0",
@@ -349,7 +351,7 @@
"@types/mocha": "^5.2.7",
"@types/moment-timezone": "^0.5.12",
"@types/mustache": "^0.8.31",
- "@types/node": "^10.12.27",
+ "@types/node": ">=10.17.17 <10.20.0",
"@types/node-forge": "^0.9.0",
"@types/normalize-path": "^3.0.0",
"@types/numeral": "^0.0.26",
@@ -459,7 +461,7 @@
"multistream": "^2.1.1",
"murmurhash3js": "3.0.1",
"mutation-observer": "^1.0.3",
- "nock": "10.0.6",
+ "nock": "12.0.3",
"node-sass": "^4.13.1",
"normalize-path": "^3.0.0",
"nyc": "^14.1.1",
diff --git a/packages/kbn-config-schema/README.md b/packages/kbn-config-schema/README.md
index 8719a2ae558ab..a4f2c1f6458cf 100644
--- a/packages/kbn-config-schema/README.md
+++ b/packages/kbn-config-schema/README.md
@@ -239,7 +239,7 @@ __Output type:__ `{ [K in keyof TProps]: TypeOf } as TObject`
__Options:__
* `defaultValue: TObject | Reference | (() => TObject)` - defines a default value, see [Default values](#default-values) section for more details.
* `validate: (value: TObject) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details.
- * `allowUnknowns: boolean` - indicates whether unknown object properties should be allowed. It's `false` by default.
+ * `unknowns: 'allow' | 'ignore' | 'forbid'` - indicates whether unknown object properties should be allowed, ignored, or forbidden. It's `forbid` by default.
__Usage:__
```typescript
@@ -250,7 +250,7 @@ const valueSchema = schema.object({
```
__Notes:__
-* Using `allowUnknowns` is discouraged and should only be used in exceptional circumstances. Consider using `schema.recordOf()` instead.
+* Using `unknowns: 'allow'` is discouraged and should only be used in exceptional circumstances. Consider using `schema.recordOf()` instead.
* Currently `schema.object()` always has a default value of `{}`, but this may change in the near future. Try to not rely on this behaviour and specify default value explicitly or use `schema.maybe()` if the value is optional.
* `schema.object()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object.
diff --git a/packages/kbn-config-schema/src/internals/index.ts b/packages/kbn-config-schema/src/internals/index.ts
index 8f5d09e5b8b49..f84e14d2f741d 100644
--- a/packages/kbn-config-schema/src/internals/index.ts
+++ b/packages/kbn-config-schema/src/internals/index.ts
@@ -314,7 +314,8 @@ export const internals = Joi.extend([
for (const [entryKey, entryValue] of value) {
const { value: validatedEntryKey, error: keyError } = Joi.validate(
entryKey,
- params.key
+ params.key,
+ { presence: 'required' }
);
if (keyError) {
@@ -323,7 +324,8 @@ export const internals = Joi.extend([
const { value: validatedEntryValue, error: valueError } = Joi.validate(
entryValue,
- params.value
+ params.value,
+ { presence: 'required' }
);
if (valueError) {
@@ -374,7 +376,8 @@ export const internals = Joi.extend([
for (const [entryKey, entryValue] of Object.entries(value)) {
const { value: validatedEntryKey, error: keyError } = Joi.validate(
entryKey,
- params.key
+ params.key,
+ { presence: 'required' }
);
if (keyError) {
@@ -383,7 +386,8 @@ export const internals = Joi.extend([
const { value: validatedEntryValue, error: valueError } = Joi.validate(
entryValue,
- params.value
+ params.value,
+ { presence: 'required' }
);
if (valueError) {
diff --git a/packages/kbn-config-schema/src/types/map_of_type.test.ts b/packages/kbn-config-schema/src/types/map_of_type.test.ts
index b015f51bdc8ad..1c5a227ef0fac 100644
--- a/packages/kbn-config-schema/src/types/map_of_type.test.ts
+++ b/packages/kbn-config-schema/src/types/map_of_type.test.ts
@@ -159,6 +159,24 @@ test('object within mapOf', () => {
expect(type.validate(value)).toEqual(expected);
});
+test('enforces required object fields within mapOf', () => {
+ const type = schema.mapOf(
+ schema.string(),
+ schema.object({
+ bar: schema.object({
+ baz: schema.number(),
+ }),
+ })
+ );
+ const value = {
+ foo: {},
+ };
+
+ expect(() => type.validate(value)).toThrowErrorMatchingInlineSnapshot(
+ `"[foo.bar.baz]: expected value of type [number] but got [undefined]"`
+ );
+});
+
test('error preserves full path', () => {
const type = schema.object({
grandParentKey: schema.object({
diff --git a/packages/kbn-config-schema/src/types/map_type.ts b/packages/kbn-config-schema/src/types/map_type.ts
index 231c3726ae9d5..6da664bf95616 100644
--- a/packages/kbn-config-schema/src/types/map_type.ts
+++ b/packages/kbn-config-schema/src/types/map_type.ts
@@ -57,7 +57,10 @@ export class MapOfType extends Type> {
path.length,
0,
// If `key` validation failed, let's stress that to make error more obvious.
- type === 'map.key' ? `key("${entryKey}")` : entryKey.toString()
+ type === 'map.key' ? `key("${entryKey}")` : entryKey.toString(),
+ // Error could have happened deep inside value/key schema and error message should
+ // include full path.
+ ...(reason instanceof SchemaTypeError ? reason.path : [])
);
return reason instanceof SchemaTypesError
diff --git a/packages/kbn-config-schema/src/types/object_type.test.ts b/packages/kbn-config-schema/src/types/object_type.test.ts
index 29e341983fde9..47a0f5f7a5491 100644
--- a/packages/kbn-config-schema/src/types/object_type.test.ts
+++ b/packages/kbn-config-schema/src/types/object_type.test.ts
@@ -276,10 +276,10 @@ test('individual keys can validated', () => {
);
});
-test('allow unknown keys when allowUnknowns = true', () => {
+test('allow unknown keys when unknowns = `allow`', () => {
const type = schema.object(
{ foo: schema.string({ defaultValue: 'test' }) },
- { allowUnknowns: true }
+ { unknowns: 'allow' }
);
expect(
@@ -292,10 +292,10 @@ test('allow unknown keys when allowUnknowns = true', () => {
});
});
-test('allowUnknowns = true affects only own keys', () => {
+test('unknowns = `allow` affects only own keys', () => {
const type = schema.object(
{ foo: schema.object({ bar: schema.string() }) },
- { allowUnknowns: true }
+ { unknowns: 'allow' }
);
expect(() =>
@@ -308,10 +308,10 @@ test('allowUnknowns = true affects only own keys', () => {
).toThrowErrorMatchingInlineSnapshot(`"[foo.baz]: definition for this key is missing"`);
});
-test('does not allow unknown keys when allowUnknowns = false', () => {
+test('does not allow unknown keys when unknowns = `forbid`', () => {
const type = schema.object(
{ foo: schema.string({ defaultValue: 'test' }) },
- { allowUnknowns: false }
+ { unknowns: 'forbid' }
);
expect(() =>
type.validate({
@@ -319,3 +319,34 @@ test('does not allow unknown keys when allowUnknowns = false', () => {
})
).toThrowErrorMatchingInlineSnapshot(`"[bar]: definition for this key is missing"`);
});
+
+test('allow and remove unknown keys when unknowns = `ignore`', () => {
+ const type = schema.object(
+ { foo: schema.string({ defaultValue: 'test' }) },
+ { unknowns: 'ignore' }
+ );
+
+ expect(
+ type.validate({
+ bar: 'baz',
+ })
+ ).toEqual({
+ foo: 'test',
+ });
+});
+
+test('unknowns = `ignore` affects only own keys', () => {
+ const type = schema.object(
+ { foo: schema.object({ bar: schema.string() }) },
+ { unknowns: 'ignore' }
+ );
+
+ expect(() =>
+ type.validate({
+ foo: {
+ bar: 'bar',
+ baz: 'baz',
+ },
+ })
+ ).toThrowErrorMatchingInlineSnapshot(`"[foo.baz]: definition for this key is missing"`);
+});
diff --git a/packages/kbn-config-schema/src/types/object_type.ts b/packages/kbn-config-schema/src/types/object_type.ts
index f34acd0d2ce65..5a50e714a5931 100644
--- a/packages/kbn-config-schema/src/types/object_type.ts
+++ b/packages/kbn-config-schema/src/types/object_type.ts
@@ -30,17 +30,25 @@ export type TypeOf> = RT['type'];
// this might not have perfect _rendering_ output, but it will be typed.
export type ObjectResultType = Readonly<{ [K in keyof P]: TypeOf
}>;
+interface UnknownOptions {
+ /**
+ * Options for dealing with unknown keys:
+ * - allow: unknown keys will be permitted
+ * - ignore: unknown keys will not fail validation, but will be stripped out
+ * - forbid (default): unknown keys will fail validation
+ */
+ unknowns?: 'allow' | 'ignore' | 'forbid';
+}
+
export type ObjectTypeOptions
= TypeOptions<
{ [K in keyof P]: TypeOf
}
-> & {
- /** Should uknown keys not be defined in the schema be allowed. Defaults to `false` */
- allowUnknowns?: boolean;
-};
+> &
+ UnknownOptions;
export class ObjectType
extends Type> {
private props: Record;
- constructor(props: P, { allowUnknowns = false, ...typeOptions }: ObjectTypeOptions = {}) {
+ constructor(props: P, { unknowns = 'forbid', ...typeOptions }: ObjectTypeOptions
= {}) {
const schemaKeys = {} as Record;
for (const [key, value] of Object.entries(props)) {
schemaKeys[key] = value.getSchema();
@@ -50,7 +58,8 @@ export class ObjectType extends Type>
.keys(schemaKeys)
.default()
.optional()
- .unknown(Boolean(allowUnknowns));
+ .unknown(unknowns === 'allow')
+ .options({ stripUnknown: { objects: unknowns === 'ignore' } });
super(schema, typeOptions);
this.props = schemaKeys;
diff --git a/packages/kbn-config-schema/src/types/record_of_type.test.ts b/packages/kbn-config-schema/src/types/record_of_type.test.ts
index ef15e7b0f6ad6..aee7dde71c3e4 100644
--- a/packages/kbn-config-schema/src/types/record_of_type.test.ts
+++ b/packages/kbn-config-schema/src/types/record_of_type.test.ts
@@ -159,6 +159,24 @@ test('object within recordOf', () => {
expect(type.validate(value)).toEqual({ foo: { bar: 123 } });
});
+test('enforces required object fields within recordOf', () => {
+ const type = schema.recordOf(
+ schema.string(),
+ schema.object({
+ bar: schema.object({
+ baz: schema.number(),
+ }),
+ })
+ );
+ const value = {
+ foo: {},
+ };
+
+ expect(() => type.validate(value)).toThrowErrorMatchingInlineSnapshot(
+ `"[foo.bar.baz]: expected value of type [number] but got [undefined]"`
+ );
+});
+
test('error preserves full path', () => {
const type = schema.object({
grandParentKey: schema.object({
diff --git a/packages/kbn-config-schema/src/types/record_type.ts b/packages/kbn-config-schema/src/types/record_type.ts
index c6d4b4d71b4f1..ef9e70cbabc08 100644
--- a/packages/kbn-config-schema/src/types/record_type.ts
+++ b/packages/kbn-config-schema/src/types/record_type.ts
@@ -49,7 +49,10 @@ export class RecordOfType extends Type> {
path.length,
0,
// If `key` validation failed, let's stress that to make error more obvious.
- type === 'record.key' ? `key("${entryKey}")` : entryKey.toString()
+ type === 'record.key' ? `key("${entryKey}")` : entryKey.toString(),
+ // Error could have happened deep inside value/key schema and error message should
+ // include full path.
+ ...(reason instanceof SchemaTypeError ? reason.path : [])
);
return reason instanceof SchemaTypesError
diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json
index bea153d0a672b..ee9f349f49051 100644
--- a/packages/kbn-dev-utils/package.json
+++ b/packages/kbn-dev-utils/package.json
@@ -12,7 +12,7 @@
"dependencies": {
"chalk": "^2.4.2",
"dedent": "^0.7.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"exit-hook": "^2.2.0",
"getopts": "^2.2.5",
"load-json-file": "^6.2.0",
diff --git a/packages/kbn-dev-utils/src/run/run.ts b/packages/kbn-dev-utils/src/run/run.ts
index e185f86cc3bf7..35477e988d837 100644
--- a/packages/kbn-dev-utils/src/run/run.ts
+++ b/packages/kbn-dev-utils/src/run/run.ts
@@ -17,6 +17,8 @@
* under the License.
*/
+import { inspect } from 'util';
+
// @ts-ignore @types are outdated and module is super simple
import exitHook from 'exit-hook';
@@ -62,7 +64,11 @@ export async function run(fn: RunFn, options: Options = {}) {
process.on('unhandledRejection', error => {
log.error('UNHANDLED PROMISE REJECTION');
- log.error(error);
+ log.error(
+ error instanceof Error
+ ? error
+ : new Error(`non-Error type rejection value: ${inspect(error)}`)
+ );
process.exit(1);
});
diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json
index f9d7bffed1e22..8b964d8399904 100644
--- a/packages/kbn-es/package.json
+++ b/packages/kbn-es/package.json
@@ -11,7 +11,7 @@
"chalk": "^2.4.2",
"dedent": "^0.7.0",
"del": "^5.1.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"getopts": "^2.2.4",
"glob": "^7.1.2",
"node-fetch": "^2.6.0",
diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json
index ac98a0e675fb1..b3b1eff41e4b5 100644
--- a/packages/kbn-plugin-generator/package.json
+++ b/packages/kbn-plugin-generator/package.json
@@ -6,7 +6,7 @@
"dependencies": {
"chalk": "^2.4.2",
"dedent": "^0.7.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"getopts": "^2.2.4",
"lodash.camelcase": "^4.3.0",
"lodash.kebabcase": "^4.1.1",
diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json
index 3b358c03b8053..c348aa43789d1 100644
--- a/packages/kbn-plugin-helpers/package.json
+++ b/packages/kbn-plugin-helpers/package.json
@@ -17,7 +17,7 @@
"argv-split": "^2.0.1",
"commander": "^3.0.0",
"del": "^5.1.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"globby": "^8.0.1",
"gulp-babel": "^8.0.0",
"gulp-rename": "1.4.0",
diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js
index 338d489300526..62b12e8e38c87 100644
--- a/packages/kbn-pm/dist/index.js
+++ b/packages/kbn-pm/dist/index.js
@@ -99,16 +99,16 @@ __webpack_require__.r(__webpack_exports__);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; });
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return _utils_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"]; });
-/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516);
+/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(515);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return _utils_project__WEBPACK_IMPORTED_MODULE_3__["Project"]; });
-/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(578);
+/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(577);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__["copyWorkspacePackages"]; });
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(579);
+/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(578);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; });
/*
@@ -152,7 +152,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17);
-/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(689);
+/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(688);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(34);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
@@ -2506,9 +2506,9 @@ module.exports = require("path");
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; });
/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18);
-/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(586);
-/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(686);
-/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(687);
+/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(585);
+/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(685);
+/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(686);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -2549,10 +2549,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(19);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34);
-/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(500);
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(501);
-/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(580);
-/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(585);
+/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(499);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(500);
+/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(579);
+/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(584);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -4490,10 +4490,10 @@ const tslib_1 = __webpack_require__(36);
var proc_runner_1 = __webpack_require__(37);
exports.withProcRunner = proc_runner_1.withProcRunner;
exports.ProcRunner = proc_runner_1.ProcRunner;
-tslib_1.__exportStar(__webpack_require__(415), exports);
-var serializers_1 = __webpack_require__(420);
+tslib_1.__exportStar(__webpack_require__(414), exports);
+var serializers_1 = __webpack_require__(419);
exports.createAbsolutePathSerializer = serializers_1.createAbsolutePathSerializer;
-var certs_1 = __webpack_require__(445);
+var certs_1 = __webpack_require__(444);
exports.CA_CERT_PATH = certs_1.CA_CERT_PATH;
exports.ES_KEY_PATH = certs_1.ES_KEY_PATH;
exports.ES_CERT_PATH = certs_1.ES_CERT_PATH;
@@ -4505,17 +4505,17 @@ exports.KBN_KEY_PATH = certs_1.KBN_KEY_PATH;
exports.KBN_CERT_PATH = certs_1.KBN_CERT_PATH;
exports.KBN_P12_PATH = certs_1.KBN_P12_PATH;
exports.KBN_P12_PASSWORD = certs_1.KBN_P12_PASSWORD;
-var run_1 = __webpack_require__(446);
+var run_1 = __webpack_require__(445);
exports.run = run_1.run;
exports.createFailError = run_1.createFailError;
exports.createFlagError = run_1.createFlagError;
exports.combineErrors = run_1.combineErrors;
exports.isFailError = run_1.isFailError;
-var repo_root_1 = __webpack_require__(422);
+var repo_root_1 = __webpack_require__(421);
exports.REPO_ROOT = repo_root_1.REPO_ROOT;
-var kbn_client_1 = __webpack_require__(451);
+var kbn_client_1 = __webpack_require__(450);
exports.KbnClient = kbn_client_1.KbnClient;
-tslib_1.__exportStar(__webpack_require__(493), exports);
+tslib_1.__exportStar(__webpack_require__(492), exports);
/***/ }),
@@ -32149,13 +32149,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
const execa_1 = tslib_1.__importDefault(__webpack_require__(351));
const fs_1 = __webpack_require__(23);
-const Rx = tslib_1.__importStar(__webpack_require__(392));
+const Rx = tslib_1.__importStar(__webpack_require__(391));
const operators_1 = __webpack_require__(169);
const chalk_1 = tslib_1.__importDefault(__webpack_require__(2));
-const tree_kill_1 = tslib_1.__importDefault(__webpack_require__(412));
+const tree_kill_1 = tslib_1.__importDefault(__webpack_require__(411));
const util_1 = __webpack_require__(29);
const treeKillAsync = util_1.promisify((...args) => tree_kill_1.default(...args));
-const observe_lines_1 = __webpack_require__(413);
+const observe_lines_1 = __webpack_require__(412);
const errors_1 = __webpack_require__(349);
const SECOND = 1000;
const STOP_TIMEOUT = 30 * SECOND;
@@ -32271,9 +32271,9 @@ const onetime = __webpack_require__(368);
const makeError = __webpack_require__(370);
const normalizeStdio = __webpack_require__(375);
const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(376);
-const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(381);
-const {mergePromise, getSpawnedPromise} = __webpack_require__(390);
-const {joinCommand, parseCommand} = __webpack_require__(391);
+const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(380);
+const {mergePromise, getSpawnedPromise} = __webpack_require__(389);
+const {joinCommand, parseCommand} = __webpack_require__(390);
const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100;
@@ -32305,8 +32305,8 @@ const handleArgs = (file, args, options = {}) => {
reject: true,
cleanup: true,
all: false,
- ...options,
- windowsHide: true
+ windowsHide: true,
+ ...options
};
options.env = getEnv(options);
@@ -33430,15 +33430,18 @@ const makeError = ({
const errorCode = error && error.code;
const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled});
- const message = `Command ${prefix}: ${command}`;
+ const execaMessage = `Command ${prefix}: ${command}`;
+ const shortMessage = error instanceof Error ? `${execaMessage}\n${error.message}` : execaMessage;
+ const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n');
if (error instanceof Error) {
error.originalMessage = error.message;
- error.message = `${message}\n${error.message}`;
+ error.message = message;
} else {
error = new Error(message);
}
+ error.shortMessage = shortMessage;
error.command = command;
error.exitCode = exitCode;
error.signal = signal;
@@ -33954,7 +33957,6 @@ module.exports.node = opts => {
const os = __webpack_require__(11);
const onExit = __webpack_require__(377);
-const pFinally = __webpack_require__(380);
const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5;
@@ -33971,9 +33973,17 @@ const setKillTimeout = (kill, signal, options, killResult) => {
}
const timeout = getForceKillAfterTimeout(options);
- setTimeout(() => {
+ const t = setTimeout(() => {
kill('SIGKILL');
- }, timeout).unref();
+ }, timeout);
+
+ // Guarded because there's no `.unref()` when `execa` is used in the renderer
+ // process in Electron. This cannot be tested since we don't run tests in
+ // Electron.
+ // istanbul ignore else
+ if (t.unref) {
+ t.unref();
+ }
};
const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => {
@@ -34028,7 +34038,7 @@ const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise
}, timeout);
});
- const safeSpawnedPromise = pFinally(spawnedPromise, () => {
+ const safeSpawnedPromise = spawnedPromise.finally(() => {
clearTimeout(timeoutId);
});
@@ -34036,7 +34046,7 @@ const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise
};
// `cleanup` option handling
-const setExitHandler = (spawned, {cleanup, detached}, timedPromise) => {
+const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => {
if (!cleanup || detached) {
return timedPromise;
}
@@ -34045,8 +34055,9 @@ const setExitHandler = (spawned, {cleanup, detached}, timedPromise) => {
spawned.kill();
});
- // TODO: Use native "finally" syntax when targeting Node.js 10
- return pFinally(timedPromise, removeExitHandler);
+ return timedPromise.finally(() => {
+ removeExitHandler();
+ });
};
module.exports = {
@@ -34291,33 +34302,9 @@ module.exports = require("events");
"use strict";
-
-module.exports = async (
- promise,
- onFinally = (() => {})
-) => {
- let value;
- try {
- value = await promise;
- } catch (error) {
- await onFinally();
- throw error;
- }
-
- await onFinally();
- return value;
-};
-
-
-/***/ }),
-/* 381 */
-/***/ (function(module, exports, __webpack_require__) {
-
-"use strict";
-
-const isStream = __webpack_require__(382);
-const getStream = __webpack_require__(383);
-const mergeStream = __webpack_require__(389);
+const isStream = __webpack_require__(381);
+const getStream = __webpack_require__(382);
+const mergeStream = __webpack_require__(388);
// `input` option
const handleInput = (spawned, input) => {
@@ -34414,7 +34401,7 @@ module.exports = {
/***/ }),
-/* 382 */
+/* 381 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -34450,13 +34437,13 @@ module.exports = isStream;
/***/ }),
-/* 383 */
+/* 382 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const pump = __webpack_require__(384);
-const bufferStream = __webpack_require__(388);
+const pump = __webpack_require__(383);
+const bufferStream = __webpack_require__(387);
class MaxBufferError extends Error {
constructor() {
@@ -34515,11 +34502,11 @@ module.exports.MaxBufferError = MaxBufferError;
/***/ }),
-/* 384 */
+/* 383 */
/***/ (function(module, exports, __webpack_require__) {
-var once = __webpack_require__(385)
-var eos = __webpack_require__(387)
+var once = __webpack_require__(384)
+var eos = __webpack_require__(386)
var fs = __webpack_require__(23) // we only need fs to get the ReadStream and WriteStream prototypes
var noop = function () {}
@@ -34603,10 +34590,10 @@ module.exports = pump
/***/ }),
-/* 385 */
+/* 384 */
/***/ (function(module, exports, __webpack_require__) {
-var wrappy = __webpack_require__(386)
+var wrappy = __webpack_require__(385)
module.exports = wrappy(once)
module.exports.strict = wrappy(onceStrict)
@@ -34651,7 +34638,7 @@ function onceStrict (fn) {
/***/ }),
-/* 386 */
+/* 385 */
/***/ (function(module, exports) {
// Returns a wrapper function that returns a wrapped callback
@@ -34690,10 +34677,10 @@ function wrappy (fn, cb) {
/***/ }),
-/* 387 */
+/* 386 */
/***/ (function(module, exports, __webpack_require__) {
-var once = __webpack_require__(385);
+var once = __webpack_require__(384);
var noop = function() {};
@@ -34783,7 +34770,7 @@ module.exports = eos;
/***/ }),
-/* 388 */
+/* 387 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -34842,7 +34829,7 @@ module.exports = options => {
/***/ }),
-/* 389 */
+/* 388 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -34890,7 +34877,7 @@ module.exports = function (/*streams...*/) {
/***/ }),
-/* 390 */
+/* 389 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -34913,12 +34900,7 @@ const mergePromiseProperty = (spawned, promise, property) => {
const mergePromise = (spawned, promise) => {
mergePromiseProperty(spawned, promise, 'then');
mergePromiseProperty(spawned, promise, 'catch');
-
- // TODO: Remove the `if`-guard when targeting Node.js 10
- if (Promise.prototype.finally) {
- mergePromiseProperty(spawned, promise, 'finally');
- }
-
+ mergePromiseProperty(spawned, promise, 'finally');
return spawned;
};
@@ -34949,7 +34931,7 @@ module.exports = {
/***/ }),
-/* 391 */
+/* 390 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -34994,7 +34976,7 @@ module.exports = {
/***/ }),
-/* 392 */
+/* 391 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35032,10 +35014,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(298);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queue"]; });
-/* harmony import */ var _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(393);
+/* harmony import */ var _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(392);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrame"]; });
-/* harmony import */ var _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(396);
+/* harmony import */ var _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(395);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualTimeScheduler"]; });
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualAction", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualAction"]; });
@@ -35063,7 +35045,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(232);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "identity", function() { return _internal_util_identity__WEBPACK_IMPORTED_MODULE_19__["identity"]; });
-/* harmony import */ var _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(397);
+/* harmony import */ var _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(396);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isObservable", function() { return _internal_util_isObservable__WEBPACK_IMPORTED_MODULE_20__["isObservable"]; });
/* harmony import */ var _internal_util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(250);
@@ -35081,10 +35063,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(335);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TimeoutError", function() { return _internal_util_TimeoutError__WEBPACK_IMPORTED_MODULE_25__["TimeoutError"]; });
-/* harmony import */ var _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(398);
+/* harmony import */ var _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(397);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindCallback", function() { return _internal_observable_bindCallback__WEBPACK_IMPORTED_MODULE_26__["bindCallback"]; });
-/* harmony import */ var _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(399);
+/* harmony import */ var _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(398);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bindNodeCallback", function() { return _internal_observable_bindNodeCallback__WEBPACK_IMPORTED_MODULE_27__["bindNodeCallback"]; });
/* harmony import */ var _internal_observable_combineLatest__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(214);
@@ -35099,49 +35081,49 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(242);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["empty"]; });
-/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(400);
+/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(399);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__["forkJoin"]; });
/* harmony import */ var _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(218);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "from", function() { return _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__["from"]; });
-/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(401);
+/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(400);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__["fromEvent"]; });
-/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(402);
+/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(401);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__["fromEventPattern"]; });
-/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(403);
+/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(402);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__["generate"]; });
-/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(404);
+/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(403);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__["iif"]; });
-/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(405);
+/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(404);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__["interval"]; });
/* harmony import */ var _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(278);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__["merge"]; });
-/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(406);
+/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(405);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "never", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["never"]; });
/* harmony import */ var _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(227);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "of", function() { return _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__["of"]; });
-/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(407);
+/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(406);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__["onErrorResumeNext"]; });
-/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(408);
+/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(407);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__["pairs"]; });
-/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(409);
+/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(408);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__["partition"]; });
/* harmony import */ var _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(302);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__["race"]; });
-/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(410);
+/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(409);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "range", function() { return _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__["range"]; });
/* harmony import */ var _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(243);
@@ -35150,7 +35132,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(204);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__["timer"]; });
-/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(411);
+/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(410);
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "using", function() { return _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__["using"]; });
/* harmony import */ var _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(346);
@@ -35226,14 +35208,14 @@ __webpack_require__.r(__webpack_exports__);
/***/ }),
-/* 393 */
+/* 392 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "animationFrame", function() { return animationFrame; });
-/* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(394);
-/* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(395);
+/* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(393);
+/* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(394);
/** PURE_IMPORTS_START _AnimationFrameAction,_AnimationFrameScheduler PURE_IMPORTS_END */
@@ -35242,7 +35224,7 @@ var animationFrame = /*@__PURE__*/ new _AnimationFrameScheduler__WEBPACK_IMPORTE
/***/ }),
-/* 394 */
+/* 393 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35291,7 +35273,7 @@ var AnimationFrameAction = /*@__PURE__*/ (function (_super) {
/***/ }),
-/* 395 */
+/* 394 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35335,7 +35317,7 @@ var AnimationFrameScheduler = /*@__PURE__*/ (function (_super) {
/***/ }),
-/* 396 */
+/* 395 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35458,7 +35440,7 @@ var VirtualAction = /*@__PURE__*/ (function (_super) {
/***/ }),
-/* 397 */
+/* 396 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35474,7 +35456,7 @@ function isObservable(obj) {
/***/ }),
-/* 398 */
+/* 397 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35594,7 +35576,7 @@ function dispatchError(state) {
/***/ }),
-/* 399 */
+/* 398 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35722,7 +35704,7 @@ function dispatchError(arg) {
/***/ }),
-/* 400 */
+/* 399 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35805,7 +35787,7 @@ function forkJoinInternal(sources, keys) {
/***/ }),
-/* 401 */
+/* 400 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35881,7 +35863,7 @@ function isEventTarget(sourceObj) {
/***/ }),
-/* 402 */
+/* 401 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -35926,7 +35908,7 @@ function fromEventPattern(addHandler, removeHandler, resultSelector) {
/***/ }),
-/* 403 */
+/* 402 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36063,7 +36045,7 @@ function dispatch(state) {
/***/ }),
-/* 404 */
+/* 403 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36087,7 +36069,7 @@ function iif(condition, trueResult, falseResult) {
/***/ }),
-/* 405 */
+/* 404 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36127,7 +36109,7 @@ function dispatch(state) {
/***/ }),
-/* 406 */
+/* 405 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36147,7 +36129,7 @@ function never() {
/***/ }),
-/* 407 */
+/* 406 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36187,7 +36169,7 @@ function onErrorResumeNext() {
/***/ }),
-/* 408 */
+/* 407 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36238,7 +36220,7 @@ function dispatch(state) {
/***/ }),
-/* 409 */
+/* 408 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36263,7 +36245,7 @@ function partition(source, predicate, thisArg) {
/***/ }),
-/* 410 */
+/* 409 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36322,7 +36304,7 @@ function dispatch(state) {
/***/ }),
-/* 411 */
+/* 410 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -36367,7 +36349,7 @@ function using(resourceFactory, observableFactory) {
/***/ }),
-/* 412 */
+/* 411 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36492,7 +36474,7 @@ function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesLi
/***/ }),
-/* 413 */
+/* 412 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36517,10 +36499,10 @@ function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesLi
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
-const Rx = tslib_1.__importStar(__webpack_require__(392));
+const Rx = tslib_1.__importStar(__webpack_require__(391));
const operators_1 = __webpack_require__(169);
const SEP = /\r?\n/;
-const observe_readable_1 = __webpack_require__(414);
+const observe_readable_1 = __webpack_require__(413);
/**
* Creates an Observable from a Readable Stream that:
* - splits data from `readable` into lines
@@ -36561,7 +36543,7 @@ exports.observeLines = observeLines;
/***/ }),
-/* 414 */
+/* 413 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36586,7 +36568,7 @@ exports.observeLines = observeLines;
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
-const Rx = tslib_1.__importStar(__webpack_require__(392));
+const Rx = tslib_1.__importStar(__webpack_require__(391));
const operators_1 = __webpack_require__(169);
/**
* Produces an Observable from a ReadableSteam that:
@@ -36600,7 +36582,7 @@ exports.observeReadable = observeReadable;
/***/ }),
-/* 415 */
+/* 414 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36624,19 +36606,19 @@ exports.observeReadable = observeReadable;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-var tooling_log_1 = __webpack_require__(416);
+var tooling_log_1 = __webpack_require__(415);
exports.ToolingLog = tooling_log_1.ToolingLog;
-var tooling_log_text_writer_1 = __webpack_require__(417);
+var tooling_log_text_writer_1 = __webpack_require__(416);
exports.ToolingLogTextWriter = tooling_log_text_writer_1.ToolingLogTextWriter;
-var log_levels_1 = __webpack_require__(418);
+var log_levels_1 = __webpack_require__(417);
exports.pickLevelFromFlags = log_levels_1.pickLevelFromFlags;
exports.parseLogLevel = log_levels_1.parseLogLevel;
-var tooling_log_collecting_writer_1 = __webpack_require__(419);
+var tooling_log_collecting_writer_1 = __webpack_require__(418);
exports.ToolingLogCollectingWriter = tooling_log_collecting_writer_1.ToolingLogCollectingWriter;
/***/ }),
-/* 416 */
+/* 415 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36661,8 +36643,8 @@ exports.ToolingLogCollectingWriter = tooling_log_collecting_writer_1.ToolingLogC
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
-const Rx = tslib_1.__importStar(__webpack_require__(392));
-const tooling_log_text_writer_1 = __webpack_require__(417);
+const Rx = tslib_1.__importStar(__webpack_require__(391));
+const tooling_log_text_writer_1 = __webpack_require__(416);
class ToolingLog {
constructor(writerConfig) {
this.identWidth = 0;
@@ -36724,7 +36706,7 @@ exports.ToolingLog = ToolingLog;
/***/ }),
-/* 417 */
+/* 416 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36751,7 +36733,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
const util_1 = __webpack_require__(29);
const chalk_1 = tslib_1.__importDefault(__webpack_require__(2));
-const log_levels_1 = __webpack_require__(418);
+const log_levels_1 = __webpack_require__(417);
const { magentaBright, yellow, red, blue, green, dim } = chalk_1.default;
const PREFIX_INDENT = ' '.repeat(6);
const MSG_PREFIXES = {
@@ -36818,7 +36800,7 @@ exports.ToolingLogTextWriter = ToolingLogTextWriter;
/***/ }),
-/* 418 */
+/* 417 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36874,7 +36856,7 @@ exports.parseLogLevel = parseLogLevel;
/***/ }),
-/* 419 */
+/* 418 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36898,7 +36880,7 @@ exports.parseLogLevel = parseLogLevel;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-const tooling_log_text_writer_1 = __webpack_require__(417);
+const tooling_log_text_writer_1 = __webpack_require__(416);
class ToolingLogCollectingWriter extends tooling_log_text_writer_1.ToolingLogTextWriter {
constructor() {
super({
@@ -36917,7 +36899,7 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter;
/***/ }),
-/* 420 */
+/* 419 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36941,12 +36923,12 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-var absolute_path_serializer_1 = __webpack_require__(421);
+var absolute_path_serializer_1 = __webpack_require__(420);
exports.createAbsolutePathSerializer = absolute_path_serializer_1.createAbsolutePathSerializer;
/***/ }),
-/* 421 */
+/* 420 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -36970,7 +36952,7 @@ exports.createAbsolutePathSerializer = absolute_path_serializer_1.createAbsolute
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-const repo_root_1 = __webpack_require__(422);
+const repo_root_1 = __webpack_require__(421);
function createAbsolutePathSerializer(rootPath = repo_root_1.REPO_ROOT) {
return {
print: (value) => value.replace(rootPath, '').replace(/\\/g, '/'),
@@ -36981,7 +36963,7 @@ exports.createAbsolutePathSerializer = createAbsolutePathSerializer;
/***/ }),
-/* 422 */
+/* 421 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -37008,7 +36990,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
const path_1 = tslib_1.__importDefault(__webpack_require__(16));
const fs_1 = tslib_1.__importDefault(__webpack_require__(23));
-const load_json_file_1 = tslib_1.__importDefault(__webpack_require__(423));
+const load_json_file_1 = tslib_1.__importDefault(__webpack_require__(422));
const isKibanaDir = (dir) => {
try {
const path = path_1.default.resolve(dir, 'package.json');
@@ -37044,16 +37026,16 @@ exports.REPO_ROOT = cursor;
/***/ }),
-/* 423 */
+/* 422 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const path = __webpack_require__(16);
const {promisify} = __webpack_require__(29);
-const fs = __webpack_require__(424);
-const stripBom = __webpack_require__(428);
-const parseJson = __webpack_require__(429);
+const fs = __webpack_require__(423);
+const stripBom = __webpack_require__(427);
+const parseJson = __webpack_require__(428);
const parse = (data, filePath, options = {}) => {
data = stripBom(data);
@@ -37070,13 +37052,13 @@ module.exports.sync = (filePath, options) => parse(fs.readFileSync(filePath, 'ut
/***/ }),
-/* 424 */
+/* 423 */
/***/ (function(module, exports, __webpack_require__) {
var fs = __webpack_require__(23)
-var polyfills = __webpack_require__(425)
-var legacy = __webpack_require__(426)
-var clone = __webpack_require__(427)
+var polyfills = __webpack_require__(424)
+var legacy = __webpack_require__(425)
+var clone = __webpack_require__(426)
var queue = []
@@ -37355,7 +37337,7 @@ function retry () {
/***/ }),
-/* 425 */
+/* 424 */
/***/ (function(module, exports, __webpack_require__) {
var constants = __webpack_require__(25)
@@ -37690,7 +37672,7 @@ function patch (fs) {
/***/ }),
-/* 426 */
+/* 425 */
/***/ (function(module, exports, __webpack_require__) {
var Stream = __webpack_require__(27).Stream
@@ -37814,7 +37796,7 @@ function legacy (fs) {
/***/ }),
-/* 427 */
+/* 426 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -37840,7 +37822,7 @@ function clone (obj) {
/***/ }),
-/* 428 */
+/* 427 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -37862,15 +37844,15 @@ module.exports = string => {
/***/ }),
-/* 429 */
+/* 428 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const errorEx = __webpack_require__(430);
-const fallback = __webpack_require__(432);
-const {default: LinesAndColumns} = __webpack_require__(433);
-const {codeFrameColumns} = __webpack_require__(434);
+const errorEx = __webpack_require__(429);
+const fallback = __webpack_require__(431);
+const {default: LinesAndColumns} = __webpack_require__(432);
+const {codeFrameColumns} = __webpack_require__(433);
const JSONError = errorEx('JSONError', {
fileName: errorEx.append('in %s'),
@@ -37919,14 +37901,14 @@ module.exports = (string, reviver, filename) => {
/***/ }),
-/* 430 */
+/* 429 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var util = __webpack_require__(29);
-var isArrayish = __webpack_require__(431);
+var isArrayish = __webpack_require__(430);
var errorEx = function errorEx(name, properties) {
if (!name || name.constructor !== String) {
@@ -38059,7 +38041,7 @@ module.exports = errorEx;
/***/ }),
-/* 431 */
+/* 430 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -38076,7 +38058,7 @@ module.exports = function isArrayish(obj) {
/***/ }),
-/* 432 */
+/* 431 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -38115,7 +38097,7 @@ function parseJson (txt, reviver, context) {
/***/ }),
-/* 433 */
+/* 432 */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -38179,7 +38161,7 @@ var LinesAndColumns = (function () {
/***/ }),
-/* 434 */
+/* 433 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -38192,7 +38174,7 @@ exports.codeFrameColumns = codeFrameColumns;
exports.default = _default;
function _highlight() {
- const data = _interopRequireWildcard(__webpack_require__(435));
+ const data = _interopRequireWildcard(__webpack_require__(434));
_highlight = function () {
return data;
@@ -38358,7 +38340,7 @@ function _default(rawLines, lineNumber, colNumber, opts = {}) {
}
/***/ }),
-/* 435 */
+/* 434 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -38372,7 +38354,7 @@ exports.getChalk = getChalk;
exports.default = highlight;
function _jsTokens() {
- const data = _interopRequireWildcard(__webpack_require__(436));
+ const data = _interopRequireWildcard(__webpack_require__(435));
_jsTokens = function () {
return data;
@@ -38382,7 +38364,7 @@ function _jsTokens() {
}
function _esutils() {
- const data = _interopRequireDefault(__webpack_require__(437));
+ const data = _interopRequireDefault(__webpack_require__(436));
_esutils = function () {
return data;
@@ -38392,7 +38374,7 @@ function _esutils() {
}
function _chalk() {
- const data = _interopRequireDefault(__webpack_require__(441));
+ const data = _interopRequireDefault(__webpack_require__(440));
_chalk = function () {
return data;
@@ -38493,7 +38475,7 @@ function highlight(code, options = {}) {
}
/***/ }),
-/* 436 */
+/* 435 */
/***/ (function(module, exports) {
// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell
@@ -38522,7 +38504,7 @@ exports.matchToToken = function(match) {
/***/ }),
-/* 437 */
+/* 436 */
/***/ (function(module, exports, __webpack_require__) {
/*
@@ -38553,15 +38535,15 @@ exports.matchToToken = function(match) {
(function () {
'use strict';
- exports.ast = __webpack_require__(438);
- exports.code = __webpack_require__(439);
- exports.keyword = __webpack_require__(440);
+ exports.ast = __webpack_require__(437);
+ exports.code = __webpack_require__(438);
+ exports.keyword = __webpack_require__(439);
}());
/* vim: set sw=4 ts=4 et tw=80 : */
/***/ }),
-/* 438 */
+/* 437 */
/***/ (function(module, exports) {
/*
@@ -38711,7 +38693,7 @@ exports.matchToToken = function(match) {
/***/ }),
-/* 439 */
+/* 438 */
/***/ (function(module, exports) {
/*
@@ -38852,7 +38834,7 @@ exports.matchToToken = function(match) {
/***/ }),
-/* 440 */
+/* 439 */
/***/ (function(module, exports, __webpack_require__) {
/*
@@ -38882,7 +38864,7 @@ exports.matchToToken = function(match) {
(function () {
'use strict';
- var code = __webpack_require__(439);
+ var code = __webpack_require__(438);
function isStrictModeReservedWordES6(id) {
switch (id) {
@@ -39023,16 +39005,16 @@ exports.matchToToken = function(match) {
/***/ }),
-/* 441 */
+/* 440 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const escapeStringRegexp = __webpack_require__(3);
-const ansiStyles = __webpack_require__(442);
-const stdoutColor = __webpack_require__(443).stdout;
+const ansiStyles = __webpack_require__(441);
+const stdoutColor = __webpack_require__(442).stdout;
-const template = __webpack_require__(444);
+const template = __webpack_require__(443);
const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
@@ -39258,7 +39240,7 @@ module.exports.default = module.exports; // For TypeScript
/***/ }),
-/* 442 */
+/* 441 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39431,7 +39413,7 @@ Object.defineProperty(module, 'exports', {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module)))
/***/ }),
-/* 443 */
+/* 442 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39573,7 +39555,7 @@ module.exports = {
/***/ }),
-/* 444 */
+/* 443 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39708,7 +39690,7 @@ module.exports = (chalk, tmp) => {
/***/ }),
-/* 445 */
+/* 444 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39747,7 +39729,7 @@ exports.KBN_P12_PASSWORD = 'storepass';
/***/ }),
-/* 446 */
+/* 445 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39771,9 +39753,9 @@ exports.KBN_P12_PASSWORD = 'storepass';
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-var run_1 = __webpack_require__(447);
+var run_1 = __webpack_require__(446);
exports.run = run_1.run;
-var fail_1 = __webpack_require__(448);
+var fail_1 = __webpack_require__(447);
exports.createFailError = fail_1.createFailError;
exports.createFlagError = fail_1.createFlagError;
exports.combineErrors = fail_1.combineErrors;
@@ -39781,7 +39763,7 @@ exports.isFailError = fail_1.isFailError;
/***/ }),
-/* 447 */
+/* 446 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39806,11 +39788,12 @@ exports.isFailError = fail_1.isFailError;
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
+const util_1 = __webpack_require__(29);
// @ts-ignore @types are outdated and module is super simple
const exit_hook_1 = tslib_1.__importDefault(__webpack_require__(348));
-const tooling_log_1 = __webpack_require__(415);
-const fail_1 = __webpack_require__(448);
-const flags_1 = __webpack_require__(449);
+const tooling_log_1 = __webpack_require__(414);
+const fail_1 = __webpack_require__(447);
+const flags_1 = __webpack_require__(448);
const proc_runner_1 = __webpack_require__(37);
async function run(fn, options = {}) {
var _a;
@@ -39825,7 +39808,9 @@ async function run(fn, options = {}) {
});
process.on('unhandledRejection', error => {
log.error('UNHANDLED PROMISE REJECTION');
- log.error(error);
+ log.error(error instanceof Error
+ ? error
+ : new Error(`non-Error type rejection value: ${util_1.inspect(error)}`));
process.exit(1);
});
const handleErrorWithoutExit = (error) => {
@@ -39883,7 +39868,7 @@ exports.run = run;
/***/ }),
-/* 448 */
+/* 447 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39951,7 +39936,7 @@ exports.combineErrors = combineErrors;
/***/ }),
-/* 449 */
+/* 448 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -39978,7 +39963,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
const path_1 = __webpack_require__(16);
const dedent_1 = tslib_1.__importDefault(__webpack_require__(14));
-const getopts_1 = tslib_1.__importDefault(__webpack_require__(450));
+const getopts_1 = tslib_1.__importDefault(__webpack_require__(449));
function getFlags(argv, options) {
const unexpectedNames = new Set();
const flagOpts = options.flags || {};
@@ -40081,7 +40066,7 @@ exports.getHelp = getHelp;
/***/ }),
-/* 450 */
+/* 449 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -40293,7 +40278,7 @@ module.exports = getopts
/***/ }),
-/* 451 */
+/* 450 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -40317,14 +40302,14 @@ module.exports = getopts
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-var kbn_client_1 = __webpack_require__(452);
+var kbn_client_1 = __webpack_require__(451);
exports.KbnClient = kbn_client_1.KbnClient;
-var kbn_client_requester_1 = __webpack_require__(453);
+var kbn_client_requester_1 = __webpack_require__(452);
exports.uriencode = kbn_client_requester_1.uriencode;
/***/ }),
-/* 452 */
+/* 451 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -40348,12 +40333,12 @@ exports.uriencode = kbn_client_requester_1.uriencode;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-const kbn_client_requester_1 = __webpack_require__(453);
-const kbn_client_status_1 = __webpack_require__(495);
-const kbn_client_plugins_1 = __webpack_require__(496);
-const kbn_client_version_1 = __webpack_require__(497);
-const kbn_client_saved_objects_1 = __webpack_require__(498);
-const kbn_client_ui_settings_1 = __webpack_require__(499);
+const kbn_client_requester_1 = __webpack_require__(452);
+const kbn_client_status_1 = __webpack_require__(494);
+const kbn_client_plugins_1 = __webpack_require__(495);
+const kbn_client_version_1 = __webpack_require__(496);
+const kbn_client_saved_objects_1 = __webpack_require__(497);
+const kbn_client_ui_settings_1 = __webpack_require__(498);
class KbnClient {
/**
* Basic Kibana server client that implements common behaviors for talking
@@ -40391,7 +40376,7 @@ exports.KbnClient = KbnClient;
/***/ }),
-/* 453 */
+/* 452 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -40416,9 +40401,9 @@ exports.KbnClient = KbnClient;
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
-const url_1 = tslib_1.__importDefault(__webpack_require__(454));
-const axios_1 = tslib_1.__importDefault(__webpack_require__(455));
-const axios_2 = __webpack_require__(493);
+const url_1 = tslib_1.__importDefault(__webpack_require__(453));
+const axios_1 = tslib_1.__importDefault(__webpack_require__(454));
+const axios_2 = __webpack_require__(492);
const isConcliftOnGetError = (error) => {
return (axios_2.isAxiosResponseError(error) && error.config.method === 'GET' && error.response.status === 409);
};
@@ -40502,28 +40487,28 @@ exports.KbnClientRequester = KbnClientRequester;
/***/ }),
-/* 454 */
+/* 453 */
/***/ (function(module, exports) {
module.exports = require("url");
/***/ }),
-/* 455 */
+/* 454 */
/***/ (function(module, exports, __webpack_require__) {
-module.exports = __webpack_require__(456);
+module.exports = __webpack_require__(455);
/***/ }),
-/* 456 */
+/* 455 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
-var bind = __webpack_require__(458);
-var Axios = __webpack_require__(460);
-var defaults = __webpack_require__(461);
+var utils = __webpack_require__(456);
+var bind = __webpack_require__(457);
+var Axios = __webpack_require__(459);
+var defaults = __webpack_require__(460);
/**
* Create an instance of Axios
@@ -40556,15 +40541,15 @@ axios.create = function create(instanceConfig) {
};
// Expose Cancel & CancelToken
-axios.Cancel = __webpack_require__(490);
-axios.CancelToken = __webpack_require__(491);
-axios.isCancel = __webpack_require__(487);
+axios.Cancel = __webpack_require__(489);
+axios.CancelToken = __webpack_require__(490);
+axios.isCancel = __webpack_require__(486);
// Expose all/spread
axios.all = function all(promises) {
return Promise.all(promises);
};
-axios.spread = __webpack_require__(492);
+axios.spread = __webpack_require__(491);
module.exports = axios;
@@ -40573,14 +40558,14 @@ module.exports.default = axios;
/***/ }),
-/* 457 */
+/* 456 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var bind = __webpack_require__(458);
-var isBuffer = __webpack_require__(459);
+var bind = __webpack_require__(457);
+var isBuffer = __webpack_require__(458);
/*global toString:true*/
@@ -40883,7 +40868,7 @@ module.exports = {
/***/ }),
-/* 458 */
+/* 457 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -40901,7 +40886,7 @@ module.exports = function bind(fn, thisArg) {
/***/ }),
-/* 459 */
+/* 458 */
/***/ (function(module, exports) {
/*!
@@ -40918,16 +40903,16 @@ module.exports = function isBuffer (obj) {
/***/ }),
-/* 460 */
+/* 459 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var defaults = __webpack_require__(461);
-var utils = __webpack_require__(457);
-var InterceptorManager = __webpack_require__(484);
-var dispatchRequest = __webpack_require__(485);
+var defaults = __webpack_require__(460);
+var utils = __webpack_require__(456);
+var InterceptorManager = __webpack_require__(483);
+var dispatchRequest = __webpack_require__(484);
/**
* Create a new instance of Axios
@@ -41004,14 +40989,14 @@ module.exports = Axios;
/***/ }),
-/* 461 */
+/* 460 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
-var normalizeHeaderName = __webpack_require__(462);
+var utils = __webpack_require__(456);
+var normalizeHeaderName = __webpack_require__(461);
var DEFAULT_CONTENT_TYPE = {
'Content-Type': 'application/x-www-form-urlencoded'
@@ -41027,10 +41012,10 @@ function getDefaultAdapter() {
var adapter;
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
- adapter = __webpack_require__(463);
+ adapter = __webpack_require__(462);
} else if (typeof process !== 'undefined') {
// For node use HTTP adapter
- adapter = __webpack_require__(471);
+ adapter = __webpack_require__(470);
}
return adapter;
}
@@ -41107,13 +41092,13 @@ module.exports = defaults;
/***/ }),
-/* 462 */
+/* 461 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
module.exports = function normalizeHeaderName(headers, normalizedName) {
utils.forEach(headers, function processHeader(value, name) {
@@ -41126,18 +41111,18 @@ module.exports = function normalizeHeaderName(headers, normalizedName) {
/***/ }),
-/* 463 */
+/* 462 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
-var settle = __webpack_require__(464);
-var buildURL = __webpack_require__(467);
-var parseHeaders = __webpack_require__(468);
-var isURLSameOrigin = __webpack_require__(469);
-var createError = __webpack_require__(465);
+var utils = __webpack_require__(456);
+var settle = __webpack_require__(463);
+var buildURL = __webpack_require__(466);
+var parseHeaders = __webpack_require__(467);
+var isURLSameOrigin = __webpack_require__(468);
+var createError = __webpack_require__(464);
module.exports = function xhrAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve, reject) {
@@ -41217,7 +41202,7 @@ module.exports = function xhrAdapter(config) {
// This is only done if running in a standard browser environment.
// Specifically not if we're in a web worker, or react-native.
if (utils.isStandardBrowserEnv()) {
- var cookies = __webpack_require__(470);
+ var cookies = __webpack_require__(469);
// Add xsrf header
var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
@@ -41295,13 +41280,13 @@ module.exports = function xhrAdapter(config) {
/***/ }),
-/* 464 */
+/* 463 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var createError = __webpack_require__(465);
+var createError = __webpack_require__(464);
/**
* Resolve or reject a Promise based on response status.
@@ -41328,13 +41313,13 @@ module.exports = function settle(resolve, reject, response) {
/***/ }),
-/* 465 */
+/* 464 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var enhanceError = __webpack_require__(466);
+var enhanceError = __webpack_require__(465);
/**
* Create an Error with the specified message, config, error code, request and response.
@@ -41353,7 +41338,7 @@ module.exports = function createError(message, config, code, request, response)
/***/ }),
-/* 466 */
+/* 465 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -41381,13 +41366,13 @@ module.exports = function enhanceError(error, config, code, request, response) {
/***/ }),
-/* 467 */
+/* 466 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
function encode(val) {
return encodeURIComponent(val).
@@ -41454,13 +41439,13 @@ module.exports = function buildURL(url, params, paramsSerializer) {
/***/ }),
-/* 468 */
+/* 467 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
// Headers whose duplicates are ignored by node
// c.f. https://nodejs.org/api/http.html#http_message_headers
@@ -41514,13 +41499,13 @@ module.exports = function parseHeaders(headers) {
/***/ }),
-/* 469 */
+/* 468 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
module.exports = (
utils.isStandardBrowserEnv() ?
@@ -41589,13 +41574,13 @@ module.exports = (
/***/ }),
-/* 470 */
+/* 469 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
module.exports = (
utils.isStandardBrowserEnv() ?
@@ -41649,24 +41634,24 @@ module.exports = (
/***/ }),
-/* 471 */
+/* 470 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
-var settle = __webpack_require__(464);
-var buildURL = __webpack_require__(467);
-var http = __webpack_require__(472);
-var https = __webpack_require__(473);
-var httpFollow = __webpack_require__(474).http;
-var httpsFollow = __webpack_require__(474).https;
-var url = __webpack_require__(454);
-var zlib = __webpack_require__(482);
-var pkg = __webpack_require__(483);
-var createError = __webpack_require__(465);
-var enhanceError = __webpack_require__(466);
+var utils = __webpack_require__(456);
+var settle = __webpack_require__(463);
+var buildURL = __webpack_require__(466);
+var http = __webpack_require__(471);
+var https = __webpack_require__(472);
+var httpFollow = __webpack_require__(473).http;
+var httpsFollow = __webpack_require__(473).https;
+var url = __webpack_require__(453);
+var zlib = __webpack_require__(481);
+var pkg = __webpack_require__(482);
+var createError = __webpack_require__(464);
+var enhanceError = __webpack_require__(465);
/*eslint consistent-return:0*/
module.exports = function httpAdapter(config) {
@@ -41894,27 +41879,27 @@ module.exports = function httpAdapter(config) {
/***/ }),
-/* 472 */
+/* 471 */
/***/ (function(module, exports) {
module.exports = require("http");
/***/ }),
-/* 473 */
+/* 472 */
/***/ (function(module, exports) {
module.exports = require("https");
/***/ }),
-/* 474 */
+/* 473 */
/***/ (function(module, exports, __webpack_require__) {
-var url = __webpack_require__(454);
-var http = __webpack_require__(472);
-var https = __webpack_require__(473);
+var url = __webpack_require__(453);
+var http = __webpack_require__(471);
+var https = __webpack_require__(472);
var assert = __webpack_require__(30);
var Writable = __webpack_require__(27).Writable;
-var debug = __webpack_require__(475)("follow-redirects");
+var debug = __webpack_require__(474)("follow-redirects");
// RFC7231§4.2.1: Of the request methods defined by this specification,
// the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe.
@@ -42234,7 +42219,7 @@ module.exports.wrap = wrap;
/***/ }),
-/* 475 */
+/* 474 */
/***/ (function(module, exports, __webpack_require__) {
/**
@@ -42243,14 +42228,14 @@ module.exports.wrap = wrap;
*/
if (typeof process === 'undefined' || process.type === 'renderer') {
- module.exports = __webpack_require__(476);
+ module.exports = __webpack_require__(475);
} else {
- module.exports = __webpack_require__(479);
+ module.exports = __webpack_require__(478);
}
/***/ }),
-/* 476 */
+/* 475 */
/***/ (function(module, exports, __webpack_require__) {
/**
@@ -42259,7 +42244,7 @@ if (typeof process === 'undefined' || process.type === 'renderer') {
* Expose `debug()` as the module.
*/
-exports = module.exports = __webpack_require__(477);
+exports = module.exports = __webpack_require__(476);
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
@@ -42451,7 +42436,7 @@ function localstorage() {
/***/ }),
-/* 477 */
+/* 476 */
/***/ (function(module, exports, __webpack_require__) {
@@ -42467,7 +42452,7 @@ exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
-exports.humanize = __webpack_require__(478);
+exports.humanize = __webpack_require__(477);
/**
* Active `debug` instances.
@@ -42682,7 +42667,7 @@ function coerce(val) {
/***/ }),
-/* 478 */
+/* 477 */
/***/ (function(module, exports) {
/**
@@ -42840,14 +42825,14 @@ function plural(ms, n, name) {
/***/ }),
-/* 479 */
+/* 478 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Module dependencies.
*/
-var tty = __webpack_require__(480);
+var tty = __webpack_require__(479);
var util = __webpack_require__(29);
/**
@@ -42856,7 +42841,7 @@ var util = __webpack_require__(29);
* Expose `debug()` as the module.
*/
-exports = module.exports = __webpack_require__(477);
+exports = module.exports = __webpack_require__(476);
exports.init = init;
exports.log = log;
exports.formatArgs = formatArgs;
@@ -42871,7 +42856,7 @@ exports.useColors = useColors;
exports.colors = [ 6, 2, 3, 4, 5, 1 ];
try {
- var supportsColor = __webpack_require__(481);
+ var supportsColor = __webpack_require__(480);
if (supportsColor && supportsColor.level >= 2) {
exports.colors = [
20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68,
@@ -43032,13 +43017,13 @@ exports.enable(load());
/***/ }),
-/* 480 */
+/* 479 */
/***/ (function(module, exports) {
module.exports = require("tty");
/***/ }),
-/* 481 */
+/* 480 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43183,25 +43168,25 @@ module.exports = {
/***/ }),
-/* 482 */
+/* 481 */
/***/ (function(module, exports) {
module.exports = require("zlib");
/***/ }),
-/* 483 */
+/* 482 */
/***/ (function(module) {
module.exports = JSON.parse("{\"name\":\"axios\",\"version\":\"0.18.1\",\"description\":\"Promise based HTTP client for the browser and node.js\",\"main\":\"index.js\",\"scripts\":{\"test\":\"grunt test && bundlesize\",\"start\":\"node ./sandbox/server.js\",\"build\":\"NODE_ENV=production grunt build\",\"preversion\":\"npm test\",\"version\":\"npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json\",\"postversion\":\"git push && git push --tags\",\"examples\":\"node ./examples/server.js\",\"coveralls\":\"cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js\"},\"repository\":{\"type\":\"git\",\"url\":\"https://github.com/axios/axios.git\"},\"keywords\":[\"xhr\",\"http\",\"ajax\",\"promise\",\"node\"],\"author\":\"Matt Zabriskie\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://github.com/axios/axios/issues\"},\"homepage\":\"https://github.com/axios/axios\",\"devDependencies\":{\"bundlesize\":\"^0.5.7\",\"coveralls\":\"^2.11.9\",\"es6-promise\":\"^4.0.5\",\"grunt\":\"^1.0.1\",\"grunt-banner\":\"^0.6.0\",\"grunt-cli\":\"^1.2.0\",\"grunt-contrib-clean\":\"^1.0.0\",\"grunt-contrib-nodeunit\":\"^1.0.0\",\"grunt-contrib-watch\":\"^1.0.0\",\"grunt-eslint\":\"^19.0.0\",\"grunt-karma\":\"^2.0.0\",\"grunt-ts\":\"^6.0.0-beta.3\",\"grunt-webpack\":\"^1.0.18\",\"istanbul-instrumenter-loader\":\"^1.0.0\",\"jasmine-core\":\"^2.4.1\",\"karma\":\"^1.3.0\",\"karma-chrome-launcher\":\"^2.0.0\",\"karma-coverage\":\"^1.0.0\",\"karma-firefox-launcher\":\"^1.0.0\",\"karma-jasmine\":\"^1.0.2\",\"karma-jasmine-ajax\":\"^0.1.13\",\"karma-opera-launcher\":\"^1.0.0\",\"karma-safari-launcher\":\"^1.0.0\",\"karma-sauce-launcher\":\"^1.1.0\",\"karma-sinon\":\"^1.0.5\",\"karma-sourcemap-loader\":\"^0.3.7\",\"karma-webpack\":\"^1.7.0\",\"load-grunt-tasks\":\"^3.5.2\",\"minimist\":\"^1.2.0\",\"sinon\":\"^1.17.4\",\"webpack\":\"^1.13.1\",\"webpack-dev-server\":\"^1.14.1\",\"url-search-params\":\"^0.6.1\",\"typescript\":\"^2.0.3\"},\"browser\":{\"./lib/adapters/http.js\":\"./lib/adapters/xhr.js\"},\"typings\":\"./index.d.ts\",\"dependencies\":{\"follow-redirects\":\"1.5.10\",\"is-buffer\":\"^2.0.2\"},\"bundlesize\":[{\"path\":\"./dist/axios.min.js\",\"threshold\":\"5kB\"}]}");
/***/ }),
-/* 484 */
+/* 483 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
function InterceptorManager() {
this.handlers = [];
@@ -43254,18 +43239,18 @@ module.exports = InterceptorManager;
/***/ }),
-/* 485 */
+/* 484 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
-var transformData = __webpack_require__(486);
-var isCancel = __webpack_require__(487);
-var defaults = __webpack_require__(461);
-var isAbsoluteURL = __webpack_require__(488);
-var combineURLs = __webpack_require__(489);
+var utils = __webpack_require__(456);
+var transformData = __webpack_require__(485);
+var isCancel = __webpack_require__(486);
+var defaults = __webpack_require__(460);
+var isAbsoluteURL = __webpack_require__(487);
+var combineURLs = __webpack_require__(488);
/**
* Throws a `Cancel` if cancellation has been requested.
@@ -43347,13 +43332,13 @@ module.exports = function dispatchRequest(config) {
/***/ }),
-/* 486 */
+/* 485 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var utils = __webpack_require__(457);
+var utils = __webpack_require__(456);
/**
* Transform the data for a request or a response
@@ -43374,7 +43359,7 @@ module.exports = function transformData(data, headers, fns) {
/***/ }),
-/* 487 */
+/* 486 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43386,7 +43371,7 @@ module.exports = function isCancel(value) {
/***/ }),
-/* 488 */
+/* 487 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43407,7 +43392,7 @@ module.exports = function isAbsoluteURL(url) {
/***/ }),
-/* 489 */
+/* 488 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43428,7 +43413,7 @@ module.exports = function combineURLs(baseURL, relativeURL) {
/***/ }),
-/* 490 */
+/* 489 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43454,13 +43439,13 @@ module.exports = Cancel;
/***/ }),
-/* 491 */
+/* 490 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var Cancel = __webpack_require__(490);
+var Cancel = __webpack_require__(489);
/**
* A `CancelToken` is an object that can be used to request cancellation of an operation.
@@ -43518,7 +43503,7 @@ module.exports = CancelToken;
/***/ }),
-/* 492 */
+/* 491 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43552,7 +43537,7 @@ module.exports = function spread(callback) {
/***/ }),
-/* 493 */
+/* 492 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43577,11 +43562,11 @@ module.exports = function spread(callback) {
*/
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = __webpack_require__(36);
-tslib_1.__exportStar(__webpack_require__(494), exports);
+tslib_1.__exportStar(__webpack_require__(493), exports);
/***/ }),
-/* 494 */
+/* 493 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43614,7 +43599,7 @@ exports.isAxiosResponseError = (error) => {
/***/ }),
-/* 495 */
+/* 494 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43663,7 +43648,7 @@ exports.KbnClientStatus = KbnClientStatus;
/***/ }),
-/* 496 */
+/* 495 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43713,7 +43698,7 @@ exports.KbnClientPlugins = KbnClientPlugins;
/***/ }),
-/* 497 */
+/* 496 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43754,7 +43739,7 @@ exports.KbnClientVersion = KbnClientVersion;
/***/ }),
-/* 498 */
+/* 497 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43778,7 +43763,7 @@ exports.KbnClientVersion = KbnClientVersion;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-const kbn_client_requester_1 = __webpack_require__(453);
+const kbn_client_requester_1 = __webpack_require__(452);
class KbnClientSavedObjects {
constructor(log, requester) {
this.log = log;
@@ -43863,7 +43848,7 @@ exports.KbnClientSavedObjects = KbnClientSavedObjects;
/***/ }),
-/* 499 */
+/* 498 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -43887,7 +43872,7 @@ exports.KbnClientSavedObjects = KbnClientSavedObjects;
* under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
-const kbn_client_requester_1 = __webpack_require__(453);
+const kbn_client_requester_1 = __webpack_require__(452);
class KbnClientUiSettings {
constructor(log, requester, defaults) {
this.log = log;
@@ -43963,7 +43948,7 @@ exports.KbnClientUiSettings = KbnClientUiSettings;
/***/ }),
-/* 500 */
+/* 499 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -44029,7 +44014,7 @@ async function parallelize(items, fn, concurrency = 4) {
}
/***/ }),
-/* 501 */
+/* 500 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -44038,15 +44023,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProjectGraph", function() { return buildProjectGraph; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topologicallyBatchProjects", function() { return topologicallyBatchProjects; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "includeTransitiveProjects", function() { return includeTransitiveProjects; });
-/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(502);
+/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(501);
/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(515);
-/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(516);
-/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(578);
+/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(514);
+/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(515);
+/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(577);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -44245,7 +44230,7 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, {
}
/***/ }),
-/* 502 */
+/* 501 */
/***/ (function(module, exports, __webpack_require__) {
// Approach:
@@ -44291,26 +44276,26 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, {
module.exports = glob
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
-var inherits = __webpack_require__(509)
+var inherits = __webpack_require__(508)
var EE = __webpack_require__(379).EventEmitter
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
-var globSync = __webpack_require__(512)
-var common = __webpack_require__(513)
+var isAbsolute = __webpack_require__(510)
+var globSync = __webpack_require__(511)
+var common = __webpack_require__(512)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
-var inflight = __webpack_require__(514)
+var inflight = __webpack_require__(513)
var util = __webpack_require__(29)
var childrenIgnored = common.childrenIgnored
var isIgnored = common.isIgnored
-var once = __webpack_require__(385)
+var once = __webpack_require__(384)
function glob (pattern, options, cb) {
if (typeof options === 'function') cb = options, options = {}
@@ -45041,7 +45026,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
/***/ }),
-/* 503 */
+/* 502 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = realpath
@@ -45057,7 +45042,7 @@ var origRealpathSync = fs.realpathSync
var version = process.version
var ok = /^v[0-5]\./.test(version)
-var old = __webpack_require__(504)
+var old = __webpack_require__(503)
function newError (er) {
return er && er.syscall === 'realpath' && (
@@ -45113,7 +45098,7 @@ function unmonkeypatch () {
/***/ }),
-/* 504 */
+/* 503 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright Joyent, Inc. and other Node contributors.
@@ -45422,7 +45407,7 @@ exports.realpath = function realpath(p, cache, cb) {
/***/ }),
-/* 505 */
+/* 504 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = minimatch
@@ -45434,7 +45419,7 @@ try {
} catch (er) {}
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
-var expand = __webpack_require__(506)
+var expand = __webpack_require__(505)
var plTypes = {
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
@@ -46351,11 +46336,11 @@ function regExpEscape (s) {
/***/ }),
-/* 506 */
+/* 505 */
/***/ (function(module, exports, __webpack_require__) {
-var concatMap = __webpack_require__(507);
-var balanced = __webpack_require__(508);
+var concatMap = __webpack_require__(506);
+var balanced = __webpack_require__(507);
module.exports = expandTop;
@@ -46558,7 +46543,7 @@ function expand(str, isTop) {
/***/ }),
-/* 507 */
+/* 506 */
/***/ (function(module, exports) {
module.exports = function (xs, fn) {
@@ -46577,7 +46562,7 @@ var isArray = Array.isArray || function (xs) {
/***/ }),
-/* 508 */
+/* 507 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -46643,7 +46628,7 @@ function range(a, b, str) {
/***/ }),
-/* 509 */
+/* 508 */
/***/ (function(module, exports, __webpack_require__) {
try {
@@ -46653,12 +46638,12 @@ try {
module.exports = util.inherits;
} catch (e) {
/* istanbul ignore next */
- module.exports = __webpack_require__(510);
+ module.exports = __webpack_require__(509);
}
/***/ }),
-/* 510 */
+/* 509 */
/***/ (function(module, exports) {
if (typeof Object.create === 'function') {
@@ -46691,7 +46676,7 @@ if (typeof Object.create === 'function') {
/***/ }),
-/* 511 */
+/* 510 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -46718,22 +46703,22 @@ module.exports.win32 = win32;
/***/ }),
-/* 512 */
+/* 511 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = globSync
globSync.GlobSync = GlobSync
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
-var Glob = __webpack_require__(502).Glob
+var Glob = __webpack_require__(501).Glob
var util = __webpack_require__(29)
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
-var common = __webpack_require__(513)
+var isAbsolute = __webpack_require__(510)
+var common = __webpack_require__(512)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
@@ -47210,7 +47195,7 @@ GlobSync.prototype._makeAbs = function (f) {
/***/ }),
-/* 513 */
+/* 512 */
/***/ (function(module, exports, __webpack_require__) {
exports.alphasort = alphasort
@@ -47228,8 +47213,8 @@ function ownProp (obj, field) {
}
var path = __webpack_require__(16)
-var minimatch = __webpack_require__(505)
-var isAbsolute = __webpack_require__(511)
+var minimatch = __webpack_require__(504)
+var isAbsolute = __webpack_require__(510)
var Minimatch = minimatch.Minimatch
function alphasorti (a, b) {
@@ -47456,12 +47441,12 @@ function childrenIgnored (self, path) {
/***/ }),
-/* 514 */
+/* 513 */
/***/ (function(module, exports, __webpack_require__) {
-var wrappy = __webpack_require__(386)
+var wrappy = __webpack_require__(385)
var reqs = Object.create(null)
-var once = __webpack_require__(385)
+var once = __webpack_require__(384)
module.exports = wrappy(inflight)
@@ -47516,7 +47501,7 @@ function slice (args) {
/***/ }),
-/* 515 */
+/* 514 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -47549,7 +47534,7 @@ class CliError extends Error {
}
/***/ }),
-/* 516 */
+/* 515 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -47563,10 +47548,10 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(29);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(515);
+/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(514);
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34);
-/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(517);
-/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(563);
+/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(516);
+/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(562);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -47797,7 +47782,7 @@ function normalizePath(path) {
}
/***/ }),
-/* 517 */
+/* 516 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -47805,9 +47790,9 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readPackageJson", function() { return readPackageJson; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writePackageJson", function() { return writePackageJson; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLinkDependency", function() { return isLinkDependency; });
-/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(518);
+/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(517);
/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(read_pkg__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(544);
+/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(543);
/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(write_pkg__WEBPACK_IMPORTED_MODULE_1__);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
@@ -47841,7 +47826,7 @@ function writePackageJson(path, json) {
const isLinkDependency = depVersion => depVersion.startsWith('link:');
/***/ }),
-/* 518 */
+/* 517 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -47849,7 +47834,7 @@ const isLinkDependency = depVersion => depVersion.startsWith('link:');
const {promisify} = __webpack_require__(29);
const fs = __webpack_require__(23);
const path = __webpack_require__(16);
-const parseJson = __webpack_require__(519);
+const parseJson = __webpack_require__(518);
const readFileAsync = promisify(fs.readFile);
@@ -47864,7 +47849,7 @@ module.exports = async options => {
const json = parseJson(await readFileAsync(filePath, 'utf8'));
if (options.normalize) {
- __webpack_require__(520)(json);
+ __webpack_require__(519)(json);
}
return json;
@@ -47881,7 +47866,7 @@ module.exports.sync = options => {
const json = parseJson(fs.readFileSync(filePath, 'utf8'));
if (options.normalize) {
- __webpack_require__(520)(json);
+ __webpack_require__(519)(json);
}
return json;
@@ -47889,15 +47874,15 @@ module.exports.sync = options => {
/***/ }),
-/* 519 */
+/* 518 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const errorEx = __webpack_require__(430);
-const fallback = __webpack_require__(432);
-const {default: LinesAndColumns} = __webpack_require__(433);
-const {codeFrameColumns} = __webpack_require__(434);
+const errorEx = __webpack_require__(429);
+const fallback = __webpack_require__(431);
+const {default: LinesAndColumns} = __webpack_require__(432);
+const {codeFrameColumns} = __webpack_require__(433);
const JSONError = errorEx('JSONError', {
fileName: errorEx.append('in %s'),
@@ -47946,15 +47931,15 @@ module.exports = (string, reviver, filename) => {
/***/ }),
-/* 520 */
+/* 519 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = normalize
-var fixer = __webpack_require__(521)
+var fixer = __webpack_require__(520)
normalize.fixer = fixer
-var makeWarning = __webpack_require__(542)
+var makeWarning = __webpack_require__(541)
var fieldsToFix = ['name','version','description','repository','modules','scripts'
,'files','bin','man','bugs','keywords','readme','homepage','license']
@@ -47991,17 +47976,17 @@ function ucFirst (string) {
/***/ }),
-/* 521 */
+/* 520 */
/***/ (function(module, exports, __webpack_require__) {
-var semver = __webpack_require__(522)
-var validateLicense = __webpack_require__(523);
-var hostedGitInfo = __webpack_require__(528)
-var isBuiltinModule = __webpack_require__(531).isCore
+var semver = __webpack_require__(521)
+var validateLicense = __webpack_require__(522);
+var hostedGitInfo = __webpack_require__(527)
+var isBuiltinModule = __webpack_require__(530).isCore
var depTypes = ["dependencies","devDependencies","optionalDependencies"]
-var extractDescription = __webpack_require__(540)
-var url = __webpack_require__(454)
-var typos = __webpack_require__(541)
+var extractDescription = __webpack_require__(539)
+var url = __webpack_require__(453)
+var typos = __webpack_require__(540)
var fixer = module.exports = {
// default warning function
@@ -48415,7 +48400,7 @@ function bugsTypos(bugs, warn) {
/***/ }),
-/* 522 */
+/* 521 */
/***/ (function(module, exports) {
exports = module.exports = SemVer
@@ -49904,11 +49889,11 @@ function coerce (version) {
/***/ }),
-/* 523 */
+/* 522 */
/***/ (function(module, exports, __webpack_require__) {
-var parse = __webpack_require__(524);
-var correct = __webpack_require__(526);
+var parse = __webpack_require__(523);
+var correct = __webpack_require__(525);
var genericWarning = (
'license should be ' +
@@ -49994,10 +49979,10 @@ module.exports = function(argument) {
/***/ }),
-/* 524 */
+/* 523 */
/***/ (function(module, exports, __webpack_require__) {
-var parser = __webpack_require__(525).parser
+var parser = __webpack_require__(524).parser
module.exports = function (argument) {
return parser.parse(argument)
@@ -50005,7 +49990,7 @@ module.exports = function (argument) {
/***/ }),
-/* 525 */
+/* 524 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */
@@ -51369,10 +51354,10 @@ if ( true && __webpack_require__.c[__webpack_require__.s] === module) {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module)))
/***/ }),
-/* 526 */
+/* 525 */
/***/ (function(module, exports, __webpack_require__) {
-var licenseIDs = __webpack_require__(527);
+var licenseIDs = __webpack_require__(526);
function valid(string) {
return licenseIDs.indexOf(string) > -1;
@@ -51612,20 +51597,20 @@ module.exports = function(identifier) {
/***/ }),
-/* 527 */
+/* 526 */
/***/ (function(module) {
module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]");
/***/ }),
-/* 528 */
+/* 527 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var url = __webpack_require__(454)
-var gitHosts = __webpack_require__(529)
-var GitHost = module.exports = __webpack_require__(530)
+var url = __webpack_require__(453)
+var gitHosts = __webpack_require__(528)
+var GitHost = module.exports = __webpack_require__(529)
var protocolToRepresentationMap = {
'git+ssh': 'sshurl',
@@ -51746,7 +51731,7 @@ function parseGitUrl (giturl) {
/***/ }),
-/* 529 */
+/* 528 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -51821,12 +51806,12 @@ Object.keys(gitHosts).forEach(function (name) {
/***/ }),
-/* 530 */
+/* 529 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var gitHosts = __webpack_require__(529)
+var gitHosts = __webpack_require__(528)
var extend = Object.assign || __webpack_require__(29)._extend
var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) {
@@ -51942,21 +51927,21 @@ GitHost.prototype.toString = function (opts) {
/***/ }),
-/* 531 */
+/* 530 */
/***/ (function(module, exports, __webpack_require__) {
-var core = __webpack_require__(532);
-var async = __webpack_require__(534);
+var core = __webpack_require__(531);
+var async = __webpack_require__(533);
async.core = core;
async.isCore = function isCore(x) { return core[x]; };
-async.sync = __webpack_require__(539);
+async.sync = __webpack_require__(538);
exports = async;
module.exports = async;
/***/ }),
-/* 532 */
+/* 531 */
/***/ (function(module, exports, __webpack_require__) {
var current = (process.versions && process.versions.node && process.versions.node.split('.')) || [];
@@ -52003,7 +51988,7 @@ function versionIncluded(specifierValue) {
return matchesRange(specifierValue);
}
-var data = __webpack_require__(533);
+var data = __webpack_require__(532);
var core = {};
for (var mod in data) { // eslint-disable-line no-restricted-syntax
@@ -52015,21 +52000,21 @@ module.exports = core;
/***/ }),
-/* 533 */
+/* 532 */
/***/ (function(module) {
module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":\">= 10 && < 10.1\",\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0\"],\"v8\":\">= 1\",\"vm\":true,\"worker_threads\":\">= 11.7\",\"zlib\":true}");
/***/ }),
-/* 534 */
+/* 533 */
/***/ (function(module, exports, __webpack_require__) {
-var core = __webpack_require__(532);
+var core = __webpack_require__(531);
var fs = __webpack_require__(23);
var path = __webpack_require__(16);
-var caller = __webpack_require__(535);
-var nodeModulesPaths = __webpack_require__(536);
-var normalizeOptions = __webpack_require__(538);
+var caller = __webpack_require__(534);
+var nodeModulesPaths = __webpack_require__(535);
+var normalizeOptions = __webpack_require__(537);
var defaultIsFile = function isFile(file, cb) {
fs.stat(file, function (err, stat) {
@@ -52256,7 +52241,7 @@ module.exports = function resolve(x, options, callback) {
/***/ }),
-/* 535 */
+/* 534 */
/***/ (function(module, exports) {
module.exports = function () {
@@ -52270,11 +52255,11 @@ module.exports = function () {
/***/ }),
-/* 536 */
+/* 535 */
/***/ (function(module, exports, __webpack_require__) {
var path = __webpack_require__(16);
-var parse = path.parse || __webpack_require__(537);
+var parse = path.parse || __webpack_require__(536);
var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) {
var prefix = '/';
@@ -52318,7 +52303,7 @@ module.exports = function nodeModulesPaths(start, opts, request) {
/***/ }),
-/* 537 */
+/* 536 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -52418,7 +52403,7 @@ module.exports.win32 = win32.parse;
/***/ }),
-/* 538 */
+/* 537 */
/***/ (function(module, exports) {
module.exports = function (x, opts) {
@@ -52434,15 +52419,15 @@ module.exports = function (x, opts) {
/***/ }),
-/* 539 */
+/* 538 */
/***/ (function(module, exports, __webpack_require__) {
-var core = __webpack_require__(532);
+var core = __webpack_require__(531);
var fs = __webpack_require__(23);
var path = __webpack_require__(16);
-var caller = __webpack_require__(535);
-var nodeModulesPaths = __webpack_require__(536);
-var normalizeOptions = __webpack_require__(538);
+var caller = __webpack_require__(534);
+var nodeModulesPaths = __webpack_require__(535);
+var normalizeOptions = __webpack_require__(537);
var defaultIsFile = function isFile(file) {
try {
@@ -52594,7 +52579,7 @@ module.exports = function (x, options) {
/***/ }),
-/* 540 */
+/* 539 */
/***/ (function(module, exports) {
module.exports = extractDescription
@@ -52614,17 +52599,17 @@ function extractDescription (d) {
/***/ }),
-/* 541 */
+/* 540 */
/***/ (function(module) {
module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}");
/***/ }),
-/* 542 */
+/* 541 */
/***/ (function(module, exports, __webpack_require__) {
var util = __webpack_require__(29)
-var messages = __webpack_require__(543)
+var messages = __webpack_require__(542)
module.exports = function() {
var args = Array.prototype.slice.call(arguments, 0)
@@ -52649,20 +52634,20 @@ function makeTypoWarning (providedName, probableName, field) {
/***/ }),
-/* 543 */
+/* 542 */
/***/ (function(module) {
module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}");
/***/ }),
-/* 544 */
+/* 543 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const path = __webpack_require__(16);
-const writeJsonFile = __webpack_require__(545);
-const sortKeys = __webpack_require__(557);
+const writeJsonFile = __webpack_require__(544);
+const sortKeys = __webpack_require__(556);
const dependencyKeys = new Set([
'dependencies',
@@ -52727,18 +52712,18 @@ module.exports.sync = (filePath, data, options) => {
/***/ }),
-/* 545 */
+/* 544 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const path = __webpack_require__(16);
-const fs = __webpack_require__(546);
-const writeFileAtomic = __webpack_require__(550);
-const sortKeys = __webpack_require__(557);
-const makeDir = __webpack_require__(559);
-const pify = __webpack_require__(561);
-const detectIndent = __webpack_require__(562);
+const fs = __webpack_require__(545);
+const writeFileAtomic = __webpack_require__(549);
+const sortKeys = __webpack_require__(556);
+const makeDir = __webpack_require__(558);
+const pify = __webpack_require__(560);
+const detectIndent = __webpack_require__(561);
const init = (fn, filePath, data, options) => {
if (!filePath) {
@@ -52810,13 +52795,13 @@ module.exports.sync = (filePath, data, options) => {
/***/ }),
-/* 546 */
+/* 545 */
/***/ (function(module, exports, __webpack_require__) {
var fs = __webpack_require__(23)
-var polyfills = __webpack_require__(547)
-var legacy = __webpack_require__(548)
-var clone = __webpack_require__(549)
+var polyfills = __webpack_require__(546)
+var legacy = __webpack_require__(547)
+var clone = __webpack_require__(548)
var queue = []
@@ -53095,7 +53080,7 @@ function retry () {
/***/ }),
-/* 547 */
+/* 546 */
/***/ (function(module, exports, __webpack_require__) {
var constants = __webpack_require__(25)
@@ -53430,7 +53415,7 @@ function patch (fs) {
/***/ }),
-/* 548 */
+/* 547 */
/***/ (function(module, exports, __webpack_require__) {
var Stream = __webpack_require__(27).Stream
@@ -53554,7 +53539,7 @@ function legacy (fs) {
/***/ }),
-/* 549 */
+/* 548 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -53580,7 +53565,7 @@ function clone (obj) {
/***/ }),
-/* 550 */
+/* 549 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -53590,8 +53575,8 @@ module.exports.sync = writeFileSync
module.exports._getTmpname = getTmpname // for testing
module.exports._cleanupOnExit = cleanupOnExit
-var fs = __webpack_require__(551)
-var MurmurHash3 = __webpack_require__(555)
+var fs = __webpack_require__(550)
+var MurmurHash3 = __webpack_require__(554)
var onExit = __webpack_require__(377)
var path = __webpack_require__(16)
var activeFiles = {}
@@ -53600,7 +53585,7 @@ var activeFiles = {}
/* istanbul ignore next */
var threadId = (function getId () {
try {
- var workerThreads = __webpack_require__(556)
+ var workerThreads = __webpack_require__(555)
/// if we are in main thread, this is set to `0`
return workerThreads.threadId
@@ -53825,12 +53810,12 @@ function writeFileSync (filename, data, options) {
/***/ }),
-/* 551 */
+/* 550 */
/***/ (function(module, exports, __webpack_require__) {
var fs = __webpack_require__(23)
-var polyfills = __webpack_require__(552)
-var legacy = __webpack_require__(554)
+var polyfills = __webpack_require__(551)
+var legacy = __webpack_require__(553)
var queue = []
var util = __webpack_require__(29)
@@ -53854,7 +53839,7 @@ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
})
}
-module.exports = patch(__webpack_require__(553))
+module.exports = patch(__webpack_require__(552))
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
module.exports = patch(fs)
}
@@ -54093,10 +54078,10 @@ function retry () {
/***/ }),
-/* 552 */
+/* 551 */
/***/ (function(module, exports, __webpack_require__) {
-var fs = __webpack_require__(553)
+var fs = __webpack_require__(552)
var constants = __webpack_require__(25)
var origCwd = process.cwd
@@ -54429,7 +54414,7 @@ function chownErOk (er) {
/***/ }),
-/* 553 */
+/* 552 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -54457,7 +54442,7 @@ function clone (obj) {
/***/ }),
-/* 554 */
+/* 553 */
/***/ (function(module, exports, __webpack_require__) {
var Stream = __webpack_require__(27).Stream
@@ -54581,7 +54566,7 @@ function legacy (fs) {
/***/ }),
-/* 555 */
+/* 554 */
/***/ (function(module, exports, __webpack_require__) {
/**
@@ -54723,18 +54708,18 @@ function legacy (fs) {
/***/ }),
-/* 556 */
+/* 555 */
/***/ (function(module, exports) {
module.exports = require(undefined);
/***/ }),
-/* 557 */
+/* 556 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const isPlainObj = __webpack_require__(558);
+const isPlainObj = __webpack_require__(557);
module.exports = (obj, opts) => {
if (!isPlainObj(obj)) {
@@ -54791,7 +54776,7 @@ module.exports = (obj, opts) => {
/***/ }),
-/* 558 */
+/* 557 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -54805,15 +54790,15 @@ module.exports = function (x) {
/***/ }),
-/* 559 */
+/* 558 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const fs = __webpack_require__(23);
const path = __webpack_require__(16);
-const pify = __webpack_require__(560);
-const semver = __webpack_require__(522);
+const pify = __webpack_require__(559);
+const semver = __webpack_require__(521);
const defaults = {
mode: 0o777 & (~process.umask()),
@@ -54951,7 +54936,7 @@ module.exports.sync = (input, options) => {
/***/ }),
-/* 560 */
+/* 559 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -55026,7 +55011,7 @@ module.exports = (input, options) => {
/***/ }),
-/* 561 */
+/* 560 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -55101,7 +55086,7 @@ module.exports = (input, options) => {
/***/ }),
-/* 562 */
+/* 561 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -55230,7 +55215,7 @@ module.exports = str => {
/***/ }),
-/* 563 */
+/* 562 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -55239,7 +55224,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; });
-/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(564);
+/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(563);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -55309,7 +55294,7 @@ async function yarnWorkspacesInfo(directory) {
}
/***/ }),
-/* 564 */
+/* 563 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -55320,9 +55305,9 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(351);
/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(565);
+/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(564);
/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(log_symbols__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(570);
+/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(569);
/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
@@ -55388,12 +55373,12 @@ function spawnStreaming(command, args, opts, {
}
/***/ }),
-/* 565 */
+/* 564 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const chalk = __webpack_require__(566);
+const chalk = __webpack_require__(565);
const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color';
@@ -55415,16 +55400,16 @@ module.exports = isSupported ? main : fallbacks;
/***/ }),
-/* 566 */
+/* 565 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const escapeStringRegexp = __webpack_require__(3);
-const ansiStyles = __webpack_require__(567);
-const stdoutColor = __webpack_require__(568).stdout;
+const ansiStyles = __webpack_require__(566);
+const stdoutColor = __webpack_require__(567).stdout;
-const template = __webpack_require__(569);
+const template = __webpack_require__(568);
const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
@@ -55650,7 +55635,7 @@ module.exports.default = module.exports; // For TypeScript
/***/ }),
-/* 567 */
+/* 566 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -55823,7 +55808,7 @@ Object.defineProperty(module, 'exports', {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module)))
/***/ }),
-/* 568 */
+/* 567 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -55965,7 +55950,7 @@ module.exports = {
/***/ }),
-/* 569 */
+/* 568 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -56100,7 +56085,7 @@ module.exports = (chalk, tmp) => {
/***/ }),
-/* 570 */
+/* 569 */
/***/ (function(module, exports, __webpack_require__) {
// Copyright IBM Corp. 2014,2018. All Rights Reserved.
@@ -56108,12 +56093,12 @@ module.exports = (chalk, tmp) => {
// This file is licensed under the Apache License 2.0.
// License text available at https://opensource.org/licenses/Apache-2.0
-module.exports = __webpack_require__(571);
-module.exports.cli = __webpack_require__(575);
+module.exports = __webpack_require__(570);
+module.exports.cli = __webpack_require__(574);
/***/ }),
-/* 571 */
+/* 570 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -56128,9 +56113,9 @@ var stream = __webpack_require__(27);
var util = __webpack_require__(29);
var fs = __webpack_require__(23);
-var through = __webpack_require__(572);
-var duplexer = __webpack_require__(573);
-var StringDecoder = __webpack_require__(574).StringDecoder;
+var through = __webpack_require__(571);
+var duplexer = __webpack_require__(572);
+var StringDecoder = __webpack_require__(573).StringDecoder;
module.exports = Logger;
@@ -56319,7 +56304,7 @@ function lineMerger(host) {
/***/ }),
-/* 572 */
+/* 571 */
/***/ (function(module, exports, __webpack_require__) {
var Stream = __webpack_require__(27)
@@ -56433,7 +56418,7 @@ function through (write, end, opts) {
/***/ }),
-/* 573 */
+/* 572 */
/***/ (function(module, exports, __webpack_require__) {
var Stream = __webpack_require__(27)
@@ -56526,13 +56511,13 @@ function duplex(writer, reader) {
/***/ }),
-/* 574 */
+/* 573 */
/***/ (function(module, exports) {
module.exports = require("string_decoder");
/***/ }),
-/* 575 */
+/* 574 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -56543,11 +56528,11 @@ module.exports = require("string_decoder");
-var minimist = __webpack_require__(576);
+var minimist = __webpack_require__(575);
var path = __webpack_require__(16);
-var Logger = __webpack_require__(571);
-var pkg = __webpack_require__(577);
+var Logger = __webpack_require__(570);
+var pkg = __webpack_require__(576);
module.exports = cli;
@@ -56601,7 +56586,7 @@ function usage($0, p) {
/***/ }),
-/* 576 */
+/* 575 */
/***/ (function(module, exports) {
module.exports = function (args, opts) {
@@ -56843,29 +56828,29 @@ function isNumber (x) {
/***/ }),
-/* 577 */
+/* 576 */
/***/ (function(module) {
module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}");
/***/ }),
-/* 578 */
+/* 577 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; });
-/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(502);
+/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(501);
/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579);
+/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(578);
/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20);
-/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(517);
-/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(501);
+/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(516);
+/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(500);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -56957,7 +56942,7 @@ function packagesFromGlobPattern({
}
/***/ }),
-/* 579 */
+/* 578 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -57011,6 +56996,7 @@ function getProjectPaths({
projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack'));
projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/plugins/*'));
projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/legacy/plugins/*'));
+ projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*'));
}
if (!skipKibanaPlugins) {
@@ -57026,7 +57012,7 @@ function getProjectPaths({
}
/***/ }),
-/* 580 */
+/* 579 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -57034,13 +57020,13 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; });
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(23);
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(581);
+/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(580);
/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29);
/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(351);
/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(582);
+/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(581);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -57074,7 +57060,7 @@ async function getChangesForProjects(projects, kbn, log) {
log.verbose('getting changed files');
const {
stdout
- } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmt', '--', ...Array.from(projects.values()).map(p => p.path)], {
+ } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmt', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], {
cwd: kbn.getAbsolute()
});
const output = stdout.trim();
@@ -57117,6 +57103,11 @@ async function getChangesForProjects(projects, kbn, log) {
const changesByProject = new Map();
for (const project of sortedRelevantProjects) {
+ if (kbn.isOutsideRepo(project)) {
+ changesByProject.set(project, undefined);
+ continue;
+ }
+
const ownChanges = new Map();
const prefix = kbn.getRelative(project.path);
@@ -57141,6 +57132,10 @@ async function getChangesForProjects(projects, kbn, log) {
async function getLatestSha(project, kbn) {
+ if (kbn.isOutsideRepo(project)) {
+ return;
+ }
+
const {
stdout
} = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], {
@@ -57200,7 +57195,7 @@ async function getChecksum(project, changes, yarnLock, kbn, log) {
log.verbose(`[${project.name}] local sha:`, sha);
}
- if (Array.from(changes.values()).includes('invalid')) {
+ if (!changes || Array.from(changes.values()).includes('invalid')) {
log.warning(`[${project.name}] unable to determine local changes, caching disabled`);
return;
}
@@ -57257,19 +57252,19 @@ async function getAllChecksums(kbn, log) {
}
/***/ }),
-/* 581 */
+/* 580 */
/***/ (function(module, exports) {
module.exports = require("crypto");
/***/ }),
-/* 582 */
+/* 581 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; });
-/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(583);
+/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(582);
/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(20);
/*
@@ -57313,7 +57308,7 @@ async function readYarnLock(kbn) {
}
/***/ }),
-/* 583 */
+/* 582 */
/***/ (function(module, exports, __webpack_require__) {
module.exports =
@@ -58872,7 +58867,7 @@ module.exports = invariant;
/* 9 */
/***/ (function(module, exports) {
-module.exports = __webpack_require__(581);
+module.exports = __webpack_require__(580);
/***/ }),
/* 10 */,
@@ -61196,7 +61191,7 @@ function onceStrict (fn) {
/* 63 */
/***/ (function(module, exports) {
-module.exports = __webpack_require__(584);
+module.exports = __webpack_require__(583);
/***/ }),
/* 64 */,
@@ -62134,7 +62129,7 @@ module.exports.win32 = win32;
/* 79 */
/***/ (function(module, exports) {
-module.exports = __webpack_require__(480);
+module.exports = __webpack_require__(479);
/***/ }),
/* 80 */,
@@ -67591,13 +67586,13 @@ module.exports = process && support(supportLevel);
/******/ ]);
/***/ }),
-/* 584 */
+/* 583 */
/***/ (function(module, exports) {
module.exports = require("buffer");
/***/ }),
-/* 585 */
+/* 584 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -67694,7 +67689,7 @@ class BootstrapCacheFile {
}
/***/ }),
-/* 586 */
+/* 585 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -67702,9 +67697,9 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; });
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(587);
+/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(586);
/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(675);
+/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(674);
/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
@@ -67804,21 +67799,21 @@ const CleanCommand = {
};
/***/ }),
-/* 587 */
+/* 586 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const {promisify} = __webpack_require__(29);
const path = __webpack_require__(16);
-const globby = __webpack_require__(588);
-const isGlob = __webpack_require__(605);
-const slash = __webpack_require__(666);
+const globby = __webpack_require__(587);
+const isGlob = __webpack_require__(604);
+const slash = __webpack_require__(665);
const gracefulFs = __webpack_require__(22);
-const isPathCwd = __webpack_require__(668);
-const isPathInside = __webpack_require__(669);
-const rimraf = __webpack_require__(670);
-const pMap = __webpack_require__(671);
+const isPathCwd = __webpack_require__(667);
+const isPathInside = __webpack_require__(668);
+const rimraf = __webpack_require__(669);
+const pMap = __webpack_require__(670);
const rimrafP = promisify(rimraf);
@@ -67932,19 +67927,19 @@ module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options
/***/ }),
-/* 588 */
+/* 587 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const fs = __webpack_require__(23);
-const arrayUnion = __webpack_require__(589);
-const merge2 = __webpack_require__(590);
-const glob = __webpack_require__(591);
-const fastGlob = __webpack_require__(596);
-const dirGlob = __webpack_require__(662);
-const gitignore = __webpack_require__(664);
-const {FilterStream, UniqueStream} = __webpack_require__(667);
+const arrayUnion = __webpack_require__(588);
+const merge2 = __webpack_require__(589);
+const glob = __webpack_require__(590);
+const fastGlob = __webpack_require__(595);
+const dirGlob = __webpack_require__(661);
+const gitignore = __webpack_require__(663);
+const {FilterStream, UniqueStream} = __webpack_require__(666);
const DEFAULT_FILTER = () => false;
@@ -68117,7 +68112,7 @@ module.exports.gitignore = gitignore;
/***/ }),
-/* 589 */
+/* 588 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -68129,7 +68124,7 @@ module.exports = (...arguments_) => {
/***/ }),
-/* 590 */
+/* 589 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -68243,7 +68238,7 @@ function pauseStreams (streams, options) {
/***/ }),
-/* 591 */
+/* 590 */
/***/ (function(module, exports, __webpack_require__) {
// Approach:
@@ -68289,26 +68284,26 @@ function pauseStreams (streams, options) {
module.exports = glob
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
-var inherits = __webpack_require__(592)
+var inherits = __webpack_require__(591)
var EE = __webpack_require__(379).EventEmitter
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
-var globSync = __webpack_require__(594)
-var common = __webpack_require__(595)
+var isAbsolute = __webpack_require__(510)
+var globSync = __webpack_require__(593)
+var common = __webpack_require__(594)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
-var inflight = __webpack_require__(514)
+var inflight = __webpack_require__(513)
var util = __webpack_require__(29)
var childrenIgnored = common.childrenIgnored
var isIgnored = common.isIgnored
-var once = __webpack_require__(385)
+var once = __webpack_require__(384)
function glob (pattern, options, cb) {
if (typeof options === 'function') cb = options, options = {}
@@ -69039,7 +69034,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
/***/ }),
-/* 592 */
+/* 591 */
/***/ (function(module, exports, __webpack_require__) {
try {
@@ -69049,12 +69044,12 @@ try {
module.exports = util.inherits;
} catch (e) {
/* istanbul ignore next */
- module.exports = __webpack_require__(593);
+ module.exports = __webpack_require__(592);
}
/***/ }),
-/* 593 */
+/* 592 */
/***/ (function(module, exports) {
if (typeof Object.create === 'function') {
@@ -69087,22 +69082,22 @@ if (typeof Object.create === 'function') {
/***/ }),
-/* 594 */
+/* 593 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = globSync
globSync.GlobSync = GlobSync
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
-var Glob = __webpack_require__(591).Glob
+var Glob = __webpack_require__(590).Glob
var util = __webpack_require__(29)
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
-var common = __webpack_require__(595)
+var isAbsolute = __webpack_require__(510)
+var common = __webpack_require__(594)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
@@ -69579,7 +69574,7 @@ GlobSync.prototype._makeAbs = function (f) {
/***/ }),
-/* 595 */
+/* 594 */
/***/ (function(module, exports, __webpack_require__) {
exports.alphasort = alphasort
@@ -69597,8 +69592,8 @@ function ownProp (obj, field) {
}
var path = __webpack_require__(16)
-var minimatch = __webpack_require__(505)
-var isAbsolute = __webpack_require__(511)
+var minimatch = __webpack_require__(504)
+var isAbsolute = __webpack_require__(510)
var Minimatch = minimatch.Minimatch
function alphasorti (a, b) {
@@ -69825,17 +69820,17 @@ function childrenIgnored (self, path) {
/***/ }),
-/* 596 */
+/* 595 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const taskManager = __webpack_require__(597);
-const async_1 = __webpack_require__(625);
-const stream_1 = __webpack_require__(658);
-const sync_1 = __webpack_require__(659);
-const settings_1 = __webpack_require__(661);
-const utils = __webpack_require__(598);
+const taskManager = __webpack_require__(596);
+const async_1 = __webpack_require__(624);
+const stream_1 = __webpack_require__(657);
+const sync_1 = __webpack_require__(658);
+const settings_1 = __webpack_require__(660);
+const utils = __webpack_require__(597);
function FastGlob(source, options) {
try {
assertPatternsInput(source);
@@ -69893,13 +69888,13 @@ module.exports = FastGlob;
/***/ }),
-/* 597 */
+/* 596 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const utils = __webpack_require__(598);
+const utils = __webpack_require__(597);
function generate(patterns, settings) {
const positivePatterns = getPositivePatterns(patterns);
const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore);
@@ -69967,28 +69962,28 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask;
/***/ }),
-/* 598 */
+/* 597 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const array = __webpack_require__(599);
+const array = __webpack_require__(598);
exports.array = array;
-const errno = __webpack_require__(600);
+const errno = __webpack_require__(599);
exports.errno = errno;
-const fs = __webpack_require__(601);
+const fs = __webpack_require__(600);
exports.fs = fs;
-const path = __webpack_require__(602);
+const path = __webpack_require__(601);
exports.path = path;
-const pattern = __webpack_require__(603);
+const pattern = __webpack_require__(602);
exports.pattern = pattern;
-const stream = __webpack_require__(624);
+const stream = __webpack_require__(623);
exports.stream = stream;
/***/ }),
-/* 599 */
+/* 598 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -70001,7 +69996,7 @@ exports.flatten = flatten;
/***/ }),
-/* 600 */
+/* 599 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -70014,7 +70009,7 @@ exports.isEnoentCodeError = isEnoentCodeError;
/***/ }),
-/* 601 */
+/* 600 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -70039,7 +70034,7 @@ exports.createDirentFromStats = createDirentFromStats;
/***/ }),
-/* 602 */
+/* 601 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -70060,16 +70055,16 @@ exports.makeAbsolute = makeAbsolute;
/***/ }),
-/* 603 */
+/* 602 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = __webpack_require__(16);
-const globParent = __webpack_require__(604);
-const isGlob = __webpack_require__(605);
-const micromatch = __webpack_require__(607);
+const globParent = __webpack_require__(603);
+const isGlob = __webpack_require__(604);
+const micromatch = __webpack_require__(606);
const GLOBSTAR = '**';
function isStaticPattern(pattern) {
return !isDynamicPattern(pattern);
@@ -70158,13 +70153,13 @@ exports.matchAny = matchAny;
/***/ }),
-/* 604 */
+/* 603 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var isGlob = __webpack_require__(605);
+var isGlob = __webpack_require__(604);
var pathPosixDirname = __webpack_require__(16).posix.dirname;
var isWin32 = __webpack_require__(11).platform() === 'win32';
@@ -70199,7 +70194,7 @@ module.exports = function globParent(str) {
/***/ }),
-/* 605 */
+/* 604 */
/***/ (function(module, exports, __webpack_require__) {
/*!
@@ -70209,7 +70204,7 @@ module.exports = function globParent(str) {
* Released under the MIT License.
*/
-var isExtglob = __webpack_require__(606);
+var isExtglob = __webpack_require__(605);
var chars = { '{': '}', '(': ')', '[': ']'};
var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/;
@@ -70253,7 +70248,7 @@ module.exports = function isGlob(str, options) {
/***/ }),
-/* 606 */
+/* 605 */
/***/ (function(module, exports) {
/*!
@@ -70279,16 +70274,16 @@ module.exports = function isExtglob(str) {
/***/ }),
-/* 607 */
+/* 606 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const util = __webpack_require__(29);
-const braces = __webpack_require__(608);
-const picomatch = __webpack_require__(618);
-const utils = __webpack_require__(621);
+const braces = __webpack_require__(607);
+const picomatch = __webpack_require__(617);
+const utils = __webpack_require__(620);
const isEmptyString = val => typeof val === 'string' && (val === '' || val === './');
/**
@@ -70753,16 +70748,16 @@ module.exports = micromatch;
/***/ }),
-/* 608 */
+/* 607 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const stringify = __webpack_require__(609);
-const compile = __webpack_require__(611);
-const expand = __webpack_require__(615);
-const parse = __webpack_require__(616);
+const stringify = __webpack_require__(608);
+const compile = __webpack_require__(610);
+const expand = __webpack_require__(614);
+const parse = __webpack_require__(615);
/**
* Expand the given pattern or create a regex-compatible string.
@@ -70930,13 +70925,13 @@ module.exports = braces;
/***/ }),
-/* 609 */
+/* 608 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const utils = __webpack_require__(610);
+const utils = __webpack_require__(609);
module.exports = (ast, options = {}) => {
let stringify = (node, parent = {}) => {
@@ -70969,7 +70964,7 @@ module.exports = (ast, options = {}) => {
/***/ }),
-/* 610 */
+/* 609 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -71088,14 +71083,14 @@ exports.flatten = (...args) => {
/***/ }),
-/* 611 */
+/* 610 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const fill = __webpack_require__(612);
-const utils = __webpack_require__(610);
+const fill = __webpack_require__(611);
+const utils = __webpack_require__(609);
const compile = (ast, options = {}) => {
let walk = (node, parent = {}) => {
@@ -71152,7 +71147,7 @@ module.exports = compile;
/***/ }),
-/* 612 */
+/* 611 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -71166,7 +71161,7 @@ module.exports = compile;
const util = __webpack_require__(29);
-const toRegexRange = __webpack_require__(613);
+const toRegexRange = __webpack_require__(612);
const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
@@ -71408,7 +71403,7 @@ module.exports = fill;
/***/ }),
-/* 613 */
+/* 612 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -71421,7 +71416,7 @@ module.exports = fill;
-const isNumber = __webpack_require__(614);
+const isNumber = __webpack_require__(613);
const toRegexRange = (min, max, options) => {
if (isNumber(min) === false) {
@@ -71703,7 +71698,7 @@ module.exports = toRegexRange;
/***/ }),
-/* 614 */
+/* 613 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -71728,15 +71723,15 @@ module.exports = function(num) {
/***/ }),
-/* 615 */
+/* 614 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const fill = __webpack_require__(612);
-const stringify = __webpack_require__(609);
-const utils = __webpack_require__(610);
+const fill = __webpack_require__(611);
+const stringify = __webpack_require__(608);
+const utils = __webpack_require__(609);
const append = (queue = '', stash = '', enclose = false) => {
let result = [];
@@ -71848,13 +71843,13 @@ module.exports = expand;
/***/ }),
-/* 616 */
+/* 615 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const stringify = __webpack_require__(609);
+const stringify = __webpack_require__(608);
/**
* Constants
@@ -71876,7 +71871,7 @@ const {
CHAR_SINGLE_QUOTE, /* ' */
CHAR_NO_BREAK_SPACE,
CHAR_ZERO_WIDTH_NOBREAK_SPACE
-} = __webpack_require__(617);
+} = __webpack_require__(616);
/**
* parse
@@ -72188,7 +72183,7 @@ module.exports = parse;
/***/ }),
-/* 617 */
+/* 616 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -72252,26 +72247,26 @@ module.exports = {
/***/ }),
-/* 618 */
+/* 617 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-module.exports = __webpack_require__(619);
+module.exports = __webpack_require__(618);
/***/ }),
-/* 619 */
+/* 618 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const path = __webpack_require__(16);
-const scan = __webpack_require__(620);
-const parse = __webpack_require__(623);
-const utils = __webpack_require__(621);
+const scan = __webpack_require__(619);
+const parse = __webpack_require__(622);
+const utils = __webpack_require__(620);
/**
* Creates a matcher function from one or more glob patterns. The
@@ -72574,7 +72569,7 @@ picomatch.toRegex = (source, options) => {
* @return {Object}
*/
-picomatch.constants = __webpack_require__(622);
+picomatch.constants = __webpack_require__(621);
/**
* Expose "picomatch"
@@ -72584,13 +72579,13 @@ module.exports = picomatch;
/***/ }),
-/* 620 */
+/* 619 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const utils = __webpack_require__(621);
+const utils = __webpack_require__(620);
const {
CHAR_ASTERISK, /* * */
@@ -72608,7 +72603,7 @@ const {
CHAR_RIGHT_CURLY_BRACE, /* } */
CHAR_RIGHT_PARENTHESES, /* ) */
CHAR_RIGHT_SQUARE_BRACKET /* ] */
-} = __webpack_require__(622);
+} = __webpack_require__(621);
const isPathSeparator = code => {
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
@@ -72810,7 +72805,7 @@ module.exports = (input, options) => {
/***/ }),
-/* 621 */
+/* 620 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -72822,7 +72817,7 @@ const {
REGEX_SPECIAL_CHARS,
REGEX_SPECIAL_CHARS_GLOBAL,
REGEX_REMOVE_BACKSLASH
-} = __webpack_require__(622);
+} = __webpack_require__(621);
exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
@@ -72860,7 +72855,7 @@ exports.escapeLast = (input, char, lastIdx) => {
/***/ }),
-/* 622 */
+/* 621 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -73046,14 +73041,14 @@ module.exports = {
/***/ }),
-/* 623 */
+/* 622 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const utils = __webpack_require__(621);
-const constants = __webpack_require__(622);
+const utils = __webpack_require__(620);
+const constants = __webpack_require__(621);
/**
* Constants
@@ -74064,13 +74059,13 @@ module.exports = parse;
/***/ }),
-/* 624 */
+/* 623 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const merge2 = __webpack_require__(590);
+const merge2 = __webpack_require__(589);
function merge(streams) {
const mergedStream = merge2(streams);
streams.forEach((stream) => {
@@ -74082,14 +74077,14 @@ exports.merge = merge;
/***/ }),
-/* 625 */
+/* 624 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const stream_1 = __webpack_require__(626);
-const provider_1 = __webpack_require__(653);
+const stream_1 = __webpack_require__(625);
+const provider_1 = __webpack_require__(652);
class ProviderAsync extends provider_1.default {
constructor() {
super(...arguments);
@@ -74117,16 +74112,16 @@ exports.default = ProviderAsync;
/***/ }),
-/* 626 */
+/* 625 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = __webpack_require__(27);
-const fsStat = __webpack_require__(627);
-const fsWalk = __webpack_require__(632);
-const reader_1 = __webpack_require__(652);
+const fsStat = __webpack_require__(626);
+const fsWalk = __webpack_require__(631);
+const reader_1 = __webpack_require__(651);
class ReaderStream extends reader_1.default {
constructor() {
super(...arguments);
@@ -74179,15 +74174,15 @@ exports.default = ReaderStream;
/***/ }),
-/* 627 */
+/* 626 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const async = __webpack_require__(628);
-const sync = __webpack_require__(629);
-const settings_1 = __webpack_require__(630);
+const async = __webpack_require__(627);
+const sync = __webpack_require__(628);
+const settings_1 = __webpack_require__(629);
exports.Settings = settings_1.default;
function stat(path, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
@@ -74210,7 +74205,7 @@ function getSettings(settingsOrOptions = {}) {
/***/ }),
-/* 628 */
+/* 627 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74248,7 +74243,7 @@ function callSuccessCallback(callback, result) {
/***/ }),
-/* 629 */
+/* 628 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74277,13 +74272,13 @@ exports.read = read;
/***/ }),
-/* 630 */
+/* 629 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fs = __webpack_require__(631);
+const fs = __webpack_require__(630);
class Settings {
constructor(_options = {}) {
this._options = _options;
@@ -74300,7 +74295,7 @@ exports.default = Settings;
/***/ }),
-/* 631 */
+/* 630 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74323,16 +74318,16 @@ exports.createFileSystemAdapter = createFileSystemAdapter;
/***/ }),
-/* 632 */
+/* 631 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const async_1 = __webpack_require__(633);
-const stream_1 = __webpack_require__(648);
-const sync_1 = __webpack_require__(649);
-const settings_1 = __webpack_require__(651);
+const async_1 = __webpack_require__(632);
+const stream_1 = __webpack_require__(647);
+const sync_1 = __webpack_require__(648);
+const settings_1 = __webpack_require__(650);
exports.Settings = settings_1.default;
function walk(dir, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
@@ -74362,13 +74357,13 @@ function getSettings(settingsOrOptions = {}) {
/***/ }),
-/* 633 */
+/* 632 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const async_1 = __webpack_require__(634);
+const async_1 = __webpack_require__(633);
class AsyncProvider {
constructor(_root, _settings) {
this._root = _root;
@@ -74399,17 +74394,17 @@ function callSuccessCallback(callback, entries) {
/***/ }),
-/* 634 */
+/* 633 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = __webpack_require__(379);
-const fsScandir = __webpack_require__(635);
-const fastq = __webpack_require__(644);
-const common = __webpack_require__(646);
-const reader_1 = __webpack_require__(647);
+const fsScandir = __webpack_require__(634);
+const fastq = __webpack_require__(643);
+const common = __webpack_require__(645);
+const reader_1 = __webpack_require__(646);
class AsyncReader extends reader_1.default {
constructor(_root, _settings) {
super(_root, _settings);
@@ -74499,15 +74494,15 @@ exports.default = AsyncReader;
/***/ }),
-/* 635 */
+/* 634 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const async = __webpack_require__(636);
-const sync = __webpack_require__(641);
-const settings_1 = __webpack_require__(642);
+const async = __webpack_require__(635);
+const sync = __webpack_require__(640);
+const settings_1 = __webpack_require__(641);
exports.Settings = settings_1.default;
function scandir(path, optionsOrSettingsOrCallback, callback) {
if (typeof optionsOrSettingsOrCallback === 'function') {
@@ -74530,16 +74525,16 @@ function getSettings(settingsOrOptions = {}) {
/***/ }),
-/* 636 */
+/* 635 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fsStat = __webpack_require__(627);
-const rpl = __webpack_require__(637);
-const constants_1 = __webpack_require__(638);
-const utils = __webpack_require__(639);
+const fsStat = __webpack_require__(626);
+const rpl = __webpack_require__(636);
+const constants_1 = __webpack_require__(637);
+const utils = __webpack_require__(638);
function read(dir, settings, callback) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(dir, settings, callback);
@@ -74628,7 +74623,7 @@ function callSuccessCallback(callback, result) {
/***/ }),
-/* 637 */
+/* 636 */
/***/ (function(module, exports) {
module.exports = runParallel
@@ -74682,7 +74677,7 @@ function runParallel (tasks, cb) {
/***/ }),
-/* 638 */
+/* 637 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74698,18 +74693,18 @@ exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = MAJOR_VERSION > 10 || (MAJOR_VERSIO
/***/ }),
-/* 639 */
+/* 638 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fs = __webpack_require__(640);
+const fs = __webpack_require__(639);
exports.fs = fs;
/***/ }),
-/* 640 */
+/* 639 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74734,15 +74729,15 @@ exports.createDirentFromStats = createDirentFromStats;
/***/ }),
-/* 641 */
+/* 640 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fsStat = __webpack_require__(627);
-const constants_1 = __webpack_require__(638);
-const utils = __webpack_require__(639);
+const fsStat = __webpack_require__(626);
+const constants_1 = __webpack_require__(637);
+const utils = __webpack_require__(638);
function read(dir, settings) {
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
return readdirWithFileTypes(dir, settings);
@@ -74793,15 +74788,15 @@ exports.readdir = readdir;
/***/ }),
-/* 642 */
+/* 641 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = __webpack_require__(16);
-const fsStat = __webpack_require__(627);
-const fs = __webpack_require__(643);
+const fsStat = __webpack_require__(626);
+const fs = __webpack_require__(642);
class Settings {
constructor(_options = {}) {
this._options = _options;
@@ -74824,7 +74819,7 @@ exports.default = Settings;
/***/ }),
-/* 643 */
+/* 642 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -74849,13 +74844,13 @@ exports.createFileSystemAdapter = createFileSystemAdapter;
/***/ }),
-/* 644 */
+/* 643 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-var reusify = __webpack_require__(645)
+var reusify = __webpack_require__(644)
function fastqueue (context, worker, concurrency) {
if (typeof context === 'function') {
@@ -75029,7 +75024,7 @@ module.exports = fastqueue
/***/ }),
-/* 645 */
+/* 644 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -75069,7 +75064,7 @@ module.exports = reusify
/***/ }),
-/* 646 */
+/* 645 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -75100,13 +75095,13 @@ exports.joinPathSegments = joinPathSegments;
/***/ }),
-/* 647 */
+/* 646 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const common = __webpack_require__(646);
+const common = __webpack_require__(645);
class Reader {
constructor(_root, _settings) {
this._root = _root;
@@ -75118,14 +75113,14 @@ exports.default = Reader;
/***/ }),
-/* 648 */
+/* 647 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = __webpack_require__(27);
-const async_1 = __webpack_require__(634);
+const async_1 = __webpack_require__(633);
class StreamProvider {
constructor(_root, _settings) {
this._root = _root;
@@ -75155,13 +75150,13 @@ exports.default = StreamProvider;
/***/ }),
-/* 649 */
+/* 648 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const sync_1 = __webpack_require__(650);
+const sync_1 = __webpack_require__(649);
class SyncProvider {
constructor(_root, _settings) {
this._root = _root;
@@ -75176,15 +75171,15 @@ exports.default = SyncProvider;
/***/ }),
-/* 650 */
+/* 649 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fsScandir = __webpack_require__(635);
-const common = __webpack_require__(646);
-const reader_1 = __webpack_require__(647);
+const fsScandir = __webpack_require__(634);
+const common = __webpack_require__(645);
+const reader_1 = __webpack_require__(646);
class SyncReader extends reader_1.default {
constructor() {
super(...arguments);
@@ -75242,14 +75237,14 @@ exports.default = SyncReader;
/***/ }),
-/* 651 */
+/* 650 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = __webpack_require__(16);
-const fsScandir = __webpack_require__(635);
+const fsScandir = __webpack_require__(634);
class Settings {
constructor(_options = {}) {
this._options = _options;
@@ -75275,15 +75270,15 @@ exports.default = Settings;
/***/ }),
-/* 652 */
+/* 651 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = __webpack_require__(16);
-const fsStat = __webpack_require__(627);
-const utils = __webpack_require__(598);
+const fsStat = __webpack_require__(626);
+const utils = __webpack_require__(597);
class Reader {
constructor(_settings) {
this._settings = _settings;
@@ -75315,17 +75310,17 @@ exports.default = Reader;
/***/ }),
-/* 653 */
+/* 652 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const path = __webpack_require__(16);
-const deep_1 = __webpack_require__(654);
-const entry_1 = __webpack_require__(655);
-const error_1 = __webpack_require__(656);
-const entry_2 = __webpack_require__(657);
+const deep_1 = __webpack_require__(653);
+const entry_1 = __webpack_require__(654);
+const error_1 = __webpack_require__(655);
+const entry_2 = __webpack_require__(656);
class Provider {
constructor(_settings) {
this._settings = _settings;
@@ -75370,13 +75365,13 @@ exports.default = Provider;
/***/ }),
-/* 654 */
+/* 653 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const utils = __webpack_require__(598);
+const utils = __webpack_require__(597);
class DeepFilter {
constructor(_settings, _micromatchOptions) {
this._settings = _settings;
@@ -75436,13 +75431,13 @@ exports.default = DeepFilter;
/***/ }),
-/* 655 */
+/* 654 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const utils = __webpack_require__(598);
+const utils = __webpack_require__(597);
class EntryFilter {
constructor(_settings, _micromatchOptions) {
this._settings = _settings;
@@ -75497,13 +75492,13 @@ exports.default = EntryFilter;
/***/ }),
-/* 656 */
+/* 655 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const utils = __webpack_require__(598);
+const utils = __webpack_require__(597);
class ErrorFilter {
constructor(_settings) {
this._settings = _settings;
@@ -75519,13 +75514,13 @@ exports.default = ErrorFilter;
/***/ }),
-/* 657 */
+/* 656 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const utils = __webpack_require__(598);
+const utils = __webpack_require__(597);
class EntryTransformer {
constructor(_settings) {
this._settings = _settings;
@@ -75552,15 +75547,15 @@ exports.default = EntryTransformer;
/***/ }),
-/* 658 */
+/* 657 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = __webpack_require__(27);
-const stream_2 = __webpack_require__(626);
-const provider_1 = __webpack_require__(653);
+const stream_2 = __webpack_require__(625);
+const provider_1 = __webpack_require__(652);
class ProviderStream extends provider_1.default {
constructor() {
super(...arguments);
@@ -75588,14 +75583,14 @@ exports.default = ProviderStream;
/***/ }),
-/* 659 */
+/* 658 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const sync_1 = __webpack_require__(660);
-const provider_1 = __webpack_require__(653);
+const sync_1 = __webpack_require__(659);
+const provider_1 = __webpack_require__(652);
class ProviderSync extends provider_1.default {
constructor() {
super(...arguments);
@@ -75618,15 +75613,15 @@ exports.default = ProviderSync;
/***/ }),
-/* 660 */
+/* 659 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-const fsStat = __webpack_require__(627);
-const fsWalk = __webpack_require__(632);
-const reader_1 = __webpack_require__(652);
+const fsStat = __webpack_require__(626);
+const fsWalk = __webpack_require__(631);
+const reader_1 = __webpack_require__(651);
class ReaderSync extends reader_1.default {
constructor() {
super(...arguments);
@@ -75668,7 +75663,7 @@ exports.default = ReaderSync;
/***/ }),
-/* 661 */
+/* 660 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -75728,13 +75723,13 @@ exports.default = Settings;
/***/ }),
-/* 662 */
+/* 661 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const path = __webpack_require__(16);
-const pathType = __webpack_require__(663);
+const pathType = __webpack_require__(662);
const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0];
@@ -75810,7 +75805,7 @@ module.exports.sync = (input, options) => {
/***/ }),
-/* 663 */
+/* 662 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -75860,7 +75855,7 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink');
/***/ }),
-/* 664 */
+/* 663 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -75868,9 +75863,9 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink');
const {promisify} = __webpack_require__(29);
const fs = __webpack_require__(23);
const path = __webpack_require__(16);
-const fastGlob = __webpack_require__(596);
-const gitIgnore = __webpack_require__(665);
-const slash = __webpack_require__(666);
+const fastGlob = __webpack_require__(595);
+const gitIgnore = __webpack_require__(664);
+const slash = __webpack_require__(665);
const DEFAULT_IGNORE = [
'**/node_modules/**',
@@ -75984,7 +75979,7 @@ module.exports.sync = options => {
/***/ }),
-/* 665 */
+/* 664 */
/***/ (function(module, exports) {
// A simple implementation of make-array
@@ -76575,7 +76570,7 @@ if (
/***/ }),
-/* 666 */
+/* 665 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -76593,7 +76588,7 @@ module.exports = path => {
/***/ }),
-/* 667 */
+/* 666 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -76646,7 +76641,7 @@ module.exports = {
/***/ }),
-/* 668 */
+/* 667 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -76668,7 +76663,7 @@ module.exports = path_ => {
/***/ }),
-/* 669 */
+/* 668 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -76696,7 +76691,7 @@ module.exports = (childPath, parentPath) => {
/***/ }),
-/* 670 */
+/* 669 */
/***/ (function(module, exports, __webpack_require__) {
const assert = __webpack_require__(30)
@@ -76704,7 +76699,7 @@ const path = __webpack_require__(16)
const fs = __webpack_require__(23)
let glob = undefined
try {
- glob = __webpack_require__(591)
+ glob = __webpack_require__(590)
} catch (_err) {
// treat glob as optional.
}
@@ -77070,12 +77065,12 @@ rimraf.sync = rimrafSync
/***/ }),
-/* 671 */
+/* 670 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const AggregateError = __webpack_require__(672);
+const AggregateError = __webpack_require__(671);
module.exports = async (
iterable,
@@ -77158,13 +77153,13 @@ module.exports = async (
/***/ }),
-/* 672 */
+/* 671 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const indentString = __webpack_require__(673);
-const cleanStack = __webpack_require__(674);
+const indentString = __webpack_require__(672);
+const cleanStack = __webpack_require__(673);
const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, '');
@@ -77212,7 +77207,7 @@ module.exports = AggregateError;
/***/ }),
-/* 673 */
+/* 672 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -77254,7 +77249,7 @@ module.exports = (string, count = 1, options) => {
/***/ }),
-/* 674 */
+/* 673 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -77301,15 +77296,15 @@ module.exports = (stack, options) => {
/***/ }),
-/* 675 */
+/* 674 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const chalk = __webpack_require__(676);
-const cliCursor = __webpack_require__(680);
-const cliSpinners = __webpack_require__(684);
-const logSymbols = __webpack_require__(565);
+const chalk = __webpack_require__(675);
+const cliCursor = __webpack_require__(679);
+const cliSpinners = __webpack_require__(683);
+const logSymbols = __webpack_require__(564);
class Ora {
constructor(options) {
@@ -77456,16 +77451,16 @@ module.exports.promise = (action, options) => {
/***/ }),
-/* 676 */
+/* 675 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
const escapeStringRegexp = __webpack_require__(3);
-const ansiStyles = __webpack_require__(677);
-const stdoutColor = __webpack_require__(678).stdout;
+const ansiStyles = __webpack_require__(676);
+const stdoutColor = __webpack_require__(677).stdout;
-const template = __webpack_require__(679);
+const template = __webpack_require__(678);
const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
@@ -77691,7 +77686,7 @@ module.exports.default = module.exports; // For TypeScript
/***/ }),
-/* 677 */
+/* 676 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -77864,7 +77859,7 @@ Object.defineProperty(module, 'exports', {
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(5)(module)))
/***/ }),
-/* 678 */
+/* 677 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78006,7 +78001,7 @@ module.exports = {
/***/ }),
-/* 679 */
+/* 678 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78141,12 +78136,12 @@ module.exports = (chalk, tmp) => {
/***/ }),
-/* 680 */
+/* 679 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const restoreCursor = __webpack_require__(681);
+const restoreCursor = __webpack_require__(680);
let hidden = false;
@@ -78187,12 +78182,12 @@ exports.toggle = (force, stream) => {
/***/ }),
-/* 681 */
+/* 680 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const onetime = __webpack_require__(682);
+const onetime = __webpack_require__(681);
const signalExit = __webpack_require__(377);
module.exports = onetime(() => {
@@ -78203,12 +78198,12 @@ module.exports = onetime(() => {
/***/ }),
-/* 682 */
+/* 681 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const mimicFn = __webpack_require__(683);
+const mimicFn = __webpack_require__(682);
module.exports = (fn, opts) => {
// TODO: Remove this in v3
@@ -78249,7 +78244,7 @@ module.exports = (fn, opts) => {
/***/ }),
-/* 683 */
+/* 682 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78265,22 +78260,22 @@ module.exports = (to, from) => {
/***/ }),
-/* 684 */
+/* 683 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-module.exports = __webpack_require__(685);
+module.exports = __webpack_require__(684);
/***/ }),
-/* 685 */
+/* 684 */
/***/ (function(module) {
module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}");
/***/ }),
-/* 686 */
+/* 685 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -78289,8 +78284,8 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34);
-/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500);
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(501);
+/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(499);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(500);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -78340,7 +78335,7 @@ const RunCommand = {
};
/***/ }),
-/* 687 */
+/* 686 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -78349,9 +78344,9 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34);
-/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(500);
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(501);
-/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(688);
+/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(499);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(500);
+/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(687);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -78435,13 +78430,13 @@ const WatchCommand = {
};
/***/ }),
-/* 688 */
+/* 687 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; });
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(392);
+/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(391);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(169);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
@@ -78509,7 +78504,7 @@ function waitUntilWatchIsReady(stream, opts = {}) {
}
/***/ }),
-/* 689 */
+/* 688 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -78517,15 +78512,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runCommand", function() { return runCommand; });
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(690);
+/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(689);
/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(indent_string__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(691);
+/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(690);
/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(wrap_ansi__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(515);
+/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(514);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(34);
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(501);
-/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(698);
-/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(699);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(500);
+/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(697);
+/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(698);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -78613,7 +78608,7 @@ function toArray(value) {
}
/***/ }),
-/* 690 */
+/* 689 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78647,13 +78642,13 @@ module.exports = (str, count, opts) => {
/***/ }),
-/* 691 */
+/* 690 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const stringWidth = __webpack_require__(692);
-const stripAnsi = __webpack_require__(696);
+const stringWidth = __webpack_require__(691);
+const stripAnsi = __webpack_require__(695);
const ESCAPES = new Set([
'\u001B',
@@ -78847,13 +78842,13 @@ module.exports = (str, cols, opts) => {
/***/ }),
-/* 692 */
+/* 691 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const stripAnsi = __webpack_require__(693);
-const isFullwidthCodePoint = __webpack_require__(695);
+const stripAnsi = __webpack_require__(692);
+const isFullwidthCodePoint = __webpack_require__(694);
module.exports = str => {
if (typeof str !== 'string' || str.length === 0) {
@@ -78890,18 +78885,18 @@ module.exports = str => {
/***/ }),
-/* 693 */
+/* 692 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const ansiRegex = __webpack_require__(694);
+const ansiRegex = __webpack_require__(693);
module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input;
/***/ }),
-/* 694 */
+/* 693 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78918,7 +78913,7 @@ module.exports = () => {
/***/ }),
-/* 695 */
+/* 694 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78971,18 +78966,18 @@ module.exports = x => {
/***/ }),
-/* 696 */
+/* 695 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const ansiRegex = __webpack_require__(697);
+const ansiRegex = __webpack_require__(696);
module.exports = input => typeof input === 'string' ? input.replace(ansiRegex(), '') : input;
/***/ }),
-/* 697 */
+/* 696 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -78999,7 +78994,7 @@ module.exports = () => {
/***/ }),
-/* 698 */
+/* 697 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -79152,7 +79147,7 @@ function addProjectToTree(tree, pathParts, project) {
}
/***/ }),
-/* 699 */
+/* 698 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -79160,10 +79155,12 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; });
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(700);
+/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(699);
/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501);
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579);
+/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(703);
+/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(500);
+/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(578);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -79192,6 +79189,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
+
/**
* Helper class for dealing with a set of projects as children of
* the Kibana project. The kbn/pm is currently implemented to be
@@ -79206,7 +79204,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
class Kibana {
static async loadFrom(rootPath) {
- return new Kibana((await Object(_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({
+ return new Kibana((await Object(_projects__WEBPACK_IMPORTED_MODULE_3__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_4__["getProjectPaths"])({
rootPath
}))));
}
@@ -79265,7 +79263,7 @@ class Kibana {
getProjectAndDeps(name) {
const project = this.getProject(name);
- return Object(_projects__WEBPACK_IMPORTED_MODULE_2__["includeTransitiveProjects"])([project], this.allWorkspaceProjects);
+ return Object(_projects__WEBPACK_IMPORTED_MODULE_3__["includeTransitiveProjects"])([project], this.allWorkspaceProjects);
}
/** filter the projects to just those matching certain paths/include/exclude tags */
@@ -79274,7 +79272,7 @@ class Kibana {
const allProjects = this.getAllProjects();
const filteredProjects = new Map();
const pkgJsonPaths = Array.from(allProjects.values()).map(p => p.packageJsonLocation);
- const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])(_objectSpread({}, options, {
+ const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_4__["getProjectPaths"])(_objectSpread({}, options, {
rootPath: this.kibanaProject.path
})).map(g => path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(g, 'package.json'));
const matchingPkgJsonPaths = multimatch__WEBPACK_IMPORTED_MODULE_1___default()(pkgJsonPaths, filteredPkgJsonGlobs);
@@ -79292,18 +79290,26 @@ class Kibana {
return filteredProjects;
}
+ isPartOfRepo(project) {
+ return project.path === this.kibanaProject.path || is_path_inside__WEBPACK_IMPORTED_MODULE_2___default()(project.path, this.kibanaProject.path);
+ }
+
+ isOutsideRepo(project) {
+ return !this.isPartOfRepo(project);
+ }
+
}
/***/ }),
-/* 700 */
+/* 699 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-const minimatch = __webpack_require__(505);
-const arrayUnion = __webpack_require__(701);
-const arrayDiffer = __webpack_require__(702);
-const arrify = __webpack_require__(703);
+const minimatch = __webpack_require__(504);
+const arrayUnion = __webpack_require__(700);
+const arrayDiffer = __webpack_require__(701);
+const arrify = __webpack_require__(702);
module.exports = (list, patterns, options = {}) => {
list = arrify(list);
@@ -79327,7 +79333,7 @@ module.exports = (list, patterns, options = {}) => {
/***/ }),
-/* 701 */
+/* 700 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -79339,7 +79345,7 @@ module.exports = (...arguments_) => {
/***/ }),
-/* 702 */
+/* 701 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -79354,7 +79360,7 @@ module.exports = arrayDiffer;
/***/ }),
-/* 703 */
+/* 702 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
@@ -79383,6 +79389,34 @@ const arrify = value => {
module.exports = arrify;
+/***/ }),
+/* 703 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+const path = __webpack_require__(16);
+
+module.exports = (childPath, parentPath) => {
+ childPath = path.resolve(childPath);
+ parentPath = path.resolve(parentPath);
+
+ if (process.platform === 'win32') {
+ childPath = childPath.toLowerCase();
+ parentPath = parentPath.toLowerCase();
+ }
+
+ if (childPath === parentPath) {
+ return false;
+ }
+
+ childPath += path.sep;
+ parentPath += path.sep;
+
+ return childPath.startsWith(parentPath);
+};
+
+
/***/ }),
/* 704 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
@@ -79425,15 +79459,15 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; });
/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(706);
/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(587);
+/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(586);
/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579);
+/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(578);
/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20);
/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34);
-/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(517);
-/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(501);
+/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(516);
+/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(500);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
@@ -79576,7 +79610,7 @@ const os = __webpack_require__(11);
const pAll = __webpack_require__(707);
const arrify = __webpack_require__(709);
const globby = __webpack_require__(710);
-const isGlob = __webpack_require__(605);
+const isGlob = __webpack_require__(604);
const cpFile = __webpack_require__(913);
const junk = __webpack_require__(925);
const CpyError = __webpack_require__(926);
@@ -80103,26 +80137,26 @@ if ('Set' in global) {
module.exports = glob
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
var inherits = __webpack_require__(714)
var EE = __webpack_require__(379).EventEmitter
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
+var isAbsolute = __webpack_require__(510)
var globSync = __webpack_require__(716)
var common = __webpack_require__(717)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
-var inflight = __webpack_require__(514)
+var inflight = __webpack_require__(513)
var util = __webpack_require__(29)
var childrenIgnored = common.childrenIgnored
var isIgnored = common.isIgnored
-var once = __webpack_require__(385)
+var once = __webpack_require__(384)
function glob (pattern, options, cb) {
if (typeof options === 'function') cb = options, options = {}
@@ -80908,14 +80942,14 @@ module.exports = globSync
globSync.GlobSync = GlobSync
var fs = __webpack_require__(23)
-var rp = __webpack_require__(503)
-var minimatch = __webpack_require__(505)
+var rp = __webpack_require__(502)
+var minimatch = __webpack_require__(504)
var Minimatch = minimatch.Minimatch
var Glob = __webpack_require__(713).Glob
var util = __webpack_require__(29)
var path = __webpack_require__(16)
var assert = __webpack_require__(30)
-var isAbsolute = __webpack_require__(511)
+var isAbsolute = __webpack_require__(510)
var common = __webpack_require__(717)
var alphasort = common.alphasort
var alphasorti = common.alphasorti
@@ -81411,8 +81445,8 @@ function ownProp (obj, field) {
}
var path = __webpack_require__(16)
-var minimatch = __webpack_require__(505)
-var isAbsolute = __webpack_require__(511)
+var minimatch = __webpack_require__(504)
+var isAbsolute = __webpack_require__(510)
var Minimatch = minimatch.Minimatch
function alphasorti (a, b) {
@@ -82064,7 +82098,7 @@ module.exports = function globParent(str) {
* Licensed under the MIT License.
*/
-var isExtglob = __webpack_require__(606);
+var isExtglob = __webpack_require__(605);
module.exports = function isGlob(str) {
if (typeof str !== 'string' || str === '') {
@@ -82245,7 +82279,7 @@ module.exports.win32 = win32;
* Released under the MIT License.
*/
-var isExtglob = __webpack_require__(606);
+var isExtglob = __webpack_require__(605);
var chars = { '{': '}', '(': ')', '[': ']'};
module.exports = function isGlob(str, options) {
@@ -92518,7 +92552,7 @@ function plural(ms, n, name) {
* Module dependencies.
*/
-var tty = __webpack_require__(480);
+var tty = __webpack_require__(479);
var util = __webpack_require__(29);
/**
@@ -96237,7 +96271,7 @@ void (function(root, factory) {
// Copyright 2014 Simon Lydell
// X11 (“MIT”) Licensed. (See LICENSE.)
-var url = __webpack_require__(454)
+var url = __webpack_require__(453)
function resolveUrl(/* ...urls */) {
return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) {
@@ -102525,7 +102559,7 @@ function plural(ms, n, name) {
* Module dependencies.
*/
-var tty = __webpack_require__(480);
+var tty = __webpack_require__(479);
var util = __webpack_require__(29);
/**
@@ -105778,7 +105812,7 @@ exports.flatten = flatten;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
-var merge2 = __webpack_require__(590);
+var merge2 = __webpack_require__(589);
/**
* Merge multiple streams and propagate their errors into one stream in parallel.
*/
@@ -109316,8 +109350,8 @@ module.exports = NestedError;
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return prepareExternalProjectDependencies; });
-/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(517);
-/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(516);
+/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(516);
+/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(515);
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json
index 444d46307b059..a236db9eee18a 100644
--- a/packages/kbn-pm/package.json
+++ b/packages/kbn-pm/package.json
@@ -26,7 +26,7 @@
"@types/lodash.clonedeepwith": "^4.5.3",
"@types/log-symbols": "^2.0.0",
"@types/ncp": "^2.0.1",
- "@types/node": "^10.12.27",
+ "@types/node": ">=10.17.17 <10.20.0",
"@types/ora": "^1.3.5",
"@types/read-pkg": "^4.0.0",
"@types/strip-ansi": "^3.0.0",
@@ -42,12 +42,13 @@
"cpy": "^8.0.0",
"dedent": "^0.7.0",
"del": "^5.1.0",
- "execa": "^3.2.0",
+ "execa": "^4.0.0",
"getopts": "^2.2.4",
"glob": "^7.1.2",
"globby": "^8.0.1",
"has-ansi": "^3.0.0",
"indent-string": "^3.2.0",
+ "is-path-inside": "^3.0.2",
"lodash.clonedeepwith": "^4.5.0",
"log-symbols": "^2.2.0",
"multimatch": "^4.0.0",
diff --git a/packages/kbn-pm/src/config.ts b/packages/kbn-pm/src/config.ts
index 6ba8d58a26f88..59b43b230e603 100644
--- a/packages/kbn-pm/src/config.ts
+++ b/packages/kbn-pm/src/config.ts
@@ -48,6 +48,7 @@ export function getProjectPaths({ rootPath, ossOnly, skipKibanaPlugins }: Option
projectPaths.push(resolve(rootPath, 'x-pack'));
projectPaths.push(resolve(rootPath, 'x-pack/plugins/*'));
projectPaths.push(resolve(rootPath, 'x-pack/legacy/plugins/*'));
+ projectPaths.push(resolve(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*'));
}
if (!skipKibanaPlugins) {
diff --git a/packages/kbn-pm/src/utils/kibana.ts b/packages/kbn-pm/src/utils/kibana.ts
index 36f697d19fc1f..58af98b2a92db 100644
--- a/packages/kbn-pm/src/utils/kibana.ts
+++ b/packages/kbn-pm/src/utils/kibana.ts
@@ -20,6 +20,7 @@
import Path from 'path';
import multimatch from 'multimatch';
+import isPathInside from 'is-path-inside';
import { ProjectMap, getProjects, includeTransitiveProjects } from './projects';
import { Project } from './project';
@@ -121,4 +122,15 @@ export class Kibana {
return filteredProjects;
}
+
+ isPartOfRepo(project: Project) {
+ return (
+ project.path === this.kibanaProject.path ||
+ isPathInside(project.path, this.kibanaProject.path)
+ );
+ }
+
+ isOutsideRepo(project: Project) {
+ return !this.isPartOfRepo(project);
+ }
}
diff --git a/packages/kbn-pm/src/utils/project_checksums.ts b/packages/kbn-pm/src/utils/project_checksums.ts
index 2fd24c8fc9577..572f2adb19bd9 100644
--- a/packages/kbn-pm/src/utils/project_checksums.ts
+++ b/packages/kbn-pm/src/utils/project_checksums.ts
@@ -43,7 +43,14 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too
const { stdout } = await execa(
'git',
- ['ls-files', '-dmt', '--', ...Array.from(projects.values()).map(p => p.path)],
+ [
+ 'ls-files',
+ '-dmt',
+ '--',
+ ...Array.from(projects.values())
+ .filter(p => kbn.isPartOfRepo(p))
+ .map(p => p.path),
+ ],
{
cwd: kbn.getAbsolute(),
}
@@ -84,9 +91,14 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too
}
const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter);
- const changesByProject = new Map();
+ const changesByProject = new Map();
for (const project of sortedRelevantProjects) {
+ if (kbn.isOutsideRepo(project)) {
+ changesByProject.set(project, undefined);
+ continue;
+ }
+
const ownChanges: Changes = new Map();
const prefix = kbn.getRelative(project.path);
@@ -114,6 +126,10 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too
/** Get the latest commit sha for a project */
async function getLatestSha(project: Project, kbn: Kibana) {
+ if (kbn.isOutsideRepo(project)) {
+ return;
+ }
+
const { stdout } = await execa(
'git',
['log', '-n', '1', '--pretty=format:%H', '--', project.path],
@@ -175,7 +191,7 @@ function resolveDepsForProject(project: Project, yarnLock: YarnLock, kbn: Kibana
*/
async function getChecksum(
project: Project,
- changes: Changes,
+ changes: Changes | undefined,
yarnLock: YarnLock,
kbn: Kibana,
log: ToolingLog
@@ -185,7 +201,7 @@ async function getChecksum(
log.verbose(`[${project.name}] local sha:`, sha);
}
- if (Array.from(changes.values()).includes('invalid')) {
+ if (!changes || Array.from(changes.values()).includes('invalid')) {
log.warning(`[${project.name}] unable to determine local changes, caching disabled`);
return;
}
@@ -248,7 +264,7 @@ export async function getAllChecksums(kbn: Kibana, log: ToolingLog) {
Array.from(projects.values()).map(async project => {
cacheKeys.set(
project.name,
- await getChecksum(project, changesByProject.get(project)!, yarnLock, kbn, log)
+ await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log)
);
})
);
diff --git a/packages/kbn-storybook/package.json b/packages/kbn-storybook/package.json
index 73deadba0a619..0b38554f7806c 100644
--- a/packages/kbn-storybook/package.json
+++ b/packages/kbn-storybook/package.json
@@ -15,7 +15,6 @@
"@storybook/react": "^5.2.8",
"@storybook/theming": "^5.2.8",
"copy-webpack-plugin": "5.0.3",
- "execa": "1.0.0",
"fast-glob": "2.2.7",
"glob-watcher": "5.0.3",
"jest-specific-snapshot": "2.0.0",
diff --git a/packages/kbn-test/src/functional_test_runner/cli.ts b/packages/kbn-test/src/functional_test_runner/cli.ts
index 11b9450f2af6e..276a51c3a6a99 100644
--- a/packages/kbn-test/src/functional_test_runner/cli.ts
+++ b/packages/kbn-test/src/functional_test_runner/cli.ts
@@ -18,6 +18,7 @@
*/
import { resolve } from 'path';
+import { inspect } from 'util';
import { run, createFlagError, Flags } from '@kbn/dev-utils';
import { FunctionalTestRunner } from './functional_test_runner';
@@ -48,12 +49,15 @@ export function runFtrCli() {
kbnTestServer: {
installDir: parseInstallDir(flags),
},
+ suiteFiles: {
+ include: toArray(flags.include as string | string[]).map(makeAbsolutePath),
+ exclude: toArray(flags.exclude as string | string[]).map(makeAbsolutePath),
+ },
suiteTags: {
include: toArray(flags['include-tag'] as string | string[]),
exclude: toArray(flags['exclude-tag'] as string | string[]),
},
updateBaselines: flags.updateBaselines,
- excludeTestFiles: flags.exclude || undefined,
}
);
@@ -83,7 +87,11 @@ export function runFtrCli() {
}
};
- process.on('unhandledRejection', err => teardown(err));
+ process.on('unhandledRejection', err =>
+ teardown(
+ err instanceof Error ? err : new Error(`non-Error type rejection value: ${inspect(err)}`)
+ )
+ );
process.on('SIGTERM', () => teardown());
process.on('SIGINT', () => teardown());
@@ -104,7 +112,15 @@ export function runFtrCli() {
},
{
flags: {
- string: ['config', 'grep', 'exclude', 'include-tag', 'exclude-tag', 'kibana-install-dir'],
+ string: [
+ 'config',
+ 'grep',
+ 'include',
+ 'exclude',
+ 'include-tag',
+ 'exclude-tag',
+ 'kibana-install-dir',
+ ],
boolean: ['bail', 'invert', 'test-stats', 'updateBaselines', 'throttle', 'headless'],
default: {
config: 'test/functional/config.js',
@@ -115,7 +131,8 @@ export function runFtrCli() {
--bail stop tests after the first failure
--grep pattern used to select which tests to run
--invert invert grep to exclude tests
- --exclude=file path to a test file that should not be loaded
+ --include=file a test file to be included, pass multiple times for multiple files
+ --exclude=file a test file to be excluded, pass multiple times for multiple files
--include-tag=tag a tag to be included, pass multiple times for multiple tags
--exclude-tag=tag a tag to be excluded, pass multiple times for multiple tags
--test-stats print the number of tests (included and excluded) to STDERR
diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts
index 75623d6c08890..66f17ab579ec3 100644
--- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts
+++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts
@@ -64,9 +64,16 @@ export const schema = Joi.object()
testFiles: Joi.array().items(Joi.string()),
testRunner: Joi.func(),
- excludeTestFiles: Joi.array()
- .items(Joi.string())
- .default([]),
+ suiteFiles: Joi.object()
+ .keys({
+ include: Joi.array()
+ .items(Joi.string())
+ .default([]),
+ exclude: Joi.array()
+ .items(Joi.string())
+ .default([]),
+ })
+ .default(),
suiteTags: Joi.object()
.keys({
@@ -248,5 +255,20 @@ export const schema = Joi.object()
fixedHeaderHeight: Joi.number().default(50),
})
.default(),
+
+ // settings for the security service if there is no defaultRole defined, then default to superuser role.
+ security: Joi.object()
+ .keys({
+ roles: Joi.object().default(),
+ defaultRoles: Joi.array()
+ .items(Joi.string())
+ .when('$primary', {
+ is: true,
+ then: Joi.array().min(1),
+ })
+ .default(['superuser']),
+ disableTestUser: Joi.boolean(),
+ })
+ .default(),
})
.default();
diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/decorate_mocha_ui.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/decorate_mocha_ui.js
index 64fc51a04aac9..1cac852a7e713 100644
--- a/packages/kbn-test/src/functional_test_runner/lib/mocha/decorate_mocha_ui.js
+++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/decorate_mocha_ui.js
@@ -16,7 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+import { relative } from 'path';
+import { REPO_ROOT } from '@kbn/dev-utils';
import { createAssignmentProxy } from './assignment_proxy';
import { wrapFunction } from './wrap_function';
import { wrapRunnableArgs } from './wrap_runnable_args';
@@ -65,6 +66,10 @@ export function decorateMochaUi(lifecycle, context) {
this._tags = [].concat(this._tags || [], tags);
};
+ const relativeFilePath = relative(REPO_ROOT, this.file);
+ this.tags(relativeFilePath);
+ this.suiteTag = relativeFilePath; // The tag that uniquely targets this suite/file
+
provider.call(this);
after(async () => {
diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js
index 70b0c0874e5e9..6ee65b1b7e394 100644
--- a/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js
+++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js
@@ -31,28 +31,12 @@ import { decorateMochaUi } from './decorate_mocha_ui';
* @param {String} path
* @return {undefined} - mutates mocha, no return value
*/
-export const loadTestFiles = ({
- mocha,
- log,
- lifecycle,
- providers,
- paths,
- excludePaths,
- updateBaselines,
-}) => {
- const pendingExcludes = new Set(excludePaths.slice(0));
-
+export const loadTestFiles = ({ mocha, log, lifecycle, providers, paths, updateBaselines }) => {
const innerLoadTestFile = path => {
if (typeof path !== 'string' || !isAbsolute(path)) {
throw new TypeError('loadTestFile() only accepts absolute paths');
}
- if (pendingExcludes.has(path)) {
- pendingExcludes.delete(path);
- log.warning('Skipping test file %s', path);
- return;
- }
-
loadTracer(path, `testFile[${path}]`, () => {
log.verbose('Loading test file %s', path);
@@ -94,13 +78,4 @@ export const loadTestFiles = ({
};
paths.forEach(innerLoadTestFile);
-
- if (pendingExcludes.size) {
- throw new Error(
- `After loading all test files some exclude paths were not consumed:${[
- '',
- ...pendingExcludes,
- ].join('\n -')}`
- );
- }
};
diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js
index 326877919d985..61851cece0e8f 100644
--- a/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js
+++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js
@@ -18,6 +18,8 @@
*/
import Mocha from 'mocha';
+import { relative } from 'path';
+import { REPO_ROOT } from '@kbn/dev-utils';
import { loadTestFiles } from './load_test_files';
import { filterSuitesByTags } from './filter_suites_by_tags';
@@ -50,10 +52,20 @@ export async function setupMocha(lifecycle, log, config, providers) {
lifecycle,
providers,
paths: config.get('testFiles'),
- excludePaths: config.get('excludeTestFiles'),
updateBaselines: config.get('updateBaselines'),
});
+ // Each suite has a tag that is the path relative to the root of the repo
+ // So we just need to take input paths, make them relative to the root, and use them as tags
+ // Also, this is a separate filterSuitesByTags() call so that the test suites will be filtered first by
+ // files, then by tags. This way, you can target tags (like smoke) in a specific file.
+ filterSuitesByTags({
+ log,
+ mocha,
+ include: config.get('suiteFiles.include').map(file => relative(REPO_ROOT, file)),
+ exclude: config.get('suiteFiles.exclude').map(file => relative(REPO_ROOT, file)),
+ });
+
filterSuitesByTags({
log,
mocha,
diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap b/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap
index bbf8b38712ac1..434c374d5d23d 100644
--- a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap
+++ b/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap
@@ -16,6 +16,8 @@ Options:
--bail Stop the test run at the first failure.
--grep Pattern to select which tests to run.
--updateBaselines Replace baseline screenshots with whatever is generated from the test.
+ --include Files that must included to be run, can be included multiple times.
+ --exclude Files that must NOT be included to be run, can be included multiple times.
--include-tag Tags that suites must include to be run, can be included multiple times.
--exclude-tag Tags that suites must NOT include to be run, can be included multiple times.
--assert-none-excluded Exit with 1/0 based on if any test is excluded with the current set of tags.
@@ -34,6 +36,10 @@ Object {
"createLogger": [Function],
"esFrom": "snapshot",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -52,6 +58,10 @@ Object {
"debug": true,
"esFrom": "snapshot",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -69,6 +79,10 @@ Object {
"createLogger": [Function],
"esFrom": "snapshot",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -90,6 +104,10 @@ Object {
"extraKbnOpts": Object {
"server.foo": "bar",
},
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -107,6 +125,10 @@ Object {
"esFrom": "snapshot",
"extraKbnOpts": undefined,
"quiet": true,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -124,6 +146,10 @@ Object {
"esFrom": "snapshot",
"extraKbnOpts": undefined,
"silent": true,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -140,6 +166,10 @@ Object {
"createLogger": [Function],
"esFrom": "source",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -156,6 +186,10 @@ Object {
"createLogger": [Function],
"esFrom": "source",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -173,6 +207,10 @@ Object {
"esFrom": "snapshot",
"extraKbnOpts": undefined,
"installDir": "foo",
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -190,6 +228,10 @@ Object {
"esFrom": "snapshot",
"extraKbnOpts": undefined,
"grep": "management",
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -206,6 +248,10 @@ Object {
"createLogger": [Function],
"esFrom": "snapshot",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
@@ -223,6 +269,10 @@ Object {
"createLogger": [Function],
"esFrom": "snapshot",
"extraKbnOpts": undefined,
+ "suiteFiles": Object {
+ "exclude": Array [],
+ "include": Array [],
+ },
"suiteTags": Object {
"exclude": Array [],
"include": Array [],
diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/cli.test.js.snap b/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/cli.test.js.snap
index b12739b3b5df5..6ede71a6c3940 100644
--- a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/cli.test.js.snap
+++ b/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/cli.test.js.snap
@@ -16,6 +16,8 @@ Options:
--bail Stop the test run at the first failure.
--grep Pattern to select which tests to run.
--updateBaselines Replace baseline screenshots with whatever is generated from the test.
+ --include Files that must included to be run, can be included multiple times.
+ --exclude Files that must NOT be included to be run, can be included multiple times.
--include-tag Tags that suites must include to be run, can be included multiple times.
--exclude-tag Tags that suites must NOT include to be run, can be included multiple times.
--assert-none-excluded Exit with 1/0 based on if any test is excluded with the current set of tags.
diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/args.js b/packages/kbn-test/src/functional_tests/cli/run_tests/args.js
index b34006a38a45d..7d2414305de8e 100644
--- a/packages/kbn-test/src/functional_tests/cli/run_tests/args.js
+++ b/packages/kbn-test/src/functional_tests/cli/run_tests/args.js
@@ -46,6 +46,14 @@ const options = {
updateBaselines: {
desc: 'Replace baseline screenshots with whatever is generated from the test.',
},
+ include: {
+ arg: '',
+ desc: 'Files that must included to be run, can be included multiple times.',
+ },
+ exclude: {
+ arg: '',
+ desc: 'Files that must NOT be included to be run, can be included multiple times.',
+ },
'include-tag': {
arg: '',
desc: 'Tags that suites must include to be run, can be included multiple times.',
@@ -115,6 +123,13 @@ export function processOptions(userOptions, defaultConfigPaths) {
delete userOptions['kibana-install-dir'];
}
+ userOptions.suiteFiles = {
+ include: [].concat(userOptions.include || []),
+ exclude: [].concat(userOptions.exclude || []),
+ };
+ delete userOptions.include;
+ delete userOptions.exclude;
+
userOptions.suiteTags = {
include: [].concat(userOptions['include-tag'] || []),
exclude: [].concat(userOptions['exclude-tag'] || []),
diff --git a/packages/kbn-test/src/functional_tests/lib/run_ftr.js b/packages/kbn-test/src/functional_tests/lib/run_ftr.js
index 9b631e33f3b24..14883ac977c43 100644
--- a/packages/kbn-test/src/functional_tests/lib/run_ftr.js
+++ b/packages/kbn-test/src/functional_tests/lib/run_ftr.js
@@ -22,7 +22,7 @@ import { CliError } from './run_cli';
async function createFtr({
configPath,
- options: { installDir, log, bail, grep, updateBaselines, suiteTags },
+ options: { installDir, log, bail, grep, updateBaselines, suiteFiles, suiteTags },
}) {
const config = await readConfigFile(log, configPath);
@@ -37,6 +37,10 @@ async function createFtr({
installDir,
},
updateBaselines,
+ suiteFiles: {
+ include: [...suiteFiles.include, ...config.get('suiteFiles.include')],
+ exclude: [...suiteFiles.exclude, ...config.get('suiteFiles.exclude')],
+ },
suiteTags: {
include: [...suiteTags.include, ...config.get('suiteTags.include')],
exclude: [...suiteTags.exclude, ...config.get('suiteTags.exclude')],
diff --git a/packages/kbn-test/src/mocha/__tests__/junit_report_generation.js b/packages/kbn-test/src/mocha/__tests__/junit_report_generation.js
index 7472e271bd1e9..6edd0a551ebd0 100644
--- a/packages/kbn-test/src/mocha/__tests__/junit_report_generation.js
+++ b/packages/kbn-test/src/mocha/__tests__/junit_report_generation.js
@@ -129,7 +129,7 @@ describe('dev/mocha/junit report generation', () => {
name: 'SUITE SUB_SUITE never runs',
'metadata-json': '{}',
},
- 'system-out': testFail['system-out'],
+ 'system-out': ['-- logs are only reported for failed tests --'],
skipped: [''],
});
});
diff --git a/packages/kbn-test/src/mocha/junit_report_generation.js b/packages/kbn-test/src/mocha/junit_report_generation.js
index 95e84117106a4..b56741b48d367 100644
--- a/packages/kbn-test/src/mocha/junit_report_generation.js
+++ b/packages/kbn-test/src/mocha/junit_report_generation.js
@@ -126,13 +126,15 @@ export function setupJUnitReportGeneration(runner, options = {}) {
[...results, ...skippedResults].forEach(result => {
const el = addTestcaseEl(result.node);
- el.ele('system-out').dat(escapeCdata(getSnapshotOfRunnableLogs(result.node) || ''));
if (result.failed) {
+ el.ele('system-out').dat(escapeCdata(getSnapshotOfRunnableLogs(result.node) || ''));
el.ele('failure').dat(escapeCdata(inspect(result.error)));
return;
}
+ el.ele('system-out').dat('-- logs are only reported for failed tests --');
+
if (result.skipped) {
el.ele('skipped');
}
diff --git a/src/core/public/chrome/chrome_service.mock.ts b/src/core/public/chrome/chrome_service.mock.ts
index bd932c5961eca..89007461b63e6 100644
--- a/src/core/public/chrome/chrome_service.mock.ts
+++ b/src/core/public/chrome/chrome_service.mock.ts
@@ -61,8 +61,6 @@ const createStartContractMock = () => {
getBrand$: jest.fn(),
setIsVisible: jest.fn(),
getIsVisible$: jest.fn(),
- setIsCollapsed: jest.fn(),
- getIsCollapsed$: jest.fn(),
addApplicationClass: jest.fn(),
removeApplicationClass: jest.fn(),
getApplicationClasses$: jest.fn(),
@@ -73,15 +71,16 @@ const createStartContractMock = () => {
getHelpExtension$: jest.fn(),
setHelpExtension: jest.fn(),
setHelpSupportUrl: jest.fn(),
+ getIsNavDrawerLocked$: jest.fn(),
};
startContract.navLinks.getAll.mockReturnValue([]);
startContract.getBrand$.mockReturnValue(new BehaviorSubject({} as ChromeBrand));
startContract.getIsVisible$.mockReturnValue(new BehaviorSubject(false));
- startContract.getIsCollapsed$.mockReturnValue(new BehaviorSubject(false));
startContract.getApplicationClasses$.mockReturnValue(new BehaviorSubject(['class-name']));
startContract.getBadge$.mockReturnValue(new BehaviorSubject({} as ChromeBadge));
startContract.getBreadcrumbs$.mockReturnValue(new BehaviorSubject([{} as ChromeBreadcrumb]));
startContract.getHelpExtension$.mockReturnValue(new BehaviorSubject(undefined));
+ startContract.getIsNavDrawerLocked$.mockReturnValue(new BehaviorSubject(false));
return startContract;
};
diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts
index 9018b21973634..bf531aaa00fac 100644
--- a/src/core/public/chrome/chrome_service.test.ts
+++ b/src/core/public/chrome/chrome_service.test.ts
@@ -259,40 +259,6 @@ describe('start', () => {
});
});
- describe('is collapsed', () => {
- it('updates/emits isCollapsed', async () => {
- const { chrome, service } = await start();
- const promise = chrome
- .getIsCollapsed$()
- .pipe(toArray())
- .toPromise();
-
- chrome.setIsCollapsed(true);
- chrome.setIsCollapsed(false);
- chrome.setIsCollapsed(true);
- service.stop();
-
- await expect(promise).resolves.toMatchInlineSnapshot(`
- Array [
- false,
- true,
- false,
- true,
- ]
- `);
- });
-
- it('only stores true in localStorage', async () => {
- const { chrome } = await start();
-
- chrome.setIsCollapsed(true);
- expect(store.size).toBe(1);
-
- chrome.setIsCollapsed(false);
- expect(store.size).toBe(0);
- });
- });
-
describe('application classes', () => {
it('updates/emits the application classes', async () => {
const { chrome, service } = await start();
@@ -442,12 +408,12 @@ describe('start', () => {
});
describe('stop', () => {
- it('completes applicationClass$, isCollapsed$, breadcrumbs$, isVisible$, and brand$ observables', async () => {
+ it('completes applicationClass$, getIsNavDrawerLocked, breadcrumbs$, isVisible$, and brand$ observables', async () => {
const { chrome, service } = await start();
const promise = Rx.combineLatest(
chrome.getBrand$(),
chrome.getApplicationClasses$(),
- chrome.getIsCollapsed$(),
+ chrome.getIsNavDrawerLocked$(),
chrome.getBreadcrumbs$(),
chrome.getIsVisible$(),
chrome.getHelpExtension$()
@@ -465,7 +431,7 @@ describe('stop', () => {
Rx.combineLatest(
chrome.getBrand$(),
chrome.getApplicationClasses$(),
- chrome.getIsCollapsed$(),
+ chrome.getIsNavDrawerLocked$(),
chrome.getBreadcrumbs$(),
chrome.getIsVisible$(),
chrome.getHelpExtension$()
diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx
index 2b0b115ce068e..7c9b644b8b984 100644
--- a/src/core/public/chrome/chrome_service.tsx
+++ b/src/core/public/chrome/chrome_service.tsx
@@ -34,14 +34,14 @@ import { ChromeNavLinks, NavLinksService } from './nav_links';
import { ChromeRecentlyAccessed, RecentlyAccessedService } from './recently_accessed';
import { NavControlsService, ChromeNavControls } from './nav_controls';
import { DocTitleService, ChromeDocTitle } from './doc_title';
-import { LoadingIndicator, HeaderWrapper as Header } from './ui';
+import { LoadingIndicator, Header } from './ui';
import { DocLinksStart } from '../doc_links';
import { ChromeHelpExtensionMenuLink } from './ui/header/header_help_menu';
import { KIBANA_ASK_ELASTIC_LINK } from './constants';
import { IUiSettingsClient } from '../ui_settings';
export { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle };
-const IS_COLLAPSED_KEY = 'core.chrome.isCollapsed';
+const IS_LOCKED_KEY = 'core.chrome.isLocked';
/** @public */
export interface ChromeBadge {
@@ -146,18 +146,25 @@ export class ChromeService {
const appTitle$ = new BehaviorSubject('Kibana');
const brand$ = new BehaviorSubject({});
- const isCollapsed$ = new BehaviorSubject(!!localStorage.getItem(IS_COLLAPSED_KEY));
const applicationClasses$ = new BehaviorSubject>(new Set());
const helpExtension$ = new BehaviorSubject(undefined);
const breadcrumbs$ = new BehaviorSubject([]);
const badge$ = new BehaviorSubject(undefined);
const helpSupportUrl$ = new BehaviorSubject(KIBANA_ASK_ELASTIC_LINK);
+ const isNavDrawerLocked$ = new BehaviorSubject(localStorage.getItem(IS_LOCKED_KEY) === 'true');
const navControls = this.navControls.start();
const navLinks = this.navLinks.start({ application, http });
const recentlyAccessed = await this.recentlyAccessed.start({ http });
const docTitle = this.docTitle.start({ document: window.document });
+ const setIsNavDrawerLocked = (isLocked: boolean) => {
+ isNavDrawerLocked$.next(isLocked);
+ localStorage.setItem(IS_LOCKED_KEY, `${isLocked}`);
+ };
+
+ const getIsNavDrawerLocked$ = isNavDrawerLocked$.pipe(takeUntil(this.stop$));
+
if (!this.params.browserSupportsCsp && injectedMetadata.getCspConfig().warnLegacyBrowsers) {
notifications.toasts.addWarning(
i18n.translate('core.chrome.legacyBrowserWarning', {
@@ -193,6 +200,8 @@ export class ChromeService {
recentlyAccessed$={recentlyAccessed.get$()}
navControlsLeft$={navControls.getLeft$()}
navControlsRight$={navControls.getRight$()}
+ onIsLockedUpdate={setIsNavDrawerLocked}
+ isLocked$={getIsNavDrawerLocked$}
/>
),
@@ -214,17 +223,6 @@ export class ChromeService {
setIsVisible: (isVisible: boolean) => this.toggleHidden$.next(!isVisible),
- getIsCollapsed$: () => isCollapsed$.pipe(takeUntil(this.stop$)),
-
- setIsCollapsed: (isCollapsed: boolean) => {
- isCollapsed$.next(isCollapsed);
- if (isCollapsed) {
- localStorage.setItem(IS_COLLAPSED_KEY, 'true');
- } else {
- localStorage.removeItem(IS_COLLAPSED_KEY);
- }
- },
-
getApplicationClasses$: () =>
applicationClasses$.pipe(
map(set => [...set]),
@@ -262,6 +260,8 @@ export class ChromeService {
},
setHelpSupportUrl: (url: string) => helpSupportUrl$.next(url),
+
+ getIsNavDrawerLocked$: () => getIsNavDrawerLocked$,
};
}
@@ -353,16 +353,6 @@ export interface ChromeStart {
*/
setIsVisible(isVisible: boolean): void;
- /**
- * Get an observable of the current collapsed state of the chrome.
- */
- getIsCollapsed$(): Observable;
-
- /**
- * Set the collapsed state of the chrome navigation.
- */
- setIsCollapsed(isCollapsed: boolean): void;
-
/**
* Get the current set of classNames that will be set on the application container.
*/
@@ -413,6 +403,11 @@ export interface ChromeStart {
* @param url The updated support URL
*/
setHelpSupportUrl(url: string): void;
+
+ /**
+ * Get an observable of the current locked state of the nav drawer.
+ */
+ getIsNavDrawerLocked$(): Observable;
}
/** @internal */
diff --git a/src/core/public/chrome/ui/_loading_indicator.scss b/src/core/public/chrome/ui/_loading_indicator.scss
index 80694347393ce..026c23b93b040 100644
--- a/src/core/public/chrome/ui/_loading_indicator.scss
+++ b/src/core/public/chrome/ui/_loading_indicator.scss
@@ -22,29 +22,34 @@ $kbnLoadingIndicatorColor2: tint($euiColorAccent, 60%);
}
}
- .kbnLoadingIndicator__bar {
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- position: absolute;
- z-index: $euiZLevel1 + 1;
- visibility: visible;
- display: block;
- animation: kbn-animate-loading-indicator 2s linear infinite;
- background-color: $kbnLoadingIndicatorColor2;
- background-image: linear-gradient(to right,
- $kbnLoadingIndicatorColor1 0%,
- $kbnLoadingIndicatorColor1 50%,
- $kbnLoadingIndicatorColor2 50%,
- $kbnLoadingIndicatorColor2 100%
- );
- background-repeat: repeat-x;
- background-size: $kbnLoadingIndicatorBackgroundSize $kbnLoadingIndicatorBackgroundSize;
- width: 200%;
- }
+.kbnLoadingIndicator__bar {
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ position: absolute;
+ z-index: $euiZLevel1 + 1;
+ visibility: visible;
+ display: block;
+ animation: kbn-animate-loading-indicator 2s linear infinite;
+ background-color: $kbnLoadingIndicatorColor2;
+ background-image: linear-gradient(
+ to right,
+ $kbnLoadingIndicatorColor1 0%,
+ $kbnLoadingIndicatorColor1 50%,
+ $kbnLoadingIndicatorColor2 50%,
+ $kbnLoadingIndicatorColor2 100%
+ );
+ background-repeat: repeat-x;
+ background-size: $kbnLoadingIndicatorBackgroundSize $kbnLoadingIndicatorBackgroundSize;
+ width: 200%;
+}
- @keyframes kbn-animate-loading-indicator {
- from { transform: translateX(0); }
- to { transform: translateX(-$kbnLoadingIndicatorBackgroundSize); }
+@keyframes kbn-animate-loading-indicator {
+ from {
+ transform: translateX(0);
}
+ to {
+ transform: translateX(-$kbnLoadingIndicatorBackgroundSize);
+ }
+}
diff --git a/src/core/public/chrome/ui/header/header.tsx b/src/core/public/chrome/ui/header/header.tsx
index c9a583f39b30c..4dec084fd8a83 100644
--- a/src/core/public/chrome/ui/header/header.tsx
+++ b/src/core/public/chrome/ui/header/header.tsx
@@ -30,6 +30,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Component, createRef } from 'react';
+import classnames from 'classnames';
import * as Rx from 'rxjs';
import {
ChromeBadge,
@@ -68,8 +69,8 @@ export interface HeaderProps {
navControlsLeft$: Rx.Observable;
navControlsRight$: Rx.Observable;
basePath: HttpStart['basePath'];
- isLocked?: boolean;
- onIsLockedUpdate?: OnIsLockedUpdate;
+ isLocked$: Rx.Observable;
+ onIsLockedUpdate: OnIsLockedUpdate;
}
interface State {
@@ -81,6 +82,7 @@ interface State {
navControlsLeft: readonly ChromeNavControl[];
navControlsRight: readonly ChromeNavControl[];
currentAppId: string | undefined;
+ isLocked: boolean;
}
export class Header extends Component {
@@ -99,6 +101,7 @@ export class Header extends Component {
navControlsLeft: [],
navControlsRight: [],
currentAppId: '',
+ isLocked: false,
};
}
@@ -109,11 +112,12 @@ export class Header extends Component {
this.props.forceAppSwitcherNavigation$,
this.props.navLinks$,
this.props.recentlyAccessed$,
- // Types for combineLatest only handle up to 6 inferred types so we combine these two separately.
+ // Types for combineLatest only handle up to 6 inferred types so we combine these separately.
Rx.combineLatest(
this.props.navControlsLeft$,
this.props.navControlsRight$,
- this.props.application.currentAppId$
+ this.props.application.currentAppId$,
+ this.props.isLocked$
)
).subscribe({
next: ([
@@ -122,7 +126,7 @@ export class Header extends Component {
forceNavigation,
navLinks,
recentlyAccessed,
- [navControlsLeft, navControlsRight, currentAppId],
+ [navControlsLeft, navControlsRight, currentAppId, isLocked],
]) => {
this.setState({
appTitle,
@@ -133,6 +137,7 @@ export class Header extends Component {
navControlsLeft,
navControlsRight,
currentAppId,
+ isLocked,
});
},
});
@@ -181,8 +186,16 @@ export class Header extends Component {
return null;
}
+ const className = classnames(
+ 'chrHeaderWrapper',
+ {
+ 'chrHeaderWrapper--navIsLocked': this.state.isLocked,
+ },
+ 'hide-for-sharing'
+ );
+
return (
-
+
@@ -220,7 +233,7 @@ export class Header extends Component {
= props => {
- const initialIsLocked = localStorage.getItem(IS_LOCKED_KEY);
- const [isLocked, setIsLocked] = useState(initialIsLocked === 'true');
- const setIsLockedStored = (locked: boolean) => {
- localStorage.setItem(IS_LOCKED_KEY, `${locked}`);
- setIsLocked(locked);
- };
- const className = classnames(
- 'chrHeaderWrapper',
- {
- 'chrHeaderWrapper--navIsLocked': isLocked,
- },
- 'hide-for-sharing'
- );
- return (
-
-
-
- );
-};
diff --git a/src/core/public/chrome/ui/header/index.ts b/src/core/public/chrome/ui/header/index.ts
index 4521f1f74b31b..49e002a66d939 100644
--- a/src/core/public/chrome/ui/header/index.ts
+++ b/src/core/public/chrome/ui/header/index.ts
@@ -18,7 +18,6 @@
*/
export { Header, HeaderProps } from './header';
-export { HeaderWrapper } from './header_wrapper';
export {
ChromeHelpExtensionMenuLink,
ChromeHelpExtensionMenuCustomLink,
diff --git a/src/core/public/chrome/ui/index.ts b/src/core/public/chrome/ui/index.ts
index 81b2fdfb0fcc0..460e19b7d9780 100644
--- a/src/core/public/chrome/ui/index.ts
+++ b/src/core/public/chrome/ui/index.ts
@@ -20,7 +20,6 @@
export { LoadingIndicator } from './loading_indicator';
export {
Header,
- HeaderWrapper,
ChromeHelpExtensionMenuLink,
ChromeHelpExtensionMenuCustomLink,
ChromeHelpExtensionMenuDiscussLink,
diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md
index fa5dc745e6931..7428280b2dccb 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -337,7 +337,7 @@ export interface ChromeStart {
getBrand$(): Observable;
getBreadcrumbs$(): Observable;
getHelpExtension$(): Observable;
- getIsCollapsed$(): Observable;
+ getIsNavDrawerLocked$(): Observable;
getIsVisible$(): Observable;
navControls: ChromeNavControls;
navLinks: ChromeNavLinks;
@@ -349,7 +349,6 @@ export interface ChromeStart {
setBreadcrumbs(newBreadcrumbs: ChromeBreadcrumb[]): void;
setHelpExtension(helpExtension?: ChromeHelpExtension): void;
setHelpSupportUrl(url: string): void;
- setIsCollapsed(isCollapsed: boolean): void;
setIsVisible(isVisible: boolean): void;
}
diff --git a/src/core/server/http/router/route.ts b/src/core/server/http/router/route.ts
index bb0a8616e7222..9789d266587af 100644
--- a/src/core/server/http/router/route.ts
+++ b/src/core/server/http/router/route.ts
@@ -179,7 +179,7 @@ export interface RouteConfig {
* access to raw values.
* In some cases you may want to use another validation library. To do this, you need to
* instruct the `@kbn/config-schema` library to output **non-validated values** with
- * setting schema as `schema.object({}, { allowUnknowns: true })`;
+ * setting schema as `schema.object({}, { unknowns: 'allow' })`;
*
* @example
* ```ts
@@ -212,7 +212,7 @@ export interface RouteConfig
{
* path: 'path/{id}',
* validate: {
* // handler has access to raw non-validated params in runtime
- * params: schema.object({}, { allowUnknowns: true })
+ * params: schema.object({}, { unknowns: 'allow' })
* },
* },
* (context, req, res,) {
diff --git a/src/core/server/http/router/router.test.ts b/src/core/server/http/router/router.test.ts
index a936da6a40a9f..9655e2153b863 100644
--- a/src/core/server/http/router/router.test.ts
+++ b/src/core/server/http/router/router.test.ts
@@ -59,7 +59,7 @@ describe('Router', () => {
{
path: '/',
options: { body: { output: 'file' } } as any, // We explicitly don't support 'file'
- validate: { body: schema.object({}, { allowUnknowns: true }) },
+ validate: { body: schema.object({}, { unknowns: 'allow' }) },
},
(context, req, res) => res.ok({})
)
diff --git a/src/core/server/rendering/views/styles.tsx b/src/core/server/rendering/views/styles.tsx
index 9ab9f2ad0d6b8..71b42e3464118 100644
--- a/src/core/server/rendering/views/styles.tsx
+++ b/src/core/server/rendering/views/styles.tsx
@@ -53,7 +53,7 @@ export const Styles: FunctionComponent = ({ darkMode }) => {
.kbnWelcomeView {
line-height: 1.5;
- background-color: #FFF;
+ background-color: ${darkMode ? '#1D1E24' : '#FFF'};
height: 100%;
display: -webkit-box;
display: -webkit-flex;
@@ -97,6 +97,7 @@ export const Styles: FunctionComponent = ({ darkMode }) => {
line-height: 40px !important;
height: 40px !important;
color: #98a2b3;
+ color: ${darkMode ? '#98A2B3' : '#69707D'};
}
.kbnLoaderWrap {
@@ -128,7 +129,7 @@ export const Styles: FunctionComponent = ({ darkMode }) => {
width: 32px;
height: 4px;
overflow: hidden;
- background-color: #D3DAE6;
+ background-color: ${darkMode ? '#25262E' : '#F5F7FA'};
line-height: 1;
}
@@ -142,7 +143,7 @@ export const Styles: FunctionComponent = ({ darkMode }) => {
left: 0;
transform: scaleX(0) translateX(0%);
animation: kbnProgress 1s cubic-bezier(.694, .0482, .335, 1) infinite;
- background-color: #006DE4;
+ background-color: ${darkMode ? '#1BA9F5' : '#006DE4'};
}
@keyframes kbnProgress {
diff --git a/src/core/server/ui_settings/routes/set_many.ts b/src/core/server/ui_settings/routes/set_many.ts
index 5623c3fe11b80..d19a36a7ce768 100644
--- a/src/core/server/ui_settings/routes/set_many.ts
+++ b/src/core/server/ui_settings/routes/set_many.ts
@@ -24,7 +24,7 @@ import { CannotOverrideError } from '../ui_settings_errors';
const validate = {
body: schema.object({
- changes: schema.object({}, { allowUnknowns: true }),
+ changes: schema.object({}, { unknowns: 'allow' }),
}),
};
diff --git a/src/core/server/ui_settings/ui_settings_config.ts b/src/core/server/ui_settings/ui_settings_config.ts
index a54d482a0296a..a0ac48e2dd089 100644
--- a/src/core/server/ui_settings/ui_settings_config.ts
+++ b/src/core/server/ui_settings/ui_settings_config.ts
@@ -39,7 +39,7 @@ const configSchema = schema.object({
})
),
},
- { allowUnknowns: true }
+ { unknowns: 'allow' }
),
});
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts
index 0c5329d8b259f..3f81bfe5aadf2 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts
@@ -28,12 +28,11 @@ export { npSetup, npStart } from 'ui/new_platform';
export { KbnUrl } from 'ui/url/kbn_url';
// @ts-ignore
-export { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url/index';
+export { KbnUrlProvider } from 'ui/url/index';
export { IInjector } from 'ui/chrome';
export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url';
export {
configureAppAngularModule,
- ensureDefaultIndexPattern,
IPrivate,
migrateLegacyQuery,
PrivateProvider,
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/application.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/application.ts
index fe0e7a1d3e6d0..9447b5384d172 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/application.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/application.ts
@@ -35,7 +35,6 @@ import {
KbnUrlProvider,
PrivateProvider,
PromiseServiceCreator,
- RedirectWhenMissingProvider,
} from '../legacy_imports';
// @ts-ignore
import { initDashboardApp } from './legacy_app';
@@ -146,8 +145,7 @@ function createLocalIconModule() {
function createLocalKbnUrlModule() {
angular
.module('app/dashboard/KbnUrl', ['app/dashboard/Private', 'ngRoute'])
- .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider))
- .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider));
+ .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider));
}
function createLocalConfigModule(core: AppMountContext['core']) {
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js
index 35b510894179d..64abbdfb87d58 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js
+++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js
@@ -23,11 +23,12 @@ import dashboardTemplate from './dashboard_app.html';
import dashboardListingTemplate from './listing/dashboard_listing_ng_wrapper.html';
import { createHashHistory } from 'history';
-import { ensureDefaultIndexPattern } from '../legacy_imports';
import { initDashboardAppDirective } from './dashboard_app';
import { createDashboardEditUrl, DashboardConstants } from './dashboard_constants';
import {
createKbnUrlStateStorage,
+ ensureDefaultIndexPattern,
+ redirectWhenMissing,
InvalidJSONProperty,
SavedObjectNotFound,
} from '../../../../../../plugins/kibana_utils/public';
@@ -136,8 +137,8 @@ export function initDashboardApp(app, deps) {
});
},
resolve: {
- dash: function($rootScope, $route, redirectWhenMissing, kbnUrl, history) {
- return ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl).then(() => {
+ dash: function($route, history) {
+ return ensureDefaultIndexPattern(deps.core, deps.data, history).then(() => {
const savedObjectsClient = deps.savedObjectsClient;
const title = $route.current.params.title;
if (title) {
@@ -171,17 +172,18 @@ export function initDashboardApp(app, deps) {
controller: createNewDashboardCtrl,
requireUICapability: 'dashboard.createNew',
resolve: {
- dash: function(redirectWhenMissing, $rootScope, kbnUrl) {
- return ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl)
- .then(() => {
- return deps.savedDashboards.get();
- })
+ dash: history =>
+ ensureDefaultIndexPattern(deps.core, deps.data, history)
+ .then(() => deps.savedDashboards.get())
.catch(
redirectWhenMissing({
- dashboard: DashboardConstants.LANDING_PAGE_PATH,
+ history,
+ mapping: {
+ dashboard: DashboardConstants.LANDING_PAGE_PATH,
+ },
+ toastNotifications: deps.core.notifications.toasts,
})
- );
- },
+ ),
},
})
.when(createDashboardEditUrl(':id'), {
@@ -189,13 +191,11 @@ export function initDashboardApp(app, deps) {
template: dashboardTemplate,
controller: createNewDashboardCtrl,
resolve: {
- dash: function($rootScope, $route, redirectWhenMissing, kbnUrl, history) {
+ dash: function($route, kbnUrl, history) {
const id = $route.current.params.id;
- return ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl)
- .then(() => {
- return deps.savedDashboards.get(id);
- })
+ return ensureDefaultIndexPattern(deps.core, deps.data, history)
+ .then(() => deps.savedDashboards.get(id))
.then(savedDashboard => {
deps.chrome.recentlyAccessed.add(
savedDashboard.getFullPath(),
@@ -207,7 +207,7 @@ export function initDashboardApp(app, deps) {
.catch(error => {
// A corrupt dashboard was detected (e.g. with invalid JSON properties)
if (error instanceof InvalidJSONProperty) {
- deps.toastNotifications.addDanger(error.message);
+ deps.core.notifications.toasts.addDanger(error.message);
kbnUrl.redirect(DashboardConstants.LANDING_PAGE_PATH);
return;
}
@@ -221,7 +221,7 @@ export function initDashboardApp(app, deps) {
pathname: DashboardConstants.CREATE_NEW_DASHBOARD_URL,
});
- deps.toastNotifications.addWarning(
+ deps.core.notifications.toasts.addWarning(
i18n.translate('kbn.dashboard.urlWasRemovedInSixZeroWarningMessage', {
defaultMessage:
'The url "dashboard/create" was removed in 6.0. Please update your bookmarks.',
@@ -234,7 +234,11 @@ export function initDashboardApp(app, deps) {
})
.catch(
redirectWhenMissing({
- dashboard: DashboardConstants.LANDING_PAGE_PATH,
+ history,
+ mapping: {
+ dashboard: DashboardConstants.LANDING_PAGE_PATH,
+ },
+ toastNotifications: deps.core.notifications.toasts,
})
);
},
diff --git a/src/legacy/core_plugins/kibana/public/discover/build_services.ts b/src/legacy/core_plugins/kibana/public/discover/build_services.ts
index c58307adaf38c..282eef0c983eb 100644
--- a/src/legacy/core_plugins/kibana/public/discover/build_services.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/build_services.ts
@@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { createHashHistory, History } from 'history';
+
import {
Capabilities,
ChromeStart,
@@ -46,6 +48,7 @@ export interface DiscoverServices {
data: DataPublicPluginStart;
docLinks: DocLinksStart;
docViewsRegistry: DocViewsRegistry;
+ history: History;
theme: ChartsPluginStart['theme'];
filterManager: FilterManager;
indexPatterns: IndexPatternsContract;
@@ -79,6 +82,7 @@ export async function buildServices(
data: plugins.data,
docLinks: core.docLinks,
docViewsRegistry,
+ history: createHashHistory(),
theme: plugins.charts.theme,
filterManager: plugins.data.query.filterManager,
getSavedSearchById: async (id: string) => savedObjectService.get(id),
diff --git a/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts b/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts
index 76d475c4f7f96..4d871bcb7a858 100644
--- a/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/get_inner_angular.ts
@@ -27,7 +27,7 @@ import { CoreStart, LegacyCoreStart, IUiSettingsClient } from 'kibana/public';
// @ts-ignore
import { StateManagementConfigProvider } from 'ui/state_management/config_provider';
// @ts-ignore
-import { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url';
+import { KbnUrlProvider } from 'ui/url';
import { DataPublicPluginStart } from '../../../../../plugins/data/public';
import { Storage } from '../../../../../plugins/kibana_utils/public';
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
@@ -173,8 +173,7 @@ export function initializeInnerAngularModule(
function createLocalKbnUrlModule() {
angular
.module('discoverKbnUrl', ['discoverPrivate', 'ngRoute'])
- .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider))
- .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider));
+ .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider));
}
function createLocalConfigModule(uiSettings: IUiSettingsClient) {
diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
index 57a9e4966d6d6..725e94f16e2e8 100644
--- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
@@ -53,17 +53,18 @@ export { wrapInI18nContext } from 'ui/i18n';
import { search } from '../../../../../plugins/data/public';
export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search;
// @ts-ignore
-export { shortenDottedString } from '../../common/utils/shorten_dotted_string';
-// @ts-ignore
export { intervalOptions } from 'ui/agg_types';
-export { subscribeWithScope } from '../../../../../plugins/kibana_legacy/public';
// @ts-ignore
export { timezoneProvider } from 'ui/vis/lib/timezone';
-export { unhashUrl } from '../../../../../plugins/kibana_utils/public';
export {
+ unhashUrl,
+ redirectWhenMissing,
ensureDefaultIndexPattern,
+} from '../../../../../plugins/kibana_utils/public';
+export {
formatMsg,
formatStack,
+ subscribeWithScope,
} from '../../../../../plugins/kibana_legacy/public';
// EXPORT types
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx
index 26d8a5abb2471..1b3b16332fa4f 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx
@@ -21,7 +21,7 @@ import classNames from 'classnames';
import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { FieldIcon, FieldIconProps } from '../../../../../../../../../plugins/kibana_react/public';
-import { shortenDottedString } from '../../../../kibana_services';
+import { shortenDottedString } from '../../../helpers';
import { getFieldTypeName } from './field_type_name';
// property field is provided at discover's field chooser
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
index f3334c9211e4b..9a383565f4f43 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js
@@ -50,6 +50,7 @@ import {
tabifyAggResponse,
getAngularModule,
ensureDefaultIndexPattern,
+ redirectWhenMissing,
} from '../../kibana_services';
const {
@@ -57,6 +58,7 @@ const {
chrome,
data,
docTitle,
+ history,
indexPatterns,
filterManager,
share,
@@ -113,10 +115,10 @@ app.config($routeProvider => {
template: indexTemplate,
reloadOnSearch: false,
resolve: {
- savedObjects: function(redirectWhenMissing, $route, kbnUrl, Promise, $rootScope) {
+ savedObjects: function($route, Promise) {
const savedSearchId = $route.current.params.id;
- return ensureDefaultIndexPattern(core, data, $rootScope, kbnUrl).then(() => {
- const { appStateContainer } = getState({});
+ return ensureDefaultIndexPattern(core, data, history).then(() => {
+ const { appStateContainer } = getState({ history });
const { index } = appStateContainer.getState();
return Promise.props({
ip: indexPatterns.getCache().then(indexPatternList => {
@@ -151,9 +153,13 @@ app.config($routeProvider => {
})
.catch(
redirectWhenMissing({
- search: '/discover',
- 'index-pattern':
- '/management/kibana/objects/savedSearches/' + $route.current.params.id,
+ history,
+ mapping: {
+ search: '/discover',
+ 'index-pattern':
+ '/management/kibana/objects/savedSearches/' + $route.current.params.id,
+ },
+ toastNotifications,
})
),
});
@@ -207,6 +213,7 @@ function discoverController(
} = getState({
defaultAppState: getStateDefaults(),
storeInSessionStorage: config.get('state:storeInSessionStorage'),
+ history,
});
if (appStateContainer.getState().index !== $scope.indexPattern.id) {
//used index pattern is different than the given by url/state which is invalid
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.test.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.test.ts
index af772cb5c76f1..3840fd0c2e3be 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.test.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.test.ts
@@ -30,7 +30,7 @@ describe('Test discover state', () => {
history.push('/');
state = getState({
defaultAppState: { index: 'test' },
- hashHistory: history,
+ history,
});
await state.replaceUrlAppState({});
await state.startSync();
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
index 10e7cd1d0c49d..981855d1ee774 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover_state.ts
@@ -17,7 +17,7 @@
* under the License.
*/
import { isEqual } from 'lodash';
-import { createHashHistory, History } from 'history';
+import { History } from 'history';
import {
createStateContainer,
createKbnUrlStateStorage,
@@ -65,9 +65,9 @@ interface GetStateParams {
*/
storeInSessionStorage?: boolean;
/**
- * Browser history used for testing
+ * Browser history
*/
- hashHistory?: History;
+ history: History;
}
export interface GetStateReturn {
@@ -121,11 +121,11 @@ const APP_STATE_URL_KEY = '_a';
export function getState({
defaultAppState = {},
storeInSessionStorage = false,
- hashHistory,
+ history,
}: GetStateParams): GetStateReturn {
const stateStorage = createKbnUrlStateStorage({
useHash: storeInSessionStorage,
- history: hashHistory ? hashHistory : createHashHistory(),
+ history,
});
const appStateFromUrl = stateStorage.get(APP_STATE_URL_KEY) as AppState;
diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx
index a2ad18d59d935..bd48b1e083871 100644
--- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx
@@ -16,7 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { IndexPattern, shortenDottedString } from '../../../../../kibana_services';
+import { IndexPattern } from '../../../../../kibana_services';
+import { shortenDottedString } from '../../../../helpers';
export type SortOrder = [string, string];
export interface ColumnProps {
diff --git a/src/legacy/ui/public/chrome/services/index.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts
similarity index 92%
rename from src/legacy/ui/public/chrome/services/index.js
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts
index 3b3967f51b2ff..7196c96989e97 100644
--- a/src/legacy/ui/public/chrome/services/index.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts
@@ -17,4 +17,4 @@
* under the License.
*/
-import './global_nav_state';
+export { shortenDottedString } from './shorten_dotted_string';
diff --git a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts
similarity index 81%
rename from src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js
rename to src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts
index ca76a2a537742..9d78a96784339 100644
--- a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js
+++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts
@@ -22,10 +22,5 @@ const DOT_PREFIX_RE = /(.).+?\./g;
/**
* Convert a dot.notated.string into a short
* version (d.n.string)
- *
- * @param {string} str - the long string to convert
- * @return {string}
*/
-export function shortenDottedString(input) {
- return typeof input !== 'string' ? input : input.replace(DOT_PREFIX_RE, '$1.');
-}
+export const shortenDottedString = (input: string) => input.replace(DOT_PREFIX_RE, '$1.');
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
index 805131042f385..a4dcfb9c38184 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/__jest__/__snapshots__/table.test.js.snap
@@ -126,6 +126,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
Array [
Object {
"align": "center",
+ "data-test-subj": "savedObjectsTableRowType",
"description": "Type of the saved object",
"field": "type",
"name": "Type",
@@ -134,6 +135,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
"width": "50px",
},
Object {
+ "data-test-subj": "savedObjectsTableRowTitle",
"dataType": "string",
"description": "Title of the saved object",
"field": "meta.title",
@@ -145,6 +147,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
"actions": Array [
Object {
"available": [Function],
+ "data-test-subj": "savedObjectsTableAction-inspect",
"description": "Inspect this saved object",
"icon": "inspect",
"name": "Inspect",
@@ -152,6 +155,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
"type": "icon",
},
Object {
+ "data-test-subj": "savedObjectsTableAction-relationships",
"description": "View the relationships this saved object has to other saved objects",
"icon": "kqlSelector",
"name": "Relationships",
@@ -198,6 +202,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
}
}
responsive={true}
+ rowProps={[Function]}
selection={
Object {
"onSelectionChange": [Function],
@@ -334,6 +339,7 @@ exports[`Table should render normally 1`] = `
Array [
Object {
"align": "center",
+ "data-test-subj": "savedObjectsTableRowType",
"description": "Type of the saved object",
"field": "type",
"name": "Type",
@@ -342,6 +348,7 @@ exports[`Table should render normally 1`] = `
"width": "50px",
},
Object {
+ "data-test-subj": "savedObjectsTableRowTitle",
"dataType": "string",
"description": "Title of the saved object",
"field": "meta.title",
@@ -353,6 +360,7 @@ exports[`Table should render normally 1`] = `
"actions": Array [
Object {
"available": [Function],
+ "data-test-subj": "savedObjectsTableAction-inspect",
"description": "Inspect this saved object",
"icon": "inspect",
"name": "Inspect",
@@ -360,6 +368,7 @@ exports[`Table should render normally 1`] = `
"type": "icon",
},
Object {
+ "data-test-subj": "savedObjectsTableAction-relationships",
"description": "View the relationships this saved object has to other saved objects",
"icon": "kqlSelector",
"name": "Relationships",
@@ -406,6 +415,7 @@ exports[`Table should render normally 1`] = `
}
}
responsive={true}
+ rowProps={[Function]}
selection={
Object {
"onSelectionChange": [Function],
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js
index a119817fdc0c9..386b35399b754 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/table/table.js
@@ -178,6 +178,7 @@ export class Table extends PureComponent {
{ defaultMessage: 'Type of the saved object' }
),
sortable: false,
+ 'data-test-subj': 'savedObjectsTableRowType',
render: (type, object) => {
return (
@@ -201,6 +202,7 @@ export class Table extends PureComponent {
),
dataType: 'string',
sortable: false,
+ 'data-test-subj': 'savedObjectsTableRowTitle',
render: (title, object) => {
const { path } = object.meta.inAppUrl || {};
const canGoInApp = this.props.canGoInApp(object);
@@ -230,6 +232,7 @@ export class Table extends PureComponent {
icon: 'inspect',
onClick: object => goInspectObject(object),
available: object => !!object.meta.editUrl,
+ 'data-test-subj': 'savedObjectsTableAction-inspect',
},
{
name: i18n.translate(
@@ -246,10 +249,12 @@ export class Table extends PureComponent {
type: 'icon',
icon: 'kqlSelector',
onClick: object => onShowRelationships(object),
+ 'data-test-subj': 'savedObjectsTableAction-relationships',
},
...this.extraActions.map(action => {
return {
...action.euiAction,
+ 'data-test-subj': `savedObjectsTableAction-${action.id}`,
onClick: object => {
this.setState({
activeAction: action,
@@ -372,6 +377,9 @@ export class Table extends PureComponent {
pagination={pagination}
selection={selection}
onChange={onTableChange}
+ rowProps={item => ({
+ 'data-test-subj': `savedObjectsTableRow row-${item.id}`,
+ })}
/>
diff --git a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts
index 0ddf3ee67aa94..e6b7a29e28d89 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts
@@ -25,7 +25,7 @@
*/
// @ts-ignore
-export { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url';
+export { KbnUrlProvider } from 'ui/url';
export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url';
export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
export { wrapInI18nContext } from 'ui/i18n';
@@ -33,7 +33,6 @@ export { DashboardConstants } from '../dashboard/np_ready/dashboard_constants';
export { VisSavedObject, VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/';
export {
configureAppAngularModule,
- ensureDefaultIndexPattern,
IPrivate,
migrateLegacyQuery,
PrivateProvider,
diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/application.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/application.ts
index 8ef63ec5778e2..c7c3286bb5c71 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/application.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/application.ts
@@ -24,7 +24,6 @@ import { AppMountContext } from 'kibana/public';
import {
configureAppAngularModule,
KbnUrlProvider,
- RedirectWhenMissingProvider,
IPrivate,
PrivateProvider,
PromiseServiceCreator,
@@ -102,8 +101,7 @@ function createLocalAngularModule(core: AppMountContext['core'], navigation: Nav
function createLocalKbnUrlModule() {
angular
.module('app/visualize/KbnUrl', ['app/visualize/Private', 'ngRoute'])
- .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider))
- .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider));
+ .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider));
}
function createLocalPromiseModule() {
diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js
index c023c402f5fea..1fab38027f65b 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.js
@@ -31,6 +31,7 @@ import { getEditBreadcrumbs } from '../breadcrumbs';
import { addHelpMenuToAppChrome } from '../help_menu/help_menu_util';
import { unhashUrl } from '../../../../../../../plugins/kibana_utils/public';
+import { MarkdownSimple, toMountPoint } from '../../../../../../../plugins/kibana_react/public';
import { addFatalError, kbnBaseUrl } from '../../../../../../../plugins/kibana_legacy/public';
import {
SavedObjectSaveModal,
@@ -75,7 +76,6 @@ function VisualizeAppController(
$injector,
$timeout,
kbnUrl,
- redirectWhenMissing,
kbnUrlStateStorage,
history
) {
@@ -313,16 +313,33 @@ function VisualizeAppController(
}
);
+ const stopAllSyncing = () => {
+ stopStateSync();
+ stopSyncingQueryServiceStateWithUrl();
+ stopSyncingAppFilters();
+ };
+
// The savedVis is pulled from elasticsearch, but the appState is pulled from the url, with the
// defaults applied. If the url was from a previous session which included modifications to the
// appState then they won't be equal.
if (!_.isEqual(stateContainer.getState().vis, stateDefaults.vis)) {
try {
vis.setState(stateContainer.getState().vis);
- } catch {
- redirectWhenMissing({
- 'index-pattern-field': '/visualize',
+ } catch (error) {
+ // stop syncing url updtes with the state to prevent extra syncing
+ stopAllSyncing();
+
+ toastNotifications.addWarning({
+ title: i18n.translate('kbn.visualize.visualizationTypeInvalidNotificationMessage', {
+ defaultMessage: 'Invalid visualization type',
+ }),
+ text: toMountPoint({error.message} ),
});
+
+ history.replace(`${VisualizeConstants.LANDING_PAGE_PATH}?notFound=visualization`);
+
+ // prevent further controller execution
+ return;
}
}
@@ -529,9 +546,8 @@ function VisualizeAppController(
unsubscribePersisted();
unsubscribeStateUpdates();
- stopStateSync();
- stopSyncingQueryServiceStateWithUrl();
- stopSyncingAppFilters();
+
+ stopAllSyncing();
});
$timeout(() => {
diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js
index 6acdb0abdd0b5..c8acea168444f 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization.js
@@ -59,7 +59,9 @@ export function initVisualizationDirective(app, deps) {
});
$scope.$on('$destroy', () => {
- $scope._handler.destroy();
+ if ($scope._handler) {
+ $scope._handler.destroy();
+ }
});
},
};
diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js
index b9409445166bc..0f1d50b149cd9 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/legacy_app.js
@@ -21,7 +21,11 @@ import { find } from 'lodash';
import { i18n } from '@kbn/i18n';
import { createHashHistory } from 'history';
-import { createKbnUrlStateStorage } from '../../../../../../plugins/kibana_utils/public';
+import {
+ createKbnUrlStateStorage,
+ redirectWhenMissing,
+ ensureDefaultIndexPattern,
+} from '../../../../../../plugins/kibana_utils/public';
import editorTemplate from './editor/editor.html';
import visualizeListingTemplate from './listing/visualize_listing.html';
@@ -29,7 +33,6 @@ import visualizeListingTemplate from './listing/visualize_listing.html';
import { initVisualizeAppDirective } from './visualize_app';
import { VisualizeConstants } from './visualize_constants';
import { VisualizeListingController } from './listing/visualize_listing';
-import { ensureDefaultIndexPattern } from '../legacy_imports';
import {
getLandingBreadcrumbs,
@@ -79,8 +82,7 @@ export function initVisualizeApp(app, deps) {
controllerAs: 'listingController',
resolve: {
createNewVis: () => false,
- hasDefaultIndex: ($rootScope, kbnUrl) =>
- ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl),
+ hasDefaultIndex: history => ensureDefaultIndexPattern(deps.core, deps.data, history),
},
})
.when(VisualizeConstants.WIZARD_STEP_1_PAGE_PATH, {
@@ -91,8 +93,7 @@ export function initVisualizeApp(app, deps) {
controllerAs: 'listingController',
resolve: {
createNewVis: () => true,
- hasDefaultIndex: ($rootScope, kbnUrl) =>
- ensureDefaultIndexPattern(deps.core, deps.data, $rootScope, kbnUrl),
+ hasDefaultIndex: history => ensureDefaultIndexPattern(deps.core, deps.data, history),
},
})
.when(VisualizeConstants.CREATE_PATH, {
@@ -100,8 +101,8 @@ export function initVisualizeApp(app, deps) {
template: editorTemplate,
k7Breadcrumbs: getCreateBreadcrumbs,
resolve: {
- savedVis: function(redirectWhenMissing, $route, $rootScope, kbnUrl) {
- const { core, data, savedVisualizations, visualizations } = deps;
+ savedVis: function($route, history) {
+ const { core, data, savedVisualizations, visualizations, toastNotifications } = deps;
const visTypes = visualizations.all();
const visType = find(visTypes, { name: $route.current.params.type });
const shouldHaveIndex = visType.requiresSearch && visType.options.showIndexSelection;
@@ -118,7 +119,7 @@ export function initVisualizeApp(app, deps) {
);
}
- return ensureDefaultIndexPattern(core, data, $rootScope, kbnUrl)
+ return ensureDefaultIndexPattern(core, data, history)
.then(() => savedVisualizations.get($route.current.params))
.then(savedVis => {
if (savedVis.vis.type.setup) {
@@ -128,7 +129,9 @@ export function initVisualizeApp(app, deps) {
})
.catch(
redirectWhenMissing({
- '*': '/visualize',
+ history,
+ mapping: VisualizeConstants.LANDING_PAGE_PATH,
+ toastNotifications,
})
);
},
@@ -139,9 +142,9 @@ export function initVisualizeApp(app, deps) {
template: editorTemplate,
k7Breadcrumbs: getEditBreadcrumbs,
resolve: {
- savedVis: function(redirectWhenMissing, $route, $rootScope, kbnUrl) {
- const { chrome, core, data, savedVisualizations } = deps;
- return ensureDefaultIndexPattern(core, data, $rootScope, kbnUrl)
+ savedVis: function($route, history) {
+ const { chrome, core, data, savedVisualizations, toastNotifications } = deps;
+ return ensureDefaultIndexPattern(core, data, history)
.then(() => savedVisualizations.get($route.current.params.id))
.then(savedVis => {
chrome.recentlyAccessed.add(savedVis.getFullPath(), savedVis.title, savedVis.id);
@@ -155,13 +158,17 @@ export function initVisualizeApp(app, deps) {
})
.catch(
redirectWhenMissing({
- visualization: '/visualize',
- search:
- '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
- 'index-pattern':
- '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
- 'index-pattern-field':
- '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ history,
+ mapping: {
+ visualization: VisualizeConstants.LANDING_PAGE_PATH,
+ search:
+ '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ 'index-pattern':
+ '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ 'index-pattern-field':
+ '/management/kibana/objects/savedVisualizations/' + $route.current.params.id,
+ },
+ toastNotifications,
})
);
},
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
index 0263f5b2c851c..ff2546f75c51a 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
@@ -50,7 +50,7 @@ export class VisEditor extends Component {
visFields: props.visFields,
extractedIndexPatterns: [''],
};
- this.onBrush = createBrushHandler(getDataStart().query.timefilter);
+ this.onBrush = createBrushHandler(getDataStart().query.timefilter.timefilter);
this.visDataSubject = new Rx.BehaviorSubject(this.props.visData);
this.visData$ = this.visDataSubject.asObservable().pipe(share());
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss
index 90c2007b1c94a..3db09bace079f 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/_vis_types.scss
@@ -7,4 +7,21 @@
.tvbVisTimeSeries {
overflow: hidden;
}
+ .tvbVisTimeSeriesDark {
+ .echReactiveChart_unavailable {
+ color: #DFE5EF;
+ }
+ .echLegendItem {
+ color: #DFE5EF;
+ }
+ }
+ .tvbVisTimeSeriesLight {
+ .echReactiveChart_unavailable {
+ color: #343741;
+ }
+ .echLegendItem {
+ color: #343741;
+ }
+ }
}
+
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js
index 954d3d174bb8c..356ba08ac2427 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_types/timeseries/vis.js
@@ -33,9 +33,8 @@ import { getAxisLabelString } from '../../lib/get_axis_label_string';
import { getInterval } from '../../lib/get_interval';
import { areFieldsDifferent } from '../../lib/charts';
import { createXaxisFormatter } from '../../lib/create_xaxis_formatter';
-import { isBackgroundDark } from '../../../lib/set_is_reversed';
import { STACKED_OPTIONS } from '../../../visualizations/constants';
-import { getCoreStart } from '../../../services';
+import { getCoreStart, getUISettings } from '../../../services';
export class TimeseriesVisualization extends Component {
static propTypes = {
@@ -238,6 +237,7 @@ export class TimeseriesVisualization extends Component {
}
});
+ const darkMode = getUISettings().get('theme:darkMode');
return (
null;
export const AreaSeries = () => null;
+
+export { LIGHT_THEME, DARK_THEME } from '@elastic/charts';
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js b/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js
index 986111b462b35..75554a476bdea 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/index.js
@@ -19,14 +19,13 @@
import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
+import classNames from 'classnames';
import {
Axis,
Chart,
Position,
Settings,
- DARK_THEME,
- LIGHT_THEME,
AnnotationDomainTypes,
LineAnnotation,
TooltipType,
@@ -40,6 +39,7 @@ import { GRID_LINE_CONFIG, ICON_TYPES_MAP, STACKED_OPTIONS } from '../../constan
import { AreaSeriesDecorator } from './decorators/area_decorator';
import { BarSeriesDecorator } from './decorators/bar_decorator';
import { getStackAccessors } from './utils/stack_format';
+import { getTheme, getChartClasses } from './utils/theme';
const generateAnnotationData = (values, formatter) =>
values.map(({ key, docs }) => ({
@@ -57,7 +57,8 @@ const handleCursorUpdate = cursor => {
};
export const TimeSeries = ({
- isDarkMode,
+ darkMode,
+ backgroundColor,
showGrid,
legend,
legendPosition,
@@ -89,8 +90,13 @@ export const TimeSeries = ({
const timeZone = timezoneProvider(uiSettings)();
const hasBarChart = series.some(({ bars }) => bars.show);
+ // compute the theme based on the bg color
+ const theme = getTheme(darkMode, backgroundColor);
+ // apply legend style change if bgColor is configured
+ const classes = classNames('tvbVisTimeSeries', getChartClasses(backgroundColor));
+
return (
-
+
{
+ it('should return the basic themes if no bg color is specified', () => {
+ // use original dark/light theme
+ expect(getTheme(false)).toEqual(LIGHT_THEME);
+ expect(getTheme(true)).toEqual(DARK_THEME);
+
+ // discard any wrong/missing bg color
+ expect(getTheme(true, null)).toEqual(DARK_THEME);
+ expect(getTheme(true, '')).toEqual(DARK_THEME);
+ expect(getTheme(true, undefined)).toEqual(DARK_THEME);
+ });
+ it('should return a highcontrast color theme for a different background', () => {
+ // red use a near full-black color
+ expect(getTheme(false, 'red').axes.axisTitleStyle.fill).toEqual('rgb(23,23,23)');
+
+ // violet increased the text color to full white for higer contrast
+ expect(getTheme(false, '#ba26ff').axes.axisTitleStyle.fill).toEqual('rgb(255,255,255)');
+
+ // light yellow, prefer the LIGHT_THEME fill color because already with a good contrast
+ expect(getTheme(false, '#fff49f').axes.axisTitleStyle.fill).toEqual('#333');
+ });
+});
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.ts b/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.ts
new file mode 100644
index 0000000000000..a25d5e1ce1d35
--- /dev/null
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/visualizations/views/timeseries/utils/theme.ts
@@ -0,0 +1,139 @@
+/*
+ * 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 colorJS from 'color';
+import { Theme, LIGHT_THEME, DARK_THEME } from '@elastic/charts';
+
+function computeRelativeLuminosity(rgb: string) {
+ return colorJS(rgb).luminosity();
+}
+
+function computeContrast(rgb1: string, rgb2: string) {
+ return colorJS(rgb1).contrast(colorJS(rgb2));
+}
+
+function getAAARelativeLum(bgColor: string, fgColor: string, ratio = 7) {
+ const relLum1 = computeRelativeLuminosity(bgColor);
+ const relLum2 = computeRelativeLuminosity(fgColor);
+ if (relLum1 > relLum2) {
+ // relLum1 is brighter, relLum2 is darker
+ return (relLum1 + 0.05 - ratio * 0.05) / ratio;
+ } else {
+ // relLum1 is darker, relLum2 is brighter
+ return Math.min(ratio * (relLum1 + 0.05) - 0.05, 1);
+ }
+}
+
+function getGrayFromRelLum(relLum: number) {
+ if (relLum <= 0.0031308) {
+ return relLum * 12.92;
+ } else {
+ return (1.0 + 0.055) * Math.pow(relLum, 1.0 / 2.4) - 0.055;
+ }
+}
+
+function getGrayRGBfromGray(gray: number) {
+ const g = Math.round(gray * 255);
+ return `rgb(${g},${g},${g})`;
+}
+
+function getAAAGray(bgColor: string, fgColor: string, ratio = 7) {
+ const relLum = getAAARelativeLum(bgColor, fgColor, ratio);
+ const gray = getGrayFromRelLum(relLum);
+ return getGrayRGBfromGray(gray);
+}
+
+function findBestContrastColor(
+ bgColor: string,
+ lightFgColor: string,
+ darkFgColor: string,
+ ratio = 4.5
+) {
+ const lc = computeContrast(bgColor, lightFgColor);
+ const dc = computeContrast(bgColor, darkFgColor);
+ if (lc >= dc) {
+ if (lc >= ratio) {
+ return lightFgColor;
+ }
+ return getAAAGray(bgColor, lightFgColor, ratio);
+ }
+ if (dc >= ratio) {
+ return darkFgColor;
+ }
+ return getAAAGray(bgColor, darkFgColor, ratio);
+}
+
+function isValidColor(color: string | null | undefined): color is string {
+ if (typeof color !== 'string') {
+ return false;
+ }
+ if (color.length === 0) {
+ return false;
+ }
+ try {
+ colorJS(color);
+ return true;
+ } catch {
+ return false;
+ }
+}
+
+export function getTheme(darkMode: boolean, bgColor?: string | null): Theme {
+ if (!isValidColor(bgColor)) {
+ return darkMode ? DARK_THEME : LIGHT_THEME;
+ }
+
+ const bgLuminosity = computeRelativeLuminosity(bgColor);
+ const mainTheme = bgLuminosity <= 0.179 ? DARK_THEME : LIGHT_THEME;
+ const color = findBestContrastColor(
+ bgColor,
+ LIGHT_THEME.axes.axisTitleStyle.fill,
+ DARK_THEME.axes.axisTitleStyle.fill
+ );
+ return {
+ ...mainTheme,
+ axes: {
+ ...mainTheme.axes,
+ axisTitleStyle: {
+ ...mainTheme.axes.axisTitleStyle,
+ fill: color,
+ },
+ tickLabelStyle: {
+ ...mainTheme.axes.tickLabelStyle,
+ fill: color,
+ },
+ axisLineStyle: {
+ ...mainTheme.axes.axisLineStyle,
+ stroke: color,
+ },
+ tickLineStyle: {
+ ...mainTheme.axes.tickLineStyle,
+ stroke: color,
+ },
+ },
+ };
+}
+
+export function getChartClasses(bgColor?: string) {
+ // keep the original theme color if no bg color is specified
+ if (typeof bgColor !== 'string') {
+ return;
+ }
+ const bgLuminosity = computeRelativeLuminosity(bgColor);
+ return bgLuminosity <= 0.179 ? 'tvbVisTimeSeriesDark' : 'tvbVisTimeSeriesLight';
+}
diff --git a/src/legacy/ui/public/chrome/chrome.js b/src/legacy/ui/public/chrome/chrome.js
index 3355870eabfe7..7a75ad906a870 100644
--- a/src/legacy/ui/public/chrome/chrome.js
+++ b/src/legacy/ui/public/chrome/chrome.js
@@ -28,7 +28,6 @@ import '../private';
import '../promises';
import '../directives/storage';
import '../directives/watch_multi';
-import './services';
import '../react_components';
import '../i18n';
diff --git a/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap b/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap
index 27226eb010ba2..365f3afdab395 100644
--- a/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap
+++ b/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap
@@ -12,19 +12,45 @@ exports[`is rendered 1`] = `
-
- Exit full screen
+ class="euiFlexItem euiFlexItem--flexGrowZero"
+ >
+
+
+
+
diff --git a/src/legacy/ui/public/legacy_compat/index.ts b/src/legacy/ui/public/legacy_compat/index.ts
index 3b700c8d59399..2067fa6489304 100644
--- a/src/legacy/ui/public/legacy_compat/index.ts
+++ b/src/legacy/ui/public/legacy_compat/index.ts
@@ -17,7 +17,4 @@
* under the License.
*/
-export {
- configureAppAngularModule,
- ensureDefaultIndexPattern,
-} from '../../../../plugins/kibana_legacy/public';
+export { configureAppAngularModule } from '../../../../plugins/kibana_legacy/public';
diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
index ea84ba1ad2838..c58a7d2fbb5cd 100644
--- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
+++ b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
@@ -21,13 +21,15 @@ import sinon from 'sinon';
import { getFieldFormatsRegistry } from '../../../../test_utils/public/stub_field_formats';
import { METRIC_TYPE } from '@kbn/analytics';
import {
+ setFieldFormats,
setIndexPatterns,
- setQueryService,
- setUiSettings,
setInjectedMetadata,
- setFieldFormats,
- setSearchService,
+ setHttp,
+ setNotifications,
setOverlays,
+ setQueryService,
+ setSearchService,
+ setUiSettings,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../plugins/data/public/services';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
@@ -477,11 +479,13 @@ export function __start__(coreStart) {
// Services that need to be set in the legacy platform since the legacy data plugin
// which previously provided them has been removed.
+ setHttp(npStart.core.http);
+ setNotifications(npStart.core.notifications);
+ setOverlays(npStart.core.overlays);
setUiSettings(npStart.core.uiSettings);
- setQueryService(npStart.plugins.data.query);
- setIndexPatterns(npStart.plugins.data.indexPatterns);
setFieldFormats(npStart.plugins.data.fieldFormats);
+ setIndexPatterns(npStart.plugins.data.indexPatterns);
+ setQueryService(npStart.plugins.data.query);
setSearchService(npStart.plugins.data.search);
setAggs(npStart.plugins.data.search.aggs);
- setOverlays(npStart.core.overlays);
}
diff --git a/src/legacy/ui/public/new_platform/new_platform.test.ts b/src/legacy/ui/public/new_platform/new_platform.test.ts
index 498f05457bba9..dd41093f3a1f0 100644
--- a/src/legacy/ui/public/new_platform/new_platform.test.ts
+++ b/src/legacy/ui/public/new_platform/new_platform.test.ts
@@ -20,8 +20,19 @@
jest.mock('history');
import { setRootControllerMock, historyMock } from './new_platform.test.mocks';
-import { legacyAppRegister, __reset__, __setup__ } from './new_platform';
+import {
+ legacyAppRegister,
+ __reset__,
+ __setup__,
+ __start__,
+ PluginsSetup,
+ PluginsStart,
+} from './new_platform';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import * as dataServices from '../../../../plugins/data/public/services';
+import { LegacyCoreSetup, LegacyCoreStart } from '../../../../core/public';
import { coreMock } from '../../../../core/public/mocks';
+import { npSetup, npStart } from './__mocks__';
describe('ui/new_platform', () => {
describe('legacyAppRegister', () => {
@@ -108,4 +119,25 @@ describe('ui/new_platform', () => {
expect(unmountMock).toHaveBeenCalled();
});
});
+
+ describe('service getters', () => {
+ const services: Record = dataServices;
+ const getters = Object.keys(services).filter(k => k.substring(0, 3) === 'get');
+
+ getters.forEach(g => {
+ it(`sets a value for ${g}`, () => {
+ __reset__();
+ __setup__(
+ (coreMock.createSetup() as unknown) as LegacyCoreSetup,
+ (npSetup.plugins as unknown) as PluginsSetup
+ );
+ __start__(
+ (coreMock.createStart() as unknown) as LegacyCoreStart,
+ (npStart.plugins as unknown) as PluginsStart
+ );
+
+ expect(services[g]()).toBeDefined();
+ });
+ });
+ });
});
diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts
index 07e17ad562291..deb8387fee29c 100644
--- a/src/legacy/ui/public/new_platform/new_platform.ts
+++ b/src/legacy/ui/public/new_platform/new_platform.ts
@@ -31,13 +31,15 @@ import {
} from '../../../../core/public';
import { Plugin as DataPlugin } from '../../../../plugins/data/public';
import {
+ setFieldFormats,
setIndexPatterns,
- setQueryService,
- setUiSettings,
setInjectedMetadata,
- setFieldFormats,
- setSearchService,
+ setHttp,
+ setNotifications,
setOverlays,
+ setQueryService,
+ setSearchService,
+ setUiSettings,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../plugins/data/public/services';
import { Plugin as ExpressionsPlugin } from '../../../../plugins/expressions/public';
@@ -141,12 +143,14 @@ export function __start__(coreStart: LegacyCoreStart, plugins: PluginsStart) {
// Services that need to be set in the legacy platform since the legacy data plugin
// which previously provided them has been removed.
+ setHttp(npStart.core.http);
+ setNotifications(npStart.core.notifications);
+ setOverlays(npStart.core.overlays);
setUiSettings(npStart.core.uiSettings);
- setQueryService(npStart.plugins.data.query);
- setIndexPatterns(npStart.plugins.data.indexPatterns);
setFieldFormats(npStart.plugins.data.fieldFormats);
+ setIndexPatterns(npStart.plugins.data.indexPatterns);
+ setQueryService(npStart.plugins.data.query);
setSearchService(npStart.plugins.data.search);
- setOverlays(npStart.core.overlays);
}
/** Flag used to ensure `legacyAppRegister` is only called once. */
diff --git a/src/legacy/ui/public/vis/map/service_settings.js b/src/legacy/ui/public/vis/map/service_settings.js
index 233ee526c439b..9f3d21831e3da 100644
--- a/src/legacy/ui/public/vis/map/service_settings.js
+++ b/src/legacy/ui/public/vis/map/service_settings.js
@@ -47,7 +47,8 @@ uiModules
this._showZoomMessage = true;
this._emsClient = new EMSClient({
language: i18n.getLocale(),
- kbnVersion: kbnVersion,
+ appVersion: kbnVersion,
+ appName: 'kibana',
fileApiUrl: mapConfig.emsFileApiUrl,
tileApiUrl: mapConfig.emsTileApiUrl,
htmlSanitizer: $sanitize,
diff --git a/src/plugins/console/public/lib/kb/kb.js b/src/plugins/console/public/lib/kb/kb.js
index 95896bed02988..053b82bd81d0a 100644
--- a/src/plugins/console/public/lib/kb/kb.js
+++ b/src/plugins/console/public/lib/kb/kb.js
@@ -147,13 +147,9 @@ function loadApisFromJson(
}
export function setActiveApi(api) {
- if (_.isString(api)) {
+ if (!api) {
$.ajax({
- url:
- '../api/console/api_server?sense_version=' +
- encodeURIComponent('@@SENSE_VERSION') +
- '&apis=' +
- encodeURIComponent(api),
+ url: '../api/console/api_server',
dataType: 'json', // disable automatic guessing
}).then(
function(data) {
@@ -169,7 +165,7 @@ export function setActiveApi(api) {
ACTIVE_API = api;
}
-setActiveApi('es_6_0');
+setActiveApi();
export const _test = {
loadApisFromJson: loadApisFromJson,
diff --git a/src/plugins/console/server/lib/index.ts b/src/plugins/console/server/lib/index.ts
index 98004768f880b..2347084b73a66 100644
--- a/src/plugins/console/server/lib/index.ts
+++ b/src/plugins/console/server/lib/index.ts
@@ -22,4 +22,4 @@ export { ProxyConfigCollection } from './proxy_config_collection';
export { proxyRequest } from './proxy_request';
export { getElasticsearchProxyConfig } from './elasticsearch_proxy_config';
export { setHeaders } from './set_headers';
-export { addProcessorDefinition, addExtensionSpecFilePath } from './spec_definitions';
+export { addProcessorDefinition, addExtensionSpecFilePath, loadSpec } from './spec_definitions';
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0.js b/src/plugins/console/server/lib/spec_definitions/es.js
similarity index 54%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0.js
rename to src/plugins/console/server/lib/spec_definitions/es.js
index 171d232407956..fc24a64f8a6f4 100644
--- a/src/plugins/console/server/lib/spec_definitions/es_6_0.js
+++ b/src/plugins/console/server/lib/spec_definitions/es.js
@@ -18,26 +18,30 @@
*/
import Api from './api';
-import { getSpec } from './spec';
-import { register } from './es_6_0/ingest';
-const ES_6_0 = new Api('es_6_0');
-const spec = getSpec();
+import { getSpec } from './json';
+import { register } from './js/ingest';
+const ES = new Api('es');
-// adding generated specs
-Object.keys(spec).forEach(endpoint => {
- ES_6_0.addEndpointDescription(endpoint, spec[endpoint]);
-});
+export const loadSpec = () => {
+ const spec = getSpec();
-//adding globals and custom API definitions
-require('./es_6_0/aliases')(ES_6_0);
-require('./es_6_0/aggregations')(ES_6_0);
-require('./es_6_0/document')(ES_6_0);
-require('./es_6_0/filter')(ES_6_0);
-require('./es_6_0/globals')(ES_6_0);
-register(ES_6_0);
-require('./es_6_0/mappings')(ES_6_0);
-require('./es_6_0/query')(ES_6_0);
-require('./es_6_0/reindex')(ES_6_0);
-require('./es_6_0/search')(ES_6_0);
+ // adding generated specs
+ Object.keys(spec).forEach(endpoint => {
+ ES.addEndpointDescription(endpoint, spec[endpoint]);
+ });
-export default ES_6_0;
+ // adding globals and custom API definitions
+ require('./js/aliases')(ES);
+ require('./js/aggregations')(ES);
+ require('./js/document')(ES);
+ require('./js/filter')(ES);
+ require('./js/globals')(ES);
+ register(ES);
+ require('./js/mappings')(ES);
+ require('./js/settings')(ES);
+ require('./js/query')(ES);
+ require('./js/reindex')(ES);
+ require('./js/search')(ES);
+};
+
+export default ES;
diff --git a/src/plugins/console/server/lib/spec_definitions/index.d.ts b/src/plugins/console/server/lib/spec_definitions/index.d.ts
index 0a79d3fb386f1..da0125a186c15 100644
--- a/src/plugins/console/server/lib/spec_definitions/index.d.ts
+++ b/src/plugins/console/server/lib/spec_definitions/index.d.ts
@@ -19,6 +19,13 @@
export declare function addProcessorDefinition(...args: any[]): any;
-export declare function resolveApi(senseVersion: string, apis: string[]): object;
+export declare function resolveApi(): object;
export declare function addExtensionSpecFilePath(...args: any[]): any;
+
+/**
+ * A function that synchronously reads files JSON from disk and builds
+ * the autocomplete structures served to the client. This must be called
+ * after any extensions have been loaded.
+ */
+export declare function loadSpec(): any;
diff --git a/src/plugins/console/server/lib/spec_definitions/index.js b/src/plugins/console/server/lib/spec_definitions/index.js
index 3fe1913d5a193..abf55639fbee8 100644
--- a/src/plugins/console/server/lib/spec_definitions/index.js
+++ b/src/plugins/console/server/lib/spec_definitions/index.js
@@ -17,8 +17,10 @@
* under the License.
*/
-export { addProcessorDefinition } from './es_6_0/ingest';
+export { addProcessorDefinition } from './js/ingest';
-export { addExtensionSpecFilePath } from './spec';
+export { addExtensionSpecFilePath } from './json';
+
+export { loadSpec } from './es';
export { resolveApi } from './server';
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/aggregations.js b/src/plugins/console/server/lib/spec_definitions/js/aggregations.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/aggregations.js
rename to src/plugins/console/server/lib/spec_definitions/js/aggregations.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/aliases.js b/src/plugins/console/server/lib/spec_definitions/js/aliases.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/aliases.js
rename to src/plugins/console/server/lib/spec_definitions/js/aliases.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/document.js b/src/plugins/console/server/lib/spec_definitions/js/document.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/document.js
rename to src/plugins/console/server/lib/spec_definitions/js/document.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/filter.js b/src/plugins/console/server/lib/spec_definitions/js/filter.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/filter.js
rename to src/plugins/console/server/lib/spec_definitions/js/filter.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/globals.js b/src/plugins/console/server/lib/spec_definitions/js/globals.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/globals.js
rename to src/plugins/console/server/lib/spec_definitions/js/globals.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/ingest.js b/src/plugins/console/server/lib/spec_definitions/js/ingest.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/ingest.js
rename to src/plugins/console/server/lib/spec_definitions/js/ingest.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js b/src/plugins/console/server/lib/spec_definitions/js/mappings.js
similarity index 99%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js
rename to src/plugins/console/server/lib/spec_definitions/js/mappings.js
index 8c31e5bc6fbb2..5884d14d4dc8b 100644
--- a/src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js
+++ b/src/plugins/console/server/lib/spec_definitions/js/mappings.js
@@ -19,9 +19,7 @@
const _ = require('lodash');
-const BOOLEAN = {
- __one_of: [true, false],
-};
+import { BOOLEAN } from './shared';
export default function(api) {
api.addEndpointDescription('put_mapping', {
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/dsl.js b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.js
similarity index 99%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/dsl.js
rename to src/plugins/console/server/lib/spec_definitions/js/query/dsl.js
index a5f0d15dee0e9..16b952fe0fe4f 100644
--- a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/dsl.js
+++ b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.js
@@ -281,9 +281,11 @@ export function queryDsl(api) {
__scope_link: '.',
},
],
- filter: {
- __scope_link: 'GLOBAL.filter',
- },
+ filter: [
+ {
+ __scope_link: 'GLOBAL.filter',
+ },
+ ],
minimum_should_match: 1,
boost: 1.0,
},
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/index.js b/src/plugins/console/server/lib/spec_definitions/js/query/index.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/index.js
rename to src/plugins/console/server/lib/spec_definitions/js/query/index.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/templates.js b/src/plugins/console/server/lib/spec_definitions/js/query/templates.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/templates.js
rename to src/plugins/console/server/lib/spec_definitions/js/query/templates.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/reindex.js b/src/plugins/console/server/lib/spec_definitions/js/reindex.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/reindex.js
rename to src/plugins/console/server/lib/spec_definitions/js/reindex.js
diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/search.js b/src/plugins/console/server/lib/spec_definitions/js/search.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/es_6_0/search.js
rename to src/plugins/console/server/lib/spec_definitions/js/search.js
diff --git a/src/plugins/console/server/lib/spec_definitions/js/settings.js b/src/plugins/console/server/lib/spec_definitions/js/settings.js
new file mode 100644
index 0000000000000..26cd0987c34a5
--- /dev/null
+++ b/src/plugins/console/server/lib/spec_definitions/js/settings.js
@@ -0,0 +1,74 @@
+/*
+ * 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 { BOOLEAN } from './shared';
+
+export default function(api) {
+ api.addEndpointDescription('put_settings', {
+ data_autocomplete_rules: {
+ refresh_interval: '1s',
+ number_of_shards: 1,
+ number_of_replicas: 1,
+ 'blocks.read_only': BOOLEAN,
+ 'blocks.read': BOOLEAN,
+ 'blocks.write': BOOLEAN,
+ 'blocks.metadata': BOOLEAN,
+ term_index_interval: 32,
+ term_index_divisor: 1,
+ 'translog.flush_threshold_ops': 5000,
+ 'translog.flush_threshold_size': '200mb',
+ 'translog.flush_threshold_period': '30m',
+ 'translog.disable_flush': BOOLEAN,
+ 'cache.filter.max_size': '2gb',
+ 'cache.filter.expire': '2h',
+ 'gateway.snapshot_interval': '10s',
+ routing: {
+ allocation: {
+ include: {
+ tag: '',
+ },
+ exclude: {
+ tag: '',
+ },
+ require: {
+ tag: '',
+ },
+ total_shards_per_node: -1,
+ },
+ },
+ 'recovery.initial_shards': {
+ __one_of: ['quorum', 'quorum-1', 'half', 'full', 'full-1'],
+ },
+ 'ttl.disable_purge': BOOLEAN,
+ analysis: {
+ analyzer: {},
+ tokenizer: {},
+ filter: {},
+ char_filter: {},
+ },
+ 'cache.query.enable': BOOLEAN,
+ shadow_replicas: BOOLEAN,
+ shared_filesystem: BOOLEAN,
+ data_path: 'path',
+ codec: {
+ __one_of: ['default', 'best_compression', 'lucene_default'],
+ },
+ },
+ });
+}
diff --git a/src/plugins/console/server/lib/spec_definitions/js/shared.js b/src/plugins/console/server/lib/spec_definitions/js/shared.js
new file mode 100644
index 0000000000000..ace189e2d0913
--- /dev/null
+++ b/src/plugins/console/server/lib/spec_definitions/js/shared.js
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+export const BOOLEAN = Object.freeze({
+ __one_of: [true, false],
+});
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/.eslintrc b/src/plugins/console/server/lib/spec_definitions/json/.eslintrc
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/.eslintrc
rename to src/plugins/console/server/lib/spec_definitions/json/.eslintrc
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/_common.json b/src/plugins/console/server/lib/spec_definitions/json/generated/_common.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/_common.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/_common.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/bulk.json b/src/plugins/console/server/lib/spec_definitions/json/generated/bulk.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/bulk.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/bulk.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.aliases.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.aliases.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.aliases.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.aliases.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.allocation.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.allocation.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.allocation.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.allocation.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.count.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.count.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.count.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.count.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.fielddata.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.fielddata.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.fielddata.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.fielddata.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.health.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.health.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.health.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.health.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.help.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.help.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.help.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.help.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.indices.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.indices.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.indices.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.indices.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.master.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.master.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.master.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.master.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodeattrs.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodeattrs.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodeattrs.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodeattrs.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodes.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodes.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodes.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodes.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.pending_tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.pending_tasks.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.pending_tasks.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.pending_tasks.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.plugins.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.plugins.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.plugins.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.plugins.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.recovery.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.recovery.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.recovery.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.recovery.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.repositories.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.repositories.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.repositories.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.repositories.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.segments.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.segments.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.segments.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.segments.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.shards.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.shards.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.shards.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.shards.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.snapshots.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.snapshots.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.snapshots.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.snapshots.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.tasks.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.tasks.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.tasks.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.templates.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.templates.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.templates.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.templates.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.thread_pool.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.thread_pool.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.thread_pool.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.thread_pool.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/clear_scroll.json b/src/plugins/console/server/lib/spec_definitions/json/generated/clear_scroll.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/clear_scroll.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/clear_scroll.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.allocation_explain.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.allocation_explain.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.allocation_explain.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.allocation_explain.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.get_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.get_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.get_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.get_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.health.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.health.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.health.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.health.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.pending_tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.pending_tasks.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.pending_tasks.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.pending_tasks.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.put_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.put_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.put_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.remote_info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.remote_info.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.remote_info.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.remote_info.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.reroute.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.reroute.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.reroute.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.reroute.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.state.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.state.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.state.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.state.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.stats.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.stats.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.stats.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/count.json b/src/plugins/console/server/lib/spec_definitions/json/generated/count.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/count.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/count.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/create.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/create.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/create.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query_rethrottle.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query_rethrottle.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query_rethrottle.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_script.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_script.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_script.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/exists.json b/src/plugins/console/server/lib/spec_definitions/json/generated/exists.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/exists.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/exists.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/exists_source.json b/src/plugins/console/server/lib/spec_definitions/json/generated/exists_source.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/exists_source.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/exists_source.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/explain.json b/src/plugins/console/server/lib/spec_definitions/json/generated/explain.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/explain.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/explain.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/field_caps.json b/src/plugins/console/server/lib/spec_definitions/json/generated/field_caps.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/field_caps.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/field_caps.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/get.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_context.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script_context.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_context.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script_context.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_languages.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script_languages.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_languages.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script_languages.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_source.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_source.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_source.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_source.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/index.json b/src/plugins/console/server/lib/spec_definitions/json/generated/index.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/index.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/index.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.analyze.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.analyze.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.analyze.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.analyze.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clear_cache.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.clear_cache.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clear_cache.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.clear_cache.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clone.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.clone.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clone.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.clone.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.close.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.close.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.close.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.close.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.create.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.create.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.create.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_alias.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_alias.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_alias.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_alias.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_alias.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_alias.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_type.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_type.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush_synced.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush_synced.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.forcemerge.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.forcemerge.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.forcemerge.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.forcemerge.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_alias.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_alias.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_alias.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_field_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_field_mapping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_field_mapping.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_field_mapping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_mapping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_mapping.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_mapping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_upgrade.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.open.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.open.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.open.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.open.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_alias.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_alias.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_alias.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_mapping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_mapping.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_mapping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.recovery.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.recovery.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.recovery.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.recovery.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.refresh.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.refresh.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.refresh.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.refresh.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.rollover.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.rollover.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.rollover.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.rollover.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.segments.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.segments.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.segments.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.segments.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shard_stores.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.shard_stores.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shard_stores.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.shard_stores.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shrink.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.shrink.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shrink.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.shrink.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.split.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.split.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.split.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.split.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.stats.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.stats.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.stats.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.update_aliases.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.update_aliases.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.update_aliases.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.update_aliases.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.upgrade.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.validate_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.validate_query.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.validate_query.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.validate_query.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/info.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/info.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/info.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.delete_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.delete_pipeline.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.delete_pipeline.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.delete_pipeline.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.get_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.get_pipeline.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.get_pipeline.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.get_pipeline.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.processor_grok.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.processor_grok.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.processor_grok.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.processor_grok.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.put_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.put_pipeline.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.put_pipeline.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.put_pipeline.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.simulate.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.simulate.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.simulate.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.simulate.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/mget.json b/src/plugins/console/server/lib/spec_definitions/json/generated/mget.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/mget.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/mget.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/msearch.json b/src/plugins/console/server/lib/spec_definitions/json/generated/msearch.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/msearch.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/msearch.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/msearch_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/msearch_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/msearch_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/msearch_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/mtermvectors.json b/src/plugins/console/server/lib/spec_definitions/json/generated/mtermvectors.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/mtermvectors.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/mtermvectors.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.hot_threads.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.hot_threads.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.hot_threads.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.hot_threads.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.info.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.info.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.info.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.reload_secure_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.reload_secure_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.reload_secure_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.reload_secure_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.stats.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.stats.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.stats.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.usage.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.usage.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.usage.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.usage.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ping.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/ping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/put_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/put_script.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/put_script.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/put_script.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/rank_eval.json b/src/plugins/console/server/lib/spec_definitions/json/generated/rank_eval.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/rank_eval.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/rank_eval.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/reindex.json b/src/plugins/console/server/lib/spec_definitions/json/generated/reindex.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/reindex.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/reindex.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/reindex_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/reindex_rethrottle.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/reindex_rethrottle.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/reindex_rethrottle.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/render_search_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/render_search_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/render_search_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/render_search_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/scripts_painless_execute.json b/src/plugins/console/server/lib/spec_definitions/json/generated/scripts_painless_execute.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/scripts_painless_execute.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/scripts_painless_execute.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/scroll.json b/src/plugins/console/server/lib/spec_definitions/json/generated/scroll.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/scroll.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/scroll.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/search.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search_shards.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search_shards.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search_shards.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/search_shards.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/search_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.cleanup_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.cleanup_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.cleanup_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.cleanup_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.restore.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.restore.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.restore.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.restore.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.status.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.status.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.status.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.status.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.verify_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.verify_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.verify_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.verify_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.cancel.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.cancel.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.cancel.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.cancel.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.get.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.get.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.get.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.list.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.list.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.list.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.list.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/termvectors.json b/src/plugins/console/server/lib/spec_definitions/json/generated/termvectors.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/termvectors.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/termvectors.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/update.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query_rethrottle.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query_rethrottle.json
rename to src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query_rethrottle.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/index.js b/src/plugins/console/server/lib/spec_definitions/json/index.js
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/index.js
rename to src/plugins/console/server/lib/spec_definitions/json/index.js
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/clear_scroll.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/clear_scroll.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/clear_scroll.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/clear_scroll.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.health.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.health.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.health.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.health.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.put_settings.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.put_settings.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.put_settings.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.reroute.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.reroute.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.reroute.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.reroute.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/count.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/count.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/count.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/count.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.analyze.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.analyze.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.clone.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.clone.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.clone.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.clone.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.create.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.create.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.create.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.create.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.delete_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.delete_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.delete_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.delete_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.exists_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.exists_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.exists_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.exists_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_field_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_field_mapping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_field_mapping.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_field_mapping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_mapping.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_mapping.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_mapping.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_alias.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_alias.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_alias.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_alias.json
diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json
new file mode 100644
index 0000000000000..2ae8fd82be4d8
--- /dev/null
+++ b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json
@@ -0,0 +1,7 @@
+{
+ "indices.put_settings": {
+ "data_autocomplete_rules": {
+ "__scope_link": "put_settings"
+ }
+ }
+}
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_template.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_template.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_template.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.rollover.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.rollover.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.rollover.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.rollover.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.update_aliases.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.update_aliases.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.update_aliases.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.update_aliases.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.validate_query.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.validate_query.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.validate_query.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.validate_query.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create_repository.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create_repository.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.restore.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.restore.json
similarity index 100%
rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.restore.json
rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.restore.json
diff --git a/src/plugins/console/server/lib/spec_definitions/server.js b/src/plugins/console/server/lib/spec_definitions/server.js
index dd700bf019507..cb855958d403a 100644
--- a/src/plugins/console/server/lib/spec_definitions/server.js
+++ b/src/plugins/console/server/lib/spec_definitions/server.js
@@ -17,21 +17,10 @@
* under the License.
*/
-import _ from 'lodash';
+import es from './es';
-const KNOWN_APIS = ['es_6_0'];
-
-export function resolveApi(senseVersion, apis) {
- const result = {};
- _.each(apis, function(name) {
- {
- if (KNOWN_APIS.includes(name)) {
- // for now we ignore sense_version. might add it in the api name later
- const api = require('./' + name); // eslint-disable-line import/no-dynamic-require
- result[name] = api.asJson();
- }
- }
- });
-
- return result;
+export function resolveApi() {
+ return {
+ es: es.asJson(),
+ };
}
diff --git a/src/plugins/console/server/lib/spec_definitions/server.test.js b/src/plugins/console/server/lib/spec_definitions/server.test.js
deleted file mode 100644
index 747689237c177..0000000000000
--- a/src/plugins/console/server/lib/spec_definitions/server.test.js
+++ /dev/null
@@ -1,51 +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 { resolveApi } from './server';
-
-describe('resolveApi', () => {
- it('allows known APIs to be resolved', () => {
- const mockReply = jest.fn(result => ({ type: () => result }));
- const result = resolveApi('Sense Version', ['es_6_0'], { response: mockReply });
- expect(result).toMatchObject({
- es_6_0: {
- endpoints: expect.any(Object),
- globals: expect.any(Object),
- name: expect.any(String),
- },
- });
- });
-
- it('does not resolve APIs that are not known', () => {
- const mockReply = jest.fn(result => ({ type: () => result }));
- const result = resolveApi('Sense Version', ['unknown'], { response: mockReply });
- expect(result).toEqual({});
- });
-
- it('handles request for apis that are known and unknown', () => {
- const mockReply = jest.fn(result => ({ type: () => result }));
- const result = resolveApi('Sense Version', ['es_6_0'], { response: mockReply });
- expect(result).toMatchObject({
- es_6_0: {
- endpoints: expect.any(Object),
- globals: expect.any(Object),
- name: expect.any(String),
- },
- });
- });
-});
diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json
deleted file mode 100644
index 2e1e3024665a4..0000000000000
--- a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json
+++ /dev/null
@@ -1,108 +0,0 @@
-{
- "indices.put_settings": {
- "data_autocomplete_rules": {
- "refresh_interval": "1s",
- "number_of_shards": 1,
- "number_of_replicas": 1,
- "blocks.read_only": {
- "__one_of": [
- false,
- true
- ]
- },
- "blocks.read": {
- "__one_of": [
- true,
- false
- ]
- },
- "blocks.write": {
- "__one_of": [
- true,
- false
- ]
- },
- "blocks.metadata": {
- "__one_of": [
- true,
- false
- ]
- },
- "term_index_interval": 32,
- "term_index_divisor": 1,
- "translog.flush_threshold_ops": 5000,
- "translog.flush_threshold_size": "200mb",
- "translog.flush_threshold_period": "30m",
- "translog.disable_flush": {
- "__one_of": [
- true,
- false
- ]
- },
- "cache.filter.max_size": "2gb",
- "cache.filter.expire": "2h",
- "gateway.snapshot_interval": "10s",
- "routing": {
- "allocation": {
- "include": {
- "tag": ""
- },
- "exclude": {
- "tag": ""
- },
- "require": {
- "tag": ""
- },
- "total_shards_per_node": -1
- }
- },
- "recovery.initial_shards": {
- "__one_of": [
- "quorum",
- "quorum-1",
- "half",
- "full",
- "full-1"
- ]
- },
- "ttl.disable_purge": {
- "__one_of": [
- true,
- false
- ]
- },
- "analysis": {
- "analyzer": {},
- "tokenizer": {},
- "filter": {},
- "char_filter": {}
- },
- "cache.query.enable": {
- "__one_of": [
- true,
- false
- ]
- },
- "shadow_replicas": {
- "__one_of": [
- true,
- false
- ]
- },
- "shared_filesystem": {
- "__one_of": [
- true,
- false
- ]
- },
- "data_path": "path",
- "codec": {
- "__one_of": [
- "default",
- "best_compression",
- "lucene_default"
- ]
- }
- }
- }
-}
diff --git a/src/plugins/console/server/plugin.ts b/src/plugins/console/server/plugin.ts
index 65647bd5acb7c..1954918f4d74f 100644
--- a/src/plugins/console/server/plugin.ts
+++ b/src/plugins/console/server/plugin.ts
@@ -21,7 +21,12 @@ import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'kibana/serv
import { readLegacyEsConfig } from '../../../legacy/core_plugins/console_legacy';
-import { ProxyConfigCollection, addExtensionSpecFilePath, addProcessorDefinition } from './lib';
+import {
+ ProxyConfigCollection,
+ addExtensionSpecFilePath,
+ addProcessorDefinition,
+ loadSpec,
+} from './lib';
import { ConfigType } from './config';
import { registerProxyRoute } from './routes/api/console/proxy';
import { registerSpecDefinitionsRoute } from './routes/api/console/spec_definitions';
@@ -75,5 +80,7 @@ export class ConsoleServerPlugin implements Plugin {
};
}
- start() {}
+ start() {
+ loadSpec();
+ }
}
diff --git a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts
index e2ece37f407ac..88bc250bbfce6 100644
--- a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts
+++ b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts
@@ -16,33 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
import { IRouter, RequestHandler } from 'kibana/server';
import { resolveApi } from '../../../../lib/spec_definitions';
export const registerSpecDefinitionsRoute = ({ router }: { router: IRouter }) => {
- const handler: RequestHandler> = async (
- ctx,
- request,
- response
- ) => {
- const { sense_version: version, apis } = request.query;
-
+ const handler: RequestHandler = async (ctx, request, response) => {
return response.ok({
- body: resolveApi(version, apis.split(',')),
+ body: resolveApi(),
headers: {
'Content-Type': 'application/json',
},
});
};
- const validate = {
- query: schema.object({
- sense_version: schema.string({ defaultValue: '' }),
- apis: schema.string(),
- }),
- };
-
- router.get({ path: '/api/console/api_server', validate }, handler);
- router.post({ path: '/api/console/api_server', validate }, handler);
+ router.get({ path: '/api/console/api_server', validate: false }, handler);
+ router.post({ path: '/api/console/api_server', validate: false }, handler);
};
diff --git a/src/plugins/data/README.md b/src/plugins/data/README.md
index 53618ec049e7c..0fa304c988935 100644
--- a/src/plugins/data/README.md
+++ b/src/plugins/data/README.md
@@ -6,4 +6,4 @@
- `filter`
- `index_patterns`
- `query`
-- `search`
+- `search`
\ No newline at end of file
diff --git a/src/plugins/data/common/index.ts b/src/plugins/data/common/index.ts
index cf8c0bfe3d434..e4a663a1599f1 100644
--- a/src/plugins/data/common/index.ts
+++ b/src/plugins/data/common/index.ts
@@ -26,3 +26,4 @@ export * from './query';
export * from './search';
export * from './search/aggs';
export * from './types';
+export * from './utils';
diff --git a/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts b/src/plugins/data/common/query/filter_manager/compare_filters.test.ts
similarity index 99%
rename from src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts
rename to src/plugins/data/common/query/filter_manager/compare_filters.test.ts
index da8f5b3564948..b0bb2f754d6cf 100644
--- a/src/plugins/data/public/query/filter_manager/lib/compare_filters.test.ts
+++ b/src/plugins/data/common/query/filter_manager/compare_filters.test.ts
@@ -18,7 +18,7 @@
*/
import { compareFilters, COMPARE_ALL_OPTIONS } from './compare_filters';
-import { buildEmptyFilter, buildQueryFilter, FilterStateStore } from '../../../../common';
+import { buildEmptyFilter, buildQueryFilter, FilterStateStore } from '../../es_query';
describe('filter manager utilities', () => {
describe('compare filters', () => {
diff --git a/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts b/src/plugins/data/common/query/filter_manager/compare_filters.ts
similarity index 98%
rename from src/plugins/data/public/query/filter_manager/lib/compare_filters.ts
rename to src/plugins/data/common/query/filter_manager/compare_filters.ts
index a2105fdc1d3ef..e047d5e0665d5 100644
--- a/src/plugins/data/public/query/filter_manager/lib/compare_filters.ts
+++ b/src/plugins/data/common/query/filter_manager/compare_filters.ts
@@ -18,7 +18,7 @@
*/
import { defaults, isEqual, omit, map } from 'lodash';
-import { FilterMeta, Filter } from '../../../../common';
+import { FilterMeta, Filter } from '../../es_query';
export interface FilterCompareOptions {
disabled?: boolean;
diff --git a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts b/src/plugins/data/common/query/filter_manager/dedup_filters.test.ts
similarity index 95%
rename from src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts
rename to src/plugins/data/common/query/filter_manager/dedup_filters.test.ts
index ecc0ec94e07c8..228489de37daa 100644
--- a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts
+++ b/src/plugins/data/common/query/filter_manager/dedup_filters.test.ts
@@ -18,14 +18,8 @@
*/
import { dedupFilters } from './dedup_filters';
-import {
- Filter,
- IIndexPattern,
- IFieldType,
- buildRangeFilter,
- buildQueryFilter,
- FilterStateStore,
-} from '../../../../common';
+import { Filter, buildRangeFilter, buildQueryFilter, FilterStateStore } from '../../es_query';
+import { IIndexPattern, IFieldType } from '../../index_patterns';
describe('filter manager utilities', () => {
let indexPattern: IIndexPattern;
diff --git a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts b/src/plugins/data/common/query/filter_manager/dedup_filters.ts
similarity index 97%
rename from src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts
rename to src/plugins/data/common/query/filter_manager/dedup_filters.ts
index d5d0e70504b41..7d1b00ac10c0d 100644
--- a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.ts
+++ b/src/plugins/data/common/query/filter_manager/dedup_filters.ts
@@ -19,7 +19,7 @@
import { filter, find } from 'lodash';
import { compareFilters, FilterCompareOptions } from './compare_filters';
-import { Filter } from '../../../../common';
+import { Filter } from '../../es_query';
/**
* Combine 2 filter collections, removing duplicates
diff --git a/src/plugins/data/common/query/filter_manager/index.ts b/src/plugins/data/common/query/filter_manager/index.ts
new file mode 100644
index 0000000000000..315c124f083a8
--- /dev/null
+++ b/src/plugins/data/common/query/filter_manager/index.ts
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+export { dedupFilters } from './dedup_filters';
+export { uniqFilters } from './uniq_filters';
+export { compareFilters, COMPARE_ALL_OPTIONS, FilterCompareOptions } from './compare_filters';
diff --git a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts b/src/plugins/data/common/query/filter_manager/uniq_filters.test.ts
similarity index 99%
rename from src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts
rename to src/plugins/data/common/query/filter_manager/uniq_filters.test.ts
index 8b525a3d2a2e4..5a35e85c95eaa 100644
--- a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.test.ts
+++ b/src/plugins/data/common/query/filter_manager/uniq_filters.test.ts
@@ -18,7 +18,7 @@
*/
import { uniqFilters } from './uniq_filters';
-import { buildQueryFilter, Filter, FilterStateStore } from '../../../../common';
+import { buildQueryFilter, Filter, FilterStateStore } from '../../es_query';
describe('filter manager utilities', () => {
describe('niqFilter', () => {
diff --git a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts b/src/plugins/data/common/query/filter_manager/uniq_filters.ts
similarity index 96%
rename from src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts
rename to src/plugins/data/common/query/filter_manager/uniq_filters.ts
index 44c102d7ab15d..683cbf7c78a89 100644
--- a/src/plugins/data/public/query/filter_manager/lib/uniq_filters.ts
+++ b/src/plugins/data/common/query/filter_manager/uniq_filters.ts
@@ -17,8 +17,8 @@
* under the License.
*/
import { each, union } from 'lodash';
+import { Filter } from '../../es_query';
import { dedupFilters } from './dedup_filters';
-import { Filter } from '../../../../common';
/**
* Remove duplicate filters from an array of filters
diff --git a/src/plugins/data/common/query/index.ts b/src/plugins/data/common/query/index.ts
index d8f7b5091eb8f..421cc4f63e4ef 100644
--- a/src/plugins/data/common/query/index.ts
+++ b/src/plugins/data/common/query/index.ts
@@ -17,4 +17,5 @@
* under the License.
*/
+export * from './filter_manager';
export * from './types';
diff --git a/src/plugins/data/common/utils/abort_utils.test.ts b/src/plugins/data/common/utils/abort_utils.test.ts
new file mode 100644
index 0000000000000..d2a25f2c2dd52
--- /dev/null
+++ b/src/plugins/data/common/utils/abort_utils.test.ts
@@ -0,0 +1,114 @@
+/*
+ * 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 { AbortError, toPromise, getCombinedSignal } from './abort_utils';
+
+jest.useFakeTimers();
+
+const flushPromises = () => new Promise(resolve => setImmediate(resolve));
+
+describe('AbortUtils', () => {
+ describe('AbortError', () => {
+ test('should preserve `message`', () => {
+ const message = 'my error message';
+ const error = new AbortError(message);
+ expect(error.message).toBe(message);
+ });
+
+ test('should have a name of "AbortError"', () => {
+ const error = new AbortError();
+ expect(error.name).toBe('AbortError');
+ });
+ });
+
+ describe('toPromise', () => {
+ describe('resolves', () => {
+ test('should not resolve if the signal does not abort', async () => {
+ const controller = new AbortController();
+ const promise = toPromise(controller.signal);
+ const whenResolved = jest.fn();
+ promise.then(whenResolved);
+ await flushPromises();
+ expect(whenResolved).not.toBeCalled();
+ });
+
+ test('should resolve if the signal does abort', async () => {
+ const controller = new AbortController();
+ const promise = toPromise(controller.signal);
+ const whenResolved = jest.fn();
+ promise.then(whenResolved);
+ controller.abort();
+ await flushPromises();
+ expect(whenResolved).toBeCalled();
+ });
+ });
+
+ describe('rejects', () => {
+ test('should not reject if the signal does not abort', async () => {
+ const controller = new AbortController();
+ const promise = toPromise(controller.signal, true);
+ const whenRejected = jest.fn();
+ promise.catch(whenRejected);
+ await flushPromises();
+ expect(whenRejected).not.toBeCalled();
+ });
+
+ test('should reject if the signal does abort', async () => {
+ const controller = new AbortController();
+ const promise = toPromise(controller.signal, true);
+ const whenRejected = jest.fn();
+ promise.catch(whenRejected);
+ controller.abort();
+ await flushPromises();
+ expect(whenRejected).toBeCalled();
+ });
+ });
+ });
+
+ describe('getCombinedSignal', () => {
+ test('should return an AbortSignal', () => {
+ const signal = getCombinedSignal([]);
+ expect(signal instanceof AbortSignal).toBe(true);
+ });
+
+ test('should not abort if none of the signals abort', async () => {
+ const controller1 = new AbortController();
+ const controller2 = new AbortController();
+ setTimeout(() => controller1.abort(), 2000);
+ setTimeout(() => controller2.abort(), 1000);
+ const signal = getCombinedSignal([controller1.signal, controller2.signal]);
+ expect(signal.aborted).toBe(false);
+ jest.advanceTimersByTime(500);
+ await flushPromises();
+ expect(signal.aborted).toBe(false);
+ });
+
+ test('should abort when the first signal aborts', async () => {
+ const controller1 = new AbortController();
+ const controller2 = new AbortController();
+ setTimeout(() => controller1.abort(), 2000);
+ setTimeout(() => controller2.abort(), 1000);
+ const signal = getCombinedSignal([controller1.signal, controller2.signal]);
+ expect(signal.aborted).toBe(false);
+ jest.advanceTimersByTime(1000);
+ await flushPromises();
+ expect(signal.aborted).toBe(true);
+ });
+ });
+});
diff --git a/src/plugins/data/common/utils/abort_utils.ts b/src/plugins/data/common/utils/abort_utils.ts
new file mode 100644
index 0000000000000..5051515f3a826
--- /dev/null
+++ b/src/plugins/data/common/utils/abort_utils.ts
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * Class used to signify that something was aborted. Useful for applications to conditionally handle
+ * this type of error differently than other errors.
+ */
+export class AbortError extends Error {
+ constructor(message = 'Aborted') {
+ super(message);
+ this.message = message;
+ this.name = 'AbortError';
+ }
+}
+
+/**
+ * Returns a `Promise` corresponding with when the given `AbortSignal` is aborted. Useful for
+ * situations when you might need to `Promise.race` multiple `AbortSignal`s, or an `AbortSignal`
+ * with any other expected errors (or completions).
+ * @param signal The `AbortSignal` to generate the `Promise` from
+ * @param shouldReject If `false`, the promise will be resolved, otherwise it will be rejected
+ */
+export function toPromise(signal: AbortSignal, shouldReject = false) {
+ return new Promise((resolve, reject) => {
+ const action = shouldReject ? reject : resolve;
+ if (signal.aborted) action();
+ signal.addEventListener('abort', action);
+ });
+}
+
+/**
+ * Returns an `AbortSignal` that will be aborted when the first of the given signals aborts.
+ * @param signals
+ */
+export function getCombinedSignal(signals: AbortSignal[]) {
+ const promises = signals.map(signal => toPromise(signal));
+ const controller = new AbortController();
+ Promise.race(promises).then(() => controller.abort());
+ return controller.signal;
+}
diff --git a/src/plugins/data/common/utils/index.ts b/src/plugins/data/common/utils/index.ts
index 8b8686c51b9c1..33989f3ad50a7 100644
--- a/src/plugins/data/common/utils/index.ts
+++ b/src/plugins/data/common/utils/index.ts
@@ -19,3 +19,4 @@
/** @internal */
export { shortenDottedString } from './shorten_dotted_string';
+export { AbortError, toPromise, getCombinedSignal } from './abort_utils';
diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts
index 58bd9a5ab05d7..339a5fea91c5f 100644
--- a/src/plugins/data/public/index.ts
+++ b/src/plugins/data/public/index.ts
@@ -47,13 +47,13 @@ import {
isQueryStringFilter,
isRangeFilter,
toggleFilterNegated,
+ compareFilters,
+ COMPARE_ALL_OPTIONS,
} from '../common';
import { FilterLabel } from './ui/filter_bar';
import {
- compareFilters,
- COMPARE_ALL_OPTIONS,
generateFilters,
onlyDisabledFiltersChanged,
changeTimeFilter,
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
index b6ca91169a933..305aa8575e4d7 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.test.ts
@@ -18,6 +18,8 @@
*/
import { defaults, pluck, last, get } from 'lodash';
+
+jest.mock('../../../../kibana_utils/public/history');
import { IndexPattern } from './index_pattern';
import { DuplicateField } from '../../../../kibana_utils/public';
diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts
index c5cff1c5c68d9..e3fc0e97af09b 100644
--- a/src/plugins/data/public/mocks.ts
+++ b/src/plugins/data/public/mocks.ts
@@ -19,9 +19,7 @@
import { Plugin, DataPublicPluginSetup, DataPublicPluginStart, IndexPatternsContract } from '.';
import { fieldFormatsMock } from '../common/field_formats/mocks';
-import { searchSetupMock } from './search/mocks';
-import { AggTypeFieldFilters } from './search/aggs';
-import { searchAggsStartMock } from './search/aggs/mocks';
+import { searchSetupMock, searchStartMock } from './search/mocks';
import { queryServiceMock } from './query/mocks';
export type Setup = jest.Mocked>;
@@ -35,59 +33,28 @@ const autocompleteMock: any = {
const createSetupContract = (): Setup => {
const querySetupMock = queryServiceMock.createSetupContract();
- const setupContract = {
+ return {
autocomplete: autocompleteMock,
search: searchSetupMock,
fieldFormats: fieldFormatsMock as DataPublicPluginSetup['fieldFormats'],
query: querySetupMock,
- __LEGACY: {
- esClient: {
- search: jest.fn(),
- msearch: jest.fn(),
- },
- },
};
-
- return setupContract;
};
const createStartContract = (): Start => {
const queryStartMock = queryServiceMock.createStartContract();
- const startContract = {
+ return {
actions: {
createFiltersFromEvent: jest.fn().mockResolvedValue(['yes']),
},
autocomplete: autocompleteMock,
- getSuggestions: jest.fn(),
- search: {
- aggs: searchAggsStartMock(),
- search: jest.fn(),
- __LEGACY: {
- AggConfig: jest.fn() as any,
- AggType: jest.fn(),
- aggTypeFieldFilters: new AggTypeFieldFilters(),
- FieldParamType: jest.fn(),
- MetricAggType: jest.fn(),
- parentPipelineAggHelper: jest.fn() as any,
- siblingPipelineAggHelper: jest.fn() as any,
- esClient: {
- search: jest.fn(),
- msearch: jest.fn(),
- },
- },
- },
+ search: searchStartMock,
fieldFormats: fieldFormatsMock as DataPublicPluginStart['fieldFormats'],
query: queryStartMock,
ui: {
IndexPatternSelect: jest.fn(),
SearchBar: jest.fn(),
},
- __LEGACY: {
- esClient: {
- search: jest.fn(),
- msearch: jest.fn(),
- },
- },
indexPatterns: ({
make: () => ({
fieldsFetcher: {
@@ -97,7 +64,6 @@ const createStartContract = (): Start => {
get: jest.fn().mockReturnValue(Promise.resolve({})),
} as unknown) as IndexPatternsContract,
};
- return startContract;
};
export { searchSourceMock } from './search/mocks';
diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts
index a01c133712206..fc5dde94fa851 100644
--- a/src/plugins/data/public/plugin.ts
+++ b/src/plugins/data/public/plugin.ts
@@ -39,6 +39,7 @@ import { createIndexPatternSelect } from './ui/index_pattern_select';
import { IndexPatternsService } from './index_patterns';
import {
setFieldFormats,
+ setHttp,
setIndexPatterns,
setInjectedMetadata,
setNotifications,
@@ -128,6 +129,7 @@ export class DataPublicPlugin implements Plugin string;
getPhraseFilterValue: (filter: import("../common").PhraseFilter) => string | number | boolean;
getDisplayValueFromFilter: typeof getDisplayValueFromFilter;
- compareFilters: (first: import("../common").Filter | import("../common").Filter[], second: import("../common").Filter | import("../common").Filter[], comparatorOptions?: import("./query/filter_manager/lib/compare_filters").FilterCompareOptions) => boolean;
- COMPARE_ALL_OPTIONS: import("./query/filter_manager/lib/compare_filters").FilterCompareOptions;
+ compareFilters: (first: import("../common").Filter | import("../common").Filter[], second: import("../common").Filter | import("../common").Filter[], comparatorOptions?: import("../common").FilterCompareOptions) => boolean;
+ COMPARE_ALL_OPTIONS: import("../common").FilterCompareOptions;
generateFilters: typeof generateFilters;
onlyDisabledFiltersChanged: (newFilters?: import("../common").Filter[] | undefined, oldFilters?: import("../common").Filter[] | undefined) => boolean;
changeTimeFilter: typeof changeTimeFilter;
@@ -1843,8 +1843,8 @@ export type TSearchStrategyProvider = (context: ISearc
// src/plugins/data/public/index.ts:405:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:406:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:409: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:34: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:38: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: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/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:60:5 - (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts
diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts
index c951953b26555..fba1866ebd615 100644
--- a/src/plugins/data/public/query/filter_manager/filter_manager.ts
+++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts
@@ -22,13 +22,19 @@ import { Subject } from 'rxjs';
import { IUiSettingsClient } from 'src/core/public';
-import { COMPARE_ALL_OPTIONS, compareFilters } from './lib/compare_filters';
import { sortFilters } from './lib/sort_filters';
import { mapAndFlattenFilters } from './lib/map_and_flatten_filters';
-import { uniqFilters } from './lib/uniq_filters';
import { onlyDisabledFiltersChanged } from './lib/only_disabled';
import { PartitionedFilters } from './types';
-import { FilterStateStore, Filter, isFilterPinned } from '../../../common';
+
+import {
+ FilterStateStore,
+ Filter,
+ uniqFilters,
+ isFilterPinned,
+ compareFilters,
+ COMPARE_ALL_OPTIONS,
+} from '../../../common';
export class FilterManager {
private filters: Filter[] = [];
diff --git a/src/plugins/data/public/query/filter_manager/index.ts b/src/plugins/data/public/query/filter_manager/index.ts
index 09990adacde45..be512c503d531 100644
--- a/src/plugins/data/public/query/filter_manager/index.ts
+++ b/src/plugins/data/public/query/filter_manager/index.ts
@@ -19,8 +19,6 @@
export { FilterManager } from './filter_manager';
-export { uniqFilters } from './lib/uniq_filters';
export { mapAndFlattenFilters } from './lib/map_and_flatten_filters';
export { onlyDisabledFiltersChanged } from './lib/only_disabled';
export { generateFilters } from './lib/generate_filters';
-export { compareFilters, COMPARE_ALL_OPTIONS } from './lib/compare_filters';
diff --git a/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts b/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts
index 34e1ac38ae95f..18c51ebeabe54 100644
--- a/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts
+++ b/src/plugins/data/public/query/filter_manager/lib/only_disabled.ts
@@ -18,8 +18,7 @@
*/
import { filter } from 'lodash';
-import { Filter } from '../../../../common';
-import { compareFilters, COMPARE_ALL_OPTIONS } from './compare_filters';
+import { Filter, compareFilters, COMPARE_ALL_OPTIONS } from '../../../../common';
const isEnabled = (f: Filter) => f && f.meta && !f.meta.disabled;
diff --git a/src/plugins/data/public/query/state_sync/connect_to_query_state.ts b/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
index a22e66860c765..331d8969f2483 100644
--- a/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
+++ b/src/plugins/data/public/query/state_sync/connect_to_query_state.ts
@@ -21,10 +21,9 @@ import { Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import _ from 'lodash';
import { BaseStateContainer } from '../../../../kibana_utils/public';
-import { COMPARE_ALL_OPTIONS, compareFilters } from '../filter_manager/lib/compare_filters';
import { QuerySetup, QueryStart } from '../query_service';
import { QueryState, QueryStateChange } from './types';
-import { FilterStateStore } from '../../../common/es_query/filters';
+import { FilterStateStore, COMPARE_ALL_OPTIONS, compareFilters } from '../../../common';
/**
* Helper to setup two-way syncing of global data and a state container
diff --git a/src/plugins/data/public/query/state_sync/create_global_query_observable.ts b/src/plugins/data/public/query/state_sync/create_global_query_observable.ts
index d0d97bfaaeb36..dd075f9be7d94 100644
--- a/src/plugins/data/public/query/state_sync/create_global_query_observable.ts
+++ b/src/plugins/data/public/query/state_sync/create_global_query_observable.ts
@@ -20,10 +20,10 @@
import { Observable, Subscription } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { TimefilterSetup } from '../timefilter';
-import { COMPARE_ALL_OPTIONS, compareFilters, FilterManager } from '../filter_manager';
+import { FilterManager } from '../filter_manager';
import { QueryState, QueryStateChange } from './index';
import { createStateContainer } from '../../../../kibana_utils/public';
-import { isFilterPinned } from '../../../common/es_query/filters';
+import { isFilterPinned, compareFilters, COMPARE_ALL_OPTIONS } from '../../../common';
export function createQueryStateObservable({
timefilter: { timefilter },
diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts
index ac72cfd6f62ca..f3d2d99af5998 100644
--- a/src/plugins/data/public/search/index.ts
+++ b/src/plugins/data/public/search/index.ts
@@ -56,4 +56,6 @@ export {
SortDirection,
} from './search_source';
+export { SearchInterceptor } from './search_interceptor';
+
export { FetchOptions } from './fetch';
diff --git a/src/plugins/data/public/search/mocks.ts b/src/plugins/data/public/search/mocks.ts
index 71b4eece91cef..12cf258759a99 100644
--- a/src/plugins/data/public/search/mocks.ts
+++ b/src/plugins/data/public/search/mocks.ts
@@ -17,7 +17,9 @@
* under the License.
*/
-import { searchAggsSetupMock } from './aggs/mocks';
+import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks';
+import { AggTypeFieldFilters } from './aggs/param_types/filter';
+import { ISearchStart } from './types';
export * from './search_source/mocks';
@@ -26,3 +28,24 @@ export const searchSetupMock = {
registerSearchStrategyContext: jest.fn(),
registerSearchStrategyProvider: jest.fn(),
};
+
+export const searchStartMock: jest.Mocked = {
+ aggs: searchAggsStartMock(),
+ search: jest.fn(),
+ cancel: jest.fn(),
+ getPendingCount$: jest.fn(),
+ runBeyondTimeout: jest.fn(),
+ __LEGACY: {
+ AggConfig: jest.fn() as any,
+ AggType: jest.fn(),
+ aggTypeFieldFilters: new AggTypeFieldFilters(),
+ FieldParamType: jest.fn(),
+ MetricAggType: jest.fn(),
+ parentPipelineAggHelper: jest.fn() as any,
+ siblingPipelineAggHelper: jest.fn() as any,
+ esClient: {
+ search: jest.fn(),
+ msearch: jest.fn(),
+ },
+ },
+};
diff --git a/src/plugins/data/public/search/request_timeout_error.ts b/src/plugins/data/public/search/request_timeout_error.ts
new file mode 100644
index 0000000000000..92894deb4f0ff
--- /dev/null
+++ b/src/plugins/data/public/search/request_timeout_error.ts
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * Class used to signify that a request timed out. Useful for applications to conditionally handle
+ * this type of error differently than other errors.
+ */
+export class RequestTimeoutError extends Error {
+ constructor(message = 'Request timed out') {
+ super(message);
+ this.message = message;
+ this.name = 'RequestTimeoutError';
+ }
+}
diff --git a/src/plugins/data/public/search/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor.test.ts
new file mode 100644
index 0000000000000..a89d17464b9e0
--- /dev/null
+++ b/src/plugins/data/public/search/search_interceptor.test.ts
@@ -0,0 +1,157 @@
+/*
+ * 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 { Observable, Subject } from 'rxjs';
+import { IKibanaSearchRequest } from '../../common/search';
+import { RequestTimeoutError } from './request_timeout_error';
+import { SearchInterceptor } from './search_interceptor';
+
+jest.useFakeTimers();
+
+const flushPromises = () => new Promise(resolve => setImmediate(resolve));
+const mockSearch = jest.fn();
+let searchInterceptor: SearchInterceptor;
+
+describe('SearchInterceptor', () => {
+ beforeEach(() => {
+ mockSearch.mockClear();
+ searchInterceptor = new SearchInterceptor(1000);
+ });
+
+ describe('search', () => {
+ test('should invoke `search` with the request', () => {
+ mockSearch.mockReturnValue(new Observable());
+ const mockRequest: IKibanaSearchRequest = {};
+ searchInterceptor.search(mockSearch, mockRequest);
+ expect(mockSearch.mock.calls[0][0]).toBe(mockRequest);
+ });
+
+ test('should mirror the observable to completion if the request does not time out', () => {
+ const mockResponse = new Subject();
+ mockSearch.mockReturnValue(mockResponse.asObservable());
+ const response = searchInterceptor.search(mockSearch, {});
+
+ setTimeout(() => mockResponse.next('hi'), 250);
+ setTimeout(() => mockResponse.complete(), 500);
+
+ const next = jest.fn();
+ const complete = jest.fn();
+ response.subscribe({ next, complete });
+
+ jest.advanceTimersByTime(1000);
+
+ expect(next).toHaveBeenCalledWith('hi');
+ expect(complete).toHaveBeenCalled();
+ });
+
+ test('should mirror the observable to error if the request does not time out', () => {
+ const mockResponse = new Subject();
+ mockSearch.mockReturnValue(mockResponse.asObservable());
+ const response = searchInterceptor.search(mockSearch, {});
+
+ setTimeout(() => mockResponse.next('hi'), 250);
+ setTimeout(() => mockResponse.error('error'), 500);
+
+ const next = jest.fn();
+ const error = jest.fn();
+ response.subscribe({ next, error });
+
+ jest.advanceTimersByTime(1000);
+
+ expect(next).toHaveBeenCalledWith('hi');
+ expect(error).toHaveBeenCalledWith('error');
+ });
+
+ test('should return a `RequestTimeoutError` if the request times out', () => {
+ mockSearch.mockReturnValue(new Observable());
+ const response = searchInterceptor.search(mockSearch, {});
+
+ const error = jest.fn();
+ response.subscribe({ error });
+
+ jest.advanceTimersByTime(1000);
+
+ expect(error).toHaveBeenCalled();
+ expect(error.mock.calls[0][0] instanceof RequestTimeoutError).toBe(true);
+ });
+ });
+
+ describe('cancelPending', () => {
+ test('should abort all pending requests', async () => {
+ mockSearch.mockReturnValue(new Observable());
+
+ searchInterceptor.search(mockSearch, {});
+ searchInterceptor.search(mockSearch, {});
+ searchInterceptor.cancelPending();
+
+ await flushPromises();
+
+ const areAllRequestsAborted = mockSearch.mock.calls.every(([, { signal }]) => signal.aborted);
+ expect(areAllRequestsAborted).toBe(true);
+ });
+ });
+
+ describe('runBeyondTimeout', () => {
+ test('should prevent the request from timing out', () => {
+ const mockResponse = new Subject();
+ mockSearch.mockReturnValue(mockResponse.asObservable());
+ const response = searchInterceptor.search(mockSearch, {});
+
+ setTimeout(searchInterceptor.runBeyondTimeout, 500);
+ setTimeout(() => mockResponse.next('hi'), 250);
+ setTimeout(() => mockResponse.complete(), 2000);
+
+ const next = jest.fn();
+ const complete = jest.fn();
+ const error = jest.fn();
+ response.subscribe({ next, error, complete });
+
+ jest.advanceTimersByTime(2000);
+
+ expect(next).toHaveBeenCalledWith('hi');
+ expect(error).not.toHaveBeenCalled();
+ expect(complete).toHaveBeenCalled();
+ });
+ });
+
+ describe('getPendingCount$', () => {
+ test('should observe the number of pending requests', () => {
+ let i = 0;
+ const mockResponses = [new Subject(), new Subject()];
+ mockSearch.mockImplementation(() => mockResponses[i++]);
+
+ const pendingCount$ = searchInterceptor.getPendingCount$();
+
+ const next = jest.fn();
+ pendingCount$.subscribe(next);
+
+ const error = jest.fn();
+ searchInterceptor.search(mockSearch, {}).subscribe({ error });
+ searchInterceptor.search(mockSearch, {}).subscribe({ error });
+
+ setTimeout(() => mockResponses[0].complete(), 250);
+ setTimeout(() => mockResponses[1].error('error'), 500);
+
+ jest.advanceTimersByTime(500);
+
+ expect(next).toHaveBeenCalled();
+ expect(next.mock.calls).toEqual([[0], [1], [2], [1], [0]]);
+ });
+ });
+});
diff --git a/src/plugins/data/public/search/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor.ts
new file mode 100644
index 0000000000000..3f83214f6050c
--- /dev/null
+++ b/src/plugins/data/public/search/search_interceptor.ts
@@ -0,0 +1,121 @@
+/*
+ * 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 { BehaviorSubject, fromEvent, throwError } from 'rxjs';
+import { mergeMap, takeUntil, finalize } from 'rxjs/operators';
+import { getCombinedSignal } from '../../common/utils';
+import { IKibanaSearchRequest } from '../../common/search';
+import { ISearchGeneric, ISearchOptions } from './i_search';
+import { RequestTimeoutError } from './request_timeout_error';
+
+export class SearchInterceptor {
+ /**
+ * `abortController` used to signal all searches to abort.
+ */
+ private abortController = new AbortController();
+
+ /**
+ * Observable that emits when the number of pending requests changes.
+ */
+ private pendingCount$ = new BehaviorSubject(0);
+
+ /**
+ * The IDs from `setTimeout` when scheduling the automatic timeout for each request.
+ */
+ private timeoutIds: Set = new Set();
+
+ /**
+ * This class should be instantiated with a `requestTimeout` corresponding with how many ms after
+ * requests are initiated that they should automatically cancel.
+ * @param requestTimeout Usually config value `elasticsearch.requestTimeout`
+ */
+ constructor(private readonly requestTimeout?: number) {}
+
+ /**
+ * Abort our `AbortController`, which in turn aborts any intercepted searches.
+ */
+ public cancelPending = () => {
+ this.abortController.abort();
+ this.abortController = new AbortController();
+ };
+
+ /**
+ * Un-schedule timing out all of the searches intercepted.
+ */
+ public runBeyondTimeout = () => {
+ this.timeoutIds.forEach(clearTimeout);
+ this.timeoutIds.clear();
+ };
+
+ /**
+ * Returns an `Observable` over the current number of pending searches. This could mean that one
+ * of the search requests is still in flight, or that it has only received partial responses.
+ */
+ public getPendingCount$ = () => {
+ return this.pendingCount$.asObservable();
+ };
+
+ /**
+ * Searches using the given `search` method. Overrides the `AbortSignal` with one that will abort
+ * either when `cancelPending` is called, when the request times out, or when the original
+ * `AbortSignal` is aborted. Updates the `pendingCount` when the request is started/finalized.
+ */
+ public search = (
+ search: ISearchGeneric,
+ request: IKibanaSearchRequest,
+ options?: ISearchOptions
+ ) => {
+ // Schedule this request to automatically timeout after some interval
+ const timeoutController = new AbortController();
+ const { signal: timeoutSignal } = timeoutController;
+ const timeoutId = window.setTimeout(() => {
+ timeoutController.abort();
+ }, this.requestTimeout);
+ this.addTimeoutId(timeoutId);
+
+ // Get a combined `AbortSignal` that will be aborted whenever the first of the following occurs:
+ // 1. The user manually aborts (via `cancelPending`)
+ // 2. The request times out
+ // 3. The passed-in signal aborts (e.g. when re-fetching, or whenever the app determines)
+ const signals = [this.abortController.signal, timeoutSignal, options?.signal].filter(
+ Boolean
+ ) as AbortSignal[];
+ const combinedSignal = getCombinedSignal(signals);
+
+ // If the request timed out, throw a `RequestTimeoutError`
+ const timeoutError$ = fromEvent(timeoutSignal, 'abort').pipe(
+ mergeMap(() => throwError(new RequestTimeoutError()))
+ );
+
+ return search(request as any, { ...options, signal: combinedSignal }).pipe(
+ takeUntil(timeoutError$),
+ finalize(() => this.removeTimeoutId(timeoutId))
+ );
+ };
+
+ private addTimeoutId(id: number) {
+ this.timeoutIds.add(id);
+ this.pendingCount$.next(this.timeoutIds.size);
+ }
+
+ private removeTimeoutId(id: number) {
+ this.timeoutIds.delete(id);
+ this.pendingCount$.next(this.timeoutIds.size);
+ }
+}
diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts
index 691c8aa0e984d..62c7e0468bb88 100644
--- a/src/plugins/data/public/search/search_service.ts
+++ b/src/plugins/data/public/search/search_service.ts
@@ -25,6 +25,7 @@ import { TStrategyTypes } from './strategy_types';
import { getEsClient, LegacyApiCaller } from './es_client';
import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search';
import { esSearchStrategyProvider } from './es_search/es_search_strategy';
+import { SearchInterceptor } from './search_interceptor';
import {
getAggTypes,
AggType,
@@ -91,6 +92,16 @@ export class SearchService implements Plugin {
}
public start(core: CoreStart): ISearchStart {
+ /**
+ * 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.
+ * TODO: Make this modular so that apps can opt in/out of search collection, or even provide
+ * their own search collector instances
+ */
+ const searchInterceptor = new SearchInterceptor(
+ core.injectedMetadata.getInjectedVar('esRequestTimeout') as number
+ );
+
const aggTypesStart = this.aggTypesRegistry.start();
return {
@@ -103,13 +114,16 @@ export class SearchService implements Plugin {
},
types: aggTypesStart,
},
+ cancel: () => searchInterceptor.cancelPending(),
+ getPendingCount$: () => searchInterceptor.getPendingCount$(),
+ runBeyondTimeout: () => searchInterceptor.runBeyondTimeout(),
search: (request, options, strategyName) => {
const strategyProvider = this.getSearchStrategy(strategyName || DEFAULT_SEARCH_STRATEGY);
const { search } = strategyProvider({
core,
getSearchStrategy: this.getSearchStrategy,
});
- return search(request as any, options);
+ return searchInterceptor.search(search as any, request, options);
},
__LEGACY: {
esClient: this.esClient!,
diff --git a/src/plugins/data/public/search/search_source/search_source.test.ts b/src/plugins/data/public/search/search_source/search_source.test.ts
index d2b8308bfb258..fcd116a3f4121 100644
--- a/src/plugins/data/public/search/search_source/search_source.test.ts
+++ b/src/plugins/data/public/search/search_source/search_source.test.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { SearchSource } from '../search_source';
+import { SearchSource } from './search_source';
import { IndexPattern } from '../..';
import { mockDataServices } from '../aggs/test_helpers';
diff --git a/src/plugins/data/public/search/search_strategy/default_search_strategy.test.ts b/src/plugins/data/public/search/search_strategy/default_search_strategy.test.ts
index e4f492c89e0ef..210a0e5fd1ac7 100644
--- a/src/plugins/data/public/search/search_strategy/default_search_strategy.test.ts
+++ b/src/plugins/data/public/search/search_strategy/default_search_strategy.test.ts
@@ -18,9 +18,9 @@
*/
import { IUiSettingsClient } from '../../../../../core/public';
-import { ISearchStart } from '../types';
import { SearchStrategySearchParams } from './types';
import { defaultSearchStrategy } from './default_search_strategy';
+import { searchStartMock } from '../mocks';
const { search } = defaultSearchStrategy;
@@ -56,6 +56,12 @@ describe('defaultSearchStrategy', function() {
searchMockResponse.abort.mockClear();
searchMock.mockClear();
+ const searchService = searchStartMock;
+ searchService.aggs.calculateAutoTimeExpression = jest.fn().mockReturnValue('1d');
+ searchService.search = newSearchMock;
+ searchService.__LEGACY.esClient.search = searchMock;
+ searchService.__LEGACY.esClient.msearch = msearchMock;
+
searchArgs = {
searchRequests: [
{
@@ -63,15 +69,7 @@ describe('defaultSearchStrategy', function() {
},
],
esShardTimeout: 0,
- searchService: ({
- search: newSearchMock,
- __LEGACY: {
- esClient: {
- search: searchMock,
- msearch: msearchMock,
- },
- },
- } as unknown) as jest.Mocked,
+ searchService,
};
es = searchArgs.searchService.__LEGACY.esClient;
diff --git a/src/plugins/data/public/search/types.ts b/src/plugins/data/public/search/types.ts
index 1732c384b1a85..1b551f978b971 100644
--- a/src/plugins/data/public/search/types.ts
+++ b/src/plugins/data/public/search/types.ts
@@ -17,6 +17,7 @@
* under the License.
*/
+import { Observable } from 'rxjs';
import { CoreStart } from 'kibana/public';
import { SearchAggsSetup, SearchAggsStart, SearchAggsStartLegacy } from './aggs';
import { ISearch, ISearchGeneric } from './i_search';
@@ -86,6 +87,9 @@ export interface ISearchSetup {
export interface ISearchStart {
aggs: SearchAggsStart;
+ cancel: () => void;
+ getPendingCount$: () => Observable;
+ runBeyondTimeout: () => void;
search: ISearchGeneric;
__LEGACY: ISearchStartLegacy & SearchAggsStartLegacy;
}
diff --git a/src/plugins/data/server/autocomplete/value_suggestions_route.ts b/src/plugins/data/server/autocomplete/value_suggestions_route.ts
index 03dbd40984412..b7569a22e9fc9 100644
--- a/src/plugins/data/server/autocomplete/value_suggestions_route.ts
+++ b/src/plugins/data/server/autocomplete/value_suggestions_route.ts
@@ -39,7 +39,7 @@ export function registerValueSuggestionsRoute(
{
index: schema.string(),
},
- { allowUnknowns: false }
+ { unknowns: 'allow' }
),
body: schema.object(
{
@@ -47,7 +47,7 @@ export function registerValueSuggestionsRoute(
query: schema.string(),
boolFilter: schema.maybe(schema.any()),
},
- { allowUnknowns: false }
+ { unknowns: 'allow' }
),
},
},
diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts
index 0165486fc2de7..5038b4226fad8 100644
--- a/src/plugins/data/server/index.ts
+++ b/src/plugins/data/server/index.ts
@@ -166,7 +166,7 @@ export { ParsedInterval } from '../common';
export {
ISearch,
- ICancel,
+ ISearchCancel,
ISearchOptions,
IRequestTypesMap,
IResponseTypesMap,
diff --git a/src/plugins/data/server/search/i_route_handler_search_context.ts b/src/plugins/data/server/search/i_route_handler_search_context.ts
index 89862781b826e..9888c774ea104 100644
--- a/src/plugins/data/server/search/i_route_handler_search_context.ts
+++ b/src/plugins/data/server/search/i_route_handler_search_context.ts
@@ -17,9 +17,9 @@
* under the License.
*/
-import { ISearchGeneric, ICancelGeneric } from './i_search';
+import { ISearchGeneric, ISearchCancelGeneric } from './i_search';
export interface IRouteHandlerSearchContext {
search: ISearchGeneric;
- cancel: ICancelGeneric;
+ cancel: ISearchCancelGeneric;
}
diff --git a/src/plugins/data/server/search/i_search.ts b/src/plugins/data/server/search/i_search.ts
index ea014c5e136d9..fa4aa72ac7287 100644
--- a/src/plugins/data/server/search/i_search.ts
+++ b/src/plugins/data/server/search/i_search.ts
@@ -42,7 +42,7 @@ export type ISearchGeneric = Promise;
-export type ICancelGeneric = (
+export type ISearchCancelGeneric = (
id: string,
strategy?: T
) => Promise;
@@ -52,4 +52,4 @@ export type ISearch = (
options?: ISearchOptions
) => Promise;
-export type ICancel = (id: string) => Promise;
+export type ISearchCancel = (id: string) => Promise;
diff --git a/src/plugins/data/server/search/i_search_strategy.ts b/src/plugins/data/server/search/i_search_strategy.ts
index 4cfc9608383a9..9b405034f883f 100644
--- a/src/plugins/data/server/search/i_search_strategy.ts
+++ b/src/plugins/data/server/search/i_search_strategy.ts
@@ -18,7 +18,7 @@
*/
import { APICaller } from 'kibana/server';
-import { ISearch, ICancel, ISearchGeneric } from './i_search';
+import { ISearch, ISearchCancel, ISearchGeneric } from './i_search';
import { TStrategyTypes } from './strategy_types';
import { ISearchContext } from './i_search_context';
@@ -28,7 +28,7 @@ import { ISearchContext } from './i_search_context';
*/
export interface ISearchStrategy {
search: ISearch;
- cancel?: ICancel;
+ cancel?: ISearchCancel;
}
/**
diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts
index 385e96ee803b6..15738a3befb27 100644
--- a/src/plugins/data/server/search/index.ts
+++ b/src/plugins/data/server/search/index.ts
@@ -21,7 +21,13 @@ export { ISearchSetup } from './i_search_setup';
export { ISearchContext } from './i_search_context';
-export { ISearch, ICancel, ISearchOptions, IRequestTypesMap, IResponseTypesMap } from './i_search';
+export {
+ ISearch,
+ ISearchCancel,
+ ISearchOptions,
+ IRequestTypesMap,
+ IResponseTypesMap,
+} from './i_search';
export { TStrategyTypes } from './strategy_types';
diff --git a/src/plugins/data/server/search/routes.ts b/src/plugins/data/server/search/routes.ts
index e618f99084aed..b90d7d4ff80ce 100644
--- a/src/plugins/data/server/search/routes.ts
+++ b/src/plugins/data/server/search/routes.ts
@@ -28,9 +28,9 @@ export function registerSearchRoute(router: IRouter): void {
validate: {
params: schema.object({ strategy: schema.string() }),
- query: schema.object({}, { allowUnknowns: true }),
+ query: schema.object({}, { unknowns: 'allow' }),
- body: schema.object({}, { allowUnknowns: true }),
+ body: schema.object({}, { unknowns: 'allow' }),
},
},
async (context, request, res) => {
@@ -64,7 +64,7 @@ export function registerSearchRoute(router: IRouter): void {
id: schema.string(),
}),
- query: schema.object({}, { allowUnknowns: true }),
+ query: schema.object({}, { unknowns: 'allow' }),
},
},
async (context, request, res) => {
diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md
index 2a2d9bb414c14..178b2949a9456 100644
--- a/src/plugins/data/server/server.api.md
+++ b/src/plugins/data/server/server.api.md
@@ -329,12 +329,6 @@ export function getDefaultSearchParams(config: SharedGlobalConfig): {
restTotalHitsAsInt: boolean;
};
-// Warning: (ae-forgotten-export) The symbol "TStrategyTypes" needs to be exported by the entry point index.d.ts
-// Warning: (ae-missing-release-tag) "ICancel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
-//
-// @public (undocumented)
-export type ICancel = (id: string) => Promise;
-
// Warning: (ae-missing-release-tag) "IFieldFormatsRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -507,11 +501,17 @@ export interface IResponseTypesMap {
[ES_SEARCH_STRATEGY]: IEsSearchResponse;
}
+// Warning: (ae-forgotten-export) The symbol "TStrategyTypes" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "ISearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export type ISearch = (request: IRequestTypesMap[T], options?: ISearchOptions) => Promise;
+// Warning: (ae-missing-release-tag) "ISearchCancel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
+//
+// @public (undocumented)
+export type ISearchCancel = (id: string) => Promise;
+
// Warning: (ae-missing-release-tag) "ISearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
diff --git a/src/plugins/es_ui_shared/public/index.ts b/src/plugins/es_ui_shared/public/index.ts
index 2925e5e16458e..8ed01b9b61c7e 100644
--- a/src/plugins/es_ui_shared/public/index.ts
+++ b/src/plugins/es_ui_shared/public/index.ts
@@ -27,3 +27,5 @@ export {
sendRequest,
useRequest,
} from './request/np_ready_request';
+
+export { indices } from './indices';
diff --git a/src/legacy/ui/public/indices/constants/index.js b/src/plugins/es_ui_shared/public/indices/constants/index.ts
similarity index 94%
rename from src/legacy/ui/public/indices/constants/index.js
rename to src/plugins/es_ui_shared/public/indices/constants/index.ts
index 72ecc2e4c87de..825975fa161b5 100644
--- a/src/legacy/ui/public/indices/constants/index.js
+++ b/src/plugins/es_ui_shared/public/indices/constants/index.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { indexPatterns } from '../../../../../plugins/data/public';
+import { indexPatterns } from '../../../../data/public';
export const INDEX_ILLEGAL_CHARACTERS_VISIBLE = [...indexPatterns.ILLEGAL_CHARACTERS_VISIBLE, '*'];
diff --git a/src/plugins/es_ui_shared/public/indices/index.ts b/src/plugins/es_ui_shared/public/indices/index.ts
new file mode 100644
index 0000000000000..a6d279a5c2b4f
--- /dev/null
+++ b/src/plugins/es_ui_shared/public/indices/index.ts
@@ -0,0 +1,33 @@
+/*
+ * 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 { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from './constants';
+
+import {
+ indexNameBeginsWithPeriod,
+ findIllegalCharactersInIndexName,
+ indexNameContainsSpaces,
+} from './validate';
+
+export const indices = {
+ INDEX_ILLEGAL_CHARACTERS_VISIBLE,
+ indexNameBeginsWithPeriod,
+ findIllegalCharactersInIndexName,
+ indexNameContainsSpaces,
+};
diff --git a/src/legacy/ui/public/indices/validate/index.js b/src/plugins/es_ui_shared/public/indices/validate/index.ts
similarity index 100%
rename from src/legacy/ui/public/indices/validate/index.js
rename to src/plugins/es_ui_shared/public/indices/validate/index.ts
diff --git a/src/legacy/ui/public/indices/validate/validate_index.test.js b/src/plugins/es_ui_shared/public/indices/validate/validate_index.test.ts
similarity index 100%
rename from src/legacy/ui/public/indices/validate/validate_index.test.js
rename to src/plugins/es_ui_shared/public/indices/validate/validate_index.test.ts
diff --git a/src/legacy/ui/public/indices/validate/validate_index.js b/src/plugins/es_ui_shared/public/indices/validate/validate_index.ts
similarity index 67%
rename from src/legacy/ui/public/indices/validate/validate_index.js
rename to src/plugins/es_ui_shared/public/indices/validate/validate_index.ts
index 5deaa83a807d9..00ac1342400ac 100644
--- a/src/legacy/ui/public/indices/validate/validate_index.js
+++ b/src/plugins/es_ui_shared/public/indices/validate/validate_index.ts
@@ -19,23 +19,29 @@
import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../constants';
-// Names beginning with periods are reserved for system indices.
-export function indexNameBeginsWithPeriod(indexName = '') {
+// Names beginning with periods are reserved for hidden indices.
+export function indexNameBeginsWithPeriod(indexName?: string): boolean {
+ if (indexName === undefined) {
+ return false;
+ }
return indexName[0] === '.';
}
-export function findIllegalCharactersInIndexName(indexName) {
- const illegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.reduce((chars, char) => {
- if (indexName.includes(char)) {
- chars.push(char);
- }
+export function findIllegalCharactersInIndexName(indexName: string): string[] {
+ const illegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.reduce(
+ (chars: string[], char: string): string[] => {
+ if (indexName.includes(char)) {
+ chars.push(char);
+ }
- return chars;
- }, []);
+ return chars;
+ },
+ []
+ );
return illegalCharacters;
}
-export function indexNameContainsSpaces(indexName) {
+export function indexNameContainsSpaces(indexName: string): boolean {
return indexName.includes(' ');
}
diff --git a/src/plugins/es_ui_shared/static/forms/helpers/field_validators/index_name.ts b/src/plugins/es_ui_shared/static/forms/helpers/field_validators/index_name.ts
index 524cac27341ab..5e969fa715172 100644
--- a/src/plugins/es_ui_shared/static/forms/helpers/field_validators/index_name.ts
+++ b/src/plugins/es_ui_shared/static/forms/helpers/field_validators/index_name.ts
@@ -17,14 +17,11 @@
* under the License.
*/
-// Note: we can't import from "ui/indices" as the TS Type definition don't exist
-// import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from 'ui/indices';
+import { indices } from '../../../../public';
import { ValidationFunc } from '../../hook_form_lib';
import { startsWith, containsChars } from '../../../validators/string';
import { ERROR_CODE } from './types';
-const INDEX_ILLEGAL_CHARACTERS = ['\\', '/', '?', '"', '<', '>', '|', '*'];
-
export const indexNameField = (i18n: any) => (
...args: Parameters
): ReturnType> => {
@@ -51,7 +48,9 @@ export const indexNameField = (i18n: any) => (
};
}
- const { charsFound, doesContain } = containsChars(INDEX_ILLEGAL_CHARACTERS)(value as string);
+ const { charsFound, doesContain } = containsChars(indices.INDEX_ILLEGAL_CHARACTERS_VISIBLE)(
+ value as string
+ );
if (doesContain) {
return {
message: i18n.translate('esUi.forms.fieldValidation.indexNameInvalidCharactersError', {
diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts
index f70a32f2f09c1..d0ab178296408 100644
--- a/src/plugins/expressions/common/execution/execution.ts
+++ b/src/plugins/expressions/common/execution/execution.ts
@@ -22,6 +22,7 @@ import { Executor } from '../executor';
import { createExecutionContainer, ExecutionContainer } from './container';
import { createError } from '../util';
import { Defer, now } from '../../../kibana_utils/common';
+import { AbortError } from '../../../data/common';
import { RequestAdapter, DataAdapter } from '../../../inspector/common';
import { isExpressionValueError, ExpressionValueError } from '../expression_types/specs/error';
import {
@@ -190,10 +191,7 @@ export class Execution<
for (const link of chainArr) {
// if execution was aborted return error
if (this.context.abortSignal && this.context.abortSignal.aborted) {
- return createError({
- message: 'The expression was aborted.',
- name: 'AbortError',
- });
+ return createError(new AbortError('The expression was aborted.'));
}
const { function: fnName, arguments: fnArgs } = link;
diff --git a/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts b/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts
index 4092dfbba00d5..b8be273d7bbd3 100644
--- a/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts
+++ b/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts
@@ -16,10 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-
+import { uniq } from 'lodash';
import { i18n } from '@kbn/i18n';
import { ExpressionFunctionDefinition } from '../../expression_functions';
import { KibanaContext } from '../../expression_types';
+import { Query, uniqFilters } from '../../../../data/common';
interface Arguments {
q?: string | null;
@@ -35,6 +36,15 @@ export type ExpressionFunctionKibanaContext = ExpressionFunctionDefinition<
Promise
>;
+const getParsedValue = (data: any, defaultValue: any) =>
+ typeof data === 'string' && data.length ? JSON.parse(data) || defaultValue : defaultValue;
+
+const mergeQueries = (first: Query | Query[] = [], second: Query | Query[]) =>
+ uniq(
+ [...(Array.isArray(first) ? first : [first]), ...(Array.isArray(second) ? second : [second])],
+ (n: any) => JSON.stringify(n.query)
+ );
+
export const kibanaContextFunction: ExpressionFunctionKibanaContext = {
name: 'kibana_context',
type: 'kibana_context',
@@ -75,9 +85,9 @@ export const kibanaContextFunction: ExpressionFunctionKibanaContext = {
},
async fn(input, args, { getSavedObject }) {
- const queryArg = args.q ? JSON.parse(args.q) : [];
- let queries = Array.isArray(queryArg) ? queryArg : [queryArg];
- let filters = args.filters ? JSON.parse(args.filters) : [];
+ const timeRange = getParsedValue(args.timeRange, input?.timeRange);
+ let queries = mergeQueries(input?.query, getParsedValue(args?.q, []));
+ let filters = [...(input?.filters || []), ...getParsedValue(args?.filters, [])];
if (args.savedSearchId) {
if (typeof getSavedObject !== 'function') {
@@ -89,29 +99,20 @@ export const kibanaContextFunction: ExpressionFunctionKibanaContext = {
}
const obj = await getSavedObject('search', args.savedSearchId);
const search = obj.attributes.kibanaSavedObjectMeta as { searchSourceJSON: string };
- const data = JSON.parse(search.searchSourceJSON) as { query: string; filter: any[] };
- queries = queries.concat(data.query);
- filters = filters.concat(data.filter);
- }
+ const { query, filter } = getParsedValue(search.searchSourceJSON, {});
- if (input && input.query) {
- queries = queries.concat(input.query);
- }
-
- if (input && input.filters) {
- filters = filters.concat(input.filters).filter((f: any) => !f.meta.disabled);
+ if (query) {
+ queries = mergeQueries(queries, query);
+ }
+ if (filter) {
+ filters = [...filters, ...(Array.isArray(filter) ? filter : [filter])];
+ }
}
- const timeRange = args.timeRange
- ? JSON.parse(args.timeRange)
- : input
- ? input.timeRange
- : undefined;
-
return {
type: 'kibana_context',
query: queries,
- filters,
+ filters: uniqFilters(filters).filter((f: any) => !f.meta?.disabled),
timeRange,
};
},
diff --git a/src/plugins/kibana_legacy/public/angular/index.ts b/src/plugins/kibana_legacy/public/angular/index.ts
index 5fc37ac39612a..16bae6c4cffe0 100644
--- a/src/plugins/kibana_legacy/public/angular/index.ts
+++ b/src/plugins/kibana_legacy/public/angular/index.ts
@@ -21,7 +21,6 @@ export { PromiseServiceCreator } from './promises';
// @ts-ignore
export { watchMultiDecorator } from './watch_multi';
export * from './angular_config';
-export { ensureDefaultIndexPattern } from './ensure_default_index_pattern';
// @ts-ignore
export { createTopNavDirective, createTopNavHelper, loadKbnTopNavDirectives } from './kbn_top_nav';
export { subscribeWithScope } from './subscribe_with_scope';
diff --git a/src/plugins/kibana_react/public/exit_full_screen_button/__snapshots__/exit_full_screen_button.test.tsx.snap b/src/plugins/kibana_react/public/exit_full_screen_button/__snapshots__/exit_full_screen_button.test.tsx.snap
index 39bd66ff71c61..ee97a5acfd3d2 100644
--- a/src/plugins/kibana_react/public/exit_full_screen_button/__snapshots__/exit_full_screen_button.test.tsx.snap
+++ b/src/plugins/kibana_react/public/exit_full_screen_button/__snapshots__/exit_full_screen_button.test.tsx.snap
@@ -17,27 +17,88 @@ exports[`is rendered 1`] = `
-
-
- Exit full screen
-
-
-
-
+
+
+
+
+
+
+
+
+ Elastic Kibana
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/kibana_react/public/exit_full_screen_button/_exit_full_screen_button.scss b/src/plugins/kibana_react/public/exit_full_screen_button/_exit_full_screen_button.scss
index e810fe0ccdba6..a2e951cb5b775 100644
--- a/src/plugins/kibana_react/public/exit_full_screen_button/_exit_full_screen_button.scss
+++ b/src/plugins/kibana_react/public/exit_full_screen_button/_exit_full_screen_button.scss
@@ -4,66 +4,40 @@
*/
.dshExitFullScreenButton {
- height: $euiSizeXXL;
- left: 0;
- bottom: 0;
+ @include euiBottomShadow;
+
+ left: $euiSizeS;
+ bottom: $euiSizeS;
position: fixed;
display: block;
padding: 0;
border: none;
background: none;
z-index: 5;
+ background: $euiColorFullShade;
+ padding: $euiSizeXS;
+ border-radius: $euiBorderRadius;
+ text-align: left;
- &:hover,
- &:focus {
- transition: all $euiAnimSpeedExtraSlow $euiAnimSlightResistance;
- z-index: 10 !important; /* 1 */
+ &:hover {
+ background: $euiColorFullShade;
- .dshExitFullScreenButton__text {
- transition: all $euiAnimSpeedNormal $euiAnimSlightResistance;
- transform: translateX(-$euiSize);
+ .dshExitFullScreenButton__icon {
+ color: $euiColorEmptyShade;
}
}
}
-.dshExitFullScreenButton__logo {
- display: block;
- // Just darken the background for all themes because the logo is always white
- background-color: shade($euiColorPrimary, 25%);
- height: $euiSizeXXL;
-
- // These numbers are very specific to the Kibana logo size
- width: 92px;
- background-image: url('ui/assets/images/kibana.svg');
- background-position: 8px 5px;
- background-size: 72px 30px;
- background-repeat: no-repeat;
-
- z-index: $euiZLevel1;
+.dshExitFullScreenButton__title {
+ line-height: 1.2;
+ color: $euiColorEmptyShade;
}
-/**
- * 1. Calc made to allow caret in text to peek out / animate.
- */
-
.dshExitFullScreenButton__text {
- background: $euiColorPrimary;
- color: $euiColorEmptyShade;
- line-height: $euiSizeXXL;
- display: inline-block;
- font-size: $euiFontSizeS;
- height: $euiSizeXXL;
- position: absolute;
- left: calc(100% + #{$euiSize}); /* 1 */
- top: 0px;
- bottom: 0px;
- white-space: nowrap;
- padding: 0px $euiSizeXS 0px $euiSizeM;
- transition: all .2s ease;
- transform: translateX(-100%);
- z-index: -1;
-
- .euiIcon {
- margin-left: $euiSizeXS;
- }
+ line-height: 1.2;
+ color: makeHighContrastColor($euiColorMediumShade, $euiColorFullShade);
+}
+
+.dshExitFullScreenButton__icon {
+ color: makeHighContrastColor($euiColorMediumShade, $euiColorFullShade);
}
diff --git a/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx b/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx
index 5ce508ec1ed5b..97fc02ac64e12 100644
--- a/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx
+++ b/src/plugins/kibana_react/public/exit_full_screen_button/exit_full_screen_button.tsx
@@ -20,7 +20,7 @@
import { i18n } from '@kbn/i18n';
import React, { PureComponent } from 'react';
import { EuiScreenReaderOnly, keyCodes } from '@elastic/eui';
-import { EuiIcon } from '@elastic/eui';
+import { EuiIcon, EuiTitle, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
export interface ExitFullScreenButtonProps {
onExitFullScreenMode: () => void;
@@ -61,17 +61,40 @@ class ExitFullScreenButtonUi extends PureComponent {
)}
className="dshExitFullScreenButton"
onClick={this.props.onExitFullScreenMode}
+ data-test-subj="exitFullScreenModeLogo"
>
-
-
- {i18n.translate('kibana-react.exitFullScreenButton.exitFullScreenModeButtonLabel', {
- defaultMessage: 'Exit full screen',
- })}
-
-
+
+
+
+
+
+
+
+
+ {i18n.translate(
+ 'kibana-react.exitFullScreenButton.exitFullScreenModeButtonTitle',
+ {
+ defaultMessage: 'Elastic Kibana',
+ }
+ )}
+
+
+
+
+ {i18n.translate(
+ 'kibana-react.exitFullScreenButton.exitFullScreenModeButtonText',
+ {
+ defaultMessage: 'Exit full screen',
+ }
+ )}
+
+
+
+
+
+
+
+
diff --git a/src/plugins/kibana_legacy/public/angular/ensure_default_index_pattern.tsx b/src/plugins/kibana_utils/public/history/ensure_default_index_pattern.tsx
similarity index 67%
rename from src/plugins/kibana_legacy/public/angular/ensure_default_index_pattern.tsx
rename to src/plugins/kibana_utils/public/history/ensure_default_index_pattern.tsx
index 1a3bb84ae7575..7992f650cb372 100644
--- a/src/plugins/kibana_legacy/public/angular/ensure_default_index_pattern.tsx
+++ b/src/plugins/kibana_utils/public/history/ensure_default_index_pattern.tsx
@@ -18,14 +18,13 @@
*/
import { contains } from 'lodash';
-import { IRootScopeService } from 'angular';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { History } from 'history';
import { i18n } from '@kbn/i18n';
-import { I18nProvider } from '@kbn/i18n/react';
import { EuiCallOut } from '@elastic/eui';
import { CoreStart } from 'kibana/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
+import { toMountPoint } from '../../../kibana_react/public';
let bannerId: string;
let timeoutId: NodeJS.Timeout | undefined;
@@ -39,18 +38,17 @@ let timeoutId: NodeJS.Timeout | undefined;
* resolve to wait for the URL change to happen.
*/
export async function ensureDefaultIndexPattern(
- newPlatform: CoreStart,
+ core: CoreStart,
data: DataPublicPluginStart,
- $rootScope: IRootScopeService,
- kbnUrl: any
+ history: History
) {
const patterns = await data.indexPatterns.getIds();
- let defaultId = newPlatform.uiSettings.get('defaultIndex');
+ let defaultId = core.uiSettings.get('defaultIndex');
let defined = !!defaultId;
const exists = contains(patterns, defaultId);
if (defined && !exists) {
- newPlatform.uiSettings.remove('defaultIndex');
+ core.uiSettings.remove('defaultIndex');
defaultId = defined = false;
}
@@ -61,10 +59,9 @@ export async function ensureDefaultIndexPattern(
// If there is any index pattern created, set the first as default
if (patterns.length >= 1) {
defaultId = patterns[0];
- newPlatform.uiSettings.set('defaultIndex', defaultId);
+ core.uiSettings.set('defaultIndex', defaultId);
} else {
- const canManageIndexPatterns =
- newPlatform.application.capabilities.management.kibana.index_patterns;
+ const canManageIndexPatterns = core.application.capabilities.management.kibana.index_patterns;
const redirectTarget = canManageIndexPatterns ? '/management/kibana/index_pattern' : '/home';
if (timeoutId) {
@@ -73,31 +70,27 @@ export async function ensureDefaultIndexPattern(
// Avoid being hostile to new users who don't have an index pattern setup yet
// give them a friendly info message instead of a terse error message
- bannerId = newPlatform.overlays.banners.replace(bannerId, (element: HTMLElement) => {
- ReactDOM.render(
-
-
- ,
- element
- );
- return () => ReactDOM.unmountComponentAtNode(element);
- });
+ bannerId = core.overlays.banners.replace(
+ bannerId,
+ toMountPoint(
+
+ )
+ );
// hide the message after the user has had a chance to acknowledge it -- so it doesn't permanently stick around
timeoutId = setTimeout(() => {
- newPlatform.overlays.banners.remove(bannerId);
+ core.overlays.banners.remove(bannerId);
timeoutId = undefined;
}, 15000);
- kbnUrl.change(redirectTarget);
- $rootScope.$digest();
+ history.push(redirectTarget);
// return never-resolving promise to stop resolving and wait for the url change
return new Promise(() => {});
diff --git a/src/plugins/kibana_utils/public/history/index.ts b/src/plugins/kibana_utils/public/history/index.ts
index b4b5658c1c886..1a73bbb6b04a1 100644
--- a/src/plugins/kibana_utils/public/history/index.ts
+++ b/src/plugins/kibana_utils/public/history/index.ts
@@ -18,3 +18,5 @@
*/
export { removeQueryParam } from './remove_query_param';
+export { redirectWhenMissing } from './redirect_when_missing';
+export { ensureDefaultIndexPattern } from './ensure_default_index_pattern';
diff --git a/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx
new file mode 100644
index 0000000000000..cbdeef6fbe96c
--- /dev/null
+++ b/src/plugins/kibana_utils/public/history/redirect_when_missing.tsx
@@ -0,0 +1,80 @@
+/*
+ * 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 React from 'react';
+import { History } from 'history';
+import { i18n } from '@kbn/i18n';
+
+import { ToastsSetup } from 'kibana/public';
+import { MarkdownSimple, toMountPoint } from '../../../kibana_react/public';
+import { SavedObjectNotFound } from '../errors';
+
+interface Mapping {
+ [key: string]: string;
+}
+
+/**
+ * Creates an error handler that will redirect to a url when a SavedObjectNotFound
+ * error is thrown
+ */
+export function redirectWhenMissing({
+ history,
+ mapping,
+ toastNotifications,
+}: {
+ history: History;
+ /**
+ * a mapping of url's to redirect to based on the saved object that
+ * couldn't be found, or just a string that will be used for all types
+ */
+ mapping: string | Mapping;
+ /**
+ * Toast notifications service to show toasts in error cases.
+ */
+ toastNotifications: ToastsSetup;
+}) {
+ let localMappingObject: Mapping;
+
+ if (typeof mapping === 'string') {
+ localMappingObject = { '*': mapping };
+ } else {
+ localMappingObject = mapping;
+ }
+
+ return (error: SavedObjectNotFound) => {
+ // if this error is not "404", rethrow
+ // we can't check "error instanceof SavedObjectNotFound" since this class can live in a separate bundle
+ // and the error will be an instance of other class with the same interface (actually the copy of SavedObjectNotFound class)
+ if (!error.savedObjectType) {
+ throw error;
+ }
+
+ let url = localMappingObject[error.savedObjectType] || localMappingObject['*'] || '/';
+ url += (url.indexOf('?') >= 0 ? '&' : '?') + `notFound=${error.savedObjectType}`;
+
+ toastNotifications.addWarning({
+ title: i18n.translate('kibana_utils.history.savedObjectIsMissingNotificationMessage', {
+ defaultMessage: 'Saved object is missing',
+ }),
+ text: toMountPoint({error.message} ),
+ });
+
+ history.replace(url);
+ };
+}
diff --git a/src/plugins/kibana_utils/public/index.ts b/src/plugins/kibana_utils/public/index.ts
index ee38d5e8111c9..1876e688c989a 100644
--- a/src/plugins/kibana_utils/public/index.ts
+++ b/src/plugins/kibana_utils/public/index.ts
@@ -73,5 +73,5 @@ export {
StartSyncStateFnType,
StopSyncStateFnType,
} from './state_sync';
-export { removeQueryParam } from './history';
+export { removeQueryParam, redirectWhenMissing, ensureDefaultIndexPattern } from './history';
export { applyDiff } from './state_management/utils/diff_object';
diff --git a/src/plugins/timelion/config.ts b/src/plugins/timelion/config.ts
index 561fb4de9f58d..eaea1aaca1b7b 100644
--- a/src/plugins/timelion/config.ts
+++ b/src/plugins/timelion/config.ts
@@ -25,7 +25,7 @@ export const configSchema = schema.object(
graphiteUrls: schema.maybe(schema.arrayOf(schema.string())),
},
// This option should be removed as soon as we entirely migrate config from legacy Timelion plugin.
- { allowUnknowns: true }
+ { unknowns: 'allow' }
);
export type ConfigSchema = TypeOf;
diff --git a/src/plugins/timelion/server/routes/run.ts b/src/plugins/timelion/server/routes/run.ts
index b7a4179da768e..b773bba68ea81 100644
--- a/src/plugins/timelion/server/routes/run.ts
+++ b/src/plugins/timelion/server/routes/run.ts
@@ -78,15 +78,11 @@ export function runRoute(
es: schema.object({
filter: schema.object({
bool: schema.object({
- filter: schema.maybe(
- schema.arrayOf(schema.object({}, { allowUnknowns: true }))
- ),
- must: schema.maybe(schema.arrayOf(schema.object({}, { allowUnknowns: true }))),
- should: schema.maybe(
- schema.arrayOf(schema.object({}, { allowUnknowns: true }))
- ),
+ filter: schema.maybe(schema.arrayOf(schema.object({}, { unknowns: 'allow' }))),
+ must: schema.maybe(schema.arrayOf(schema.object({}, { unknowns: 'allow' }))),
+ should: schema.maybe(schema.arrayOf(schema.object({}, { unknowns: 'allow' }))),
must_not: schema.maybe(
- schema.arrayOf(schema.object({}, { allowUnknowns: true }))
+ schema.arrayOf(schema.object({}, { unknowns: 'allow' }))
),
}),
}),
diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts
index e2d1e4d114ad5..9abbc4ad617dc 100644
--- a/src/plugins/vis_type_timeseries/server/routes/vis.ts
+++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts
@@ -23,7 +23,7 @@ import { getVisData, GetVisDataOptions } from '../lib/get_vis_data';
import { visPayloadSchema } from './post_vis_schema';
import { Framework, ValidationTelemetryServiceSetup } from '../index';
-const escapeHatch = schema.object({}, { allowUnknowns: true });
+const escapeHatch = schema.object({}, { unknowns: 'allow' });
export const visDataRoutes = (
router: IRouter,
diff --git a/src/setup_node_env/exit_on_warning.js b/src/setup_node_env/exit_on_warning.js
index 5be5ccd72bd02..6321cd7ba8db0 100644
--- a/src/setup_node_env/exit_on_warning.js
+++ b/src/setup_node_env/exit_on_warning.js
@@ -35,4 +35,16 @@ if (process.noProcessWarnings !== true) {
process.exit(1);
});
+
+ // While the above warning listener would also be called on
+ // unhandledRejection warnings, we can give a better error message if we
+ // handle them separately:
+ process.on('unhandledRejection', function(reason) {
+ console.error('Unhandled Promise rejection detected:');
+ console.error();
+ console.error(reason);
+ console.error();
+ console.error('Terminating process...');
+ process.exit(1);
+ });
}
diff --git a/test/common/services/security/role.ts b/test/common/services/security/role.ts
index 0e7572882f80d..dfc6ff9b164e5 100644
--- a/test/common/services/security/role.ts
+++ b/test/common/services/security/role.ts
@@ -43,7 +43,6 @@ export class Role {
`Expected status code of 204, received ${status} ${statusText}: ${util.inspect(data)}`
);
}
- this.log.debug(`created role ${name}`);
}
public async delete(name: string) {
@@ -56,6 +55,5 @@ export class Role {
)}`
);
}
- this.log.debug(`deleted role ${name}`);
}
}
diff --git a/test/common/services/security/security.ts b/test/common/services/security/security.ts
index 4eebb7b6697e0..6ad0933a2a5a2 100644
--- a/test/common/services/security/security.ts
+++ b/test/common/services/security/security.ts
@@ -23,15 +23,21 @@ import { Role } from './role';
import { User } from './user';
import { RoleMappings } from './role_mappings';
import { FtrProviderContext } from '../../ftr_provider_context';
+import { createTestUserService } from './test_user';
-export function SecurityServiceProvider({ getService }: FtrProviderContext) {
+export async function SecurityServiceProvider(context: FtrProviderContext) {
+ const { getService } = context;
const log = getService('log');
const config = getService('config');
const url = formatUrl(config.get('servers.kibana'));
+ const role = new Role(url, log);
+ const user = new User(url, log);
+ const testUser = await createTestUserService(role, user, context);
return new (class SecurityService {
- role = new Role(url, log);
roleMappings = new RoleMappings(url, log);
- user = new User(url, log);
+ testUser = testUser;
+ role = role;
+ user = user;
})();
}
diff --git a/test/common/services/security/test_user.ts b/test/common/services/security/test_user.ts
new file mode 100644
index 0000000000000..7f01c64d291a5
--- /dev/null
+++ b/test/common/services/security/test_user.ts
@@ -0,0 +1,92 @@
+/*
+ * 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 { Role } from './role';
+import { User } from './user';
+import { FtrProviderContext } from '../../ftr_provider_context';
+import { Browser } from '../../../functional/services/browser';
+import { TestSubjects } from '../../../functional/services/test_subjects';
+
+export async function createTestUserService(
+ role: Role,
+ user: User,
+ { getService, hasService }: FtrProviderContext
+) {
+ const log = getService('log');
+ const config = getService('config');
+ // @ts-ignore browser service is not normally available in common.
+ const browser: Browser | void = hasService('browser') && getService('browser');
+ const testSubjects: TestSubjects | void =
+ // @ts-ignore testSubject service is not normally available in common.
+ hasService('testSubjects') && getService('testSubjects');
+ const kibanaServer = getService('kibanaServer');
+
+ const enabledPlugins = config.get('security.disableTestUser')
+ ? []
+ : await kibanaServer.plugins.getEnabledIds();
+ const isEnabled = () => {
+ return enabledPlugins.includes('security') && !config.get('security.disableTestUser');
+ };
+ if (isEnabled()) {
+ log.debug('===============creating roles and users===============');
+ for (const [name, definition] of Object.entries(config.get('security.roles'))) {
+ // create the defined roles (need to map array to create roles)
+ await role.create(name, definition);
+ }
+ try {
+ // delete the test_user if present (will it error if the user doesn't exist?)
+ await user.delete('test_user');
+ } catch (exception) {
+ log.debug('no test user to delete');
+ }
+
+ // create test_user with username and pwd
+ log.debug(`default roles = ${config.get('security.defaultRoles')}`);
+ await user.create('test_user', {
+ password: 'changeme',
+ roles: config.get('security.defaultRoles'),
+ full_name: 'test user',
+ });
+ }
+
+ return new (class TestUser {
+ async restoreDefaults() {
+ if (isEnabled()) {
+ await this.setRoles(config.get('security.defaultRoles'));
+ }
+ }
+
+ async setRoles(roles: string[]) {
+ if (isEnabled()) {
+ log.debug(`set roles = ${roles}`);
+ await user.create('test_user', {
+ password: 'changeme',
+ roles,
+ full_name: 'test user',
+ });
+
+ if (browser && testSubjects) {
+ if (await testSubjects.exists('kibanaChrome', { allowHidden: true })) {
+ await browser.refresh();
+ await testSubjects.find('kibanaChrome', config.get('timeouts.find') * 10);
+ }
+ }
+ }
+ }
+ })();
+}
diff --git a/test/functional/apps/context/_date_nanos.js b/test/functional/apps/context/_date_nanos.js
index d4acdb0b4d5c0..bd132e3745caa 100644
--- a/test/functional/apps/context/_date_nanos.js
+++ b/test/functional/apps/context/_date_nanos.js
@@ -26,11 +26,13 @@ const TEST_STEP_SIZE = 3;
export default function({ getService, getPageObjects }) {
const kibanaServer = getService('kibanaServer');
const docTable = getService('docTable');
+ const security = getService('security');
const PageObjects = getPageObjects(['common', 'context', 'timePicker', 'discover']);
const esArchiver = getService('esArchiver');
describe('context view for date_nanos', () => {
before(async function() {
+ await security.testUser.setRoles(['kibana_admin', 'kibana_date_nanos']);
await esArchiver.loadIfNeeded('date_nanos');
await kibanaServer.uiSettings.replace({ defaultIndex: TEST_INDEX_PATTERN });
await kibanaServer.uiSettings.update({
@@ -39,8 +41,9 @@ export default function({ getService, getPageObjects }) {
});
});
- after(function unloadMakelogs() {
- return esArchiver.unload('date_nanos');
+ after(async function unloadMakelogs() {
+ await security.testUser.restoreDefaults();
+ await esArchiver.unload('date_nanos');
});
it('displays predessors - anchor - successors in right order ', async function() {
diff --git a/test/functional/apps/context/_date_nanos_custom_timestamp.js b/test/functional/apps/context/_date_nanos_custom_timestamp.js
index 046cca0aba8c6..7834b29931a65 100644
--- a/test/functional/apps/context/_date_nanos_custom_timestamp.js
+++ b/test/functional/apps/context/_date_nanos_custom_timestamp.js
@@ -26,12 +26,14 @@ const TEST_STEP_SIZE = 3;
export default function({ getService, getPageObjects }) {
const kibanaServer = getService('kibanaServer');
const docTable = getService('docTable');
+ const security = getService('security');
const PageObjects = getPageObjects(['common', 'context', 'timePicker', 'discover']);
const esArchiver = getService('esArchiver');
// skipped due to a recent change in ES that caused search_after queries with data containing
// custom timestamp formats like in the testdata to fail
describe.skip('context view for date_nanos with custom timestamp', () => {
before(async function() {
+ await security.testUser.setRoles(['kibana_admin', 'kibana_date_nanos_custom']);
await esArchiver.loadIfNeeded('date_nanos_custom');
await kibanaServer.uiSettings.replace({ defaultIndex: TEST_INDEX_PATTERN });
await kibanaServer.uiSettings.update({
@@ -40,10 +42,6 @@ export default function({ getService, getPageObjects }) {
});
});
- after(function unloadMakelogs() {
- return esArchiver.unload('date_nanos_custom');
- });
-
it('displays predessors - anchor - successors in right order ', async function() {
await PageObjects.context.navigateTo(TEST_INDEX_PATTERN, '1');
const actualRowsText = await docTable.getRowsText();
@@ -54,5 +52,10 @@ export default function({ getService, getPageObjects }) {
];
expect(actualRowsText).to.eql(expectedRowsText);
});
+
+ after(async function() {
+ await security.testUser.restoreDefaults();
+ await esArchiver.unload('date_nanos_custom');
+ });
});
}
diff --git a/test/functional/apps/dashboard/dashboard_filtering.js b/test/functional/apps/dashboard/dashboard_filtering.js
index ec8a48ca74911..f388993dcaf7d 100644
--- a/test/functional/apps/dashboard/dashboard_filtering.js
+++ b/test/functional/apps/dashboard/dashboard_filtering.js
@@ -33,6 +33,7 @@ export default function({ getService, getPageObjects }) {
const filterBar = getService('filterBar');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
+ const security = getService('security');
const dashboardPanelActions = getService('dashboardPanelActions');
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'timePicker']);
@@ -41,6 +42,7 @@ export default function({ getService, getPageObjects }) {
before(async () => {
await esArchiver.load('dashboard/current/kibana');
+ await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader', 'animals']);
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
@@ -49,6 +51,10 @@ export default function({ getService, getPageObjects }) {
await PageObjects.dashboard.gotoDashboardLandingPage();
});
+ after(async () => {
+ await security.testUser.restoreDefaults();
+ });
+
describe('adding a filter that excludes all data', () => {
before(async () => {
await PageObjects.dashboard.clickNewDashboard();
diff --git a/test/functional/apps/dashboard/index.js b/test/functional/apps/dashboard/index.js
index 13e8631445393..5e96a55b19014 100644
--- a/test/functional/apps/dashboard/index.js
+++ b/test/functional/apps/dashboard/index.js
@@ -23,6 +23,7 @@ export default function({ getService, loadTestFile }) {
async function loadCurrentData() {
await browser.setWindowSize(1300, 900);
+ await esArchiver.unload('logstash_functional');
await esArchiver.loadIfNeeded('dashboard/current/data');
}
diff --git a/test/functional/apps/dashboard/time_zones.js b/test/functional/apps/dashboard/time_zones.js
index f374d6526fcf1..b7698a7d6ac4b 100644
--- a/test/functional/apps/dashboard/time_zones.js
+++ b/test/functional/apps/dashboard/time_zones.js
@@ -22,7 +22,6 @@ import expect from '@kbn/expect';
export default function({ getService, getPageObjects }) {
const pieChart = getService('pieChart');
- const browser = getService('browser');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['dashboard', 'timePicker', 'settings', 'common']);
@@ -48,7 +47,6 @@ export default function({ getService, getPageObjects }) {
after(async () => {
await kibanaServer.uiSettings.replace({ 'dateFormat:tz': 'UTC' });
- await browser.refresh();
});
it('Exported dashboard adjusts EST time to UTC', async () => {
diff --git a/test/functional/apps/discover/_date_nanos.js b/test/functional/apps/discover/_date_nanos.js
index 9b06b9ac84cfd..99a37cc18feaa 100644
--- a/test/functional/apps/discover/_date_nanos.js
+++ b/test/functional/apps/discover/_date_nanos.js
@@ -23,6 +23,7 @@ export default function({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
const PageObjects = getPageObjects(['common', 'timePicker', 'discover']);
const kibanaServer = getService('kibanaServer');
+ const security = getService('security');
const fromTime = 'Sep 22, 2019 @ 20:31:44.000';
const toTime = 'Sep 23, 2019 @ 03:31:44.000';
@@ -30,12 +31,14 @@ export default function({ getService, getPageObjects }) {
before(async function() {
await esArchiver.loadIfNeeded('date_nanos');
await kibanaServer.uiSettings.replace({ defaultIndex: 'date-nanos' });
+ await security.testUser.setRoles(['kibana_admin', 'kibana_date_nanos']);
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
});
- after(function unloadMakelogs() {
- return esArchiver.unload('date_nanos');
+ after(async function unloadMakelogs() {
+ await security.testUser.restoreDefaults();
+ await esArchiver.unload('date_nanos');
});
it('should show a timestamp with nanoseconds in the first result row', async function() {
diff --git a/test/functional/apps/discover/_date_nanos_mixed.js b/test/functional/apps/discover/_date_nanos_mixed.js
index 0bb6848db4d10..b88ae87601cc5 100644
--- a/test/functional/apps/discover/_date_nanos_mixed.js
+++ b/test/functional/apps/discover/_date_nanos_mixed.js
@@ -23,6 +23,7 @@ export default function({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
const PageObjects = getPageObjects(['common', 'timePicker', 'discover']);
const kibanaServer = getService('kibanaServer');
+ const security = getService('security');
const fromTime = 'Jan 1, 2019 @ 00:00:00.000';
const toTime = 'Jan 1, 2019 @ 23:59:59.999';
@@ -30,12 +31,14 @@ export default function({ getService, getPageObjects }) {
before(async function() {
await esArchiver.loadIfNeeded('date_nanos_mixed');
await kibanaServer.uiSettings.replace({ defaultIndex: 'timestamp-*' });
+ await security.testUser.setRoles(['kibana_admin', 'kibana_date_nanos_mixed']);
await PageObjects.common.navigateToApp('discover');
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
});
- after(function unloadMakelogs() {
- return esArchiver.unload('date_nanos_mixed');
+ after(async () => {
+ await security.testUser.restoreDefaults();
+ esArchiver.unload('date_nanos_mixed');
});
it('shows a list of records of indices with date & date_nanos fields in the right order', async function() {
diff --git a/test/functional/apps/discover/_discover_histogram.js b/test/functional/apps/discover/_discover_histogram.js
index 9310838666256..f815c505a8c27 100644
--- a/test/functional/apps/discover/_discover_histogram.js
+++ b/test/functional/apps/discover/_discover_histogram.js
@@ -25,6 +25,7 @@ export default function({ getService, getPageObjects }) {
const browser = getService('browser');
const elasticChart = getService('elasticChart');
const kibanaServer = getService('kibanaServer');
+ const security = getService('security');
const PageObjects = getPageObjects(['settings', 'common', 'discover', 'header', 'timePicker']);
const defaultSettings = {
defaultIndex: 'long-window-logstash-*',
@@ -35,6 +36,11 @@ export default function({ getService, getPageObjects }) {
before(async function() {
log.debug('load kibana index with default index pattern');
await PageObjects.common.navigateToApp('home');
+ await security.testUser.setRoles([
+ 'kibana_admin',
+ 'test_logstash_reader',
+ 'long_window_logstash',
+ ]);
await esArchiver.loadIfNeeded('logstash_functional');
await esArchiver.load('long_window_logstash');
await esArchiver.load('visualize');
@@ -56,6 +62,7 @@ export default function({ getService, getPageObjects }) {
await esArchiver.unload('long_window_logstash');
await esArchiver.unload('visualize');
await esArchiver.unload('discover');
+ await security.testUser.restoreDefaults();
});
it('should visualize monthly data with different day intervals', async () => {
diff --git a/test/functional/apps/discover/_large_string.js b/test/functional/apps/discover/_large_string.js
index a5052b2403074..5e9048e2bc481 100644
--- a/test/functional/apps/discover/_large_string.js
+++ b/test/functional/apps/discover/_large_string.js
@@ -25,10 +25,12 @@ export default function({ getService, getPageObjects }) {
const retry = getService('retry');
const kibanaServer = getService('kibanaServer');
const queryBar = getService('queryBar');
+ const security = getService('security');
const PageObjects = getPageObjects(['common', 'home', 'settings', 'discover']);
describe('test large strings', function() {
before(async function() {
+ await security.testUser.setRoles(['kibana_admin', 'kibana_large_strings']);
await esArchiver.load('empty_kibana');
await esArchiver.loadIfNeeded('hamlet');
await kibanaServer.uiSettings.replace({ defaultIndex: 'testlargestring' });
@@ -77,6 +79,7 @@ export default function({ getService, getPageObjects }) {
});
after(async () => {
+ await security.testUser.restoreDefaults();
await esArchiver.unload('hamlet');
});
});
diff --git a/test/functional/apps/getting_started/_shakespeare.js b/test/functional/apps/getting_started/_shakespeare.js
index 5af1676cf423f..ded4eca908410 100644
--- a/test/functional/apps/getting_started/_shakespeare.js
+++ b/test/functional/apps/getting_started/_shakespeare.js
@@ -23,6 +23,7 @@ export default function({ getService, getPageObjects }) {
const log = getService('log');
const esArchiver = getService('esArchiver');
const retry = getService('retry');
+ const security = getService('security');
const PageObjects = getPageObjects([
'console',
'common',
@@ -46,11 +47,16 @@ export default function({ getService, getPageObjects }) {
'Load empty_kibana and Shakespeare Getting Started data\n' +
'https://www.elastic.co/guide/en/kibana/current/tutorial-load-dataset.html'
);
+ await security.testUser.setRoles(['kibana_admin', 'test_shakespeare_reader']);
await esArchiver.load('empty_kibana', { skipExisting: true });
log.debug('Load shakespeare data');
await esArchiver.loadIfNeeded('getting_started/shakespeare');
});
+ after(async () => {
+ await security.testUser.restoreDefaults();
+ });
+
it('should create shakespeare index pattern', async function() {
log.debug('Create shakespeare index pattern');
await PageObjects.settings.createIndexPattern('shakes', null);
diff --git a/test/functional/apps/home/_sample_data.ts b/test/functional/apps/home/_sample_data.ts
index 8bc528e045566..5812b9b96e42a 100644
--- a/test/functional/apps/home/_sample_data.ts
+++ b/test/functional/apps/home/_sample_data.ts
@@ -25,6 +25,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
const retry = getService('retry');
const find = getService('find');
const log = getService('log');
+ const security = getService('security');
const pieChart = getService('pieChart');
const renderable = getService('renderable');
const dashboardExpect = getService('dashboardExpect');
@@ -34,10 +35,15 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
this.tags('smoke');
before(async () => {
+ await security.testUser.setRoles(['kibana_admin', 'kibana_sample_admin']);
await PageObjects.common.navigateToUrl('home', 'tutorial_directory/sampleData');
await PageObjects.header.waitUntilLoadingHasFinished();
});
+ after(async () => {
+ await security.testUser.restoreDefaults();
+ });
+
it('should display registered flights sample data sets', async () => {
await retry.try(async () => {
const exists = await PageObjects.home.doesSampleDataSetExist('flights');
diff --git a/test/functional/apps/management/_handle_alias.js b/test/functional/apps/management/_handle_alias.js
index 55f6b56d9f0d1..4ef02f6c9e873 100644
--- a/test/functional/apps/management/_handle_alias.js
+++ b/test/functional/apps/management/_handle_alias.js
@@ -23,11 +23,13 @@ export default function({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
const es = getService('legacyEs');
const retry = getService('retry');
+ const security = getService('security');
const PageObjects = getPageObjects(['common', 'home', 'settings', 'discover', 'timePicker']);
// FLAKY: https://github.com/elastic/kibana/issues/59717
describe.skip('Index patterns on aliases', function() {
before(async function() {
+ await security.testUser.setRoles(['kibana_admin', 'test_alias_reader']);
await esArchiver.loadIfNeeded('alias');
await esArchiver.load('empty_kibana');
await es.indices.updateAliases({
@@ -84,6 +86,7 @@ export default function({ getService, getPageObjects }) {
});
after(async () => {
+ await security.testUser.restoreDefaults();
await esArchiver.unload('alias');
});
});
diff --git a/test/functional/apps/management/_test_huge_fields.js b/test/functional/apps/management/_test_huge_fields.js
index 643cbcbe89482..bc280e51ae048 100644
--- a/test/functional/apps/management/_test_huge_fields.js
+++ b/test/functional/apps/management/_test_huge_fields.js
@@ -21,6 +21,7 @@ import expect from '@kbn/expect';
export default function({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
+ const security = getService('security');
const PageObjects = getPageObjects(['common', 'home', 'settings']);
describe('test large number of fields', function() {
@@ -28,6 +29,7 @@ export default function({ getService, getPageObjects }) {
const EXPECTED_FIELD_COUNT = '10006';
before(async function() {
+ await security.testUser.setRoles(['kibana_admin', 'test_testhuge_reader']);
await esArchiver.loadIfNeeded('large_fields');
await PageObjects.settings.createIndexPattern('testhuge', 'date');
});
@@ -38,6 +40,7 @@ export default function({ getService, getPageObjects }) {
});
after(async () => {
+ await security.testUser.restoreDefaults();
await esArchiver.unload('large_fields');
});
});
diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js
index 101b2d4f547dd..bf836cfe778b4 100644
--- a/test/functional/apps/visualize/_area_chart.js
+++ b/test/functional/apps/visualize/_area_chart.js
@@ -24,6 +24,7 @@ export default function({ getService, getPageObjects }) {
const inspector = getService('inspector');
const browser = getService('browser');
const retry = getService('retry');
+ const security = getService('security');
const PageObjects = getPageObjects([
'common',
'visualize',
@@ -58,7 +59,14 @@ export default function({ getService, getPageObjects }) {
return PageObjects.visEditor.clickGo();
};
- before(initAreaChart);
+ before(async function() {
+ await security.testUser.setRoles([
+ 'kibana_admin',
+ 'long_window_logstash',
+ 'test_logstash_reader',
+ ]);
+ await initAreaChart();
+ });
it('should save and load with special characters', async function() {
const vizNamewithSpecialChars = vizName1 + '/?&=%';
@@ -284,6 +292,7 @@ export default function({ getService, getPageObjects }) {
.pop()
.replace('embed=true', '');
await PageObjects.common.navigateToUrl('visualize', embedUrl);
+ await security.testUser.restoreDefaults();
});
});
diff --git a/test/functional/apps/visualize/_experimental_vis.js b/test/functional/apps/visualize/_experimental_vis.js
index 2ce15cf913eff..c45a95abab86e 100644
--- a/test/functional/apps/visualize/_experimental_vis.js
+++ b/test/functional/apps/visualize/_experimental_vis.js
@@ -23,7 +23,7 @@ export default ({ getService, getPageObjects }) => {
const log = getService('log');
const PageObjects = getPageObjects(['visualize']);
- describe('visualize app', function() {
+ describe('experimental visualizations in visualize app ', function() {
this.tags('smoke');
describe('experimental visualizations', () => {
diff --git a/test/functional/apps/visualize/_linked_saved_searches.ts b/test/functional/apps/visualize/_linked_saved_searches.ts
index 345987a803394..ea42f7c671985 100644
--- a/test/functional/apps/visualize/_linked_saved_searches.ts
+++ b/test/functional/apps/visualize/_linked_saved_searches.ts
@@ -32,7 +32,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
'visChart',
]);
- describe('visualize app', function describeIndexTests() {
+ describe('saved search visualizations from visualize app', function describeIndexTests() {
describe('linked saved searched', () => {
const savedSearchName = 'vis_saved_search';
diff --git a/test/functional/apps/visualize/_markdown_vis.js b/test/functional/apps/visualize/_markdown_vis.js
index fee6c074af5d2..649fe0a8e4c2e 100644
--- a/test/functional/apps/visualize/_markdown_vis.js
+++ b/test/functional/apps/visualize/_markdown_vis.js
@@ -29,7 +29,7 @@ export default function({ getPageObjects, getService }) {
Inline HTML that should not be rendered as html
`;
- describe('visualize app', () => {
+ describe('markdown app in visualize app', () => {
before(async function() {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickMarkdownWidget();
diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts
index 6a4bed3ba5892..867db66ac81dc 100644
--- a/test/functional/apps/visualize/_tsvb_chart.ts
+++ b/test/functional/apps/visualize/_tsvb_chart.ts
@@ -25,11 +25,13 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const log = getService('log');
const inspector = getService('inspector');
+ const security = getService('security');
const PageObjects = getPageObjects(['visualize', 'visualBuilder', 'timePicker', 'visChart']);
describe('visual builder', function describeIndexTests() {
this.tags('smoke');
beforeEach(async () => {
+ await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']);
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisualBuilder();
await PageObjects.visualBuilder.checkVisualBuilderIsPresent();
@@ -111,8 +113,10 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.visualBuilder.resetPage();
await PageObjects.visualBuilder.clickMetric();
await PageObjects.visualBuilder.checkMetricTabIsPresent();
+ await security.testUser.setRoles(['kibana_admin', 'kibana_sample_admin']);
});
after(async () => {
+ await security.testUser.restoreDefaults();
await esArchiver.unload('kibana_sample_data_flights');
});
diff --git a/test/functional/apps/visualize/_vega_chart.js b/test/functional/apps/visualize/_vega_chart.js
index df0603c7f95f5..7a19bde341cdd 100644
--- a/test/functional/apps/visualize/_vega_chart.js
+++ b/test/functional/apps/visualize/_vega_chart.js
@@ -25,7 +25,7 @@ export default function({ getService, getPageObjects }) {
const inspector = getService('inspector');
const log = getService('log');
- describe('visualize app', () => {
+ describe('vega chart in visualize app', () => {
before(async () => {
log.debug('navigateToApp visualize');
await PageObjects.visualize.navigateToNewVisualization();
diff --git a/test/functional/apps/visualize/input_control_vis/input_control_range.ts b/test/functional/apps/visualize/input_control_vis/input_control_range.ts
index f48ba7b54daf1..8f079f5cc430d 100644
--- a/test/functional/apps/visualize/input_control_vis/input_control_range.ts
+++ b/test/functional/apps/visualize/input_control_vis/input_control_range.ts
@@ -25,10 +25,12 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const find = getService('find');
+ const security = getService('security');
const { visualize, visEditor } = getPageObjects(['visualize', 'visEditor']);
describe('input control range', () => {
before(async () => {
+ await security.testUser.setRoles(['kibana_admin', 'kibana_sample_admin']);
await esArchiver.load('kibana_sample_data_flights_index_pattern');
await visualize.navigateToNewVisualization();
await visualize.clickInputControlVis();
@@ -63,6 +65,7 @@ export default function({ getService, getPageObjects }: FtrProviderContext) {
await esArchiver.loadIfNeeded('long_window_logstash');
await esArchiver.load('visualize');
await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-*' });
+ await security.testUser.restoreDefaults();
});
});
}
diff --git a/test/functional/config.js b/test/functional/config.js
index e84b7e0a98a68..11399bd6187c8 100644
--- a/test/functional/config.js
+++ b/test/functional/config.js
@@ -103,5 +103,172 @@ export default async function({ readConfigFile }) {
browser: {
type: 'chrome',
},
+
+ security: {
+ roles: {
+ test_logstash_reader: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['logstash*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+ test_shakespeare_reader: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['shakes*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+ test_testhuge_reader: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['testhuge*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+ test_alias_reader: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['alias*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+ //for sample data - can remove but not add sample data.( not ml)- for ml use built in role.
+ kibana_sample_admin: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['kibana_sample*'],
+ privileges: ['read', 'view_index_metadata', 'manage', 'create_index', 'index'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ kibana_date_nanos: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['date-nanos'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ kibana_date_nanos_custom: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['date_nanos_custom_timestamp'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ kibana_date_nanos_mixed: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['date_nanos_mixed', 'timestamp-*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ kibana_large_strings: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['testlargestring'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ long_window_logstash: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['long-window-logstash-*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+
+ animals: {
+ elasticsearch: {
+ cluster: [],
+ indices: [
+ {
+ names: ['animals-*'],
+ privileges: ['read', 'view_index_metadata'],
+ field_security: { grant: ['*'], except: [] },
+ },
+ ],
+ run_as: [],
+ },
+ kibana: [],
+ },
+ },
+ defaultRoles: ['test_logstash_reader', 'kibana_admin'],
+ },
};
}
diff --git a/test/functional/page_objects/common_page.ts b/test/functional/page_objects/common_page.ts
index 60966511c1f99..6895034f22ed5 100644
--- a/test/functional/page_objects/common_page.ts
+++ b/test/functional/page_objects/common_page.ts
@@ -105,13 +105,16 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo
const wantedLoginPage = appUrl.includes('/login') || appUrl.includes('/logout');
if (loginPage && !wantedLoginPage) {
- log.debug(
- `Found login page. Logging in with username = ${config.get('servers.kibana.username')}`
- );
- await PageObjects.shield.login(
- config.get('servers.kibana.username'),
- config.get('servers.kibana.password')
- );
+ log.debug('Found login page');
+ if (config.get('security.disableTestUser')) {
+ await PageObjects.shield.login(
+ config.get('servers.kibana.username'),
+ config.get('servers.kibana.password')
+ );
+ } else {
+ await PageObjects.shield.login('test_user', 'changeme');
+ }
+
await find.byCssSelector(
'[data-test-subj="kibanaChrome"] nav:not(.ng-hide)',
6 * defaultFindTimeout
@@ -511,6 +514,12 @@ export function CommonPageProvider({ getService, getPageObjects }: FtrProviderCo
}
});
}
+
+ async setFileInputPath(path: string) {
+ log.debug(`Setting the path '${path}' on the file input`);
+ const input = await find.byCssSelector('.euiFilePicker__input');
+ await input.type(path);
+ }
}
return new CommonPage();
diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts
index c244deba5f17e..0ad1a1dc51321 100644
--- a/test/functional/page_objects/settings_page.ts
+++ b/test/functional/page_objects/settings_page.ts
@@ -612,9 +612,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider
log.debug(`Clicking importObjects`);
await testSubjects.click('importObjects');
- log.debug(`Setting the path on the file input`);
- const input = await find.byCssSelector('.euiFilePicker__input');
- await input.type(path);
+ await PageObjects.common.setFileInputPath(path);
if (!overwriteAll) {
log.debug(`Toggling overwriteAll`);
diff --git a/test/functional/screenshots/baseline/area_chart.png b/test/functional/screenshots/baseline/area_chart.png
index 2c2d599139100..1a381d61dd9f1 100644
Binary files a/test/functional/screenshots/baseline/area_chart.png and b/test/functional/screenshots/baseline/area_chart.png differ
diff --git a/test/functional/screenshots/baseline/tsvb_dashboard.png b/test/functional/screenshots/baseline/tsvb_dashboard.png
index d703be89b7460..f5ebccbcb96c6 100644
Binary files a/test/functional/screenshots/baseline/tsvb_dashboard.png and b/test/functional/screenshots/baseline/tsvb_dashboard.png differ
diff --git a/test/functional/services/browser.ts b/test/functional/services/browser.ts
index 02349b4e6cca2..5017947e95d03 100644
--- a/test/functional/services/browser.ts
+++ b/test/functional/services/browser.ts
@@ -21,6 +21,7 @@ import { cloneDeep } from 'lodash';
import { Key, Origin } from 'selenium-webdriver';
// @ts-ignore internal modules are not typed
import { LegacyActionSequence } from 'selenium-webdriver/lib/actions';
+import { ProvidedType } from '@kbn/test/types/ftr';
import Jimp from 'jimp';
import { modifyUrl } from '../../../src/core/utils';
@@ -28,6 +29,7 @@ import { WebElementWrapper } from './lib/web_element_wrapper';
import { FtrProviderContext } from '../ftr_provider_context';
import { Browsers } from './remote/browsers';
+export type Browser = ProvidedType;
export async function BrowserProvider({ getService }: FtrProviderContext) {
const log = getService('log');
const { driver, browserType } = await getService('__webdriver__').init();
diff --git a/test/functional/services/test_subjects.ts b/test/functional/services/test_subjects.ts
index d47b838c8d72a..e5c2e61c48a0b 100644
--- a/test/functional/services/test_subjects.ts
+++ b/test/functional/services/test_subjects.ts
@@ -19,6 +19,7 @@
import testSubjSelector from '@kbn/test-subj-selector';
import { map as mapAsync } from 'bluebird';
+import { ProvidedType } from '@kbn/test/types/ftr';
import { WebElementWrapper } from './lib/web_element_wrapper';
import { FtrProviderContext } from '../ftr_provider_context';
@@ -32,6 +33,7 @@ interface SetValueOptions {
typeCharByChar?: boolean;
}
+export type TestSubjects = ProvidedType;
export function TestSubjectsProvider({ getService }: FtrProviderContext) {
const log = getService('log');
const retry = getService('retry');
diff --git a/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts b/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts
index fad19728b7514..3f6a8e8773e04 100644
--- a/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts
+++ b/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts
@@ -33,7 +33,7 @@ export class RenderingPlugin implements Plugin {
{
includeUserSettings: schema.boolean({ defaultValue: true }),
},
- { allowUnknowns: true }
+ { unknowns: 'allow' }
),
params: schema.object({
id: schema.maybe(schema.string()),
diff --git a/test/scripts/jenkins_xpack_build_kibana.sh b/test/scripts/jenkins_xpack_build_kibana.sh
index f87d6e1102c45..2bf9d2d9c158b 100755
--- a/test/scripts/jenkins_xpack_build_kibana.sh
+++ b/test/scripts/jenkins_xpack_build_kibana.sh
@@ -6,6 +6,7 @@ source src/dev/ci_setup/setup_env.sh
echo " -> building kibana platform plugins"
node scripts/build_kibana_platform_plugins \
--scan-dir "$XPACK_DIR/test/plugin_functional/plugins" \
+ --scan-dir "$XPACK_DIR/test/functional_with_es_ssl/fixtures/plugins" \
--verbose;
# doesn't persist, also set in kibanaPipeline.groovy
diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json
index 60a8d1fcbf229..1564eb94a6903 100644
--- a/x-pack/.i18nrc.json
+++ b/x-pack/.i18nrc.json
@@ -22,7 +22,7 @@
"xpack.infra": "plugins/infra",
"xpack.ingestManager": "plugins/ingest_manager",
"xpack.lens": "legacy/plugins/lens",
- "xpack.licenseMgmt": "legacy/plugins/license_management",
+ "xpack.licenseMgmt": "plugins/license_management",
"xpack.licensing": "plugins/licensing",
"xpack.logstash": "legacy/plugins/logstash",
"xpack.main": "legacy/plugins/xpack_main",
diff --git a/x-pack/index.js b/x-pack/index.js
index ab31d40c5d718..fb14b3dc10a4d 100644
--- a/x-pack/index.js
+++ b/x-pack/index.js
@@ -16,7 +16,6 @@ import { logstash } from './legacy/plugins/logstash';
import { beats } from './legacy/plugins/beats_management';
import { apm } from './legacy/plugins/apm';
import { maps } from './legacy/plugins/maps';
-import { licenseManagement } from './legacy/plugins/license_management';
import { indexManagement } from './legacy/plugins/index_management';
import { indexLifecycleManagement } from './legacy/plugins/index_lifecycle_management';
import { spaces } from './legacy/plugins/spaces';
@@ -52,7 +51,6 @@ module.exports = function(kibana) {
apm(kibana),
maps(kibana),
canvas(kibana),
- licenseManagement(kibana),
indexManagement(kibana),
indexLifecycleManagement(kibana),
infra(kibana),
diff --git a/x-pack/legacy/plugins/actions/server/mappings.json b/x-pack/legacy/plugins/actions/server/mappings.json
index a9c4d80b00af1..ef6a0c9919920 100644
--- a/x-pack/legacy/plugins/actions/server/mappings.json
+++ b/x-pack/legacy/plugins/actions/server/mappings.json
@@ -2,7 +2,12 @@
"action": {
"properties": {
"name": {
- "type": "text"
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ }
},
"actionTypeId": {
"type": "keyword"
diff --git a/x-pack/legacy/plugins/alerting/server/mappings.json b/x-pack/legacy/plugins/alerting/server/mappings.json
index 31733f44e7ce6..a7e85febf2446 100644
--- a/x-pack/legacy/plugins/alerting/server/mappings.json
+++ b/x-pack/legacy/plugins/alerting/server/mappings.json
@@ -5,7 +5,12 @@
"type": "boolean"
},
"name": {
- "type": "text"
+ "type": "text",
+ "fields": {
+ "keyword": {
+ "type": "keyword"
+ }
+ }
},
"tags": {
"type": "keyword"
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx
index 31fc4db8f1a2f..cff190cd98a11 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx
@@ -209,7 +209,7 @@ export function MachineLearningFlyoutView({
{i18n.translate(
'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createNewJobButtonLabel',
{
- defaultMessage: 'Create new job'
+ defaultMessage: 'Create job'
}
)}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx
index 6f7b743d8b779..b18f462b54171 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx
@@ -13,7 +13,7 @@ import { getCytoscapeElements } from './get_cytoscape_elements';
import serviceMapResponse from './cytoscape-layout-test-response.json';
import { iconForNode } from './icons';
-const elementsFromResponses = getCytoscapeElements([serviceMapResponse], '');
+const elementsFromResponses = getCytoscapeElements(serviceMapResponse, '');
storiesOf('app/ServiceMap/Cytoscape', module).add(
'example',
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.test.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.test.tsx
new file mode 100644
index 0000000000000..d61dea80666a0
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.test.tsx
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { act, render, wait } from '@testing-library/react';
+import cytoscape from 'cytoscape';
+import React, { FunctionComponent } from 'react';
+import { MockApmPluginContextWrapper } from '../../../utils/testHelpers';
+import { CytoscapeContext } from './Cytoscape';
+import { EmptyBanner } from './EmptyBanner';
+
+const cy = cytoscape({});
+
+const wrapper: FunctionComponent = ({ children }) => (
+
+ {children}
+
+);
+
+describe('EmptyBanner', () => {
+ describe('when cy is undefined', () => {
+ it('renders null', () => {
+ const noCytoscapeWrapper: FunctionComponent = ({ children }) => (
+
+
+ {children}
+
+
+ );
+ const component = render( , {
+ wrapper: noCytoscapeWrapper
+ });
+
+ expect(component.container.children).toHaveLength(0);
+ });
+ });
+
+ describe('with no nodes', () => {
+ it('renders null', () => {
+ const component = render( , {
+ wrapper
+ });
+
+ expect(component.container.children).toHaveLength(0);
+ });
+ });
+
+ describe('with one node', () => {
+ it('does not render null', async () => {
+ const component = render( , { wrapper });
+
+ await act(async () => {
+ cy.add({ data: { id: 'test id' } });
+ await wait(() => {
+ expect(component.container.children.length).toBeGreaterThan(0);
+ });
+ });
+ });
+ });
+});
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.tsx
index 418430e37b21e..464bf166eb80f 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/EmptyBanner.tsx
@@ -7,37 +7,70 @@
import { EuiCallOut } from '@elastic/eui';
import lightTheme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
-import React from 'react';
+import React, { useContext, useEffect, useState } from 'react';
import styled from 'styled-components';
import { ElasticDocsLink } from '../../shared/Links/ElasticDocsLink';
+import { CytoscapeContext } from './Cytoscape';
-const EmptyBannerCallOut = styled(EuiCallOut)`
+const EmptyBannerContainer = styled.div`
margin: ${lightTheme.gutterTypes.gutterSmall};
/* Add some extra margin so it displays to the right of the controls. */
- margin-left: calc(
- ${lightTheme.gutterTypes.gutterLarge} +
- ${lightTheme.gutterTypes.gutterExtraLarge}
+ left: calc(
+ ${lightTheme.gutterTypes.gutterExtraLarge} +
+ ${lightTheme.gutterTypes.gutterSmall}
);
position: absolute;
z-index: 1;
`;
export function EmptyBanner() {
+ const cy = useContext(CytoscapeContext);
+ const [nodeCount, setNodeCount] = useState(0);
+
+ useEffect(() => {
+ const handler: cytoscape.EventHandler = event =>
+ setNodeCount(event.cy.nodes().length);
+
+ if (cy) {
+ cy.on('add remove', 'node', handler);
+ }
+
+ return () => {
+ if (cy) {
+ cy.removeListener('add remove', 'node', handler);
+ }
+ };
+ }, [cy]);
+
+ // Only show if there's a single node.
+ if (!cy || nodeCount !== 1) {
+ return null;
+ }
+
+ // Since we're absolutely positioned, we need to get the full width and
+ // subtract the space for controls and margins.
+ const width =
+ cy.width() -
+ parseInt(lightTheme.gutterTypes.gutterExtraLarge, 10) -
+ parseInt(lightTheme.gutterTypes.gutterLarge, 10);
+
return (
-
- {i18n.translate('xpack.apm.serviceMap.emptyBanner.message', {
- defaultMessage:
- "We will map out connected services and external requests if we can detect them. Please make sure you're running the latest version of the APM agent."
- })}{' '}
-
- {i18n.translate('xpack.apm.serviceMap.emptyBanner.docsLink', {
- defaultMessage: 'Learn more in the docs'
+
+
-
+ >
+ {i18n.translate('xpack.apm.serviceMap.emptyBanner.message', {
+ defaultMessage:
+ "We will map out connected services and external requests if we can detect them. Please make sure you're running the latest version of the APM agent."
+ })}{' '}
+
+ {i18n.translate('xpack.apm.serviceMap.emptyBanner.docsLink', {
+ defaultMessage: 'Learn more in the docs'
+ })}
+
+
+
);
}
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
index 9213349a1492b..77f0b64ba0fb1 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx
@@ -6,10 +6,12 @@
import {
EuiButton,
- EuiEmptyPrompt,
+ EuiPanel,
EuiFlexGroup,
EuiFlexItem,
- EuiPanel
+ EuiTitle,
+ EuiText,
+ EuiSpacer
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
@@ -18,7 +20,8 @@ import { useKibanaUrl } from '../../../hooks/useKibanaUrl';
export function PlatinumLicensePrompt() {
// Set the height to give it some top margin
- const style = { height: '60vh' };
+ const flexGroupStyle = { height: '60vh' };
+ const flexItemStyle = { width: 600, textAlign: 'center' as const };
const licensePageUrl = useKibanaUrl(
'/app/kibana',
@@ -29,30 +32,41 @@ export function PlatinumLicensePrompt() {
-
-
-
- {i18n.translate(
- 'xpack.apm.serviceMap.licensePromptButtonText',
- {
- defaultMessage: 'Start 30-day Platinum trial'
- }
- )}
-
- ]}
- body={{invalidLicenseMessage}
}
- title={
+
+
+
+
+
{i18n.translate('xpack.apm.serviceMap.licensePromptTitle', {
defaultMessage: 'Service maps is available in Platinum.'
})}
- }
- />
+
+
+
+ {invalidLicenseMessage}
+
+
+
+ {i18n.translate('xpack.apm.serviceMap.licensePromptButtonText', {
+ defaultMessage: 'Start 30-day Platinum trial'
+ })}
+
+
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/get_cytoscape_elements.ts b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/get_cytoscape_elements.ts
index 9ba70646598fc..4017aa2e3cdd9 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/get_cytoscape_elements.ts
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/get_cytoscape_elements.ts
@@ -4,166 +4,63 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ValuesType } from 'utility-types';
-import { sortBy, isEqual } from 'lodash';
-import {
- Connection,
- ConnectionNode
-} from '../../../../../../../plugins/apm/common/service_map';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { ServiceMapAPIResponse } from '../../../../../../../plugins/apm/server/lib/service_map/get_service_map';
import { getAPMHref } from '../../shared/Links/apm/APMLink';
-function getConnectionNodeId(node: ConnectionNode): string {
- if ('destination.address' in node) {
- // use a prefix to distinguish exernal destination ids from services
- return `>${node['destination.address']}`;
- }
- return node['service.name'];
-}
-
-function getConnectionId(connection: Connection) {
- return `${getConnectionNodeId(connection.source)}~${getConnectionNodeId(
- connection.destination
- )}`;
-}
export function getCytoscapeElements(
- responses: ServiceMapAPIResponse[],
+ response: ServiceMapAPIResponse,
search: string
) {
- const discoveredServices = responses.flatMap(
- response => response.discoveredServices
- );
-
- const serviceNodes = responses
- .flatMap(response => response.services)
- .map(service => ({
- ...service,
- id: service['service.name']
- }));
-
- // maps destination.address to service.name if possible
- function getConnectionNode(node: ConnectionNode) {
- let mappedNode: ConnectionNode | undefined;
-
- if ('destination.address' in node) {
- mappedNode = discoveredServices.find(map => isEqual(map.from, node))?.to;
- }
-
- if (!mappedNode) {
- mappedNode = node;
- }
-
- return {
- ...mappedNode,
- id: getConnectionNodeId(mappedNode)
- };
- }
-
- // build connections with mapped nodes
- const connections = responses
- .flatMap(response => response.connections)
- .map(connection => {
- const source = getConnectionNode(connection.source);
- const destination = getConnectionNode(connection.destination);
-
- return {
- source,
- destination,
- id: getConnectionId({ source, destination })
- };
- })
- .filter(connection => connection.source.id !== connection.destination.id);
-
- const nodes = connections
- .flatMap(connection => [connection.source, connection.destination])
- .concat(serviceNodes);
-
- type ConnectionWithId = ValuesType;
- type ConnectionNodeWithId = ValuesType;
-
- const connectionsById = connections.reduce((connectionMap, connection) => {
- return {
- ...connectionMap,
- [connection.id]: connection
- };
- }, {} as Record);
+ const { nodes, connections } = response;
const nodesById = nodes.reduce((nodeMap, node) => {
return {
...nodeMap,
[node.id]: node
};
- }, {} as Record);
-
- const cyNodes = (Object.values(nodesById) as ConnectionNodeWithId[]).map(
- node => {
- let data = {};
-
- if ('service.name' in node) {
- data = {
- href: getAPMHref(
- `/services/${node['service.name']}/service-map`,
- search
- ),
- agentName: node['agent.name'],
- frameworkName: node['service.framework.name'],
- type: 'service'
- };
- }
-
- if ('span.type' in node) {
- data = {
- // For nodes with span.type "db", convert it to "database". Otherwise leave it as-is.
- type: node['span.type'] === 'db' ? 'database' : node['span.type'],
- // Externals should not have a subtype so make it undefined if the type is external.
- subtype: node['span.type'] !== 'external' && node['span.subtype']
- };
- }
-
- return {
- group: 'nodes' as const,
- data: {
- id: node.id,
- label:
- 'service.name' in node
- ? node['service.name']
- : node['destination.address'],
- ...data
- }
+ }, {} as Record>);
+
+ const cyNodes = (Object.values(nodesById) as Array<
+ ValuesType
+ >).map(node => {
+ let data = {};
+
+ if ('service.name' in node) {
+ data = {
+ href: getAPMHref(
+ `/services/${node['service.name']}/service-map`,
+ search
+ ),
+ agentName: node['agent.name'],
+ frameworkName: node['service.framework.name'],
+ type: 'service'
};
}
- );
-
- // instead of adding connections in two directions,
- // we add a `bidirectional` flag to use in styling
- // and hide the inverse edge when rendering
- const dedupedConnections = (sortBy(
- Object.values(connectionsById),
- // make sure that order is stable
- 'id'
- ) as ConnectionWithId[]).reduce<
- Array<
- ConnectionWithId & { bidirectional?: boolean; isInverseEdge?: boolean }
- >
- >((prev, connection) => {
- const reversedConnection = prev.find(
- c =>
- c.destination.id === connection.source.id &&
- c.source.id === connection.destination.id
- );
- if (reversedConnection) {
- reversedConnection.bidirectional = true;
- return prev.concat({
- ...connection,
- isInverseEdge: true
- });
+ if ('span.type' in node) {
+ data = {
+ // For nodes with span.type "db", convert it to "database". Otherwise leave it as-is.
+ type: node['span.type'] === 'db' ? 'database' : node['span.type'],
+ // Externals should not have a subtype so make it undefined if the type is external.
+ subtype: node['span.type'] !== 'external' && node['span.subtype']
+ };
}
- return prev.concat(connection);
- }, []);
+ return {
+ group: 'nodes' as const,
+ data: {
+ id: node.id,
+ label:
+ 'service.name' in node
+ ? node['service.name']
+ : node['destination.address'],
+ ...data
+ }
+ };
+ });
- const cyEdges = dedupedConnections.map(connection => {
+ const cyEdges = connections.map(connection => {
return {
group: 'edges' as const,
classes: connection.isInverseEdge ? 'invisible' : undefined,
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/dot-net.svg b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/dot-net.svg
index 9f7427f0e1001..da7f1a8fde45d 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/dot-net.svg
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/dot-net.svg
@@ -1,127 +1,3 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
index 7bbb77a49c84b..6222a00a9e888 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx
@@ -4,24 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { EuiBetaBadge } from '@elastic/eui';
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
-import { ElementDefinition } from 'cytoscape';
-import { find, isEqual } from 'lodash';
-import React, {
- useCallback,
- useEffect,
- useMemo,
- useRef,
- useState
-} from 'react';
+import React, { useMemo } from 'react';
+import styled from 'styled-components';
import { isValidPlatinumLicense } from '../../../../../../../plugins/apm/common/service_map';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { ServiceMapAPIResponse } from '../../../../../../../plugins/apm/server/lib/service_map/get_service_map';
-import { useApmPluginContext } from '../../../hooks/useApmPluginContext';
import { useDeepObjectIdentity } from '../../../hooks/useDeepObjectIdentity';
+import { useFetcher } from '../../../hooks/useFetcher';
import { useLicense } from '../../../hooks/useLicense';
-import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator';
import { useLocation } from '../../../hooks/useLocation';
import { useUrlParams } from '../../../hooks/useUrlParams';
import { callApmApi } from '../../../services/rest/createCallApmApi';
@@ -56,14 +47,17 @@ ${theme.euiColorLightShade}`,
margin: `-${theme.gutterTypes.gutterLarge}`,
marginTop: 0
};
-
-const MAX_REQUESTS = 5;
+const BetaBadgeContainer = styled.div`
+ right: ${theme.gutterTypes.gutterMedium};
+ position: absolute;
+ top: ${theme.gutterTypes.gutterSmall};
+ z-index: 1; /* The element containing the cytoscape canvas has z-index = 0. */
+`;
export function ServiceMap({ serviceName }: ServiceMapProps) {
const license = useLicense();
const { search } = useLocation();
const { urlParams, uiFilters } = useUrlParams();
- const { notifications } = useApmPluginContext().core;
const params = useDeepObjectIdentity({
start: urlParams.start,
end: urlParams.end,
@@ -75,95 +69,28 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
}
});
- const renderedElements = useRef([]);
-
- const [responses, setResponses] = useState([]);
-
- const { setIsLoading } = useLoadingIndicator();
-
- const [, _setUnusedState] = useState(false);
-
- const elements = useMemo(() => getCytoscapeElements(responses, search), [
- responses,
- search
- ]);
-
- const forceUpdate = useCallback(() => _setUnusedState(value => !value), []);
-
- const getNext = useCallback(
- async (input: { reset?: boolean; after?: string | undefined }) => {
- const { start, end, uiFilters: strippedUiFilters, ...query } = params;
-
- if (input.reset) {
- renderedElements.current = [];
- setResponses([]);
- }
-
- if (start && end) {
- setIsLoading(true);
- try {
- const data = await callApmApi({
- pathname: '/api/apm/service-map',
- params: {
- query: {
- ...query,
- start,
- end,
- uiFilters: JSON.stringify(strippedUiFilters),
- after: input.after
- }
- }
- });
- setResponses(resp => resp.concat(data));
-
- const shouldGetNext =
- responses.length + 1 < MAX_REQUESTS && data.after;
-
- if (shouldGetNext) {
- await getNext({ after: data.after });
- } else {
- setIsLoading(false);
+ const { data } = useFetcher(() => {
+ const { start, end } = params;
+ if (start && end) {
+ return callApmApi({
+ pathname: '/api/apm/service-map',
+ params: {
+ query: {
+ ...params,
+ start,
+ end,
+ uiFilters: JSON.stringify(params.uiFilters)
}
- } catch (error) {
- setIsLoading(false);
- notifications.toasts.addError(error, {
- title: i18n.translate('xpack.apm.errorServiceMapData', {
- defaultMessage: `Error loading service connections`
- })
- });
}
- }
- },
- [params, setIsLoading, responses.length, notifications.toasts]
- );
-
- useEffect(() => {
- const loadServiceMaps = async () => {
- await getNext({ reset: true });
- };
-
- loadServiceMaps();
-
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [params]);
-
- useEffect(() => {
- if (renderedElements.current.length === 0) {
- renderedElements.current = elements;
- return;
+ });
}
+ }, [params]);
- const newElements = elements.filter(element => {
- return !find(renderedElements.current, el => isEqual(el, element));
- });
+ const elements = useMemo(() => {
+ return data ? getCytoscapeElements(data as any, search) : [];
+ }, [data, search]);
- if (newElements.length > 0 && renderedElements.current.length > 0) {
- renderedElements.current = elements;
- forceUpdate();
- }
- }, [elements, forceUpdate]);
-
- const { ref: wrapperRef, width, height } = useRefDimensions();
+ const { ref, height, width } = useRefDimensions();
if (!license) {
return null;
@@ -172,20 +99,32 @@ export function ServiceMap({ serviceName }: ServiceMapProps) {
return isValidPlatinumLicense(license) ? (
- {serviceName && renderedElements.current.length === 1 && (
-
- )}
+ {serviceName && }
+
+
+
) : (
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js
index 193d99e1c9533..faadfd4bb26d7 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/demodata.js
@@ -21,6 +21,6 @@ export const demodata = () => ({
name: 'demodata',
displayName: strings.getDisplayName(),
help: strings.getHelp(),
- image: 'logoElasticStack',
+ image: 'training',
template: templateFromReactComponent(DemodataDatasource),
});
diff --git a/x-pack/legacy/plugins/canvas/public/expression_types/datasources/esdocs.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/esdocs.js
similarity index 58%
rename from x-pack/legacy/plugins/canvas/public/expression_types/datasources/esdocs.js
rename to x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/esdocs.js
index eacb7e891b482..282ec17e94c9b 100644
--- a/x-pack/legacy/plugins/canvas/public/expression_types/datasources/esdocs.js
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/esdocs.js
@@ -6,15 +6,24 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { EuiFormRow, EuiSelect, EuiTextArea, EuiCallOut, EuiSpacer } from '@elastic/eui';
-import { getSimpleArg, setSimpleArg } from '../../lib/arg_helpers';
-import { ESFieldsSelect } from '../../components/es_fields_select';
-import { ESFieldSelect } from '../../components/es_field_select';
-import { ESIndexSelect } from '../../components/es_index_select';
-import { templateFromReactComponent } from '../../lib/template_from_react_component';
-import { ExpressionDataSourceStrings } from '../../../i18n';
-
-const { ESDocs: strings } = ExpressionDataSourceStrings;
+import {
+ EuiFormRow,
+ EuiAccordion,
+ EuiSelect,
+ EuiTextArea,
+ EuiCallOut,
+ EuiSpacer,
+ EuiLink,
+ EuiText,
+} from '@elastic/eui';
+import { getSimpleArg, setSimpleArg } from '../../../public/lib/arg_helpers';
+import { ESFieldsSelect } from '../../../public/components/es_fields_select';
+import { ESFieldSelect } from '../../../public/components/es_field_select';
+import { ESIndexSelect } from '../../../public/components/es_index_select';
+import { templateFromReactComponent } from '../../../public/lib/template_from_react_component';
+import { DataSourceStrings, LUCENE_QUERY_URL } from '../../../i18n';
+
+const { ESDocs: strings } = DataSourceStrings;
const EsdocsDatasource = ({ args, updateArgs, defaultIndex }) => {
const setArg = (name, value) => {
@@ -74,12 +83,6 @@ const EsdocsDatasource = ({ args, updateArgs, defaultIndex }) => {
return (
-
- {strings.getWarning()}
-
-
-
-
{
setArg('index', index)} />
-
- setArg(getArgName(), e.target.value)}
- compressed
- />
-
-
{
/>
-
+
- setArg('sort', [field, sortOrder].join(', '))}
- />
-
+
+
+ setArg('sort', [field, sortOrder].join(', '))}
+ />
+
+
+
+ setArg('sort', [sortField, e.target.value].join(', '))}
+ options={sortOptions}
+ compressed
+ />
+
+
+
+
+ {strings.getQueryLabel()}
+
+
+ }
+ display="rowCompressed"
+ >
+ setArg(getArgName(), e.target.value)}
+ compressed
+ />
+
+
-
- setArg('sort', [sortField, e.target.value].join(', '))}
- options={sortOptions}
- compressed
- />
-
+
+
+
+ {strings.getWarning()}
+
);
};
@@ -150,6 +165,6 @@ export const esdocs = () => ({
name: 'esdocs',
displayName: strings.getDisplayName(),
help: strings.getHelp(),
- image: 'logoElasticsearch',
+ image: 'documents',
template: templateFromReactComponent(EsdocsDatasource),
});
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js
index 707f2305e1368..44e335dd7b41f 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/essql.js
@@ -95,7 +95,6 @@ export const essql = () => ({
name: 'essql',
displayName: strings.getDisplayName(),
help: strings.getHelp(),
- // Replace this with a SQL logo when we have one in EUI
- image: 'logoElasticsearch',
+ image: 'database',
template: templateFromReactComponent(EssqlDatasource),
});
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js
index 13aa2a06306a0..5bddf1d3f4b6b 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/index.js
@@ -4,8 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { demodata } from './demodata';
import { essql } from './essql';
+import { esdocs } from './esdocs';
+import { demodata } from './demodata';
import { timelion } from './timelion';
-export const datasourceSpecs = [demodata, essql, timelion];
+export const datasourceSpecs = [essql, esdocs, demodata, timelion];
diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js
index b30e43c1c3c57..b36f1a747f120 100644
--- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js
+++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/uis/datasources/timelion.js
@@ -13,12 +13,13 @@ import {
EuiSpacer,
EuiCode,
EuiTextArea,
+ EuiText,
+ EuiLink,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { getSimpleArg, setSimpleArg } from '../../../public/lib/arg_helpers';
import { templateFromReactComponent } from '../../../public/lib/template_from_react_component';
-import { DataSourceStrings, TIMELION, CANVAS } from '../../../i18n';
-import { TooltipIcon } from '../../../public/components/tooltip_icon';
+import { DataSourceStrings, TIMELION_QUERY_URL, TIMELION, CANVAS } from '../../../i18n';
const { Timelion: strings } = DataSourceStrings;
@@ -86,8 +87,14 @@ const TimelionDatasource = ({ args, updateArgs, defaultIndex }) => {
}
+ labelAppend={
+
+
+ {strings.queryLabel()}
+
+
+ }
+ display="rowCompressed"
>
{
rows={15}
/>
+
{
// TODO: Time timelion interval picker should be a drop down
}
@@ -124,6 +132,6 @@ export const timelion = () => ({
name: 'timelion',
displayName: TIMELION,
help: strings.getHelp(),
- image: 'timelionApp',
+ image: 'visTimelion',
template: templateFromReactComponent(TimelionDatasource),
});
diff --git a/x-pack/legacy/plugins/canvas/i18n/constants.ts b/x-pack/legacy/plugins/canvas/i18n/constants.ts
index 4cb05b0426fa1..099effc697fc5 100644
--- a/x-pack/legacy/plugins/canvas/i18n/constants.ts
+++ b/x-pack/legacy/plugins/canvas/i18n/constants.ts
@@ -25,6 +25,7 @@ export const JS = 'JavaScript';
export const JSON = 'JSON';
export const KIBANA = 'Kibana';
export const LUCENE = 'Lucene';
+export const LUCENE_QUERY_URL = 'https://www.elastic.co/guide/en/kibana/current/lucene-query.html';
export const MARKDOWN = 'Markdown';
export const MOMENTJS = 'MomentJS';
export const MOMENTJS_TIMEZONE_URL = 'https://momentjs.com/timezone/';
@@ -37,6 +38,7 @@ export const SQL_URL =
'https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-spec.html';
export const SVG = 'SVG';
export const TIMELION = 'Timelion';
+export const TIMELION_QUERY_URL = 'https://www.elastic.co/blog/timelion-tutorial-from-zero-to-hero';
export const TINYMATH = '`TinyMath`';
export const TINYMATH_URL =
'https://www.elastic.co/guide/en/kibana/current/canvas-tinymath-functions.html';
diff --git a/x-pack/legacy/plugins/canvas/i18n/expression_types.ts b/x-pack/legacy/plugins/canvas/i18n/expression_types.ts
index bdd190f26c97a..5d3a3cd742bb4 100644
--- a/x-pack/legacy/plugins/canvas/i18n/expression_types.ts
+++ b/x-pack/legacy/plugins/canvas/i18n/expression_types.ts
@@ -5,7 +5,6 @@
*/
import { i18n } from '@kbn/i18n';
-import { LUCENE, ELASTICSEARCH } from './constants';
export const ArgTypesStrings = {
Color: {
@@ -143,86 +142,3 @@ export const ArgTypesStrings = {
}),
},
};
-
-export const ExpressionDataSourceStrings = {
- ESDocs: {
- getDisplayName: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocsTitle', {
- defaultMessage: 'Elasticsearch raw documents',
- }),
- getHelp: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocsLabel', {
- defaultMessage: 'Pull back raw documents from elasticsearch',
- }),
- getWarningTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.warningTitle', {
- defaultMessage: 'Query with caution',
- }),
- getWarning: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.warningDescription', {
- defaultMessage: `
- This datasource pulls directly from {elasticsearch}
- without the use of aggregations. It is best used with low volume datasets and in
- situations where you need to view raw documents or plot exact, non-aggregated values on a
- chart.`,
- values: {
- elasticsearch: ELASTICSEARCH,
- },
- }),
- getIndexTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.indexTitle', {
- defaultMessage: 'Index',
- }),
- getIndexLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.indexLabel', {
- defaultMessage: 'Enter an index name or select an index pattern',
- }),
- getQueryTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.queryTitle', {
- defaultMessage: 'Query',
- }),
- getQueryLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.queryLabel', {
- defaultMessage: '{lucene} query string syntax',
- values: {
- lucene: LUCENE,
- },
- }),
- getSortFieldTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.sortFieldTitle', {
- defaultMessage: 'Sort Field',
- }),
- getSortFieldLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.sortFieldLabel', {
- defaultMessage: 'Document sort field',
- }),
- getSortOrderTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.sortOrderTitle', {
- defaultMessage: 'Sort Order',
- }),
- getSortOrderLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.sortOrderLabel', {
- defaultMessage: 'Document sort order',
- }),
- getFieldsTitle: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.fieldsTitle', {
- defaultMessage: 'Fields',
- }),
- getFieldsLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.fieldsLabel', {
- defaultMessage: 'The fields to extract. Kibana scripted fields are not currently available',
- }),
- getFieldsWarningLabel: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.fieldsWarningLabel', {
- defaultMessage: 'This datasource performs best with 10 or fewer fields',
- }),
- getAscendingOption: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.ascendingDropDown', {
- defaultMessage: 'Ascending',
- }),
- getDescendingOption: () =>
- i18n.translate('xpack.canvas.expressionTypes.datasources.esdocs.descendingDropDown', {
- defaultMessage: 'Descending',
- }),
- },
-};
diff --git a/x-pack/legacy/plugins/canvas/i18n/functions/dict/demodata.ts b/x-pack/legacy/plugins/canvas/i18n/functions/dict/demodata.ts
index 20c7a88ea4f4d..caedbfdec5be4 100644
--- a/x-pack/legacy/plugins/canvas/i18n/functions/dict/demodata.ts
+++ b/x-pack/legacy/plugins/canvas/i18n/functions/dict/demodata.ts
@@ -13,7 +13,7 @@ import { DemoRows } from '../../../canvas_plugin_src/functions/server/demodata/g
export const help: FunctionHelp> = {
help: i18n.translate('xpack.canvas.functions.demodataHelpText', {
defaultMessage:
- 'A mock data set that includes project {ci} times with usernames, countries, and run phases.',
+ 'A sample data set that includes project {ci} times with usernames, countries, and run phases.',
values: {
ci: 'CI',
},
diff --git a/x-pack/legacy/plugins/canvas/i18n/ui.ts b/x-pack/legacy/plugins/canvas/i18n/ui.ts
index 5b94cb0435b31..1abe56c99dc89 100644
--- a/x-pack/legacy/plugins/canvas/i18n/ui.ts
+++ b/x-pack/legacy/plugins/canvas/i18n/ui.ts
@@ -308,6 +308,7 @@ export const ArgumentStrings = {
};
export const DataSourceStrings = {
+ // Demo data source
DemoData: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.dataSources.demoDataTitle', {
@@ -319,7 +320,7 @@ export const DataSourceStrings = {
}),
getHelp: () =>
i18n.translate('xpack.canvas.uis.dataSources.demoDataLabel', {
- defaultMessage: 'Mock data set with usernames, prices, projects, countries, and phases',
+ defaultMessage: 'Sample data set used to populate default elements',
}),
getDescription: () =>
i18n.translate('xpack.canvas.uis.dataSources.demoDataDescription', {
@@ -330,6 +331,88 @@ export const DataSourceStrings = {
},
}),
},
+ // Elasticsearch documents datasource
+ ESDocs: {
+ getDisplayName: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocsTitle', {
+ defaultMessage: '{elasticsearch} documents',
+ values: {
+ elasticsearch: ELASTICSEARCH,
+ },
+ }),
+ getHelp: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocsLabel', {
+ defaultMessage: 'Pull data directly from {elasticsearch} without the use of aggregations',
+ values: {
+ elasticsearch: ELASTICSEARCH,
+ },
+ }),
+ getWarningTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.warningTitle', {
+ defaultMessage: 'Query with caution',
+ }),
+ getWarning: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.warningDescription', {
+ defaultMessage: `
+ Using this data source with larger data sets can result in slower performance. Use this source only when you need exact values.`,
+ }),
+ getIndexTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.indexTitle', {
+ defaultMessage: 'Index',
+ }),
+ getIndexLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.indexLabel', {
+ defaultMessage: 'Enter an index name or select an index pattern',
+ }),
+ getQueryTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.queryTitle', {
+ defaultMessage: 'Query',
+ }),
+ getQueryLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.queryLabel', {
+ defaultMessage: '{lucene} query string syntax',
+ values: {
+ lucene: LUCENE,
+ },
+ }),
+ getSortFieldTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.sortFieldTitle', {
+ defaultMessage: 'Sort field',
+ }),
+ getSortFieldLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.sortFieldLabel', {
+ defaultMessage: 'Document sort field',
+ }),
+ getSortOrderTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.sortOrderTitle', {
+ defaultMessage: 'Sort order',
+ }),
+ getSortOrderLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.sortOrderLabel', {
+ defaultMessage: 'Document sort order',
+ }),
+ getFieldsTitle: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.fieldsTitle', {
+ defaultMessage: 'Fields',
+ }),
+ getFieldsLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.fieldsLabel', {
+ defaultMessage: 'Scripted fields are unavailable',
+ }),
+ getFieldsWarningLabel: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.fieldsWarningLabel', {
+ defaultMessage: 'This datasource performs best with 10 or fewer fields',
+ }),
+ getAscendingOption: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.ascendingDropDown', {
+ defaultMessage: 'Ascending',
+ }),
+ getDescendingOption: () =>
+ i18n.translate('xpack.canvas.uis.dataSources.esdocs.descendingDropDown', {
+ defaultMessage: 'Descending',
+ }),
+ },
+ // Elasticsearch SQL data source
Essql: {
getDisplayName: () =>
i18n.translate('xpack.canvas.uis.dataSources.essqlTitle', {
@@ -341,7 +424,7 @@ export const DataSourceStrings = {
}),
getHelp: () =>
i18n.translate('xpack.canvas.uis.dataSources.essqlLabel', {
- defaultMessage: 'Use {elasticsearch} {sql} to get a data table',
+ defaultMessage: 'Write an {elasticsearch} {sql} query to retrieve data',
values: {
elasticsearch: ELASTICSEARCH,
sql: SQL,
@@ -353,18 +436,18 @@ export const DataSourceStrings = {
}),
getLabelAppend: () =>
i18n.translate('xpack.canvas.uis.dataSources.essql.queryTitleAppend', {
- defaultMessage: 'Learn {elasticsearchShort} {sql} syntax',
+ defaultMessage: 'Learn {elasticsearchShort} {sql} query syntax',
values: {
elasticsearchShort: ELASTICSEARCH_SHORT,
sql: SQL,
},
}),
},
+ // Timelion datasource
Timelion: {
getAbout: () =>
i18n.translate('xpack.canvas.uis.dataSources.timelion.aboutDetail', {
- defaultMessage:
- 'Use {timelion} queries to pull back timeseries data that can be used with {canvas} elements.',
+ defaultMessage: 'Use {timelion} syntax in {canvas} to retrieve timeseries data',
values: {
timelion: TIMELION,
canvas: CANVAS,
@@ -372,7 +455,7 @@ export const DataSourceStrings = {
}),
getHelp: () =>
i18n.translate('xpack.canvas.uis.dataSources.timelionLabel', {
- defaultMessage: 'Use {timelion} syntax to retrieve a timeseries',
+ defaultMessage: 'Use {timelion} syntax to retrieve timeseries data',
values: {
timelion: TIMELION,
},
@@ -392,11 +475,11 @@ export const DataSourceStrings = {
i18n.translate('xpack.canvas.uis.dataSources.timelion.intervalTitle', {
defaultMessage: 'Interval',
}),
- getQueryHelp: () =>
+ queryLabel: () =>
i18n.translate('xpack.canvas.uis.dataSources.timelion.queryLabel', {
- defaultMessage: '{lucene} Query String syntax',
+ defaultMessage: '{timelion} Query String syntax',
values: {
- lucene: LUCENE,
+ timelion: TIMELION,
},
}),
getQueryLabel: () =>
diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss
index 2407dcbbce593..52c473ac2dd38 100644
--- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss
+++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource.scss
@@ -6,8 +6,13 @@
padding: 0 $euiSizeS;
}
-.canvasDataSource__section {
- padding: $euiSizeM;
+.canvasDataSource__section,
+.canvasDataSource__list {
+ padding: $euiSizeM $euiSizeM 0;
+}
+
+.canvasDataSource__sectionFooter {
+ padding: 0 $euiSizeM;
}
.canvasDataSource__triggerButton {
@@ -19,10 +24,6 @@
margin-right: $euiSizeS;
}
-.canvasDataSource__list {
- padding: $euiSizeM;
-}
-
.canvasDataSource__card .euiCard__content {
padding-top: 0 !important; // sass-lint:disable-line no-important
}
diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js
index 8b0061e047f33..285b69f057cd8 100644
--- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js
+++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_component.js
@@ -153,7 +153,7 @@ export class DatasourceComponent extends PureComponent {
flush="left"
size="s"
>
-
+
{stateDatasource.displayName}
diff --git a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js
index 92f9b92cb1f06..153a8a7ef75e6 100644
--- a/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js
+++ b/x-pack/legacy/plugins/canvas/public/components/datasource/datasource_selector.js
@@ -15,6 +15,7 @@ export const DatasourceSelector = ({ onSelect, datasources, current }) => (
key={d.name}
title={d.displayName}
titleElement="h5"
+ titleSize="xs"
icon={ }
description={d.help}
layout="horizontal"
diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts
index 7f81adad6bf9b..949264fcc9fdb 100644
--- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts
+++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts
@@ -6,7 +6,7 @@
import { connect } from 'react-redux';
import { compose, withProps } from 'recompose';
-import * as jobCompletionNotifications from '../../../../../reporting/public/lib/job_completion_notifications';
+import { jobCompletionNotifications } from '../../../../../../../plugins/reporting/public';
// @ts-ignore Untyped local
import { getWorkpad, getPages } from '../../../state/selectors/workpad';
// @ts-ignore Untyped local
diff --git a/x-pack/legacy/plugins/canvas/public/lib/find_expression_type.js b/x-pack/legacy/plugins/canvas/public/lib/find_expression_type.js
index d6d395feade8b..2cd7c5efb74e9 100644
--- a/x-pack/legacy/plugins/canvas/public/lib/find_expression_type.js
+++ b/x-pack/legacy/plugins/canvas/public/lib/find_expression_type.js
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { datasourceRegistry } from '../expression_types/datasource';
+//import { datasourceRegistry } from '../expression_types/datasource';
import { transformRegistry } from '../expression_types/transform';
import { modelRegistry } from '../expression_types/model';
import { viewRegistry } from '../expression_types/view';
@@ -28,9 +28,6 @@ export function findExpressionType(name, type) {
case 'transform':
expression = transformRegistry.get(name);
return !expression ? acc : acc.concat(expression);
- case 'datasource':
- expression = datasourceRegistry.get(name);
- return !expression ? acc : acc.concat(expression);
default:
return acc;
}
diff --git a/x-pack/legacy/plugins/canvas/public/lib/load_expression_types.js b/x-pack/legacy/plugins/canvas/public/lib/load_expression_types.js
index fb23f9459d30b..82699eb5b88fa 100644
--- a/x-pack/legacy/plugins/canvas/public/lib/load_expression_types.js
+++ b/x-pack/legacy/plugins/canvas/public/lib/load_expression_types.js
@@ -5,11 +5,9 @@
*/
import { argTypeSpecs } from '../expression_types/arg_types';
-import { datasourceSpecs } from '../expression_types/datasources';
-import { argTypeRegistry, datasourceRegistry } from '../expression_types';
+import { argTypeRegistry } from '../expression_types';
export function loadExpressionTypes() {
// register default args, arg types, and expression types
argTypeSpecs.forEach(expFn => argTypeRegistry.register(expFn));
- datasourceSpecs.forEach(expFn => datasourceRegistry.register(expFn));
}
diff --git a/x-pack/legacy/plugins/canvas/public/plugin.tsx b/x-pack/legacy/plugins/canvas/public/plugin.tsx
index 0a3faca1a2522..f4a3aed28a0a4 100644
--- a/x-pack/legacy/plugins/canvas/public/plugin.tsx
+++ b/x-pack/legacy/plugins/canvas/public/plugin.tsx
@@ -11,8 +11,6 @@ import { initLoadingIndicator } from './lib/loading_indicator';
import { featureCatalogueEntry } from './feature_catalogue_entry';
import { ExpressionsSetup, ExpressionsStart } from '../../../../../src/plugins/expressions/public';
// @ts-ignore untyped local
-import { datasourceSpecs } from './expression_types/datasources';
-// @ts-ignore untyped local
import { argTypeSpecs } from './expression_types/arg_types';
import { transitions } from './transitions';
import { legacyRegistries } from './legacy_plugin_support';
@@ -90,7 +88,6 @@ export class CanvasPlugin
// Register core canvas stuff
canvasApi.addFunctions(initFunctions({ typesRegistry: plugins.expressions.__LEGACY.types }));
- canvasApi.addDatasourceUIs(datasourceSpecs);
canvasApi.addArgumentUIs(argTypeSpecs);
canvasApi.addTransitions(transitions);
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js
index 47b426cf41457..5bc5d8ba6e402 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js
@@ -29,12 +29,13 @@ import {
EuiTitle,
} from '@elastic/eui';
+import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public';
import { indexPatterns } from '../../../../../../../../src/plugins/data/public';
import routing from '../services/routing';
import { extractQueryParams } from '../services/query_params';
import { getRemoteClusterName } from '../services/get_remote_cluster_name';
-import { API_STATUS, INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../constants';
+import { API_STATUS } from '../constants';
import { SectionError } from './section_error';
import { AutoFollowPatternIndicesPreview } from './auto_follow_pattern_indices_preview';
import { RemoteClustersFormField } from './remote_clusters_form_field';
@@ -46,7 +47,7 @@ import {
import { AutoFollowPatternRequestFlyout } from './auto_follow_pattern_request_flyout';
const indexPatternIllegalCharacters = indexPatterns.ILLEGAL_CHARACTERS_VISIBLE.join(' ');
-const indexNameIllegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
+const indexNameIllegalCharacters = indices.INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
const getEmptyAutoFollowPattern = (remoteClusterName = '') => ({
name: '',
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js
index b42758ed4f237..50b22289e30f8 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js
@@ -28,11 +28,12 @@ import {
EuiTitle,
} from '@elastic/eui';
+import { indices } from '../../../../../../../../../src/plugins/es_ui_shared/public';
import { indexNameValidator, leaderIndexValidator } from '../../services/input_validation';
import routing from '../../services/routing';
import { getFatalErrors } from '../../services/notifications';
import { loadIndices } from '../../services/api';
-import { API_STATUS, INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../../constants';
+import { API_STATUS } from '../../constants';
import { SectionError } from '../section_error';
import { FormEntryRow } from '../form_entry_row';
import {
@@ -46,7 +47,7 @@ import { RemoteClustersFormField } from '../remote_clusters_form_field';
import { FollowerIndexRequestFlyout } from './follower_index_request_flyout';
-const indexNameIllegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
+const indexNameIllegalCharacters = indices.INDEX_ILLEGAL_CHARACTERS_VISIBLE.join(' ');
const fieldToValidatorMap = advancedSettingsFields.reduce(
(map, advancedSetting) => {
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js
index 826e5989c506e..93da20a8ed93c 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js
@@ -7,9 +7,6 @@
import { updateFields, updateFormErrors } from './follower_index_form';
jest.mock('ui/new_platform');
-jest.mock('../../constants', () => ({
- INDEX_ILLEGAL_CHARACTERS_VISIBLE: [],
-}));
describe(' state transitions', () => {
it('updateFormErrors() should merge errors with existing fieldsErrors', () => {
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js
index 67a5c66ebe0af..ed2ae52ce162f 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js
@@ -7,4 +7,3 @@
export { API_STATUS } from './api';
export { SECTIONS } from './sections';
export * from './ui_metric';
-export { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from './indices';
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/indices.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/indices.ts
deleted file mode 100644
index 47bdf285b8bd0..0000000000000
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/indices.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { indexPatterns } from '../../../../../../../../src/plugins/data/public';
-
-export const INDEX_ILLEGAL_CHARACTERS_VISIBLE = [...indexPatterns.ILLEGAL_CHARACTERS_VISIBLE, '*'];
-
-// Insert the comma into the middle, so it doesn't look as if it has grammatical meaning when
-// these characters are rendered in the UI.
-const insertionIndex = Math.floor(indexPatterns.ILLEGAL_CHARACTERS_VISIBLE.length / 2);
-INDEX_ILLEGAL_CHARACTERS_VISIBLE.splice(insertionIndex, 0, ',');
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js
index 66ffbffc258b1..1b5a39658ee46 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js
@@ -7,12 +7,15 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
+
+import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public';
import { indexPatterns } from '../../../../../../../../src/plugins/data/public';
-import {
+
+const {
indexNameBeginsWithPeriod,
findIllegalCharactersInIndexName,
indexNameContainsSpaces,
-} from '../utils';
+} = indices;
export const validateName = (name = '') => {
let errorMsg = null;
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js
index 6c91439b1686e..64c3e8412437e 100644
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js
+++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js
@@ -6,7 +6,7 @@
import React from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
-import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../constants';
+import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public';
const isEmpty = value => {
return !value || !value.trim().length;
@@ -19,7 +19,7 @@ const beginsWithPeriod = value => {
};
const findIllegalCharacters = value => {
- return INDEX_ILLEGAL_CHARACTERS_VISIBLE.reduce((chars, char) => {
+ return indices.INDEX_ILLEGAL_CHARACTERS_VISIBLE.reduce((chars, char) => {
if (value.includes(char)) {
chars.push(char);
}
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.js
deleted file mode 100644
index 4278bbaf81be4..0000000000000
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../../constants';
-
-// Names beginning with periods are reserved for system indices.
-export function indexNameBeginsWithPeriod(indexName = '') {
- return indexName[0] === '.';
-}
-
-export function findIllegalCharactersInIndexName(indexName) {
- const illegalCharacters = INDEX_ILLEGAL_CHARACTERS_VISIBLE.reduce((chars, char) => {
- if (indexName.includes(char)) {
- chars.push(char);
- }
-
- return chars;
- }, []);
-
- return illegalCharacters;
-}
-
-export function indexNameContainsSpaces(indexName) {
- return indexName.includes(' ');
-}
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.test.js
deleted file mode 100644
index 49f520d3de0c1..0000000000000
--- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/utils/validate/validate_index.test.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { INDEX_ILLEGAL_CHARACTERS_VISIBLE } from '../../constants';
-
-import {
- indexNameBeginsWithPeriod,
- findIllegalCharactersInIndexName,
- indexNameContainsSpaces,
-} from './validate_index';
-
-describe('Index name validation', () => {
- it('should not allow name to begin with a period', () => {
- const beginsWithPeriod = indexNameBeginsWithPeriod('.system_index');
- expect(beginsWithPeriod).toBe(true);
- });
-
- it('should not allow space in the name', () => {
- const containsSpaces = indexNameContainsSpaces('my name');
- expect(containsSpaces).toBe(true);
- });
-
- it('should not allow illegal characters', () => {
- INDEX_ILLEGAL_CHARACTERS_VISIBLE.forEach(char => {
- const illegalCharacters = findIllegalCharactersInIndexName(`name${char}`);
- expect(illegalCharacters).toEqual([char]);
- });
- });
-});
diff --git a/x-pack/legacy/plugins/lens/public/_config_panel.scss b/x-pack/legacy/plugins/lens/public/_config_panel.scss
deleted file mode 100644
index 5c6d25bf10818..0000000000000
--- a/x-pack/legacy/plugins/lens/public/_config_panel.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-.lnsConfigPanel__panel {
- margin-bottom: $euiSizeS;
-}
-
-.lnsConfigPanel__axis {
- background: $euiColorLightestShade;
- padding: $euiSizeS;
- border-radius: $euiBorderRadius;
-
- // Add margin to the top of the next same panel
- & + & {
- margin-top: $euiSizeS;
- }
-}
-
-.lnsConfigPanel__addLayerBtn {
- color: transparentize($euiColorMediumShade, .3);
- // sass-lint:disable-block no-important
- box-shadow: none !important;
- border: 1px dashed currentColor;
-}
diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx
index 0cba22170df1f..e18190b6c2d69 100644
--- a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.test.tsx
@@ -4,18 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
import { createMockDatasource } from '../editor_frame_service/mocks';
-import {
- DatatableVisualizationState,
- datatableVisualization,
- DataTableLayer,
-} from './visualization';
-import { mount } from 'enzyme';
+import { DatatableVisualizationState, datatableVisualization } from './visualization';
import { Operation, DataType, FramePublicAPI, TableSuggestionColumn } from '../types';
-import { generateId } from '../id_generator';
-
-jest.mock('../id_generator');
function mockFrame(): FramePublicAPI {
return {
@@ -34,12 +25,11 @@ function mockFrame(): FramePublicAPI {
describe('Datatable Visualization', () => {
describe('#initialize', () => {
it('should initialize from the empty state', () => {
- (generateId as jest.Mock).mockReturnValueOnce('id');
expect(datatableVisualization.initialize(mockFrame(), undefined)).toEqual({
layers: [
{
layerId: 'aaa',
- columns: ['id'],
+ columns: [],
},
],
});
@@ -88,7 +78,6 @@ describe('Datatable Visualization', () => {
describe('#clearLayer', () => {
it('should reset the layer', () => {
- (generateId as jest.Mock).mockReturnValueOnce('testid');
const state: DatatableVisualizationState = {
layers: [
{
@@ -101,7 +90,7 @@ describe('Datatable Visualization', () => {
layers: [
{
layerId: 'baz',
- columns: ['testid'],
+ columns: [],
},
],
});
@@ -214,29 +203,35 @@ describe('Datatable Visualization', () => {
});
});
- describe('DataTableLayer', () => {
- it('allows all kinds of operations', () => {
- const setState = jest.fn();
- const datasource = createMockDatasource();
- const layer = { layerId: 'a', columns: ['b', 'c'] };
+ describe('#getConfiguration', () => {
+ it('returns a single layer option', () => {
+ const datasource = createMockDatasource('test');
const frame = mockFrame();
- frame.datasourceLayers = { a: datasource.publicAPIMock };
+ frame.datasourceLayers = { first: datasource.publicAPIMock };
- mount(
- {} }}
- frame={frame}
- layer={layer}
- setState={setState}
- state={{ layers: [layer] }}
- />
- );
+ expect(
+ datatableVisualization.getConfiguration({
+ layerId: 'first',
+ state: {
+ layers: [{ layerId: 'first', columns: [] }],
+ },
+ frame,
+ }).groups
+ ).toHaveLength(1);
+ });
- expect(datasource.publicAPIMock.renderDimensionPanel).toHaveBeenCalled();
+ it('allows all kinds of operations', () => {
+ const datasource = createMockDatasource('test');
+ const frame = mockFrame();
+ frame.datasourceLayers = { first: datasource.publicAPIMock };
- const filterOperations =
- datasource.publicAPIMock.renderDimensionPanel.mock.calls[0][1].filterOperations;
+ const filterOperations = datatableVisualization.getConfiguration({
+ layerId: 'first',
+ state: {
+ layers: [{ layerId: 'first', columns: [] }],
+ },
+ frame,
+ }).groups[0].filterOperations;
const baseOperation: Operation = {
dataType: 'string',
@@ -253,108 +248,80 @@ describe('Datatable Visualization', () => {
);
});
- it('allows columns to be removed', () => {
- const setState = jest.fn();
- const datasource = createMockDatasource();
+ it('reorders the rendered colums based on the order from the datasource', () => {
+ const datasource = createMockDatasource('test');
const layer = { layerId: 'a', columns: ['b', 'c'] };
const frame = mockFrame();
frame.datasourceLayers = { a: datasource.publicAPIMock };
- const component = mount(
- {} }}
- frame={frame}
- layer={layer}
- setState={setState}
- state={{ layers: [layer] }}
- />
- );
-
- const onRemove = component
- .find('[data-test-subj="datatable_multicolumnEditor"]')
- .first()
- .prop('onRemove') as (k: string) => {};
-
- onRemove('b');
+ datasource.publicAPIMock.getTableSpec.mockReturnValue([{ columnId: 'c' }, { columnId: 'b' }]);
+
+ expect(
+ datatableVisualization.getConfiguration({
+ layerId: 'a',
+ state: { layers: [layer] },
+ frame,
+ }).groups[0].accessors
+ ).toEqual(['c', 'b']);
+ });
+ });
- expect(setState).toHaveBeenCalledWith({
+ describe('#removeDimension', () => {
+ it('allows columns to be removed', () => {
+ const layer = { layerId: 'layer1', columns: ['b', 'c'] };
+ expect(
+ datatableVisualization.removeDimension({
+ prevState: { layers: [layer] },
+ layerId: 'layer1',
+ columnId: 'b',
+ })
+ ).toEqual({
layers: [
{
- layerId: 'a',
+ layerId: 'layer1',
columns: ['c'],
},
],
});
});
+ });
+ describe('#setDimension', () => {
it('allows columns to be added', () => {
- (generateId as jest.Mock).mockReturnValueOnce('d');
- const setState = jest.fn();
- const datasource = createMockDatasource();
- const layer = { layerId: 'a', columns: ['b', 'c'] };
- const frame = mockFrame();
- frame.datasourceLayers = { a: datasource.publicAPIMock };
- const component = mount(
- {} }}
- frame={frame}
- layer={layer}
- setState={setState}
- state={{ layers: [layer] }}
- />
- );
-
- const onAdd = component
- .find('[data-test-subj="datatable_multicolumnEditor"]')
- .first()
- .prop('onAdd') as () => {};
-
- onAdd();
-
- expect(setState).toHaveBeenCalledWith({
+ const layer = { layerId: 'layer1', columns: ['b', 'c'] };
+ expect(
+ datatableVisualization.setDimension({
+ prevState: { layers: [layer] },
+ layerId: 'layer1',
+ columnId: 'd',
+ groupId: '',
+ })
+ ).toEqual({
layers: [
{
- layerId: 'a',
+ layerId: 'layer1',
columns: ['b', 'c', 'd'],
},
],
});
});
- it('reorders the rendered colums based on the order from the datasource', () => {
- const datasource = createMockDatasource();
- const layer = { layerId: 'a', columns: ['b', 'c'] };
- const frame = mockFrame();
- frame.datasourceLayers = { a: datasource.publicAPIMock };
- const component = mount(
- {} }}
- frame={frame}
- layer={layer}
- setState={jest.fn()}
- state={{ layers: [layer] }}
- />
- );
-
- const accessors = component
- .find('[data-test-subj="datatable_multicolumnEditor"]')
- .first()
- .prop('accessors') as string[];
-
- expect(accessors).toEqual(['b', 'c']);
-
- component.setProps({
- layer: { layerId: 'a', columns: ['c', 'b'] },
+ it('does not set a duplicate dimension', () => {
+ const layer = { layerId: 'layer1', columns: ['b', 'c'] };
+ expect(
+ datatableVisualization.setDimension({
+ prevState: { layers: [layer] },
+ layerId: 'layer1',
+ columnId: 'b',
+ groupId: '',
+ })
+ ).toEqual({
+ layers: [
+ {
+ layerId: 'layer1',
+ columns: ['b', 'c'],
+ },
+ ],
});
-
- const newAccessors = component
- .find('[data-test-subj="datatable_multicolumnEditor"]')
- .first()
- .prop('accessors') as string[];
-
- expect(newAccessors).toEqual(['c', 'b']);
});
});
});
diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx
index 79a018635134f..4248d722d5540 100644
--- a/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx
+++ b/x-pack/legacy/plugins/lens/public/datatable_visualization/visualization.tsx
@@ -4,20 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
-import { render } from 'react-dom';
-import { EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { I18nProvider } from '@kbn/i18n/react';
-import { MultiColumnEditor } from '../multi_column_editor';
-import {
- SuggestionRequest,
- Visualization,
- VisualizationLayerConfigProps,
- VisualizationSuggestion,
- Operation,
-} from '../types';
-import { generateId } from '../id_generator';
+import { SuggestionRequest, Visualization, VisualizationSuggestion, Operation } from '../types';
import chartTableSVG from '../assets/chart_datatable.svg';
export interface LayerState {
@@ -32,58 +20,10 @@ export interface DatatableVisualizationState {
function newLayerState(layerId: string): LayerState {
return {
layerId,
- columns: [generateId()],
+ columns: [],
};
}
-function updateColumns(
- state: DatatableVisualizationState,
- layer: LayerState,
- fn: (columns: string[]) => string[]
-) {
- const columns = fn(layer.columns);
- const updatedLayer = { ...layer, columns };
- const layers = state.layers.map(l => (l.layerId === layer.layerId ? updatedLayer : l));
- return { ...state, layers };
-}
-
-const allOperations = () => true;
-
-export function DataTableLayer({
- layer,
- frame,
- state,
- setState,
- dragDropContext,
-}: { layer: LayerState } & VisualizationLayerConfigProps) {
- const datasource = frame.datasourceLayers[layer.layerId];
-
- const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
- // When we add a column it could be empty, and therefore have no order
- const sortedColumns = Array.from(new Set(originalOrder.concat(layer.columns)));
-
- return (
-
- setState(updateColumns(state, layer, columns => [...columns, generateId()]))}
- onRemove={column =>
- setState(updateColumns(state, layer, columns => columns.filter(c => c !== column)))
- }
- testSubj="datatable_columns"
- data-test-subj="datatable_multicolumnEditor"
- />
-
- );
-}
-
export const datatableVisualization: Visualization<
DatatableVisualizationState,
DatatableVisualizationState
@@ -188,17 +128,56 @@ export const datatableVisualization: Visualization<
];
},
- renderLayerConfigPanel(domElement, props) {
- const layer = props.state.layers.find(l => l.layerId === props.layerId);
-
- if (layer) {
- render(
-
-
- ,
- domElement
- );
+ getConfiguration({ state, frame, layerId }) {
+ const layer = state.layers.find(l => l.layerId === layerId);
+ if (!layer) {
+ return { groups: [] };
}
+
+ const datasource = frame.datasourceLayers[layer.layerId];
+ const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
+ // When we add a column it could be empty, and therefore have no order
+ const sortedColumns = Array.from(new Set(originalOrder.concat(layer.columns)));
+
+ return {
+ groups: [
+ {
+ groupId: 'columns',
+ groupLabel: i18n.translate('xpack.lens.datatable.columns', {
+ defaultMessage: 'Columns',
+ }),
+ layerId: state.layers[0].layerId,
+ accessors: sortedColumns,
+ supportsMoreColumns: true,
+ filterOperations: () => true,
+ },
+ ],
+ };
+ },
+
+ setDimension({ prevState, layerId, columnId }) {
+ return {
+ ...prevState,
+ layers: prevState.layers.map(l => {
+ if (l.layerId !== layerId || l.columns.includes(columnId)) {
+ return l;
+ }
+ return { ...l, columns: [...l.columns, columnId] };
+ }),
+ };
+ },
+ removeDimension({ prevState, layerId, columnId }) {
+ return {
+ ...prevState,
+ layers: prevState.layers.map(l =>
+ l.layerId === layerId
+ ? {
+ ...l,
+ columns: l.columns.filter(c => c !== columnId),
+ }
+ : l
+ ),
+ };
},
toExpression(state, frame) {
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/_config_panel_wrapper.scss b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/_config_panel_wrapper.scss
new file mode 100644
index 0000000000000..62a7f6b023f31
--- /dev/null
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/_config_panel_wrapper.scss
@@ -0,0 +1,50 @@
+.lnsConfigPanel__panel {
+ margin-bottom: $euiSizeS;
+}
+
+.lnsConfigPanel__row {
+ background: $euiColorLightestShade;
+ padding: $euiSizeS;
+ border-radius: $euiBorderRadius;
+
+ // Add margin to the top of the next same panel
+ & + & {
+ margin-top: $euiSizeS;
+ }
+}
+
+.lnsConfigPanel__addLayerBtn {
+ color: transparentize($euiColorMediumShade, .3);
+ // Remove EuiButton's default shadow to make button more subtle
+ // sass-lint:disable-block no-important
+ box-shadow: none !important;
+ border: 1px dashed currentColor;
+}
+
+.lnsConfigPanel__dimension {
+ @include euiFontSizeS;
+ background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade);
+ border-radius: $euiBorderRadius;
+ display: flex;
+ align-items: center;
+ margin-top: $euiSizeXS;
+ overflow: hidden;
+}
+
+.lnsConfigPanel__trigger {
+ max-width: 100%;
+ display: block;
+}
+
+.lnsConfigPanel__triggerLink {
+ padding: $euiSizeS;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ min-height: $euiSizeXXL;
+}
+
+.lnsConfigPanel__popover {
+ line-height: 0;
+ flex-grow: 1;
+}
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx
index 1b60098fd45ad..6698c9e68b98c 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/chart_switch.test.tsx
@@ -84,7 +84,7 @@ describe('chart_switch', () => {
}
function mockDatasourceMap() {
- const datasource = createMockDatasource();
+ const datasource = createMockDatasource('testDatasource');
datasource.getDatasourceSuggestionsFromCurrentState.mockReturnValue([
{
state: {},
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/config_panel_wrapper.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/config_panel_wrapper.tsx
index 1422ee86be3e9..c2cd0485de67e 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/config_panel_wrapper.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/config_panel_wrapper.tsx
@@ -16,17 +16,21 @@ import {
EuiToolTip,
EuiButton,
EuiForm,
+ EuiFormRow,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { NativeRenderer } from '../../native_renderer';
import { Action } from './state_management';
import {
Visualization,
FramePublicAPI,
Datasource,
- VisualizationLayerConfigProps,
+ VisualizationLayerWidgetProps,
+ DatasourceDimensionEditorProps,
+ StateSetter,
} from '../../types';
-import { DragContext } from '../../drag_drop';
+import { DragContext, DragDrop, ChildDragDropProvider } from '../../drag_drop';
import { ChartSwitch } from './chart_switch';
import { trackUiEvent } from '../../lens_ui_telemetry';
import { generateId } from '../../id_generator';
@@ -47,6 +51,7 @@ interface ConfigPanelWrapperProps {
state: unknown;
}
>;
+ core: DatasourceDimensionEditorProps['core'];
}
export const ConfigPanelWrapper = memo(function ConfigPanelWrapper(props: ConfigPanelWrapperProps) {
@@ -86,8 +91,7 @@ function LayerPanels(
activeDatasourceId,
datasourceMap,
} = props;
- const dragDropContext = useContext(DragContext);
- const setState = useMemo(
+ const setVisualizationState = useMemo(
() => (newState: unknown) => {
props.dispatch({
type: 'UPDATE_VISUALIZATION_STATE',
@@ -98,6 +102,43 @@ function LayerPanels(
},
[props.dispatch, activeVisualization]
);
+ const updateDatasource = useMemo(
+ () => (datasourceId: string, newState: unknown) => {
+ props.dispatch({
+ type: 'UPDATE_DATASOURCE_STATE',
+ updater: () => newState,
+ datasourceId,
+ clearStagedPreview: false,
+ });
+ },
+ [props.dispatch]
+ );
+ const updateAll = useMemo(
+ () => (datasourceId: string, newDatasourceState: unknown, newVisualizationState: unknown) => {
+ props.dispatch({
+ type: 'UPDATE_STATE',
+ subType: 'UPDATE_ALL_STATES',
+ updater: prevState => {
+ return {
+ ...prevState,
+ datasourceStates: {
+ ...prevState.datasourceStates,
+ [datasourceId]: {
+ state: newDatasourceState,
+ isLoading: false,
+ },
+ },
+ visualization: {
+ activeId: activeVisualization.id,
+ state: newVisualizationState,
+ },
+ stagedPreview: undefined,
+ };
+ },
+ });
+ },
+ [props.dispatch]
+ );
const layerIds = activeVisualization.getLayerIds(visualizationState);
return (
@@ -108,12 +149,13 @@ function LayerPanels(
key={layerId}
layerId={layerId}
activeVisualization={activeVisualization}
- dragDropContext={dragDropContext}
- state={setState}
- setState={setState}
+ visualizationState={visualizationState}
+ updateVisualization={setVisualizationState}
+ updateDatasource={updateDatasource}
+ updateAll={updateAll}
frame={framePublicAPI}
isOnlyLayer={layerIds.length === 1}
- onRemove={() => {
+ onRemoveLayer={() => {
dispatch({
type: 'UPDATE_STATE',
subType: 'REMOVE_OR_CLEAR_LAYER',
@@ -143,7 +185,7 @@ function LayerPanels(
className="lnsConfigPanel__addLayerBtn"
fullWidth
size="s"
- data-test-subj={`lnsXY_layer_add`}
+ data-test-subj="lnsXY_layer_add"
aria-label={i18n.translate('xpack.lens.xyChart.addLayerButton', {
defaultMessage: 'Add layer',
})}
@@ -174,85 +216,399 @@ function LayerPanels(
}
function LayerPanel(
- props: ConfigPanelWrapperProps &
- VisualizationLayerConfigProps & {
- isOnlyLayer: boolean;
- activeVisualization: Visualization;
- onRemove: () => void;
- }
+ props: Exclude & {
+ frame: FramePublicAPI;
+ layerId: string;
+ isOnlyLayer: boolean;
+ activeVisualization: Visualization;
+ visualizationState: unknown;
+ updateVisualization: StateSetter;
+ updateDatasource: (datasourceId: string, newState: unknown) => void;
+ updateAll: (
+ datasourceId: string,
+ newDatasourcestate: unknown,
+ newVisualizationState: unknown
+ ) => void;
+ onRemoveLayer: () => void;
+ }
) {
- const { framePublicAPI, layerId, activeVisualization, isOnlyLayer, onRemove } = props;
+ const dragDropContext = useContext(DragContext);
+ const { framePublicAPI, layerId, activeVisualization, isOnlyLayer, onRemoveLayer } = props;
const datasourcePublicAPI = framePublicAPI.datasourceLayers[layerId];
- const layerConfigProps = {
+ if (!datasourcePublicAPI) {
+ return null;
+ }
+ const layerVisualizationConfigProps = {
layerId,
- dragDropContext: props.dragDropContext,
+ dragDropContext,
state: props.visualizationState,
- setState: props.setState,
frame: props.framePublicAPI,
+ dateRange: props.framePublicAPI.dateRange,
};
+ const datasourceId = datasourcePublicAPI.datasourceId;
+ const layerDatasourceState = props.datasourceStates[datasourceId].state;
+ const layerDatasource = props.datasourceMap[datasourceId];
- return (
-
-
-
-
-
+ const layerDatasourceDropProps = {
+ layerId,
+ dragDropContext,
+ state: layerDatasourceState,
+ setState: (newState: unknown) => {
+ props.updateDatasource(datasourceId, newState);
+ },
+ };
- {datasourcePublicAPI && (
-
- ({
+ isOpen: false,
+ openId: null,
+ addingToGroupId: null,
+ });
+
+ const { groups } = activeVisualization.getConfiguration(layerVisualizationConfigProps);
+ const isEmptyLayer = !groups.some(d => d.accessors.length > 0);
+
+ function wrapInPopover(
+ id: string,
+ groupId: string,
+ trigger: React.ReactElement,
+ panel: React.ReactElement
+ ) {
+ const noMatch = popoverState.isOpen ? !groups.some(d => d.accessors.includes(id)) : false;
+ return (
+ {
+ setPopoverState({ isOpen: false, openId: null, addingToGroupId: null });
+ }}
+ button={trigger}
+ anchorPosition="leftUp"
+ withTitle
+ panelPaddingSize="s"
+ >
+ {panel}
+
+ );
+ }
+
+ return (
+
+
+
+
+
- )}
-
-
-
-
+ {layerDatasource && (
+
+ {
+ const newState =
+ typeof updater === 'function' ? updater(layerDatasourceState) : updater;
+ // Look for removed columns
+ const nextPublicAPI = layerDatasource.getPublicAPI({
+ state: newState,
+ layerId,
+ dateRange: props.framePublicAPI.dateRange,
+ });
+ const nextTable = new Set(
+ nextPublicAPI.getTableSpec().map(({ columnId }) => columnId)
+ );
+ const removed = datasourcePublicAPI
+ .getTableSpec()
+ .map(({ columnId }) => columnId)
+ .filter(columnId => !nextTable.has(columnId));
+ let nextVisState = props.visualizationState;
+ removed.forEach(columnId => {
+ nextVisState = activeVisualization.removeDimension({
+ layerId,
+ columnId,
+ prevState: nextVisState,
+ });
+ });
-
+ props.updateAll(datasourceId, newState, nextVisState);
+ },
+ }}
+ />
+
+ )}
+
-
-
- {
- // If we don't blur the remove / clear button, it remains focused
- // which is a strange UX in this case. e.target.blur doesn't work
- // due to who knows what, but probably event re-writing. Additionally,
- // activeElement does not have blur so, we need to do some casting + safeguards.
- const el = (document.activeElement as unknown) as { blur: () => void };
+
- if (el && el.blur) {
- el.blur();
+ {groups.map((group, index) => {
+ const newId = generateId();
+ const isMissing = !isEmptyLayer && group.required && group.accessors.length === 0;
+ return (
+
+ <>
+ {group.accessors.map(accessor => (
+ {
+ layerDatasource.onDrop({
+ ...layerDatasourceDropProps,
+ droppedItem,
+ columnId: accessor,
+ filterOperations: group.filterOperations,
+ });
+ }}
+ >
+ {wrapInPopover(
+ accessor,
+ group.groupId,
+ {
+ if (popoverState.isOpen) {
+ setPopoverState({
+ isOpen: false,
+ openId: null,
+ addingToGroupId: null,
+ });
+ } else {
+ setPopoverState({
+ isOpen: true,
+ openId: accessor,
+ addingToGroupId: null, // not set for existing dimension
+ });
+ }
+ },
+ }}
+ />,
+
+ )}
- onRemove();
- }}
- >
- {isOnlyLayer
- ? i18n.translate('xpack.lens.resetLayer', {
- defaultMessage: 'Reset layer',
- })
- : i18n.translate('xpack.lens.deleteLayer', {
- defaultMessage: 'Delete layer',
- })}
-
-
-
-
+ {
+ trackUiEvent('indexpattern_dimension_removed');
+ props.updateAll(
+ datasourceId,
+ layerDatasource.removeColumn({
+ layerId,
+ columnId: accessor,
+ prevState: layerDatasourceState,
+ }),
+ props.activeVisualization.removeDimension({
+ layerId,
+ columnId: accessor,
+ prevState: props.visualizationState,
+ })
+ );
+ }}
+ />
+
+ ))}
+ {group.supportsMoreColumns ? (
+ {
+ const dropSuccess = layerDatasource.onDrop({
+ ...layerDatasourceDropProps,
+ droppedItem,
+ columnId: newId,
+ filterOperations: group.filterOperations,
+ });
+ if (dropSuccess) {
+ props.updateVisualization(
+ activeVisualization.setDimension({
+ layerId,
+ groupId: group.groupId,
+ columnId: newId,
+ prevState: props.visualizationState,
+ })
+ );
+ }
+ }}
+ >
+ {wrapInPopover(
+ newId,
+ group.groupId,
+
+ {
+ if (popoverState.isOpen) {
+ setPopoverState({
+ isOpen: false,
+ openId: null,
+ addingToGroupId: null,
+ });
+ } else {
+ setPopoverState({
+ isOpen: true,
+ openId: newId,
+ addingToGroupId: group.groupId,
+ });
+ }
+ }}
+ size="xs"
+ >
+
+
+
,
+ {
+ props.updateAll(
+ datasourceId,
+ newState,
+ activeVisualization.setDimension({
+ layerId,
+ groupId: group.groupId,
+ columnId: newId,
+ prevState: props.visualizationState,
+ })
+ );
+ setPopoverState({
+ isOpen: true,
+ openId: newId,
+ addingToGroupId: null, // clear now that dimension exists
+ });
+ },
+ }}
+ />
+ )}
+
+ ) : null}
+ >
+
+ );
+ })}
+
+
+
+
+
+ {
+ // If we don't blur the remove / clear button, it remains focused
+ // which is a strange UX in this case. e.target.blur doesn't work
+ // due to who knows what, but probably event re-writing. Additionally,
+ // activeElement does not have blur so, we need to do some casting + safeguards.
+ const el = (document.activeElement as unknown) as { blur: () => void };
+
+ if (el?.blur) {
+ el.blur();
+ }
+
+ onRemoveLayer();
+ }}
+ >
+ {isOnlyLayer
+ ? i18n.translate('xpack.lens.resetLayer', {
+ defaultMessage: 'Reset layer',
+ })
+ : i18n.translate('xpack.lens.deleteLayer', {
+ defaultMessage: 'Delete layer',
+ })}
+
+
+
+
+
);
}
@@ -263,7 +619,7 @@ function LayerSettings({
}: {
layerId: string;
activeVisualization: Visualization;
- layerConfigProps: VisualizationLayerConfigProps;
+ layerConfigProps: VisualizationLayerWidgetProps;
}) {
const [isOpen, setIsOpen] = useState(false);
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
index dd591b3992fe5..8d8d38944e18a 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx
@@ -87,14 +87,15 @@ describe('editor_frame', () => {
mockVisualization.getLayerIds.mockReturnValue(['first']);
mockVisualization2.getLayerIds.mockReturnValue(['second']);
- mockDatasource = createMockDatasource();
- mockDatasource2 = createMockDatasource();
+ mockDatasource = createMockDatasource('testDatasource');
+ mockDatasource2 = createMockDatasource('testDatasource2');
expressionRendererMock = createExpressionRendererMock();
});
describe('initialization', () => {
it('should initialize initial datasource', async () => {
+ mockVisualization.getLayerIds.mockReturnValue([]);
await act(async () => {
mount(
{
});
it('should initialize all datasources with state from doc', async () => {
- const mockDatasource3 = createMockDatasource();
+ const mockDatasource3 = createMockDatasource('testDatasource3');
const datasource1State = { datasource1: '' };
const datasource2State = { datasource2: '' };
@@ -198,9 +199,9 @@ describe('editor_frame', () => {
ExpressionRenderer={expressionRendererMock}
/>
);
- expect(mockVisualization.renderLayerConfigPanel).not.toHaveBeenCalled();
expect(mockDatasource.renderDataPanel).not.toHaveBeenCalled();
});
+ expect(mockDatasource.renderDataPanel).toHaveBeenCalled();
});
it('should not initialize visualization before datasource is initialized', async () => {
@@ -289,6 +290,7 @@ describe('editor_frame', () => {
mockDatasource2.initialize.mockReturnValue(Promise.resolve(initialState));
mockDatasource2.getLayers.mockReturnValue(['abc', 'def']);
mockDatasource2.removeLayer.mockReturnValue({ removed: true });
+ mockVisualization.getLayerIds.mockReturnValue(['first', 'abc', 'def']);
await act(async () => {
mount(
{
);
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({ state: initialState })
);
});
@@ -614,15 +615,14 @@ describe('editor_frame', () => {
);
});
const updatedState = {};
- const setVisualizationState = (mockVisualization.renderLayerConfigPanel as jest.Mock).mock
- .calls[0][1].setState;
+ const setDatasourceState = (mockDatasource.renderDataPanel as jest.Mock).mock.calls[0][1]
+ .setState;
act(() => {
- setVisualizationState(updatedState);
+ setDatasourceState(updatedState);
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledTimes(2);
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenLastCalledWith(
- expect.any(Element),
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledTimes(2);
+ expect(mockVisualization.getConfiguration).toHaveBeenLastCalledWith(
expect.objectContaining({
state: updatedState,
})
@@ -688,8 +688,7 @@ describe('editor_frame', () => {
});
const updatedPublicAPI: DatasourcePublicAPI = {
- renderLayerPanel: jest.fn(),
- renderDimensionPanel: jest.fn(),
+ datasourceId: 'testDatasource',
getOperationForColumnId: jest.fn(),
getTableSpec: jest.fn(),
};
@@ -701,9 +700,8 @@ describe('editor_frame', () => {
setDatasourceState({});
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledTimes(2);
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenLastCalledWith(
- expect.any(Element),
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledTimes(2);
+ expect(mockVisualization.getConfiguration).toHaveBeenLastCalledWith(
expect.objectContaining({
frame: expect.objectContaining({
datasourceLayers: {
@@ -719,6 +717,7 @@ describe('editor_frame', () => {
it('should pass the datasource api for each layer to the visualization', async () => {
mockDatasource.getLayers.mockReturnValue(['first']);
mockDatasource2.getLayers.mockReturnValue(['second', 'third']);
+ mockVisualization.getLayerIds.mockReturnValue(['first', 'second', 'third']);
await act(async () => {
mount(
@@ -755,10 +754,10 @@ describe('editor_frame', () => {
);
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalled();
+ expect(mockVisualization.getConfiguration).toHaveBeenCalled();
const datasourceLayers =
- mockVisualization.renderLayerConfigPanel.mock.calls[0][1].frame.datasourceLayers;
+ mockVisualization.getConfiguration.mock.calls[0][0].frame.datasourceLayers;
expect(datasourceLayers.first).toBe(mockDatasource.publicAPIMock);
expect(datasourceLayers.second).toBe(mockDatasource2.publicAPIMock);
expect(datasourceLayers.third).toBe(mockDatasource2.publicAPIMock);
@@ -811,21 +810,18 @@ describe('editor_frame', () => {
expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith(
expect.objectContaining({
state: datasource1State,
- setState: expect.anything(),
layerId: 'first',
})
);
expect(mockDatasource2.getPublicAPI).toHaveBeenCalledWith(
expect.objectContaining({
state: datasource2State,
- setState: expect.anything(),
layerId: 'second',
})
);
expect(mockDatasource2.getPublicAPI).toHaveBeenCalledWith(
expect.objectContaining({
state: datasource2State,
- setState: expect.anything(),
layerId: 'third',
})
);
@@ -858,45 +854,9 @@ describe('editor_frame', () => {
expect(mockDatasource.getPublicAPI).toHaveBeenCalledWith({
dateRange,
state: datasourceState,
- setState: expect.any(Function),
layerId: 'first',
});
});
-
- it('should re-create the public api after state has been set', async () => {
- mockDatasource.getLayers.mockReturnValue(['first']);
-
- await act(async () => {
- mount(
-
- );
- });
-
- const updatedState = {};
- const setDatasourceState = mockDatasource.getPublicAPI.mock.calls[0][0].setState;
- act(() => {
- setDatasourceState(updatedState);
- });
-
- expect(mockDatasource.getPublicAPI).toHaveBeenLastCalledWith(
- expect.objectContaining({
- state: updatedState,
- setState: expect.any(Function),
- layerId: 'first',
- })
- );
- });
});
describe('switching', () => {
@@ -1021,8 +981,7 @@ describe('editor_frame', () => {
expect(mockVisualization2.getSuggestions).toHaveBeenCalled();
expect(mockVisualization2.initialize).toHaveBeenCalledWith(expect.anything(), initialState);
- expect(mockVisualization2.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization2.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({ state: { initial: true } })
);
});
@@ -1039,8 +998,7 @@ describe('editor_frame', () => {
datasourceLayers: expect.objectContaining({ first: mockDatasource.publicAPIMock }),
})
);
- expect(mockVisualization2.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization2.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({ state: { initial: true } })
);
});
@@ -1239,9 +1197,8 @@ describe('editor_frame', () => {
.simulate('click');
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledTimes(1);
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledTimes(1);
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
state: suggestionVisState,
})
@@ -1306,8 +1263,7 @@ describe('editor_frame', () => {
.simulate('drop');
});
- expect(mockVisualization.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
state: suggestionVisState,
})
@@ -1375,14 +1331,16 @@ describe('editor_frame', () => {
instance.update();
act(() => {
- instance.find(DragDrop).prop('onDrop')!({
+ instance
+ .find(DragDrop)
+ .filter('[data-test-subj="mockVisA"]')
+ .prop('onDrop')!({
indexPatternId: '1',
field: {},
});
});
- expect(mockVisualization2.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization2.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
state: suggestionVisState,
})
@@ -1472,14 +1430,16 @@ describe('editor_frame', () => {
instance.update();
act(() => {
- instance.find(DragDrop).prop('onDrop')!({
+ instance
+ .find(DragDrop)
+ .filter('[data-test-subj="lnsWorkspace"]')
+ .prop('onDrop')!({
indexPatternId: '1',
field: {},
});
});
- expect(mockVisualization3.renderLayerConfigPanel).toHaveBeenCalledWith(
- expect.any(Element),
+ expect(mockVisualization3.getConfiguration).toHaveBeenCalledWith(
expect.objectContaining({
state: suggestionVisState,
})
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
index a456372c99c01..082519d9a8feb 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx
@@ -21,6 +21,7 @@ import { FrameLayout } from './frame_layout';
import { SuggestionPanel } from './suggestion_panel';
import { WorkspacePanel } from './workspace_panel';
import { Document } from '../../persistence/saved_object_store';
+import { RootDragDropProvider } from '../../drag_drop';
import { getSavedObjectFormat } from './save';
import { WorkspacePanelWrapper } from './workspace_panel_wrapper';
import { generateId } from '../../id_generator';
@@ -90,21 +91,11 @@ export function EditorFrame(props: EditorFrameProps) {
const layers = datasource.getLayers(datasourceState);
layers.forEach(layer => {
- const publicAPI = props.datasourceMap[id].getPublicAPI({
+ datasourceLayers[layer] = props.datasourceMap[id].getPublicAPI({
state: datasourceState,
- setState: (newState: unknown) => {
- dispatch({
- type: 'UPDATE_DATASOURCE_STATE',
- datasourceId: id,
- updater: newState,
- clearStagedPreview: true,
- });
- },
layerId: layer,
dateRange: props.dateRange,
});
-
- datasourceLayers[layer] = publicAPI;
});
});
@@ -235,74 +226,79 @@ export function EditorFrame(props: EditorFrameProps) {
]);
return (
-
- }
- configPanel={
- allLoaded && (
-
+
- )
- }
- workspacePanel={
- allLoaded && (
-
-
+ )
+ }
+ workspacePanel={
+ allLoaded && (
+
+
+
+ )
+ }
+ suggestionsPanel={
+ allLoaded && (
+
-
- )
- }
- suggestionsPanel={
- allLoaded && (
-
- )
- }
- />
+ )
+ }
+ />
+
);
}
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx
index a69da8b49e233..56afe3ed69a73 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx
@@ -6,7 +6,6 @@
import React from 'react';
import { EuiPage, EuiPageSideBar, EuiPageBody } from '@elastic/eui';
-import { RootDragDropProvider } from '../../drag_drop';
export interface FrameLayoutProps {
dataPanel: React.ReactNode;
@@ -17,19 +16,17 @@ export interface FrameLayoutProps {
export function FrameLayout(props: FrameLayoutProps) {
return (
-
-
-
- {props.dataPanel}
-
- {props.workspacePanel}
- {props.suggestionsPanel}
-
-
- {props.configPanel}
-
-
-
-
+
+
+ {props.dataPanel}
+
+ {props.workspacePanel}
+ {props.suggestionsPanel}
+
+
+ {props.configPanel}
+
+
+
);
}
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/index.scss b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/index.scss
index fee28c374ef7e..6c6a63c8c7eb6 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/index.scss
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/index.scss
@@ -1,4 +1,5 @@
@import './chart_switch';
+@import './config_panel_wrapper';
@import './data_panel_wrapper';
@import './expression_renderer';
@import './frame_layout';
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts
index 158a6cb8c979a..60bfbc493f61c 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts
@@ -11,7 +11,7 @@ import { esFilters, IIndexPattern, IFieldType } from '../../../../../../../src/p
describe('save editor frame state', () => {
const mockVisualization = createMockVisualization();
mockVisualization.getPersistableState.mockImplementation(x => x);
- const mockDatasource = createMockDatasource();
+ const mockDatasource = createMockDatasource('a');
const mockIndexPattern = ({ id: 'indexpattern' } as unknown) as IIndexPattern;
const mockField = ({ name: '@timestamp' } as unknown) as IFieldType;
@@ -45,7 +45,7 @@ describe('save editor frame state', () => {
};
it('transforms from internal state to persisted doc format', async () => {
- const datasource = createMockDatasource();
+ const datasource = createMockDatasource('a');
datasource.getPersistableState.mockImplementation(state => ({
stuff: `${state}_datasource_persisted`,
}));
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts
index 487a91c22b5d5..63b8b1f048296 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts
@@ -30,7 +30,7 @@ let datasourceStates: Record<
beforeEach(() => {
datasourceMap = {
- mock: createMockDatasource(),
+ mock: createMockDatasource('a'),
};
datasourceStates = {
@@ -147,9 +147,9 @@ describe('suggestion helpers', () => {
},
};
const multiDatasourceMap = {
- mock: createMockDatasource(),
- mock2: createMockDatasource(),
- mock3: createMockDatasource(),
+ mock: createMockDatasource('a'),
+ mock2: createMockDatasource('a'),
+ mock3: createMockDatasource('a'),
};
const droppedField = {};
getSuggestions({
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx
index 9729d6259f84a..b146f2467c46c 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx
@@ -39,7 +39,7 @@ describe('suggestion_panel', () => {
beforeEach(() => {
mockVisualization = createMockVisualization();
- mockDatasource = createMockDatasource();
+ mockDatasource = createMockDatasource('a');
expressionRendererMock = createExpressionRendererMock();
dispatchMock = jest.fn();
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
index 1115126792c86..93f6ea6ea67ac 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx
@@ -373,7 +373,6 @@ function getPreviewExpression(
layerId,
dateRange: frame.dateRange,
state: datasourceState,
- setState: () => {},
});
}
});
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx
index a51091d39f84c..748e5b876da95 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel.test.tsx
@@ -36,7 +36,7 @@ describe('workspace_panel', () => {
mockVisualization = createMockVisualization();
mockVisualization2 = createMockVisualization();
- mockDatasource = createMockDatasource();
+ mockDatasource = createMockDatasource('a');
expressionRendererMock = createExpressionRendererMock();
});
@@ -199,7 +199,7 @@ describe('workspace_panel', () => {
});
it('should include data fetching for each layer in the expression', () => {
- const mockDatasource2 = createMockDatasource();
+ const mockDatasource2 = createMockDatasource('a');
const framePublicAPI = createMockFramePublicAPI();
framePublicAPI.datasourceLayers = {
first: mockDatasource.publicAPIMock,
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx
index e606c69c8c386..5d2f68a5567eb 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/mocks.tsx
@@ -33,9 +33,24 @@ export function createMockVisualization(): jest.Mocked {
getPersistableState: jest.fn(_state => _state),
getSuggestions: jest.fn(_options => []),
initialize: jest.fn((_frame, _state?) => ({})),
- renderLayerConfigPanel: jest.fn(),
+ getConfiguration: jest.fn(props => ({
+ groups: [
+ {
+ groupId: 'a',
+ groupLabel: 'a',
+ layerId: 'layer1',
+ supportsMoreColumns: true,
+ accessors: [],
+ filterOperations: jest.fn(() => true),
+ dataTestSubj: 'mockVisA',
+ },
+ ],
+ })),
toExpression: jest.fn((_state, _frame) => null),
toPreviewExpression: jest.fn((_state, _frame) => null),
+
+ setDimension: jest.fn(),
+ removeDimension: jest.fn(),
};
}
@@ -43,12 +58,11 @@ export type DatasourceMock = jest.Mocked & {
publicAPIMock: jest.Mocked;
};
-export function createMockDatasource(): DatasourceMock {
+export function createMockDatasource(id: string): DatasourceMock {
const publicAPIMock: jest.Mocked = {
+ datasourceId: id,
getTableSpec: jest.fn(() => []),
getOperationForColumnId: jest.fn(),
- renderDimensionPanel: jest.fn(),
- renderLayerPanel: jest.fn(),
};
return {
@@ -60,12 +74,19 @@ export function createMockDatasource(): DatasourceMock {
getPublicAPI: jest.fn().mockReturnValue(publicAPIMock),
initialize: jest.fn((_state?) => Promise.resolve()),
renderDataPanel: jest.fn(),
+ renderLayerPanel: jest.fn(),
toExpression: jest.fn((_frame, _state) => null),
insertLayer: jest.fn((_state, _newLayerId) => {}),
removeLayer: jest.fn((_state, _layerId) => {}),
+ removeColumn: jest.fn(props => {}),
getLayers: jest.fn(_state => []),
getMetaData: jest.fn(_state => ({ filterableIndexPatterns: [] })),
+ renderDimensionTrigger: jest.fn(),
+ renderDimensionEditor: jest.fn(),
+ canHandleDrop: jest.fn(),
+ onDrop: jest.fn(),
+
// this is an additional property which doesn't exist on real datasources
// but can be used to validate whether specific API mock functions are called
publicAPIMock,
diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_service/service.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_service/service.test.tsx
index 6b9dc88e7ed12..47fd810bb4c53 100644
--- a/x-pack/legacy/plugins/lens/public/editor_frame_service/service.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/editor_frame_service/service.test.tsx
@@ -47,7 +47,7 @@ describe('editor_frame service', () => {
pluginSetupDependencies
);
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
- const instance = await publicAPI.createInstance({});
+ const instance = await publicAPI.createInstance();
instance.mount(mountpoint, {
onError: jest.fn(),
onChange: jest.fn(),
@@ -66,7 +66,7 @@ describe('editor_frame service', () => {
pluginSetupDependencies
);
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
- const instance = await publicAPI.createInstance({});
+ const instance = await publicAPI.createInstance();
instance.mount(mountpoint, {
onError: jest.fn(),
onChange: jest.fn(),
diff --git a/x-pack/legacy/plugins/lens/public/index.scss b/x-pack/legacy/plugins/lens/public/index.scss
index 496573f6a1c9a..2f91d14c397c7 100644
--- a/x-pack/legacy/plugins/lens/public/index.scss
+++ b/x-pack/legacy/plugins/lens/public/index.scss
@@ -4,8 +4,6 @@
@import './variables';
@import './mixins';
-@import './config_panel';
-
@import './app_plugin/index';
@import 'datatable_visualization/index';
@import './drag_drop/index';
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_dimension_panel.scss b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_dimension_panel.scss
deleted file mode 100644
index ddb37505f9985..0000000000000
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_dimension_panel.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.lnsIndexPatternDimensionPanel {
- @include euiFontSizeS;
- background-color: $euiColorEmptyShade;
- border-radius: $euiBorderRadius;
- display: flex;
- align-items: center;
- margin-top: $euiSizeXS;
- overflow: hidden;
-}
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_index.scss b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_index.scss
index 2ce3e11171fc9..26f805fe735f0 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_index.scss
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_index.scss
@@ -1,3 +1,2 @@
-@import './dimension_panel';
@import './field_select';
@import './popover';
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_popover.scss b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_popover.scss
index 8f26ab91e0f16..07a72ee1f66fc 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_popover.scss
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/_popover.scss
@@ -1,37 +1,24 @@
-.lnsPopoverEditor {
+.lnsIndexPatternDimensionEditor {
flex-grow: 1;
line-height: 0;
overflow: hidden;
}
-.lnsPopoverEditor__anchor {
- max-width: 100%;
- display: block;
-}
-
-.lnsPopoverEditor__link {
- width: 100%;
- display: flex;
- align-items: center;
- padding: $euiSizeS;
- min-height: $euiSizeXXL;
-}
-
-.lnsPopoverEditor__left,
-.lnsPopoverEditor__right {
+.lnsIndexPatternDimensionEditor__left,
+.lnsIndexPatternDimensionEditor__right {
padding: $euiSizeS;
}
-.lnsPopoverEditor__left {
+.lnsIndexPatternDimensionEditor__left {
padding-top: 0;
background-color: $euiPageBackgroundColor;
}
-.lnsPopoverEditor__right {
+.lnsIndexPatternDimensionEditor__right {
width: $euiSize * 20;
}
-.lnsPopoverEditor__operation {
+.lnsIndexPatternDimensionEditor__operation {
@include euiFontSizeS;
color: $euiColorPrimary;
@@ -41,11 +28,11 @@
}
}
-.lnsPopoverEditor__operation--selected {
+.lnsIndexPatternDimensionEditor__operation--selected {
font-weight: bold;
color: $euiTextColor;
}
-.lnsPopoverEditor__operation--incompatible {
+.lnsIndexPatternDimensionEditor__operation--incompatible {
color: $euiColorMediumShade;
}
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx
index 56f75ae4b17be..41c317ccab290 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx
@@ -7,27 +7,28 @@
import { ReactWrapper, ShallowWrapper } from 'enzyme';
import React from 'react';
import { act } from 'react-dom/test-utils';
-import {
- EuiComboBox,
- EuiSideNav,
- EuiSideNavItemType,
- EuiPopover,
- EuiFieldNumber,
-} from '@elastic/eui';
+import { EuiComboBox, EuiSideNav, EuiSideNavItemType, EuiFieldNumber } from '@elastic/eui';
import { DataPublicPluginStart } from '../../../../../../../src/plugins/data/public';
import { changeColumn } from '../state_helpers';
import {
- IndexPatternDimensionPanel,
- IndexPatternDimensionPanelComponent,
- IndexPatternDimensionPanelProps,
+ IndexPatternDimensionEditorComponent,
+ IndexPatternDimensionEditorProps,
+ onDrop,
+ canHandleDrop,
} from './dimension_panel';
-import { DropHandler, DragContextState } from '../../drag_drop';
+import { DragContextState } from '../../drag_drop';
import { createMockedDragDropContext } from '../mocks';
import { mountWithIntl as mount, shallowWithIntl as shallow } from 'test_utils/enzyme_helpers';
-import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'src/core/public';
+import {
+ IUiSettingsClient,
+ SavedObjectsClientContract,
+ HttpSetup,
+ CoreSetup,
+} from 'src/core/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { IndexPatternPrivateState } from '../types';
import { documentField } from '../document_field';
+import { OperationMetadata } from '../../types';
jest.mock('ui/new_platform');
jest.mock('../loader');
@@ -79,20 +80,12 @@ const expectedIndexPatterns = {
},
};
-describe('IndexPatternDimensionPanel', () => {
- let wrapper: ReactWrapper | ShallowWrapper;
+describe('IndexPatternDimensionEditorPanel', () => {
let state: IndexPatternPrivateState;
let setState: jest.Mock;
- let defaultProps: IndexPatternDimensionPanelProps;
+ let defaultProps: IndexPatternDimensionEditorProps;
let dragDropContext: DragContextState;
- function openPopover() {
- wrapper
- .find('[data-test-subj="indexPattern-configure-dimension"]')
- .first()
- .simulate('click');
- }
-
beforeEach(() => {
state = {
indexPatternRefs: [],
@@ -134,7 +127,6 @@ describe('IndexPatternDimensionPanel', () => {
dragDropContext = createMockedDragDropContext();
defaultProps = {
- dragDropContext,
state,
setState,
dateRange: { fromDate: 'now-1d', toDate: 'now' },
@@ -158,475 +150,582 @@ describe('IndexPatternDimensionPanel', () => {
}),
} as unknown) as DataPublicPluginStart['fieldFormats'],
} as unknown) as DataPublicPluginStart,
+ core: {} as CoreSetup,
};
jest.clearAllMocks();
});
- afterEach(() => {
- if (wrapper) {
- wrapper.unmount();
- }
- });
+ describe('Editor component', () => {
+ let wrapper: ReactWrapper | ShallowWrapper;
- it('should display a configure button if dimension has no column yet', () => {
- wrapper = mount( );
- expect(
- wrapper
- .find('[data-test-subj="indexPattern-configure-dimension"]')
- .first()
- .prop('iconType')
- ).toEqual('plusInCircleFilled');
- });
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.unmount();
+ }
+ });
- it('should call the filterOperations function', () => {
- const filterOperations = jest.fn().mockReturnValue(true);
+ it('should call the filterOperations function', () => {
+ const filterOperations = jest.fn().mockReturnValue(true);
- wrapper = shallow(
-
- );
+ wrapper = shallow(
+
+ );
- expect(filterOperations).toBeCalled();
- });
+ expect(filterOperations).toBeCalled();
+ });
- it('should show field select combo box on click', () => {
- wrapper = mount( );
+ it('should show field select combo box on click', () => {
+ wrapper = mount( );
- openPopover();
+ expect(
+ wrapper.find(EuiComboBox).filter('[data-test-subj="indexPattern-dimension-field"]')
+ ).toHaveLength(1);
+ });
- expect(
- wrapper.find(EuiComboBox).filter('[data-test-subj="indexPattern-dimension-field"]')
- ).toHaveLength(1);
- });
+ it('should not show any choices if the filter returns false', () => {
+ wrapper = mount(
+ false}
+ />
+ );
- it('should not show any choices if the filter returns false', () => {
- wrapper = mount(
- false}
- />
- );
+ expect(
+ wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')!
+ .prop('options')!
+ ).toHaveLength(0);
+ });
- openPopover();
+ it('should list all field names and document as a whole in prioritized order', () => {
+ wrapper = mount( );
- expect(
- wrapper
+ const options = wrapper
.find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')!
- .prop('options')!
- ).toHaveLength(0);
- });
-
- it('should list all field names and document as a whole in prioritized order', () => {
- wrapper = mount( );
-
- openPopover();
-
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
- expect(options).toHaveLength(2);
+ expect(options).toHaveLength(2);
- expect(options![0].label).toEqual('Records');
+ expect(options![0].label).toEqual('Records');
- expect(options![1].options!.map(({ label }) => label)).toEqual([
- 'timestamp',
- 'bytes',
- 'memory',
- 'source',
- ]);
- });
+ expect(options![1].options!.map(({ label }) => label)).toEqual([
+ 'timestamp',
+ 'bytes',
+ 'memory',
+ 'source',
+ ]);
+ });
- it('should hide fields that have no data', () => {
- const props = {
- ...defaultProps,
- state: {
- ...defaultProps.state,
- existingFields: {
- 'my-fake-index-pattern': {
- timestamp: true,
- source: true,
+ it('should hide fields that have no data', () => {
+ const props = {
+ ...defaultProps,
+ state: {
+ ...defaultProps.state,
+ existingFields: {
+ 'my-fake-index-pattern': {
+ timestamp: true,
+ source: true,
+ },
},
},
- },
- };
- wrapper = mount( );
-
- openPopover();
-
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
+ };
+ wrapper = mount( );
- expect(options![1].options!.map(({ label }) => label)).toEqual(['timestamp', 'source']);
- });
+ const options = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
- it('should indicate fields which are incompatible for the operation of the current column', () => {
- wrapper = mount(
- label)).toEqual(['timestamp', 'source']);
+ });
- // Private
- operationType: 'max',
- sourceField: 'bytes',
+ it('should indicate fields which are incompatible for the operation of the current column', () => {
+ wrapper = mount(
+
- );
-
- openPopover();
-
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
+ }}
+ />
+ );
- expect(options![0]['data-test-subj']).toEqual('lns-fieldOptionIncompatible-Records');
+ const options = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
- expect(
- options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
- ).toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'memory')[0]['data-test-subj']
- ).not.toContain('Incompatible');
- });
+ expect(options![0]['data-test-subj']).toEqual('lns-fieldOptionIncompatible-Records');
- it('should indicate operations which are incompatible for the field of the current column', () => {
- wrapper = mount(
- label === 'timestamp')[0]['data-test-subj']
+ ).toContain('Incompatible');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'memory')[0]['data-test-subj']
+ ).not.toContain('Incompatible');
+ });
- // Private
- operationType: 'max',
- sourceField: 'bytes',
+ it('should indicate operations which are incompatible for the field of the current column', () => {
+ wrapper = mount(
+
- );
-
- openPopover();
+ }}
+ />
+ );
- interface ItemType {
- name: string;
- 'data-test-subj': string;
- }
- const items: Array> = wrapper.find(EuiSideNav).prop('items');
- const options = (items[0].items as unknown) as ItemType[];
+ interface ItemType {
+ name: string;
+ 'data-test-subj': string;
+ }
+ const items: Array> = wrapper.find(EuiSideNav).prop('items');
+ const options = (items[0].items as unknown) as ItemType[];
- expect(options.find(({ name }) => name === 'Minimum')!['data-test-subj']).not.toContain(
- 'Incompatible'
- );
+ expect(options.find(({ name }) => name === 'Minimum')!['data-test-subj']).not.toContain(
+ 'Incompatible'
+ );
- expect(options.find(({ name }) => name === 'Date histogram')!['data-test-subj']).toContain(
- 'Incompatible'
- );
- });
+ expect(options.find(({ name }) => name === 'Date histogram')!['data-test-subj']).toContain(
+ 'Incompatible'
+ );
+ });
- it('should keep the operation when switching to another field compatible with this operation', () => {
- const initialState: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: {
- label: 'Max of bytes',
- dataType: 'number',
- isBucketed: false,
+ it('should keep the operation when switching to another field compatible with this operation', () => {
+ const initialState: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: {
+ label: 'Max of bytes',
+ dataType: 'number',
+ isBucketed: false,
- // Private
- operationType: 'max',
- sourceField: 'bytes',
- params: { format: { id: 'bytes' } },
+ // Private
+ operationType: 'max',
+ sourceField: 'bytes',
+ params: { format: { id: 'bytes' } },
+ },
},
},
},
- },
- };
-
- wrapper = mount( );
+ };
- openPopover();
+ wrapper = mount(
+
+ );
- const comboBox = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')!;
- const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'memory')!;
+ const comboBox = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')!;
+ const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'memory')!;
- act(() => {
- comboBox.prop('onChange')!([option]);
- });
+ act(() => {
+ comboBox.prop('onChange')!([option]);
+ });
- expect(setState).toHaveBeenCalledWith({
- ...initialState,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- operationType: 'max',
- sourceField: 'memory',
- params: { format: { id: 'bytes' } },
- // Other parts of this don't matter for this test
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...initialState,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ operationType: 'max',
+ sourceField: 'memory',
+ params: { format: { id: 'bytes' } },
+ // Other parts of this don't matter for this test
+ }),
+ },
},
},
- },
+ });
});
- });
-
- it('should switch operations when selecting a field that requires another operation', () => {
- wrapper = mount( );
- openPopover();
+ it('should switch operations when selecting a field that requires another operation', () => {
+ wrapper = mount( );
- const comboBox = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')!;
- const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'source')!;
+ const comboBox = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')!;
+ const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'source')!;
- act(() => {
- comboBox.prop('onChange')!([option]);
- });
+ act(() => {
+ comboBox.prop('onChange')!([option]);
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- operationType: 'terms',
- sourceField: 'source',
- // Other parts of this don't matter for this test
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ operationType: 'terms',
+ sourceField: 'source',
+ // Other parts of this don't matter for this test
+ }),
+ },
},
},
- },
+ });
});
- });
-
- it('should keep the field when switching to another operation compatible for this field', () => {
- wrapper = mount(
- {
+ wrapper = mount(
+
- );
-
- openPopover();
+ }}
+ />
+ );
- act(() => {
- wrapper.find('button[data-test-subj="lns-indexPatternDimension-min"]').simulate('click');
- });
+ act(() => {
+ wrapper.find('button[data-test-subj="lns-indexPatternDimension-min"]').simulate('click');
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- operationType: 'min',
- sourceField: 'bytes',
- params: { format: { id: 'bytes' } },
- // Other parts of this don't matter for this test
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ operationType: 'min',
+ sourceField: 'bytes',
+ params: { format: { id: 'bytes' } },
+ // Other parts of this don't matter for this test
+ }),
+ },
},
},
- },
+ });
});
- });
- it('should not set the state if selecting the currently active operation', () => {
- wrapper = mount( );
+ it('should not set the state if selecting the currently active operation', () => {
+ wrapper = mount( );
- openPopover();
+ act(() => {
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimension-date_histogram"]')
+ .simulate('click');
+ });
- act(() => {
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimension-date_histogram"]')
- .simulate('click');
+ expect(setState).not.toHaveBeenCalled();
});
- expect(setState).not.toHaveBeenCalled();
- });
-
- it('should update label on label input changes', () => {
- wrapper = mount( );
+ it('should update label on label input changes', () => {
+ wrapper = mount( );
- openPopover();
-
- act(() => {
- wrapper
- .find('input[data-test-subj="indexPattern-label-edit"]')
- .simulate('change', { target: { value: 'New Label' } });
- });
+ act(() => {
+ wrapper
+ .find('input[data-test-subj="indexPattern-label-edit"]')
+ .simulate('change', { target: { value: 'New Label' } });
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- label: 'New Label',
- // Other parts of this don't matter for this test
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ label: 'New Label',
+ // Other parts of this don't matter for this test
+ }),
+ },
},
},
- },
+ });
});
- });
- describe('transient invalid state', () => {
- it('should not set the state if selecting an operation incompatible with the current field', () => {
- wrapper = mount( );
+ describe('transient invalid state', () => {
+ it('should not set the state if selecting an operation incompatible with the current field', () => {
+ wrapper = mount( );
- openPopover();
+ act(() => {
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
+ .simulate('click');
+ });
+
+ expect(setState).not.toHaveBeenCalled();
+ });
+
+ it('should show error message in invalid state', () => {
+ wrapper = mount( );
- act(() => {
wrapper
.find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
.simulate('click');
+
+ expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).not.toHaveLength(
+ 0
+ );
+
+ expect(setState).not.toHaveBeenCalled();
});
- expect(setState).not.toHaveBeenCalled();
- });
+ it('should leave error state if a compatible operation is selected', () => {
+ wrapper = mount( );
- it('should show error message in invalid state', () => {
- wrapper = mount( );
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
+ .simulate('click');
- openPopover();
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimension-date_histogram"]')
+ .simulate('click');
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
+ expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).toHaveLength(0);
+ });
- expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).not.toHaveLength(0);
+ it('should indicate fields compatible with selected operation', () => {
+ wrapper = mount( );
- expect(setState).not.toHaveBeenCalled();
- });
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
+ .simulate('click');
- it('should leave error state if a compatible operation is selected', () => {
- wrapper = mount( );
+ const options = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
- openPopover();
+ expect(options![0]['data-test-subj']).toContain('Incompatible');
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
+ ).toContain('Incompatible');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj']
+ ).not.toContain('Incompatible');
+ });
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimension-date_histogram"]')
- .simulate('click');
+ it('should select compatible operation if field not compatible with selected operation', () => {
+ wrapper = mount(
+
+ );
- expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).toHaveLength(0);
- });
+ wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
- it('should leave error state if the popover gets closed', () => {
- wrapper = mount( );
+ const comboBox = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]');
+ const options = comboBox.prop('options');
- openPopover();
+ // options[1][2] is a `source` field of type `string` which doesn't support `avg` operation
+ act(() => {
+ comboBox.prop('onChange')!([options![1].options![2]]);
+ });
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col2: expect.objectContaining({
+ sourceField: 'source',
+ operationType: 'terms',
+ // Other parts of this don't matter for this test
+ }),
+ },
+ columnOrder: ['col1', 'col2'],
+ },
+ },
+ });
+ });
- act(() => {
- wrapper.find(EuiPopover).prop('closePopover')!();
+ it('should select the Records field when count is selected', () => {
+ const initialState: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col2: {
+ dataType: 'number',
+ isBucketed: false,
+ label: '',
+ operationType: 'avg',
+ sourceField: 'bytes',
+ },
+ },
+ },
+ },
+ };
+ wrapper = mount(
+
+ );
+
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-count"]')
+ .simulate('click');
+
+ const newColumnState = setState.mock.calls[0][0].layers.first.columns.col2;
+ expect(newColumnState.operationType).toEqual('count');
+ expect(newColumnState.sourceField).toEqual('Records');
});
- openPopover();
+ it('should indicate document and field compatibility with selected document operation', () => {
+ const initialState: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col2: {
+ dataType: 'number',
+ isBucketed: false,
+ label: '',
+ operationType: 'count',
+ sourceField: 'Records',
+ },
+ },
+ },
+ },
+ };
+ wrapper = mount(
+
+ );
+
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
+ .simulate('click');
- expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).toHaveLength(0);
- });
+ const options = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
- it('should indicate fields compatible with selected operation', () => {
- wrapper = mount( );
+ expect(options![0]['data-test-subj']).toContain('Incompatible');
- openPopover();
+ expect(
+ options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
+ ).toContain('Incompatible');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj']
+ ).not.toContain('Incompatible');
+ });
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
+ it('should set datasource state if compatible field is selected for operation', () => {
+ wrapper = mount( );
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
+ act(() => {
+ wrapper
+ .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
+ .simulate('click');
+ });
- expect(options![0]['data-test-subj']).toContain('Incompatible');
+ const comboBox = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')!;
+ const option = comboBox
+ .prop('options')![1]
+ .options!.find(({ label }) => label === 'source')!;
- expect(
- options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
- ).toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj']
- ).not.toContain('Incompatible');
- });
+ act(() => {
+ comboBox.prop('onChange')!([option]);
+ });
- it('should select compatible operation if field not compatible with selected operation', () => {
- wrapper = mount( );
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ sourceField: 'source',
+ operationType: 'terms',
+ }),
+ },
+ },
+ },
+ });
+ });
+ });
- openPopover();
+ it('should support selecting the operation before the field', () => {
+ wrapper = mount( );
wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
@@ -635,9 +734,8 @@ describe('IndexPatternDimensionPanel', () => {
.filter('[data-test-subj="indexPattern-dimension-field"]');
const options = comboBox.prop('options');
- // options[1][2] is a `source` field of type `string` which doesn't support `avg` operation
act(() => {
- comboBox.prop('onChange')!([options![1].options![2]]);
+ comboBox.prop('onChange')!([options![1].options![0]]);
});
expect(setState).toHaveBeenCalledWith({
@@ -648,8 +746,8 @@ describe('IndexPatternDimensionPanel', () => {
columns: {
...state.layers.first.columns,
col2: expect.objectContaining({
- sourceField: 'source',
- operationType: 'terms',
+ sourceField: 'bytes',
+ operationType: 'avg',
// Other parts of this don't matter for this test
}),
},
@@ -659,41 +757,93 @@ describe('IndexPatternDimensionPanel', () => {
});
});
- it('should select the Records field when count is selected', () => {
- const initialState: IndexPatternPrivateState = {
+ it('should select operation directly if only one field is possible', () => {
+ const initialState = {
+ ...state,
+ indexPatterns: {
+ 1: {
+ ...state.indexPatterns['1'],
+ fields: state.indexPatterns['1'].fields.filter(field => field.name !== 'memory'),
+ },
+ },
+ };
+
+ wrapper = mount(
+
+ );
+
+ wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
+
+ expect(setState).toHaveBeenCalledWith({
+ ...initialState,
+ layers: {
+ first: {
+ ...initialState.layers.first,
+ columns: {
+ ...initialState.layers.first.columns,
+ col2: expect.objectContaining({
+ sourceField: 'bytes',
+ operationType: 'avg',
+ // Other parts of this don't matter for this test
+ }),
+ },
+ columnOrder: ['col1', 'col2'],
+ },
+ },
+ });
+ });
+
+ it('should select operation directly if only document is possible', () => {
+ wrapper = mount( );
+
+ wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click');
+
+ expect(setState).toHaveBeenCalledWith({
...state,
layers: {
first: {
...state.layers.first,
columns: {
...state.layers.first.columns,
- col2: {
- dataType: 'number',
- isBucketed: false,
- label: '',
- operationType: 'avg',
- sourceField: 'bytes',
- },
+ col2: expect.objectContaining({
+ operationType: 'count',
+ // Other parts of this don't matter for this test
+ }),
},
+ columnOrder: ['col1', 'col2'],
},
},
- };
- wrapper = mount(
-
- );
+ });
+ });
- openPopover();
+ it('should indicate compatible fields when selecting the operation first', () => {
+ wrapper = mount( );
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-count"]')
- .simulate('click');
+ wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
- const newColumnState = setState.mock.calls[0][0].layers.first.columns.col2;
- expect(newColumnState.operationType).toEqual('count');
- expect(newColumnState.sourceField).toEqual('Records');
+ const options = wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('options');
+
+ expect(options![0]['data-test-subj']).toContain('Incompatible');
+
+ expect(
+ options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
+ ).toContain('Incompatible');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'bytes')[0]['data-test-subj']
+ ).not.toContain('Incompatible');
+ expect(
+ options![1].options!.filter(({ label }) => label === 'memory')[0]['data-test-subj']
+ ).not.toContain('Incompatible');
});
- it('should indicate document and field compatibility with selected document operation', () => {
+ it('should indicate document compatibility when document operation is selected', () => {
const initialState: IndexPatternPrivateState = {
...state,
layers: {
@@ -713,45 +863,56 @@ describe('IndexPatternDimensionPanel', () => {
},
};
wrapper = mount(
-
+
);
- openPopover();
-
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
-
const options = wrapper
.find(EuiComboBox)
.filter('[data-test-subj="indexPattern-dimension-field"]')
.prop('options');
- expect(options![0]['data-test-subj']).toContain('Incompatible');
+ expect(options![0]['data-test-subj']).not.toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
- ).toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'source')[0]['data-test-subj']
- ).not.toContain('Incompatible');
+ options![1].options!.map(operation =>
+ expect(operation['data-test-subj']).toContain('Incompatible')
+ );
});
- it('should set datasource state if compatible field is selected for operation', () => {
- wrapper = mount( );
+ it('should show all operations that are not filtered out', () => {
+ wrapper = mount(
+ !op.isBucketed && op.dataType === 'number'}
+ />
+ );
- openPopover();
+ interface ItemType {
+ name: React.ReactNode;
+ }
+ const items: Array> = wrapper.find(EuiSideNav).prop('items');
+ const options = (items[0].items as unknown) as ItemType[];
+
+ expect(options.map(({ name }: { name: React.ReactNode }) => name)).toEqual([
+ 'Unique count',
+ 'Average',
+ 'Count',
+ 'Maximum',
+ 'Minimum',
+ 'Sum',
+ ]);
+ });
- act(() => {
- wrapper
- .find('button[data-test-subj="lns-indexPatternDimensionIncompatible-terms"]')
- .simulate('click');
- });
+ it('should add a column on selection of a field', () => {
+ wrapper = mount( );
const comboBox = wrapper
.find(EuiComboBox)
.filter('[data-test-subj="indexPattern-dimension-field"]')!;
- const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'source')!;
+ const option = comboBox.prop('options')![1].options![0];
act(() => {
comboBox.prop('onChange')!([option]);
@@ -764,479 +925,237 @@ describe('IndexPatternDimensionPanel', () => {
...state.layers.first,
columns: {
...state.layers.first.columns,
- col1: expect.objectContaining({
- sourceField: 'source',
- operationType: 'terms',
+ col2: expect.objectContaining({
+ sourceField: 'bytes',
+ // Other parts of this don't matter for this test
}),
},
+ columnOrder: ['col1', 'col2'],
},
},
});
});
- });
-
- it('should support selecting the operation before the field', () => {
- wrapper = mount( );
-
- openPopover();
-
- wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
-
- const comboBox = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]');
- const options = comboBox.prop('options');
-
- act(() => {
- comboBox.prop('onChange')!([options![1].options![0]]);
- });
-
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col2: expect.objectContaining({
- sourceField: 'bytes',
- operationType: 'avg',
- // Other parts of this don't matter for this test
- }),
- },
- columnOrder: ['col1', 'col2'],
- },
- },
- });
- });
-
- it('should select operation directly if only one field is possible', () => {
- const initialState = {
- ...state,
- indexPatterns: {
- 1: {
- ...state.indexPatterns['1'],
- fields: state.indexPatterns['1'].fields.filter(field => field.name !== 'memory'),
- },
- },
- };
-
- wrapper = mount(
-
- );
-
- openPopover();
-
- wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
-
- expect(setState).toHaveBeenCalledWith({
- ...initialState,
- layers: {
- first: {
- ...initialState.layers.first,
- columns: {
- ...initialState.layers.first.columns,
- col2: expect.objectContaining({
- sourceField: 'bytes',
- operationType: 'avg',
- // Other parts of this don't matter for this test
- }),
- },
- columnOrder: ['col1', 'col2'],
- },
- },
- });
- });
-
- it('should select operation directly if only document is possible', () => {
- wrapper = mount( );
-
- openPopover();
-
- wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click');
-
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col2: expect.objectContaining({
- operationType: 'count',
- // Other parts of this don't matter for this test
- }),
- },
- columnOrder: ['col1', 'col2'],
- },
- },
- });
- });
- it('should indicate compatible fields when selecting the operation first', () => {
- wrapper = mount( );
-
- openPopover();
-
- wrapper.find('button[data-test-subj="lns-indexPatternDimension-avg"]').simulate('click');
-
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
-
- expect(options![0]['data-test-subj']).toContain('Incompatible');
-
- expect(
- options![1].options!.filter(({ label }) => label === 'timestamp')[0]['data-test-subj']
- ).toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'bytes')[0]['data-test-subj']
- ).not.toContain('Incompatible');
- expect(
- options![1].options!.filter(({ label }) => label === 'memory')[0]['data-test-subj']
- ).not.toContain('Incompatible');
- });
-
- it('should indicate document compatibility when document operation is selected', () => {
- const initialState: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col2: {
- dataType: 'number',
- isBucketed: false,
- label: '',
- operationType: 'count',
- sourceField: 'Records',
- },
- },
- },
- },
- };
- wrapper = mount(
-
- );
-
- openPopover();
-
- const options = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('options');
-
- expect(options![0]['data-test-subj']).not.toContain('Incompatible');
-
- options![1].options!.map(operation =>
- expect(operation['data-test-subj']).toContain('Incompatible')
- );
- });
-
- it('should show all operations that are not filtered out', () => {
- wrapper = mount(
- !op.isBucketed && op.dataType === 'number'}
- />
- );
-
- openPopover();
-
- interface ItemType {
- name: React.ReactNode;
- }
- const items: Array> = wrapper.find(EuiSideNav).prop('items');
- const options = (items[0].items as unknown) as ItemType[];
-
- expect(options.map(({ name }: { name: React.ReactNode }) => name)).toEqual([
- 'Unique count',
- 'Average',
- 'Count',
- 'Maximum',
- 'Minimum',
- 'Sum',
- ]);
- });
-
- it('should add a column on selection of a field', () => {
- wrapper = mount( );
-
- openPopover();
-
- const comboBox = wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')!;
- const option = comboBox.prop('options')![1].options![0];
-
- act(() => {
- comboBox.prop('onChange')!([option]);
- });
-
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col2: expect.objectContaining({
- sourceField: 'bytes',
- // Other parts of this don't matter for this test
- }),
- },
- columnOrder: ['col1', 'col2'],
- },
- },
- });
- });
-
- it('should use helper function when changing the function', () => {
- const initialState: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: {
- label: 'Max of bytes',
- dataType: 'number',
- isBucketed: false,
+ it('should use helper function when changing the function', () => {
+ const initialState: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: {
+ label: 'Max of bytes',
+ dataType: 'number',
+ isBucketed: false,
- // Private
- operationType: 'max',
- sourceField: 'bytes',
+ // Private
+ operationType: 'max',
+ sourceField: 'bytes',
+ },
},
},
},
- },
- };
- wrapper = mount( );
-
- openPopover();
-
- act(() => {
- wrapper
- .find('[data-test-subj="lns-indexPatternDimension-min"]')
- .first()
- .prop('onClick')!({} as React.MouseEvent<{}, MouseEvent>);
- });
-
- expect(changeColumn).toHaveBeenCalledWith({
- state: initialState,
- columnId: 'col1',
- layerId: 'first',
- newColumn: expect.objectContaining({
- sourceField: 'bytes',
- operationType: 'min',
- }),
- });
- });
-
- it('should clear the dimension with the clear button', () => {
- wrapper = mount( );
-
- const clearButton = wrapper.find(
- 'EuiButtonIcon[data-test-subj="indexPattern-dimensionPopover-remove"]'
- );
+ };
+ wrapper = mount(
+
+ );
- act(() => {
- clearButton.simulate('click');
- });
+ act(() => {
+ wrapper
+ .find('[data-test-subj="lns-indexPatternDimension-min"]')
+ .first()
+ .prop('onClick')!({} as React.MouseEvent<{}, MouseEvent>);
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- indexPatternId: '1',
- columns: {},
- columnOrder: [],
- },
- },
+ expect(changeColumn).toHaveBeenCalledWith({
+ state: initialState,
+ columnId: 'col1',
+ layerId: 'first',
+ newColumn: expect.objectContaining({
+ sourceField: 'bytes',
+ operationType: 'min',
+ }),
+ });
});
- });
-
- it('should clear the dimension when removing the selection in field combobox', () => {
- wrapper = mount( );
- openPopover();
+ it('should clear the dimension when removing the selection in field combobox', () => {
+ wrapper = mount( );
- act(() => {
- wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-field"]')
- .prop('onChange')!([]);
- });
+ act(() => {
+ wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-field"]')
+ .prop('onChange')!([]);
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- indexPatternId: '1',
- columns: {},
- columnOrder: [],
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ indexPatternId: '1',
+ columns: {},
+ columnOrder: [],
+ },
},
- },
+ });
});
- });
- it('allows custom format', () => {
- const stateWithNumberCol: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- indexPatternId: '1',
- columnOrder: ['col1'],
- columns: {
- col1: {
- label: 'Average of bar',
- dataType: 'number',
- isBucketed: false,
- // Private
- operationType: 'avg',
- sourceField: 'bar',
+ it('allows custom format', () => {
+ const stateWithNumberCol: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ indexPatternId: '1',
+ columnOrder: ['col1'],
+ columns: {
+ col1: {
+ label: 'Average of bar',
+ dataType: 'number',
+ isBucketed: false,
+ // Private
+ operationType: 'avg',
+ sourceField: 'bar',
+ },
},
},
},
- },
- };
-
- wrapper = mount( );
+ };
- openPopover();
+ wrapper = mount(
+
+ );
- act(() => {
- wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-format"]')
- .prop('onChange')!([{ value: 'bytes', label: 'Bytes' }]);
- });
+ act(() => {
+ wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-format"]')
+ .prop('onChange')!([{ value: 'bytes', label: 'Bytes' }]);
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- params: {
- format: { id: 'bytes', params: { decimals: 2 } },
- },
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ params: {
+ format: { id: 'bytes', params: { decimals: 2 } },
+ },
+ }),
+ },
},
},
- },
+ });
});
- });
- it('keeps decimal places while switching', () => {
- const stateWithNumberCol: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- indexPatternId: '1',
- columnOrder: ['col1'],
- columns: {
- col1: {
- label: 'Average of bar',
- dataType: 'number',
- isBucketed: false,
- // Private
- operationType: 'avg',
- sourceField: 'bar',
- params: {
- format: { id: 'bytes', params: { decimals: 0 } },
+ it('keeps decimal places while switching', () => {
+ const stateWithNumberCol: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ indexPatternId: '1',
+ columnOrder: ['col1'],
+ columns: {
+ col1: {
+ label: 'Average of bar',
+ dataType: 'number',
+ isBucketed: false,
+ // Private
+ operationType: 'avg',
+ sourceField: 'bar',
+ params: {
+ format: { id: 'bytes', params: { decimals: 0 } },
+ },
},
},
},
},
- },
- };
+ };
- wrapper = mount( );
+ wrapper = mount(
+
+ );
- openPopover();
+ act(() => {
+ wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-format"]')
+ .prop('onChange')!([{ value: '', label: 'Default' }]);
+ });
- act(() => {
- wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-format"]')
- .prop('onChange')!([{ value: '', label: 'Default' }]);
- });
+ act(() => {
+ wrapper
+ .find(EuiComboBox)
+ .filter('[data-test-subj="indexPattern-dimension-format"]')
+ .prop('onChange')!([{ value: 'number', label: 'Number' }]);
+ });
- act(() => {
- wrapper
- .find(EuiComboBox)
- .filter('[data-test-subj="indexPattern-dimension-format"]')
- .prop('onChange')!([{ value: 'number', label: 'Number' }]);
+ expect(
+ wrapper
+ .find(EuiFieldNumber)
+ .filter('[data-test-subj="indexPattern-dimension-formatDecimals"]')
+ .prop('value')
+ ).toEqual(0);
});
- expect(
- wrapper
- .find(EuiFieldNumber)
- .filter('[data-test-subj="indexPattern-dimension-formatDecimals"]')
- .prop('value')
- ).toEqual(0);
- });
-
- it('allows custom format with number of decimal places', () => {
- const stateWithNumberCol: IndexPatternPrivateState = {
- ...state,
- layers: {
- first: {
- indexPatternId: '1',
- columnOrder: ['col1'],
- columns: {
- col1: {
- label: 'Average of bar',
- dataType: 'number',
- isBucketed: false,
- // Private
- operationType: 'avg',
- sourceField: 'bar',
- params: {
- format: { id: 'bytes', params: { decimals: 2 } },
+ it('allows custom format with number of decimal places', () => {
+ const stateWithNumberCol: IndexPatternPrivateState = {
+ ...state,
+ layers: {
+ first: {
+ indexPatternId: '1',
+ columnOrder: ['col1'],
+ columns: {
+ col1: {
+ label: 'Average of bar',
+ dataType: 'number',
+ isBucketed: false,
+ // Private
+ operationType: 'avg',
+ sourceField: 'bar',
+ params: {
+ format: { id: 'bytes', params: { decimals: 2 } },
+ },
},
},
},
},
- },
- };
-
- wrapper = mount( );
+ };
- openPopover();
+ wrapper = mount(
+
+ );
- act(() => {
- wrapper
- .find(EuiFieldNumber)
- .filter('[data-test-subj="indexPattern-dimension-formatDecimals"]')
- .prop('onChange')!({ target: { value: '0' } });
- });
+ act(() => {
+ wrapper
+ .find(EuiFieldNumber)
+ .filter('[data-test-subj="indexPattern-dimension-formatDecimals"]')
+ .prop('onChange')!({ target: { value: '0' } });
+ });
- expect(setState).toHaveBeenCalledWith({
- ...state,
- layers: {
- first: {
- ...state.layers.first,
- columns: {
- ...state.layers.first.columns,
- col1: expect.objectContaining({
- params: {
- format: { id: 'bytes', params: { decimals: 0 } },
- },
- }),
+ expect(setState).toHaveBeenCalledWith({
+ ...state,
+ layers: {
+ first: {
+ ...state.layers.first,
+ columns: {
+ ...state.layers.first.columns,
+ col1: expect.objectContaining({
+ params: {
+ format: { id: 'bytes', params: { decimals: 0 } },
+ },
+ }),
+ },
},
},
- },
+ });
});
});
- describe('drag and drop', () => {
+ describe('Drag and drop', () => {
function dragDropState(): IndexPatternPrivateState {
return {
indexPatternRefs: [],
@@ -1287,112 +1206,80 @@ describe('IndexPatternDimensionPanel', () => {
}
it('is not droppable if no drag is happening', () => {
- wrapper = mount(
-
- );
-
expect(
- wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('droppable')
- ).toBeFalsy();
+ canHandleDrop({
+ ...defaultProps,
+ dragDropContext,
+ state: dragDropState(),
+ layerId: 'myLayer',
+ })
+ ).toBe(false);
});
it('is not droppable if the dragged item has no field', () => {
- wrapper = shallow(
-
- );
-
- expect(
- wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('droppable')
- ).toBeFalsy();
+ },
+ })
+ ).toBe(false);
});
it('is not droppable if field is not supported by filterOperations', () => {
- wrapper = shallow(
- false}
- layerId="myLayer"
- />
- );
-
- expect(
- wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('droppable')
- ).toBeFalsy();
+ },
+ state: dragDropState(),
+ filterOperations: () => false,
+ layerId: 'myLayer',
+ })
+ ).toBe(false);
});
it('is droppable if the field is supported by filterOperations', () => {
- wrapper = shallow(
- op.dataType === 'number'}
- layerId="myLayer"
- />
- );
-
- expect(
- wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('droppable')
- ).toBeTruthy();
+ },
+ state: dragDropState(),
+ filterOperations: (op: OperationMetadata) => op.dataType === 'number',
+ layerId: 'myLayer',
+ })
+ ).toBe(true);
});
- it('is notdroppable if the field belongs to another index pattern', () => {
- wrapper = shallow(
- {
+ expect(
+ canHandleDrop({
+ ...defaultProps,
+ dragDropContext: {
...dragDropContext,
dragging: {
field: { type: 'number', name: 'bar', aggregatable: true },
indexPatternId: 'foo2',
},
- }}
- state={dragDropState()}
- filterOperations={op => op.dataType === 'number'}
- layerId="myLayer"
- />
- );
-
- expect(
- wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('droppable')
- ).toBeFalsy();
+ },
+ state: dragDropState(),
+ filterOperations: (op: OperationMetadata) => op.dataType === 'number',
+ layerId: 'myLayer',
+ })
+ ).toBe(false);
});
it('appends the dropped column when a field is dropped', () => {
@@ -1401,27 +1288,18 @@ describe('IndexPatternDimensionPanel', () => {
indexPatternId: 'foo',
};
const testState = dragDropState();
- wrapper = shallow(
- op.dataType === 'number'}
- layerId="myLayer"
- />
- );
-
- act(() => {
- const onDrop = wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('onDrop') as DropHandler;
- onDrop(dragging);
+ onDrop({
+ ...defaultProps,
+ dragDropContext: {
+ ...dragDropContext,
+ dragging,
+ },
+ droppedItem: dragging,
+ state: testState,
+ columnId: 'col2',
+ filterOperations: (op: OperationMetadata) => op.dataType === 'number',
+ layerId: 'myLayer',
});
expect(setState).toBeCalledTimes(1);
@@ -1449,27 +1327,17 @@ describe('IndexPatternDimensionPanel', () => {
indexPatternId: 'foo',
};
const testState = dragDropState();
- wrapper = shallow(
- op.isBucketed}
- layerId="myLayer"
- />
- );
-
- act(() => {
- const onDrop = wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('onDrop') as DropHandler;
-
- onDrop(dragging);
+ onDrop({
+ ...defaultProps,
+ dragDropContext: {
+ ...dragDropContext,
+ dragging,
+ },
+ droppedItem: dragging,
+ state: testState,
+ columnId: 'col2',
+ filterOperations: (op: OperationMetadata) => op.isBucketed,
+ layerId: 'myLayer',
});
expect(setState).toBeCalledTimes(1);
@@ -1497,26 +1365,16 @@ describe('IndexPatternDimensionPanel', () => {
indexPatternId: 'foo',
};
const testState = dragDropState();
- wrapper = shallow(
- op.dataType === 'number'}
- layerId="myLayer"
- />
- );
-
- act(() => {
- const onDrop = wrapper
- .find('[data-test-subj="indexPattern-dropTarget"]')
- .first()
- .prop('onDrop') as DropHandler;
-
- onDrop(dragging);
+ onDrop({
+ ...defaultProps,
+ dragDropContext: {
+ ...dragDropContext,
+ dragging,
+ },
+ droppedItem: dragging,
+ state: testState,
+ filterOperations: (op: OperationMetadata) => op.dataType === 'number',
+ layerId: 'myLayer',
});
expect(setState).toBeCalledTimes(1);
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx
index 59350ff215c27..5d87137db3d39 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx
@@ -5,27 +5,36 @@
*/
import _ from 'lodash';
-import React, { memo, useMemo } from 'react';
-import { EuiButtonIcon } from '@elastic/eui';
+import React, { memo } from 'react';
import { i18n } from '@kbn/i18n';
+import { EuiLink } from '@elastic/eui';
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'src/core/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
+import {
+ DatasourceDimensionTriggerProps,
+ DatasourceDimensionEditorProps,
+ DatasourceDimensionDropProps,
+ DatasourceDimensionDropHandlerProps,
+} from '../../types';
import { DataPublicPluginStart } from '../../../../../../../src/plugins/data/public';
-import { DatasourceDimensionPanelProps, StateSetter } from '../../types';
import { IndexPatternColumn, OperationType } from '../indexpattern';
import { getAvailableOperationsByMetadata, buildColumn, changeField } from '../operations';
import { PopoverEditor } from './popover_editor';
-import { DragContextState, ChildDragDropProvider, DragDrop } from '../../drag_drop';
-import { changeColumn, deleteColumn } from '../state_helpers';
+import { changeColumn } from '../state_helpers';
import { isDraggedField, hasField } from '../utils';
import { IndexPatternPrivateState, IndexPatternField } from '../types';
import { trackUiEvent } from '../../lens_ui_telemetry';
import { DateRange } from '../../../../../../plugins/lens/common';
-export type IndexPatternDimensionPanelProps = DatasourceDimensionPanelProps & {
- state: IndexPatternPrivateState;
- setState: StateSetter;
- dragDropContext: DragContextState;
+export type IndexPatternDimensionTriggerProps = DatasourceDimensionTriggerProps<
+ IndexPatternPrivateState
+> & {
+ uniqueLabel: string;
+};
+
+export type IndexPatternDimensionEditorProps = DatasourceDimensionEditorProps<
+ IndexPatternPrivateState
+> & {
uiSettings: IUiSettingsClient;
storage: IStorageWrapper;
savedObjectsClient: SavedObjectsClientContract;
@@ -41,152 +50,181 @@ export interface OperationFieldSupportMatrix {
fieldByOperation: Partial>;
}
-export const IndexPatternDimensionPanelComponent = function IndexPatternDimensionPanel(
- props: IndexPatternDimensionPanelProps
-) {
+type Props = Pick<
+ DatasourceDimensionDropProps,
+ 'layerId' | 'columnId' | 'state' | 'filterOperations'
+>;
+
+// TODO: This code has historically been memoized, as a potentially performance
+// sensitive task. If we can add memoization without breaking the behavior, we should.
+const getOperationFieldSupportMatrix = (props: Props): OperationFieldSupportMatrix => {
const layerId = props.layerId;
const currentIndexPattern = props.state.indexPatterns[props.state.layers[layerId].indexPatternId];
- const operationFieldSupportMatrix = useMemo(() => {
- const filteredOperationsByMetadata = getAvailableOperationsByMetadata(
- currentIndexPattern
- ).filter(operation => props.filterOperations(operation.operationMetaData));
-
- const supportedOperationsByField: Partial> = {};
- const supportedFieldsByOperation: Partial> = {};
-
- filteredOperationsByMetadata.forEach(({ operations }) => {
- operations.forEach(operation => {
- if (supportedOperationsByField[operation.field]) {
- supportedOperationsByField[operation.field]!.push(operation.operationType);
- } else {
- supportedOperationsByField[operation.field] = [operation.operationType];
- }
-
- if (supportedFieldsByOperation[operation.operationType]) {
- supportedFieldsByOperation[operation.operationType]!.push(operation.field);
- } else {
- supportedFieldsByOperation[operation.operationType] = [operation.field];
- }
- });
+ const filteredOperationsByMetadata = getAvailableOperationsByMetadata(
+ currentIndexPattern
+ ).filter(operation => props.filterOperations(operation.operationMetaData));
+
+ const supportedOperationsByField: Partial> = {};
+ const supportedFieldsByOperation: Partial> = {};
+
+ filteredOperationsByMetadata.forEach(({ operations }) => {
+ operations.forEach(operation => {
+ if (supportedOperationsByField[operation.field]) {
+ supportedOperationsByField[operation.field]!.push(operation.operationType);
+ } else {
+ supportedOperationsByField[operation.field] = [operation.operationType];
+ }
+
+ if (supportedFieldsByOperation[operation.operationType]) {
+ supportedFieldsByOperation[operation.operationType]!.push(operation.field);
+ } else {
+ supportedFieldsByOperation[operation.operationType] = [operation.field];
+ }
});
- return {
- operationByField: _.mapValues(supportedOperationsByField, _.uniq),
- fieldByOperation: _.mapValues(supportedFieldsByOperation, _.uniq),
- };
- }, [currentIndexPattern, props.filterOperations]);
+ });
+ return {
+ operationByField: _.mapValues(supportedOperationsByField, _.uniq),
+ fieldByOperation: _.mapValues(supportedFieldsByOperation, _.uniq),
+ };
+};
- const selectedColumn: IndexPatternColumn | null =
- props.state.layers[layerId].columns[props.columnId] || null;
+export function canHandleDrop(props: DatasourceDimensionDropProps) {
+ const operationFieldSupportMatrix = getOperationFieldSupportMatrix(props);
+
+ const { dragging } = props.dragDropContext;
+ const layerIndexPatternId = props.state.layers[props.layerId].indexPatternId;
function hasOperationForField(field: IndexPatternField) {
return Boolean(operationFieldSupportMatrix.operationByField[field.name]);
}
- function canHandleDrop() {
- const { dragging } = props.dragDropContext;
- const layerIndexPatternId = props.state.layers[props.layerId].indexPatternId;
+ return (
+ isDraggedField(dragging) &&
+ layerIndexPatternId === dragging.indexPatternId &&
+ Boolean(hasOperationForField(dragging.field))
+ );
+}
+
+export function onDrop(
+ props: DatasourceDimensionDropHandlerProps
+): boolean {
+ const operationFieldSupportMatrix = getOperationFieldSupportMatrix(props);
+ const droppedItem = props.droppedItem;
+
+ function hasOperationForField(field: IndexPatternField) {
+ return Boolean(operationFieldSupportMatrix.operationByField[field.name]);
+ }
- return (
- isDraggedField(dragging) &&
- layerIndexPatternId === dragging.indexPatternId &&
- Boolean(hasOperationForField(dragging.field))
- );
+ if (!isDraggedField(droppedItem) || !hasOperationForField(droppedItem.field)) {
+ // TODO: What do we do if we couldn't find a column?
+ return false;
}
+ const operationsForNewField =
+ operationFieldSupportMatrix.operationByField[droppedItem.field.name];
+
+ const layerId = props.layerId;
+ const selectedColumn: IndexPatternColumn | null =
+ props.state.layers[layerId].columns[props.columnId] || null;
+ const currentIndexPattern =
+ props.state.indexPatterns[props.state.layers[layerId]?.indexPatternId];
+
+ // We need to check if dragging in a new field, was just a field change on the same
+ // index pattern and on the same operations (therefore checking if the new field supports
+ // our previous operation)
+ const hasFieldChanged =
+ selectedColumn &&
+ hasField(selectedColumn) &&
+ selectedColumn.sourceField !== droppedItem.field.name &&
+ operationsForNewField &&
+ operationsForNewField.includes(selectedColumn.operationType);
+
+ // If only the field has changed use the onFieldChange method on the operation to get the
+ // new column, otherwise use the regular buildColumn to get a new column.
+ const newColumn = hasFieldChanged
+ ? changeField(selectedColumn, currentIndexPattern, droppedItem.field)
+ : buildColumn({
+ op: operationsForNewField ? operationsForNewField[0] : undefined,
+ columns: props.state.layers[props.layerId].columns,
+ indexPattern: currentIndexPattern,
+ layerId,
+ suggestedPriority: props.suggestedPriority,
+ field: droppedItem.field,
+ previousColumn: selectedColumn,
+ });
+
+ trackUiEvent('drop_onto_dimension');
+ const hasData = Object.values(props.state.layers).some(({ columns }) => columns.length);
+ trackUiEvent(hasData ? 'drop_non_empty' : 'drop_empty');
+
+ props.setState(
+ changeColumn({
+ state: props.state,
+ layerId,
+ columnId: props.columnId,
+ newColumn,
+ // If the field has changed, the onFieldChange method needs to take care of everything including moving
+ // over params. If we create a new column above we want changeColumn to move over params.
+ keepParams: !hasFieldChanged,
+ })
+ );
+
+ return true;
+}
+
+export const IndexPatternDimensionTriggerComponent = function IndexPatternDimensionTrigger(
+ props: IndexPatternDimensionTriggerProps
+) {
+ const layerId = props.layerId;
+
+ const selectedColumn: IndexPatternColumn | null =
+ props.state.layers[layerId].columns[props.columnId] || null;
+
+ const { columnId, uniqueLabel } = props;
+ if (!selectedColumn) {
+ return null;
+ }
+ return (
+ {
+ props.togglePopover();
+ }}
+ data-test-subj="lns-dimensionTrigger"
+ aria-label={i18n.translate('xpack.lens.configure.editConfig', {
+ defaultMessage: 'Edit configuration',
+ })}
+ title={i18n.translate('xpack.lens.configure.editConfig', {
+ defaultMessage: 'Edit configuration',
+ })}
+ >
+ {uniqueLabel}
+
+ );
+};
+
+export const IndexPatternDimensionEditorComponent = function IndexPatternDimensionPanel(
+ props: IndexPatternDimensionEditorProps
+) {
+ const layerId = props.layerId;
+ const currentIndexPattern =
+ props.state.indexPatterns[props.state.layers[layerId]?.indexPatternId];
+ const operationFieldSupportMatrix = getOperationFieldSupportMatrix(props);
+
+ const selectedColumn: IndexPatternColumn | null =
+ props.state.layers[layerId].columns[props.columnId] || null;
+
return (
-
- {
- if (!isDraggedField(droppedItem) || !hasOperationForField(droppedItem.field)) {
- // TODO: What do we do if we couldn't find a column?
- return;
- }
-
- const operationsForNewField =
- operationFieldSupportMatrix.operationByField[droppedItem.field.name];
-
- // We need to check if dragging in a new field, was just a field change on the same
- // index pattern and on the same operations (therefore checking if the new field supports
- // our previous operation)
- const hasFieldChanged =
- selectedColumn &&
- hasField(selectedColumn) &&
- selectedColumn.sourceField !== droppedItem.field.name &&
- operationsForNewField &&
- operationsForNewField.includes(selectedColumn.operationType);
-
- // If only the field has changed use the onFieldChange method on the operation to get the
- // new column, otherwise use the regular buildColumn to get a new column.
- const newColumn = hasFieldChanged
- ? changeField(selectedColumn, currentIndexPattern, droppedItem.field)
- : buildColumn({
- op: operationsForNewField ? operationsForNewField[0] : undefined,
- columns: props.state.layers[props.layerId].columns,
- indexPattern: currentIndexPattern,
- layerId,
- suggestedPriority: props.suggestedPriority,
- field: droppedItem.field,
- previousColumn: selectedColumn,
- });
-
- trackUiEvent('drop_onto_dimension');
- const hasData = Object.values(props.state.layers).some(({ columns }) => columns.length);
- trackUiEvent(hasData ? 'drop_non_empty' : 'drop_empty');
-
- props.setState(
- changeColumn({
- state: props.state,
- layerId,
- columnId: props.columnId,
- newColumn,
- // If the field has changed, the onFieldChange method needs to take care of everything including moving
- // over params. If we create a new column above we want changeColumn to move over params.
- keepParams: !hasFieldChanged,
- })
- );
- }}
- >
-
- {selectedColumn && (
- {
- trackUiEvent('indexpattern_dimension_removed');
- props.setState(
- deleteColumn({
- state: props.state,
- layerId,
- columnId: props.columnId,
- })
- );
- if (props.onRemove) {
- props.onRemove(props.columnId);
- }
- }}
- />
- )}
-
-
+
);
};
-export const IndexPatternDimensionPanel = memo(IndexPatternDimensionPanelComponent);
+export const IndexPatternDimensionTrigger = memo(IndexPatternDimensionTriggerComponent);
+export const IndexPatternDimensionEditor = memo(IndexPatternDimensionEditorComponent);
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx
index 056a8d177dfe8..e26c338b6e240 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx
@@ -7,22 +7,18 @@
import _ from 'lodash';
import React, { useState, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
import {
- EuiPopover,
EuiFlexItem,
EuiFlexGroup,
EuiSideNav,
EuiCallOut,
EuiFormRow,
EuiFieldText,
- EuiLink,
- EuiButtonEmpty,
EuiSpacer,
} from '@elastic/eui';
import classNames from 'classnames';
import { IndexPatternColumn, OperationType } from '../indexpattern';
-import { IndexPatternDimensionPanelProps, OperationFieldSupportMatrix } from './dimension_panel';
+import { IndexPatternDimensionEditorProps, OperationFieldSupportMatrix } from './dimension_panel';
import {
operationDefinitionMap,
getOperationDisplay,
@@ -39,7 +35,7 @@ import { FormatSelector } from './format_selector';
const operationPanels = getOperationDisplay();
-export interface PopoverEditorProps extends IndexPatternDimensionPanelProps {
+export interface PopoverEditorProps extends IndexPatternDimensionEditorProps {
selectedColumn?: IndexPatternColumn;
operationFieldSupportMatrix: OperationFieldSupportMatrix;
currentIndexPattern: IndexPattern;
@@ -67,11 +63,9 @@ export function PopoverEditor(props: PopoverEditorProps) {
setState,
layerId,
currentIndexPattern,
- uniqueLabel,
hideGrouping,
} = props;
const { operationByField, fieldByOperation } = operationFieldSupportMatrix;
- const [isPopoverOpen, setPopoverOpen] = useState(false);
const [
incompatibleSelectedOperationType,
setInvalidOperationType,
@@ -115,14 +109,14 @@ export function PopoverEditor(props: PopoverEditorProps) {
items: getOperationTypes().map(({ operationType, compatibleWithCurrentField }) => ({
name: operationPanels[operationType].displayName,
id: operationType as string,
- className: classNames('lnsPopoverEditor__operation', {
- 'lnsPopoverEditor__operation--selected': Boolean(
+ className: classNames('lnsIndexPatternDimensionEditor__operation', {
+ 'lnsIndexPatternDimensionEditor__operation--selected': Boolean(
incompatibleSelectedOperationType === operationType ||
(!incompatibleSelectedOperationType &&
selectedColumn &&
selectedColumn.operationType === operationType)
),
- 'lnsPopoverEditor__operation--incompatible': !compatibleWithCurrentField,
+ 'lnsIndexPatternDimensionEditor__operation--incompatible': !compatibleWithCurrentField,
}),
'data-test-subj': `lns-indexPatternDimension${
compatibleWithCurrentField ? '' : 'Incompatible'
@@ -188,246 +182,193 @@ export function PopoverEditor(props: PopoverEditorProps) {
}
return (
- {
- setPopoverOpen(!isPopoverOpen);
+
+
+
+ {
+ setState(
+ deleteColumn({
+ state,
+ layerId,
+ columnId,
+ })
+ );
}}
- data-test-subj="indexPattern-configure-dimension"
- aria-label={i18n.translate('xpack.lens.configure.editConfig', {
- defaultMessage: 'Edit configuration',
- })}
- title={i18n.translate('xpack.lens.configure.editConfig', {
- defaultMessage: 'Edit configuration',
- })}
- >
- {uniqueLabel}
-
- ) : (
- <>
- setPopoverOpen(!isPopoverOpen)}
- size="xs"
- >
-
-
- >
- )
- }
- isOpen={isPopoverOpen}
- closePopover={() => {
- setPopoverOpen(false);
- setInvalidOperationType(null);
- }}
- anchorPosition="leftUp"
- withTitle
- panelPaddingSize="s"
- >
- {isPopoverOpen && (
-
-
- {
- setState(
- deleteColumn({
- state,
- layerId,
- columnId,
- })
- );
- }}
- onChoose={choice => {
- let column: IndexPatternColumn;
- if (
- !incompatibleSelectedOperationType &&
- selectedColumn &&
- 'field' in choice &&
- choice.operationType === selectedColumn.operationType
- ) {
- // If we just changed the field are not in an error state and the operation didn't change,
- // we use the operations onFieldChange method to calculate the new column.
- column = changeField(selectedColumn, currentIndexPattern, fieldMap[choice.field]);
- } else {
- // Otherwise we'll use the buildColumn method to calculate a new column
- const compatibleOperations =
- ('field' in choice &&
- operationFieldSupportMatrix.operationByField[choice.field]) ||
- [];
- let operation;
- if (compatibleOperations.length > 0) {
- operation =
- incompatibleSelectedOperationType &&
- compatibleOperations.includes(incompatibleSelectedOperationType)
- ? incompatibleSelectedOperationType
- : compatibleOperations[0];
- } else if ('field' in choice) {
- operation = choice.operationType;
- }
- column = buildColumn({
- columns: props.state.layers[props.layerId].columns,
- field: fieldMap[choice.field],
- indexPattern: currentIndexPattern,
- layerId: props.layerId,
- suggestedPriority: props.suggestedPriority,
- op: operation as OperationType,
- previousColumn: selectedColumn,
- });
+ onChoose={choice => {
+ let column: IndexPatternColumn;
+ if (
+ !incompatibleSelectedOperationType &&
+ selectedColumn &&
+ 'field' in choice &&
+ choice.operationType === selectedColumn.operationType
+ ) {
+ // If we just changed the field are not in an error state and the operation didn't change,
+ // we use the operations onFieldChange method to calculate the new column.
+ column = changeField(selectedColumn, currentIndexPattern, fieldMap[choice.field]);
+ } else {
+ // Otherwise we'll use the buildColumn method to calculate a new column
+ const compatibleOperations =
+ ('field' in choice &&
+ operationFieldSupportMatrix.operationByField[choice.field]) ||
+ [];
+ let operation;
+ if (compatibleOperations.length > 0) {
+ operation =
+ incompatibleSelectedOperationType &&
+ compatibleOperations.includes(incompatibleSelectedOperationType)
+ ? incompatibleSelectedOperationType
+ : compatibleOperations[0];
+ } else if ('field' in choice) {
+ operation = choice.operationType;
}
+ column = buildColumn({
+ columns: props.state.layers[props.layerId].columns,
+ field: fieldMap[choice.field],
+ indexPattern: currentIndexPattern,
+ layerId: props.layerId,
+ suggestedPriority: props.suggestedPriority,
+ op: operation as OperationType,
+ previousColumn: selectedColumn,
+ });
+ }
- setState(
- changeColumn({
- state,
- layerId,
- columnId,
- newColumn: column,
- keepParams: false,
- })
- );
- setInvalidOperationType(null);
- }}
- />
-
-
-
-
-
-
-
- {incompatibleSelectedOperationType && selectedColumn && (
-
- )}
- {incompatibleSelectedOperationType && !selectedColumn && (
-
- )}
- {!incompatibleSelectedOperationType && ParamEditor && (
- <>
-
-
- >
- )}
- {!incompatibleSelectedOperationType && selectedColumn && (
-
- {
- setState(
- changeColumn({
- state,
- layerId,
- columnId,
- newColumn: {
- ...selectedColumn,
- label: e.target.value,
- },
- })
- );
- }}
- />
-
- )}
-
- {!hideGrouping && (
- {
- setState({
- ...state,
- layers: {
- ...state.layers,
- [props.layerId]: {
- ...state.layers[props.layerId],
- columnOrder,
- },
- },
- });
- }}
+ setState(
+ changeColumn({
+ state,
+ layerId,
+ columnId,
+ newColumn: column,
+ keepParams: false,
+ })
+ );
+ setInvalidOperationType(null);
+ }}
+ />
+
+
+
+
+
+
+
+ {incompatibleSelectedOperationType && selectedColumn && (
+
+ )}
+ {incompatibleSelectedOperationType && !selectedColumn && (
+
+ )}
+ {!incompatibleSelectedOperationType && ParamEditor && (
+ <>
+
- )}
-
- {selectedColumn && selectedColumn.dataType === 'number' ? (
- {
+
+ >
+ )}
+ {!incompatibleSelectedOperationType && selectedColumn && (
+
+ {
setState(
- updateColumnParam({
+ changeColumn({
state,
layerId,
- currentColumn: selectedColumn,
- paramName: 'format',
- value: newFormat,
+ columnId,
+ newColumn: {
+ ...selectedColumn,
+ label: e.target.value,
+ },
})
);
}}
/>
- ) : null}
-
-
-
-
- )}
-
+
+ )}
+
+ {!hideGrouping && (
+ {
+ setState({
+ ...state,
+ layers: {
+ ...state.layers,
+ [props.layerId]: {
+ ...state.layers[props.layerId],
+ columnOrder,
+ },
+ },
+ });
+ }}
+ />
+ )}
+
+ {selectedColumn && selectedColumn.dataType === 'number' ? (
+ {
+ setState(
+ updateColumnParam({
+ state,
+ layerId,
+ currentColumn: selectedColumn,
+ paramName: 'format',
+ value: newFormat,
+ })
+ );
+ }}
+ />
+ ) : null}
+
+
+
+
+
);
}
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts
index 25121eec30f2a..76e59a170a9e9 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts
@@ -408,7 +408,6 @@ describe('IndexPattern Data Source', () => {
const initialState = stateFromPersistedState(persistedState);
publicAPI = indexPatternDatasource.getPublicAPI({
state: initialState,
- setState: () => {},
layerId: 'first',
dateRange: {
fromDate: 'now-30d',
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx
index 00f52d6a1747f..9c2a9c9bf4a09 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/indexpattern.tsx
@@ -12,7 +12,8 @@ import { CoreStart } from 'src/core/public';
import { i18n } from '@kbn/i18n';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import {
- DatasourceDimensionPanelProps,
+ DatasourceDimensionEditorProps,
+ DatasourceDimensionTriggerProps,
DatasourceDataPanelProps,
Operation,
DatasourceLayerPanelProps,
@@ -20,7 +21,12 @@ import {
} from '../types';
import { loadInitialState, changeIndexPattern, changeLayerIndexPattern } from './loader';
import { toExpression } from './to_expression';
-import { IndexPatternDimensionPanel } from './dimension_panel';
+import {
+ IndexPatternDimensionTrigger,
+ IndexPatternDimensionEditor,
+ canHandleDrop,
+ onDrop,
+} from './dimension_panel';
import { IndexPatternDataPanel } from './datapanel';
import {
getDatasourceSuggestionsForField,
@@ -38,6 +44,7 @@ import {
} from './types';
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
import { Plugin as DataPlugin } from '../../../../../../src/plugins/data/public';
+import { deleteColumn } from './state_helpers';
import { Datasource, StateSetter } from '..';
export { OperationType, IndexPatternColumn } from './operations';
@@ -80,6 +87,9 @@ export function uniqueLabels(layers: Record) {
};
Object.values(layers).forEach(layer => {
+ if (!layer.columns) {
+ return;
+ }
Object.entries(layer.columns).forEach(([columnId, column]) => {
columnLabelMap[columnId] = makeUnique(column.label);
});
@@ -156,6 +166,14 @@ export function getIndexPatternDatasource({
return Object.keys(state.layers);
},
+ removeColumn({ prevState, layerId, columnId }) {
+ return deleteColumn({
+ state: prevState,
+ layerId,
+ columnId,
+ });
+ },
+
toExpression,
getMetaData(state: IndexPatternPrivateState) {
@@ -198,15 +216,97 @@ export function getIndexPatternDatasource({
);
},
- getPublicAPI({
- state,
- setState,
- layerId,
- dateRange,
- }: PublicAPIProps) {
+ renderDimensionTrigger: (
+ domElement: Element,
+ props: DatasourceDimensionTriggerProps
+ ) => {
+ const columnLabelMap = uniqueLabels(props.state.layers);
+
+ render(
+
+
+
+
+ ,
+ domElement
+ );
+ },
+
+ renderDimensionEditor: (
+ domElement: Element,
+ props: DatasourceDimensionEditorProps
+ ) => {
+ const columnLabelMap = uniqueLabels(props.state.layers);
+
+ render(
+
+
+
+
+ ,
+ domElement
+ );
+ },
+
+ renderLayerPanel: (
+ domElement: Element,
+ props: DatasourceLayerPanelProps
+ ) => {
+ render(
+ {
+ changeLayerIndexPattern({
+ savedObjectsClient,
+ indexPatternId,
+ setState: props.setState,
+ state: props.state,
+ layerId: props.layerId,
+ onError: onIndexPatternLoadError,
+ replaceIfPossible: true,
+ });
+ }}
+ {...props}
+ />,
+ domElement
+ );
+ },
+
+ canHandleDrop,
+ onDrop,
+
+ getPublicAPI({ state, layerId }: PublicAPIProps) {
const columnLabelMap = uniqueLabels(state.layers);
return {
+ datasourceId: 'indexpattern',
+
getTableSpec: () => {
return state.layers[layerId].columnOrder.map(colId => ({ columnId: colId }));
},
@@ -218,58 +318,6 @@ export function getIndexPatternDatasource({
}
return null;
},
- renderDimensionPanel: (domElement: Element, props: DatasourceDimensionPanelProps) => {
- render(
-
-
-
-
- ,
- domElement
- );
- },
-
- renderLayerPanel: (domElement: Element, props: DatasourceLayerPanelProps) => {
- render(
- {
- changeLayerIndexPattern({
- savedObjectsClient,
- indexPatternId,
- setState,
- state,
- layerId: props.layerId,
- onError: onIndexPatternLoadError,
- replaceIfPossible: true,
- });
- }}
- {...props}
- />,
- domElement
- );
- },
};
},
getDatasourceSuggestionsForField(state, draggedField) {
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx
index af7afb9cf9342..219a6d935e436 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx
@@ -178,6 +178,7 @@ describe('Layer Data Panel', () => {
defaultProps = {
layerId: 'first',
state: initialState,
+ setState: jest.fn(),
onChangeIndexPattern: jest.fn(async () => {}),
};
});
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.tsx
index ae346ecc72cbc..eea00d52a77f9 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_datasource/layerpanel.tsx
@@ -11,7 +11,8 @@ import { DatasourceLayerPanelProps } from '../types';
import { IndexPatternPrivateState } from './types';
import { ChangeIndexPattern } from './change_indexpattern';
-export interface IndexPatternLayerPanelProps extends DatasourceLayerPanelProps {
+export interface IndexPatternLayerPanelProps
+ extends DatasourceLayerPanelProps {
state: IndexPatternPrivateState;
onChangeIndexPattern: (newId: string) => void;
}
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.test.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.test.tsx
deleted file mode 100644
index eac35f82a50fa..0000000000000
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.test.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import { ReactWrapper } from 'enzyme';
-import { mountWithIntl as mount } from 'test_utils/enzyme_helpers';
-import { MetricConfigPanel } from './metric_config_panel';
-import { DatasourceDimensionPanelProps, Operation, DatasourcePublicAPI } from '../types';
-import { State } from './types';
-import { NativeRendererProps } from '../native_renderer';
-import { createMockFramePublicAPI, createMockDatasource } from '../editor_frame_service/mocks';
-
-describe('MetricConfigPanel', () => {
- const dragDropContext = { dragging: undefined, setDragging: jest.fn() };
-
- function mockDatasource(): DatasourcePublicAPI {
- return createMockDatasource().publicAPIMock;
- }
-
- function testState(): State {
- return {
- accessor: 'foo',
- layerId: 'bar',
- };
- }
-
- function testSubj(component: ReactWrapper, subj: string) {
- return component
- .find(`[data-test-subj="${subj}"]`)
- .first()
- .props();
- }
-
- test('the value dimension panel only accepts singular numeric operations', () => {
- const state = testState();
- const component = mount(
-
- );
-
- const panel = testSubj(component, 'lns_metric_valueDimensionPanel');
- const nativeProps = (panel as NativeRendererProps).nativeProps;
- const { columnId, filterOperations } = nativeProps;
- const exampleOperation: Operation = {
- dataType: 'number',
- isBucketed: false,
- label: 'bar',
- };
- const ops: Operation[] = [
- { ...exampleOperation, dataType: 'number' },
- { ...exampleOperation, dataType: 'string' },
- { ...exampleOperation, dataType: 'boolean' },
- { ...exampleOperation, dataType: 'date' },
- ];
- expect(columnId).toEqual('shazm');
- expect(ops.filter(filterOperations)).toEqual([{ ...exampleOperation, dataType: 'number' }]);
- });
-});
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.tsx
deleted file mode 100644
index 16e24f247fb68..0000000000000
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_config_panel.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { EuiFormRow } from '@elastic/eui';
-import { State } from './types';
-import { VisualizationLayerConfigProps, OperationMetadata } from '../types';
-import { NativeRenderer } from '../native_renderer';
-
-const isMetric = (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number';
-
-export function MetricConfigPanel(props: VisualizationLayerConfigProps) {
- const { state, frame, layerId } = props;
- const datasource = frame.datasourceLayers[layerId];
-
- return (
-
-
-
- );
-}
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx
index 66ed963002f59..4d979a766cd2b 100644
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx
+++ b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_expression.tsx
@@ -91,6 +91,11 @@ export function MetricChart({
const { title, accessor, mode } = args;
let value = '-';
const firstTable = Object.values(data.tables)[0];
+ if (!accessor) {
+ return (
+
+ );
+ }
if (firstTable) {
const column = firstTable.columns[0];
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts
index 88964b95c2ac7..276f24433c670 100644
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts
+++ b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.test.ts
@@ -24,8 +24,8 @@ function mockFrame(): FramePublicAPI {
...createMockFramePublicAPI(),
addNewLayer: () => 'l42',
datasourceLayers: {
- l1: createMockDatasource().publicAPIMock,
- l42: createMockDatasource().publicAPIMock,
+ l1: createMockDatasource('l1').publicAPIMock,
+ l42: createMockDatasource('l42').publicAPIMock,
},
};
}
@@ -36,10 +36,10 @@ describe('metric_visualization', () => {
(generateId as jest.Mock).mockReturnValueOnce('test-id1');
const initialState = metricVisualization.initialize(mockFrame());
- expect(initialState.accessor).toBeDefined();
+ expect(initialState.accessor).not.toBeDefined();
expect(initialState).toMatchInlineSnapshot(`
Object {
- "accessor": "test-id1",
+ "accessor": undefined,
"layerId": "l42",
}
`);
@@ -60,7 +60,7 @@ describe('metric_visualization', () => {
it('returns a clean layer', () => {
(generateId as jest.Mock).mockReturnValueOnce('test-id1');
expect(metricVisualization.clearLayer(exampleState(), 'l1')).toEqual({
- accessor: 'test-id1',
+ accessor: undefined,
layerId: 'l1',
});
});
@@ -72,10 +72,47 @@ describe('metric_visualization', () => {
});
});
+ describe('#setDimension', () => {
+ it('sets the accessor', () => {
+ expect(
+ metricVisualization.setDimension({
+ prevState: {
+ accessor: undefined,
+ layerId: 'l1',
+ },
+ layerId: 'l1',
+ groupId: '',
+ columnId: 'newDimension',
+ })
+ ).toEqual({
+ accessor: 'newDimension',
+ layerId: 'l1',
+ });
+ });
+ });
+
+ describe('#removeDimension', () => {
+ it('removes the accessor', () => {
+ expect(
+ metricVisualization.removeDimension({
+ prevState: {
+ accessor: 'a',
+ layerId: 'l1',
+ },
+ layerId: 'l1',
+ columnId: 'a',
+ })
+ ).toEqual({
+ accessor: undefined,
+ layerId: 'l1',
+ });
+ });
+ });
+
describe('#toExpression', () => {
it('should map to a valid AST', () => {
const datasource: DatasourcePublicAPI = {
- ...createMockDatasource().publicAPIMock,
+ ...createMockDatasource('l1').publicAPIMock,
getOperationForColumnId(_: string) {
return {
id: 'a',
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.tsx
index 6714c05787837..44256df5aed6d 100644
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.tsx
+++ b/x-pack/legacy/plugins/lens/public/metric_visualization/metric_visualization.tsx
@@ -4,23 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
-import { render } from 'react-dom';
-import { I18nProvider } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { Ast } from '@kbn/interpreter/target/common';
import { getSuggestions } from './metric_suggestions';
-import { MetricConfigPanel } from './metric_config_panel';
-import { Visualization, FramePublicAPI } from '../types';
+import { Visualization, FramePublicAPI, OperationMetadata } from '../types';
import { State, PersistableState } from './types';
-import { generateId } from '../id_generator';
import chartMetricSVG from '../assets/chart_metric.svg';
const toExpression = (
state: State,
frame: FramePublicAPI,
mode: 'reduced' | 'full' = 'full'
-): Ast => {
+): Ast | null => {
+ if (!state.accessor) {
+ return null;
+ }
+
const [datasource] = Object.values(frame.datasourceLayers);
const operation = datasource && datasource.getOperationForColumnId(state.accessor);
@@ -57,7 +56,7 @@ export const metricVisualization: Visualization = {
clearLayer(state) {
return {
...state,
- accessor: generateId(),
+ accessor: undefined,
};
},
@@ -80,22 +79,37 @@ export const metricVisualization: Visualization = {
return (
state || {
layerId: frame.addNewLayer(),
- accessor: generateId(),
+ accessor: undefined,
}
);
},
getPersistableState: state => state,
- renderLayerConfigPanel: (domElement, props) =>
- render(
-
-
- ,
- domElement
- ),
+ getConfiguration(props) {
+ return {
+ groups: [
+ {
+ groupId: 'metric',
+ groupLabel: i18n.translate('xpack.lens.metric.label', { defaultMessage: 'Metric' }),
+ layerId: props.state.layerId,
+ accessors: props.state.accessor ? [props.state.accessor] : [],
+ supportsMoreColumns: false,
+ filterOperations: (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number',
+ },
+ ],
+ };
+ },
toExpression,
toPreviewExpression: (state: State, frame: FramePublicAPI) =>
toExpression(state, frame, 'reduced'),
+
+ setDimension({ prevState, columnId }) {
+ return { ...prevState, accessor: columnId };
+ },
+
+ removeDimension({ prevState }) {
+ return { ...prevState, accessor: undefined };
+ },
};
diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization/types.ts b/x-pack/legacy/plugins/lens/public/metric_visualization/types.ts
index 6348d80b15e2f..53fc103934255 100644
--- a/x-pack/legacy/plugins/lens/public/metric_visualization/types.ts
+++ b/x-pack/legacy/plugins/lens/public/metric_visualization/types.ts
@@ -6,7 +6,7 @@
export interface State {
layerId: string;
- accessor: string;
+ accessor?: string;
}
export interface MetricConfig extends State {
diff --git a/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.test.tsx b/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.test.tsx
deleted file mode 100644
index 38f48c9cdaf72..0000000000000
--- a/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.test.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import { createMockDatasource } from '../editor_frame_service/mocks';
-import { MultiColumnEditor } from './multi_column_editor';
-import { mount } from 'enzyme';
-
-jest.useFakeTimers();
-
-describe('MultiColumnEditor', () => {
- it('should add a trailing accessor if the accessor list is empty', () => {
- const onAdd = jest.fn();
- mount(
- true}
- layerId="foo"
- onAdd={onAdd}
- onRemove={jest.fn()}
- testSubj="bar"
- />
- );
-
- expect(onAdd).toHaveBeenCalledTimes(0);
-
- jest.runAllTimers();
-
- expect(onAdd).toHaveBeenCalledTimes(1);
- });
-
- it('should add a trailing accessor if the last accessor is configured', () => {
- const onAdd = jest.fn();
- mount(
- true}
- layerId="foo"
- onAdd={onAdd}
- onRemove={jest.fn()}
- testSubj="bar"
- />
- );
-
- expect(onAdd).toHaveBeenCalledTimes(0);
-
- jest.runAllTimers();
-
- expect(onAdd).toHaveBeenCalledTimes(1);
- });
-});
diff --git a/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.tsx b/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.tsx
deleted file mode 100644
index 422f1dcf60f3c..0000000000000
--- a/x-pack/legacy/plugins/lens/public/multi_column_editor/multi_column_editor.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React, { useEffect } from 'react';
-import { NativeRenderer } from '../native_renderer';
-import { DatasourcePublicAPI, OperationMetadata } from '../types';
-import { DragContextState } from '../drag_drop';
-
-interface Props {
- accessors: string[];
- datasource: DatasourcePublicAPI;
- dragDropContext: DragContextState;
- onRemove: (accessor: string) => void;
- onAdd: () => void;
- filterOperations: (op: OperationMetadata) => boolean;
- suggestedPriority?: 0 | 1 | 2 | undefined;
- testSubj: string;
- layerId: string;
-}
-
-export function MultiColumnEditor({
- accessors,
- datasource,
- dragDropContext,
- onRemove,
- onAdd,
- filterOperations,
- suggestedPriority,
- testSubj,
- layerId,
-}: Props) {
- const lastOperation = datasource.getOperationForColumnId(accessors[accessors.length - 1]);
-
- useEffect(() => {
- if (accessors.length === 0 || lastOperation !== null) {
- setTimeout(onAdd);
- }
- }, [lastOperation]);
-
- return (
- <>
- {accessors.map(accessor => (
-
-
-
- ))}
- >
- );
-}
diff --git a/x-pack/legacy/plugins/lens/public/plugin.tsx b/x-pack/legacy/plugins/lens/public/plugin.tsx
index cc029fee49d1d..c74653c70703c 100644
--- a/x-pack/legacy/plugins/lens/public/plugin.tsx
+++ b/x-pack/legacy/plugins/lens/public/plugin.tsx
@@ -114,7 +114,7 @@ export class LensPlugin {
const savedObjectsClient = coreStart.savedObjects.client;
addHelpMenuToAppChrome(coreStart.chrome);
- const instance = await this.createEditorFrame!({});
+ const instance = await this.createEditorFrame!();
setReportManager(
new LensReportManager({
diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts
index b7983eeb8dbb8..c897979b06cfb 100644
--- a/x-pack/legacy/plugins/lens/public/types.ts
+++ b/x-pack/legacy/plugins/lens/public/types.ts
@@ -13,14 +13,10 @@ import { Document } from './persistence';
import { DateRange } from '../../../../plugins/lens/common';
import { Query, Filter, SavedQuery } from '../../../../../src/plugins/data/public';
-// eslint-disable-next-line
-export interface EditorFrameOptions {}
-
export type ErrorCallback = (e: { message: string }) => void;
export interface PublicAPIProps {
state: T;
- setState: StateSetter;
layerId: string;
dateRange: DateRange;
}
@@ -34,6 +30,7 @@ export interface EditorFrameProps {
savedQuery?: SavedQuery;
// Frame loader (app or embeddable) is expected to call this when it loads and updates
+ // This should be replaced with a top-down state
onChange: (newState: {
filterableIndexPatterns: DatasourceMetaData['filterableIndexPatterns'];
doc: Document;
@@ -53,7 +50,7 @@ export interface EditorFrameSetup {
}
export interface EditorFrameStart {
- createInstance: (options: EditorFrameOptions) => Promise;
+ createInstance: () => Promise;
}
// Hints the default nesting to the data source. 0 is the highest priority
@@ -138,8 +135,14 @@ export interface Datasource {
removeLayer: (state: T, layerId: string) => T;
clearLayer: (state: T, layerId: string) => T;
getLayers: (state: T) => string[];
+ removeColumn: (props: { prevState: T; layerId: string; columnId: string }) => T;
renderDataPanel: (domElement: Element, props: DatasourceDataPanelProps) => void;
+ renderDimensionTrigger: (domElement: Element, props: DatasourceDimensionTriggerProps) => void;
+ renderDimensionEditor: (domElement: Element, props: DatasourceDimensionEditorProps) => void;
+ renderLayerPanel: (domElement: Element, props: DatasourceLayerPanelProps) => void;
+ canHandleDrop: (props: DatasourceDimensionDropProps) => boolean;
+ onDrop: (props: DatasourceDimensionDropHandlerProps) => boolean;
toExpression: (state: T, layerId: string) => Ast | string | null;
@@ -155,22 +158,11 @@ export interface Datasource {
* This is an API provided to visualizations by the frame, which calls the publicAPI on the datasource
*/
export interface DatasourcePublicAPI {
- getTableSpec: () => TableSpec;
+ datasourceId: string;
+ getTableSpec: () => Array<{ columnId: string }>;
getOperationForColumnId: (columnId: string) => Operation | null;
-
- // Render can be called many times
- renderDimensionPanel: (domElement: Element, props: DatasourceDimensionPanelProps) => void;
- renderLayerPanel: (domElement: Element, props: DatasourceLayerPanelProps) => void;
}
-export interface TableSpecColumn {
- // Column IDs are the keys for internal state in data sources and visualizations
- columnId: string;
-}
-
-// TableSpec is managed by visualizations
-export type TableSpec = TableSpecColumn[];
-
export interface DatasourceDataPanelProps {
state: T;
dragDropContext: DragContextState;
@@ -181,31 +173,61 @@ export interface DatasourceDataPanelProps {
filters: Filter[];
}
-// The only way a visualization has to restrict the query building
-export interface DatasourceDimensionPanelProps {
- layerId: string;
- columnId: string;
-
- dragDropContext: DragContextState;
-
- // Visualizations can restrict operations based on their own rules
+interface SharedDimensionProps {
+ /** Visualizations can restrict operations based on their own rules.
+ * For example, limiting to only bucketed or only numeric operations.
+ */
filterOperations: (operation: OperationMetadata) => boolean;
- // Visualizations can hint at the role this dimension would play, which
- // affects the default ordering of the query
+ /** Visualizations can hint at the role this dimension would play, which
+ * affects the default ordering of the query
+ */
suggestedPriority?: DimensionPriority;
- onRemove?: (accessor: string) => void;
- // Some dimension editors will allow users to change the operation grouping
- // from the panel, and this lets the visualization hint that it doesn't want
- // users to have that level of control
+ /** Some dimension editors will allow users to change the operation grouping
+ * from the panel, and this lets the visualization hint that it doesn't want
+ * users to have that level of control
+ */
hideGrouping?: boolean;
}
-export interface DatasourceLayerPanelProps {
+export type DatasourceDimensionProps = SharedDimensionProps & {
layerId: string;
+ columnId: string;
+ onRemove?: (accessor: string) => void;
+ state: T;
+};
+
+// The only way a visualization has to restrict the query building
+export type DatasourceDimensionEditorProps = DatasourceDimensionProps & {
+ setState: StateSetter;
+ core: Pick;
+ dateRange: DateRange;
+};
+
+export type DatasourceDimensionTriggerProps = DatasourceDimensionProps & {
+ dragDropContext: DragContextState;
+ togglePopover: () => void;
+};
+
+export interface DatasourceLayerPanelProps {
+ layerId: string;
+ state: T;
+ setState: StateSetter;
}
+export type DatasourceDimensionDropProps = SharedDimensionProps & {
+ layerId: string;
+ columnId: string;
+ state: T;
+ setState: StateSetter;
+ dragDropContext: DragContextState;
+};
+
+export type DatasourceDimensionDropHandlerProps = DatasourceDimensionDropProps & {
+ droppedItem: unknown;
+};
+
export type DataType = 'document' | 'string' | 'number' | 'date' | 'boolean' | 'ip';
// An operation represents a column in a table, not any information
@@ -239,12 +261,32 @@ export interface LensMultiTable {
};
}
-export interface VisualizationLayerConfigProps {
+export interface VisualizationConfigProps {
layerId: string;
- dragDropContext: DragContextState;
frame: FramePublicAPI;
state: T;
+}
+
+export type VisualizationLayerWidgetProps = VisualizationConfigProps & {
setState: (newState: T) => void;
+};
+
+type VisualizationDimensionGroupConfig = SharedDimensionProps & {
+ groupLabel: string;
+
+ /** ID is passed back to visualization. For example, `x` */
+ groupId: string;
+ accessors: string[];
+ supportsMoreColumns: boolean;
+ /** If required, a warning will appear if accessors are empty */
+ required?: boolean;
+ dataTestSubj?: string;
+};
+
+interface VisualizationDimensionChangeProps {
+ layerId: string;
+ columnId: string;
+ prevState: T;
}
/**
@@ -329,16 +371,18 @@ export interface Visualization {
visualizationTypes: VisualizationType[];
getLayerIds: (state: T) => string[];
-
clearLayer: (state: T, layerId: string) => T;
-
removeLayer?: (state: T, layerId: string) => T;
-
appendLayer?: (state: T, layerId: string) => T;
+ // Layer context menu is used by visualizations for styling the entire layer
+ // For example, the XY visualization uses this to have multiple chart types
getLayerContextMenuIcon?: (opts: { state: T; layerId: string }) => IconType | undefined;
+ renderLayerContextMenu?: (domElement: Element, props: VisualizationLayerWidgetProps) => void;
- renderLayerContextMenu?: (domElement: Element, props: VisualizationLayerConfigProps) => void;
+ getConfiguration: (
+ props: VisualizationConfigProps
+ ) => { groups: VisualizationDimensionGroupConfig[] };
getDescription: (
state: T
@@ -354,7 +398,13 @@ export interface Visualization {
getPersistableState: (state: T) => P;
- renderLayerConfigPanel: (domElement: Element, props: VisualizationLayerConfigProps) => void;
+ // Actions triggered by the frame which tell the datasource that a dimension is being changed
+ setDimension: (
+ props: VisualizationDimensionChangeProps & {
+ groupId: string;
+ }
+ ) => T;
+ removeDimension: (props: VisualizationDimensionChangeProps) => T;
toExpression: (state: T, frame: FramePublicAPI) => Ast | string | null;
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_visualization.test.ts.snap b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap
similarity index 96%
rename from x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_visualization.test.ts.snap
rename to x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap
index 76af8328673ad..6b68679bfd4ec 100644
--- a/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/xy_visualization.test.ts.snap
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/__snapshots__/to_expression.test.ts.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`xy_visualization #toExpression should map to a valid AST 1`] = `
+exports[`#toExpression should map to a valid AST 1`] = `
Object {
"chain": Array [
Object {
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.test.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.test.ts
new file mode 100644
index 0000000000000..6bc379ea33bca
--- /dev/null
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.test.ts
@@ -0,0 +1,133 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { Ast } from '@kbn/interpreter/target/common';
+import { Position } from '@elastic/charts';
+import { xyVisualization } from './xy_visualization';
+import { Operation } from '../types';
+import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks';
+
+describe('#toExpression', () => {
+ let mockDatasource: ReturnType;
+ let frame: ReturnType;
+
+ beforeEach(() => {
+ frame = createMockFramePublicAPI();
+ mockDatasource = createMockDatasource('testDatasource');
+
+ mockDatasource.publicAPIMock.getTableSpec.mockReturnValue([
+ { columnId: 'd' },
+ { columnId: 'a' },
+ { columnId: 'b' },
+ { columnId: 'c' },
+ ]);
+
+ mockDatasource.publicAPIMock.getOperationForColumnId.mockImplementation(col => {
+ return { label: `col_${col}`, dataType: 'number' } as Operation;
+ });
+
+ frame.datasourceLayers = {
+ first: mockDatasource.publicAPIMock,
+ };
+ });
+
+ it('should map to a valid AST', () => {
+ expect(
+ xyVisualization.toExpression(
+ {
+ legend: { position: Position.Bottom, isVisible: true },
+ preferredSeriesType: 'bar',
+ layers: [
+ {
+ layerId: 'first',
+ seriesType: 'area',
+ splitAccessor: 'd',
+ xAccessor: 'a',
+ accessors: ['b', 'c'],
+ },
+ ],
+ },
+ frame
+ )
+ ).toMatchSnapshot();
+ });
+
+ it('should not generate an expression when missing x', () => {
+ expect(
+ xyVisualization.toExpression(
+ {
+ legend: { position: Position.Bottom, isVisible: true },
+ preferredSeriesType: 'bar',
+ layers: [
+ {
+ layerId: 'first',
+ seriesType: 'area',
+ splitAccessor: undefined,
+ xAccessor: undefined,
+ accessors: ['a'],
+ },
+ ],
+ },
+ frame
+ )
+ ).toBeNull();
+ });
+
+ it('should not generate an expression when missing y', () => {
+ expect(
+ xyVisualization.toExpression(
+ {
+ legend: { position: Position.Bottom, isVisible: true },
+ preferredSeriesType: 'bar',
+ layers: [
+ {
+ layerId: 'first',
+ seriesType: 'area',
+ splitAccessor: undefined,
+ xAccessor: 'a',
+ accessors: [],
+ },
+ ],
+ },
+ frame
+ )
+ ).toBeNull();
+ });
+
+ it('should default to labeling all columns with their column label', () => {
+ const expression = xyVisualization.toExpression(
+ {
+ legend: { position: Position.Bottom, isVisible: true },
+ preferredSeriesType: 'bar',
+ layers: [
+ {
+ layerId: 'first',
+ seriesType: 'area',
+ splitAccessor: 'd',
+ xAccessor: 'a',
+ accessors: ['b', 'c'],
+ },
+ ],
+ },
+ frame
+ )! as Ast;
+
+ expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('b');
+ expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('c');
+ expect(mockDatasource.publicAPIMock.getOperationForColumnId).toHaveBeenCalledWith('d');
+ expect(expression.chain[0].arguments.xTitle).toEqual(['col_a']);
+ expect(expression.chain[0].arguments.yTitle).toEqual(['col_b']);
+ expect(
+ (expression.chain[0].arguments.layers[0] as Ast).chain[0].arguments.columnToLabel
+ ).toEqual([
+ JSON.stringify({
+ b: 'col_b',
+ c: 'col_c',
+ d: 'col_d',
+ }),
+ ]);
+ });
+});
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts
index f0e932d14f281..9b068b0ca5ef0 100644
--- a/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/to_expression.ts
@@ -9,6 +9,10 @@ import { ScaleType } from '@elastic/charts';
import { State, LayerConfig } from './types';
import { FramePublicAPI, OperationMetadata } from '../types';
+interface ValidLayer extends LayerConfig {
+ xAccessor: NonNullable;
+}
+
function xyTitles(layer: LayerConfig, frame: FramePublicAPI) {
const defaults = {
xTitle: 'x',
@@ -22,8 +26,8 @@ function xyTitles(layer: LayerConfig, frame: FramePublicAPI) {
if (!datasource) {
return defaults;
}
- const x = datasource.getOperationForColumnId(layer.xAccessor);
- const y = datasource.getOperationForColumnId(layer.accessors[0]);
+ const x = layer.xAccessor ? datasource.getOperationForColumnId(layer.xAccessor) : null;
+ const y = layer.accessors[0] ? datasource.getOperationForColumnId(layer.accessors[0]) : null;
return {
xTitle: x ? x.label : defaults.xTitle,
@@ -36,26 +40,6 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null =>
return null;
}
- const stateWithValidAccessors = {
- ...state,
- layers: state.layers.map(layer => {
- const datasource = frame.datasourceLayers[layer.layerId];
-
- const newLayer = { ...layer };
-
- if (!datasource.getOperationForColumnId(layer.splitAccessor)) {
- delete newLayer.splitAccessor;
- }
-
- return {
- ...newLayer,
- accessors: layer.accessors.filter(accessor =>
- Boolean(datasource.getOperationForColumnId(accessor))
- ),
- };
- }),
- };
-
const metadata: Record> = {};
state.layers.forEach(layer => {
metadata[layer.layerId] = {};
@@ -68,12 +52,7 @@ export const toExpression = (state: State, frame: FramePublicAPI): Ast | null =>
});
});
- return buildExpression(
- stateWithValidAccessors,
- metadata,
- frame,
- xyTitles(state.layers[0], frame)
- );
+ return buildExpression(state, metadata, frame, xyTitles(state.layers[0], frame));
};
export function toPreviewExpression(state: State, frame: FramePublicAPI) {
@@ -122,82 +101,94 @@ export const buildExpression = (
metadata: Record>,
frame?: FramePublicAPI,
{ xTitle, yTitle }: { xTitle: string; yTitle: string } = { xTitle: '', yTitle: '' }
-): Ast => ({
- type: 'expression',
- chain: [
- {
- type: 'function',
- function: 'lens_xy_chart',
- arguments: {
- xTitle: [xTitle],
- yTitle: [yTitle],
- legend: [
- {
- type: 'expression',
- chain: [
- {
- type: 'function',
- function: 'lens_xy_legendConfig',
- arguments: {
- isVisible: [state.legend.isVisible],
- position: [state.legend.position],
+): Ast | null => {
+ const validLayers = state.layers.filter((layer): layer is ValidLayer =>
+ Boolean(layer.xAccessor && layer.accessors.length)
+ );
+ if (!validLayers.length) {
+ return null;
+ }
+
+ return {
+ type: 'expression',
+ chain: [
+ {
+ type: 'function',
+ function: 'lens_xy_chart',
+ arguments: {
+ xTitle: [xTitle],
+ yTitle: [yTitle],
+ legend: [
+ {
+ type: 'expression',
+ chain: [
+ {
+ type: 'function',
+ function: 'lens_xy_legendConfig',
+ arguments: {
+ isVisible: [state.legend.isVisible],
+ position: [state.legend.position],
+ },
},
- },
- ],
- },
- ],
- layers: state.layers.map(layer => {
- const columnToLabel: Record = {};
-
- if (frame) {
- const datasource = frame.datasourceLayers[layer.layerId];
- layer.accessors.concat([layer.splitAccessor]).forEach(accessor => {
- const operation = datasource.getOperationForColumnId(accessor);
- if (operation && operation.label) {
- columnToLabel[accessor] = operation.label;
- }
- });
- }
-
- const xAxisOperation =
- frame && frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor);
-
- const isHistogramDimension = Boolean(
- xAxisOperation &&
- xAxisOperation.isBucketed &&
- xAxisOperation.scale &&
- xAxisOperation.scale !== 'ordinal'
- );
-
- return {
- type: 'expression',
- chain: [
- {
- type: 'function',
- function: 'lens_xy_layer',
- arguments: {
- layerId: [layer.layerId],
-
- hide: [Boolean(layer.hide)],
-
- xAccessor: [layer.xAccessor],
- yScaleType: [
- getScaleType(metadata[layer.layerId][layer.accessors[0]], ScaleType.Ordinal),
- ],
- xScaleType: [
- getScaleType(metadata[layer.layerId][layer.xAccessor], ScaleType.Linear),
- ],
- isHistogram: [isHistogramDimension],
- splitAccessor: [layer.splitAccessor],
- seriesType: [layer.seriesType],
- accessors: layer.accessors,
- columnToLabel: [JSON.stringify(columnToLabel)],
+ ],
+ },
+ ],
+ layers: validLayers.map(layer => {
+ const columnToLabel: Record = {};
+
+ if (frame) {
+ const datasource = frame.datasourceLayers[layer.layerId];
+ layer.accessors
+ .concat(layer.splitAccessor ? [layer.splitAccessor] : [])
+ .forEach(accessor => {
+ const operation = datasource.getOperationForColumnId(accessor);
+ if (operation && operation.label) {
+ columnToLabel[accessor] = operation.label;
+ }
+ });
+ }
+
+ const xAxisOperation =
+ frame &&
+ frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor);
+
+ const isHistogramDimension = Boolean(
+ xAxisOperation &&
+ xAxisOperation.isBucketed &&
+ xAxisOperation.scale &&
+ xAxisOperation.scale !== 'ordinal'
+ );
+
+ return {
+ type: 'expression',
+ chain: [
+ {
+ type: 'function',
+ function: 'lens_xy_layer',
+ arguments: {
+ layerId: [layer.layerId],
+
+ hide: [Boolean(layer.hide)],
+
+ xAccessor: [layer.xAccessor],
+ yScaleType: [
+ getScaleType(metadata[layer.layerId][layer.accessors[0]], ScaleType.Ordinal),
+ ],
+ xScaleType: [
+ getScaleType(metadata[layer.layerId][layer.xAccessor], ScaleType.Linear),
+ ],
+ isHistogram: [isHistogramDimension],
+ splitAccessor: layer.splitAccessor ? [layer.splitAccessor] : [],
+ seriesType: [layer.seriesType],
+ accessors: layer.accessors,
+ columnToLabel: [JSON.stringify(columnToLabel)],
+ },
},
- },
- ],
- };
- }),
+ ],
+ };
+ }),
+ },
},
- },
- ],
-});
+ ],
+ };
+};
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts
index b49e6fa6b4b6f..f7b4afc76ec4b 100644
--- a/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/types.ts
@@ -191,10 +191,10 @@ export type SeriesType =
export interface LayerConfig {
hide?: boolean;
layerId: string;
- xAccessor: string;
+ xAccessor?: string;
accessors: string[];
seriesType: SeriesType;
- splitAccessor: string;
+ splitAccessor?: string;
}
export type LayerArgs = LayerConfig & {
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx
index 301c4a58a0ffd..7544ed0f87b7d 100644
--- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.test.tsx
@@ -5,22 +5,15 @@
*/
import React from 'react';
-import { ReactWrapper } from 'enzyme';
import { mountWithIntl as mount } from 'test_utils/enzyme_helpers';
import { EuiButtonGroupProps } from '@elastic/eui';
-import { XYConfigPanel, LayerContextMenu } from './xy_config_panel';
-import { DatasourceDimensionPanelProps, Operation, FramePublicAPI } from '../types';
+import { LayerContextMenu } from './xy_config_panel';
+import { FramePublicAPI } from '../types';
import { State } from './types';
import { Position } from '@elastic/charts';
-import { NativeRendererProps } from '../native_renderer';
-import { generateId } from '../id_generator';
import { createMockFramePublicAPI, createMockDatasource } from '../editor_frame_service/mocks';
-jest.mock('../id_generator');
-
-describe('XYConfigPanel', () => {
- const dragDropContext = { dragging: undefined, setDragging: jest.fn() };
-
+describe('LayerContextMenu', () => {
let frame: FramePublicAPI;
function testState(): State {
@@ -39,17 +32,10 @@ describe('XYConfigPanel', () => {
};
}
- function testSubj(component: ReactWrapper, subj: string) {
- return component
- .find(`[data-test-subj="${subj}"]`)
- .first()
- .props();
- }
-
beforeEach(() => {
frame = createMockFramePublicAPI();
frame.datasourceLayers = {
- first: createMockDatasource().publicAPIMock,
+ first: createMockDatasource('test').publicAPIMock,
};
});
@@ -64,7 +50,6 @@ describe('XYConfigPanel', () => {
const component = mount(
{
const component = mount(
{
expect(options!.filter(({ isDisabled }) => isDisabled).map(({ id }) => id)).toEqual([]);
});
});
-
- test('the x dimension panel accepts only bucketed operations', () => {
- // TODO: this should eventually also accept raw operation
- const state = testState();
- const component = mount(
-
- );
-
- const panel = testSubj(component, 'lnsXY_xDimensionPanel');
- const nativeProps = (panel as NativeRendererProps).nativeProps;
- const { columnId, filterOperations } = nativeProps;
- const exampleOperation: Operation = {
- dataType: 'number',
- isBucketed: false,
- label: 'bar',
- };
- const bucketedOps: Operation[] = [
- { ...exampleOperation, isBucketed: true, dataType: 'number' },
- { ...exampleOperation, isBucketed: true, dataType: 'string' },
- { ...exampleOperation, isBucketed: true, dataType: 'boolean' },
- { ...exampleOperation, isBucketed: true, dataType: 'date' },
- ];
- const ops: Operation[] = [
- ...bucketedOps,
- { ...exampleOperation, dataType: 'number' },
- { ...exampleOperation, dataType: 'string' },
- { ...exampleOperation, dataType: 'boolean' },
- { ...exampleOperation, dataType: 'date' },
- ];
- expect(columnId).toEqual('shazm');
- expect(ops.filter(filterOperations)).toEqual(bucketedOps);
- });
-
- test('the y dimension panel accepts numeric operations', () => {
- const state = testState();
- const component = mount(
-
- );
-
- const filterOperations = component
- .find('[data-test-subj="lensXY_yDimensionPanel"]')
- .first()
- .prop('filterOperations') as (op: Operation) => boolean;
-
- const exampleOperation: Operation = {
- dataType: 'number',
- isBucketed: false,
- label: 'bar',
- };
- const ops: Operation[] = [
- { ...exampleOperation, dataType: 'number' },
- { ...exampleOperation, dataType: 'string' },
- { ...exampleOperation, dataType: 'boolean' },
- { ...exampleOperation, dataType: 'date' },
- ];
- expect(ops.filter(filterOperations).map(x => x.dataType)).toEqual(['number']);
- });
-
- test('allows removal of y dimensions', () => {
- const setState = jest.fn();
- const state = testState();
- const component = mount(
-
- );
-
- const onRemove = component
- .find('[data-test-subj="lensXY_yDimensionPanel"]')
- .first()
- .prop('onRemove') as (accessor: string) => {};
-
- onRemove('b');
-
- expect(setState).toHaveBeenCalledTimes(1);
- expect(setState.mock.calls[0][0]).toMatchObject({
- layers: [
- {
- ...state.layers[0],
- accessors: ['a', 'c'],
- },
- ],
- });
- });
-
- test('allows adding a y axis dimension', () => {
- (generateId as jest.Mock).mockReturnValueOnce('zed');
- const setState = jest.fn();
- const state = testState();
- const component = mount(
-
- );
-
- const onAdd = component
- .find('[data-test-subj="lensXY_yDimensionPanel"]')
- .first()
- .prop('onAdd') as () => {};
-
- onAdd();
-
- expect(setState).toHaveBeenCalledTimes(1);
- expect(setState.mock.calls[0][0]).toMatchObject({
- layers: [
- {
- ...state.layers[0],
- accessors: ['a', 'b', 'c', 'zed'],
- },
- ],
- });
- });
});
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.tsx
index dbcfa24395001..5e85680cc2b2c 100644
--- a/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.tsx
+++ b/x-pack/legacy/plugins/lens/public/xy_visualization/xy_config_panel.tsx
@@ -9,16 +9,10 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiButtonGroup, EuiFormRow } from '@elastic/eui';
import { State, SeriesType, visualizationTypes } from './types';
-import { VisualizationLayerConfigProps, OperationMetadata } from '../types';
-import { NativeRenderer } from '../native_renderer';
-import { MultiColumnEditor } from '../multi_column_editor';
-import { generateId } from '../id_generator';
+import { VisualizationLayerWidgetProps } from '../types';
import { isHorizontalChart, isHorizontalSeries } from './state_helpers';
import { trackUiEvent } from '../lens_ui_telemetry';
-const isNumericMetric = (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number';
-const isBucketed = (op: OperationMetadata) => op.isBucketed;
-
type UnwrapArray = T extends Array ? P : T;
function updateLayer(state: State, layer: UnwrapArray, index: number): State {
@@ -31,7 +25,7 @@ function updateLayer(state: State, layer: UnwrapArray, index: n
};
}
-export function LayerContextMenu(props: VisualizationLayerConfigProps