diff --git a/.eslintrc.js b/.eslintrc.js index 3d6a5c262c453..af05af0f6e402 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -69,12 +69,6 @@ module.exports = { 'jsx-a11y/no-onchange': 'off', }, }, - { - files: ['src/legacy/core_plugins/data/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['src/legacy/core_plugins/expressions/**/*.{js,ts,tsx}'], rules: { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index accc99170bb70..6519bf9c493f9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,6 +3,7 @@ # For more info, see https://help.github.com/articles/about-codeowners/ # App +/x-pack/legacy/plugins/dashboard_enhanced/ @elastic/kibana-app /x-pack/legacy/plugins/lens/ @elastic/kibana-app /x-pack/legacy/plugins/graph/ @elastic/kibana-app /src/legacy/server/url_shortening/ @elastic/kibana-app @@ -29,33 +30,32 @@ /src/plugins/dashboard/ @elastic/kibana-app # App Architecture +/examples/url_generators_examples/ @elastic/kibana-app-arch +/examples/url_generators_explorer/ @elastic/kibana-app-arch /packages/kbn-interpreter/ @elastic/kibana-app-arch -/src/legacy/core_plugins/data/ @elastic/kibana-app-arch -/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js @elastic/kibana-app-arch /src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch /src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana/public/management/ @elastic/kibana-app-arch -/src/legacy/core_plugins/kibana/server/field_formats/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana/server/routes/api/management/ @elastic/kibana-app-arch -/src/legacy/core_plugins/kibana/server/routes/api/suggestions/ @elastic/kibana-app-arch /src/legacy/core_plugins/visualizations/ @elastic/kibana-app-arch /src/legacy/server/index_patterns/ @elastic/kibana-app-arch +/src/plugins/advanced_settings/ @elastic/kibana-app-arch /src/plugins/bfetch/ @elastic/kibana-app-arch /src/plugins/data/ @elastic/kibana-app-arch /src/plugins/embeddable/ @elastic/kibana-app-arch /src/plugins/expressions/ @elastic/kibana-app-arch /src/plugins/inspector/ @elastic/kibana-app-arch /src/plugins/kibana_react/ @elastic/kibana-app-arch +/src/plugins/kibana_react/public/code_editor @elastic/kibana-canvas /src/plugins/kibana_utils/ @elastic/kibana-app-arch /src/plugins/management/ @elastic/kibana-app-arch /src/plugins/navigation/ @elastic/kibana-app-arch +/src/plugins/share/ @elastic/kibana-app-arch /src/plugins/ui_actions/ @elastic/kibana-app-arch /src/plugins/visualizations/ @elastic/kibana-app-arch -/src/plugins/share/ @elastic/kibana-app-arch -/examples/url_generators_examples/ @elastic/kibana-app-arch -/examples/url_generators_explorer/ @elastic/kibana-app-arch /x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch +/x-pack/plugins/data_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/drilldowns/ @elastic/kibana-app-arch # APM @@ -75,9 +75,9 @@ # Observability UIs /x-pack/legacy/plugins/infra/ @elastic/logs-metrics-ui /x-pack/plugins/infra/ @elastic/logs-metrics-ui -/x-pack/plugins/ingest_manager/ @elastic/ingest -/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest -/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest +/x-pack/plugins/ingest_manager/ @elastic/ingest-management +/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management +/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest-management /x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui # Machine Learning @@ -150,8 +150,11 @@ # Pulse /packages/kbn-analytics/ @elastic/pulse /src/legacy/core_plugins/ui_metric/ @elastic/pulse +/src/plugins/telemetry/ @elastic/pulse +/src/plugins/telemetry_collection_manager/ @elastic/pulse +/src/plugins/telemetry_management_section/ @elastic/pulse /src/plugins/usage_collection/ @elastic/pulse -/x-pack/legacy/plugins/telemetry/ @elastic/pulse +/x-pack/plugins/telemetry_collection_xpack/ @elastic/pulse # Kibana Alerting Services /x-pack/legacy/plugins/alerting/ @elastic/kibana-alerting-services @@ -182,6 +185,7 @@ /x-pack/plugins/remote_clusters/ @elastic/es-ui /x-pack/legacy/plugins/rollup/ @elastic/es-ui /x-pack/plugins/searchprofiler/ @elastic/es-ui +/x-pack/plugins/painless_lab/ @elastic/es-ui /x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui /x-pack/legacy/plugins/upgrade_assistant/ @elastic/es-ui /x-pack/plugins/upgrade_assistant/ @elastic/es-ui diff --git a/.github/workflows/pr-project-assigner.yml b/.github/workflows/pr-project-assigner.yml index 4058fcaadee5d..ca5d0b9864f99 100644 --- a/.github/workflows/pr-project-assigner.yml +++ b/.github/workflows/pr-project-assigner.yml @@ -8,7 +8,7 @@ jobs: name: Assign a PR to project based on label steps: - name: Assign to project - uses: elastic/github-actions/project-assigner@v1.0.3 + uses: elastic/github-actions/project-assigner@v2.0.0 id: project_assigner with: issue-mappings: | @@ -16,6 +16,6 @@ jobs: ] ghToken: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} -# { "label": "Team:AppArch", "projectName": "kibana-app-arch", "columnId": 6173897 }, -# { "label": "Feature:Lens", "projectName": "Lens", "columnId": 6219362 }, -# { "label": "Team:Canvas", "projectName": "canvas", "columnId": 6187580 } +# { "label": "Team:AppArch", "projectNumber": 37, "columnName": "Review in progress" }, +# { "label": "Feature:Lens", "projectNumber": 32, "columnName": "In progress" }, +# { "label": "Team:Canvas", "projectNumber": 38, "columnName": "Review in progress" } \ No newline at end of file diff --git a/.github/workflows/project-assigner.yml b/.github/workflows/project-assigner.yml index 08be831e0664c..eb5827e121c74 100644 --- a/.github/workflows/project-assigner.yml +++ b/.github/workflows/project-assigner.yml @@ -8,10 +8,10 @@ jobs: name: Assign issue or PR to project based on label steps: - name: Assign to project - uses: elastic/github-actions/project-assigner@v1.0.3 + uses: elastic/github-actions/project-assigner@v2.0.0 id: project_assigner with: - issue-mappings: '[{"label": "Team:AppArch", "projectName": "kibana-app-arch", "columnId": 6173895}, {"label": "Feature:Lens", "projectName": "Lens", "columnId": 6219363}, {"label": "Team:Canvas", "projectName": "canvas", "columnId": 6187593}]' + issue-mappings: '[{"label": "Team:AppArch", "projectNumber": 37, "columnName": "To triage"}, {"label": "Feature:Lens", "projectNumber": 32, "columnName": "Long-term goals"}, {"label": "Team:Canvas", "projectNumber": 38, "columnName": "Inbox"}]' ghToken: ${{ secrets.PROJECT_ASSIGNER_TOKEN }} diff --git a/.i18nrc.json b/.i18nrc.json index 07878ed3c15fb..78c4be6f4a356 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -3,11 +3,9 @@ "common.ui": "src/legacy/ui", "console": "src/plugins/console", "core": "src/core", + "discover": "src/plugins/discover", "dashboard": "src/plugins/dashboard", - "data": [ - "src/legacy/core_plugins/data", - "src/plugins/data" - ], + "data": "src/plugins/data", "embeddableApi": "src/plugins/embeddable", "embeddableExamples": "examples/embeddable_examples", "share": "src/plugins/share", @@ -38,8 +36,8 @@ "server": "src/legacy/server", "statusPage": "src/legacy/core_plugins/status_page", "telemetry": [ - "src/legacy/core_plugins/telemetry", - "src/plugins/telemetry" + "src/plugins/telemetry", + "src/plugins/telemetry_management_section" ], "tileMap": "src/legacy/core_plugins/tile_map", "timelion": ["src/legacy/core_plugins/timelion", "src/legacy/core_plugins/vis_type_timelion", "src/plugins/timelion"], diff --git a/.sass-lint.yml b/.sass-lint.yml index 9c64c1e5eea56..dd7bc0576692b 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -7,6 +7,7 @@ files: - 'x-pack/legacy/plugins/rollup/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/security/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/canvas/**/*.s+(a|c)ss' + - 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss' ignore: - 'x-pack/legacy/plugins/canvas/shareable_runtime/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/lens/**/*.s+(a|c)ss' diff --git a/Jenkinsfile b/Jenkinsfile index d43da6e0bee04..79d3c93006cb6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,7 +40,12 @@ kibanaPipeline(timeoutMinutes: 135, checkPrChanges: true) { 'xpack-ciGroup9': kibanaPipeline.xpackCiGroupProcess(9), 'xpack-ciGroup10': kibanaPipeline.xpackCiGroupProcess(10), 'xpack-accessibility': kibanaPipeline.functionalTestProcess('xpack-accessibility', './test/scripts/jenkins_xpack_accessibility.sh'), - 'xpack-siemCypress': kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh'), + 'xpack-siemCypress': { processNumber -> + whenChanged(['x-pack/legacy/plugins/siem/', 'x-pack/test/siem_cypress/']) { + kibanaPipeline.functionalTestProcess('xpack-siemCypress', './test/scripts/jenkins_siem_cypress.sh')(processNumber) + } + }, + // 'xpack-visualRegression': kibanaPipeline.functionalTestProcess('xpack-visualRegression', './test/scripts/jenkins_xpack_visual_regression.sh'), ]), ]) diff --git a/docs/api/dashboard/export-dashboard.asciidoc b/docs/api/dashboard/export-dashboard.asciidoc index 7858b69d44c79..36c551dee84fc 100644 --- a/docs/api/dashboard/export-dashboard.asciidoc +++ b/docs/api/dashboard/export-dashboard.asciidoc @@ -9,7 +9,7 @@ experimental[] Export dashboards and corresponding saved objects. [[dashboard-api-export-request]] ==== Request -`GET /api/kibana/dashboards/export` +`GET :/api/kibana/dashboards/export` [[dashboard-api-export-params]] ==== Query parameters @@ -20,9 +20,9 @@ experimental[] Export dashboards and corresponding saved objects. [[dashboard-api-export-response-body]] ==== Response body -`objects`:: +`objects`:: (array) A top level property that includes the saved objects. The order of the objects is not guaranteed. Use the exact response body as the request body for the corresponding <>. - + [[dashboard-api-export-codes]] ==== Response code @@ -33,10 +33,10 @@ experimental[] Export dashboards and corresponding saved objects. [[dashboard-api-export-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -GET api/kibana/dashboards/export?dashboard=942dcef0-b2cd-11e8-ad8e-85441f0c2e5c <1> +$ curl -X GET "localhost:5601/api/kibana/dashboards/export?dashboard=942dcef0-b2cd-11e8-ad8e-85441f0c2e5c" <1> -------------------------------------------------- // KIBANA -<1> The dashboard ID is `942dcef0-b2cd-11e8-ad8e-85441f0c2e5c`. \ No newline at end of file +<1> The dashboard ID is `942dcef0-b2cd-11e8-ad8e-85441f0c2e5c`. diff --git a/docs/api/dashboard/import-dashboard.asciidoc b/docs/api/dashboard/import-dashboard.asciidoc index 14817719ec7ee..320859f78c617 100644 --- a/docs/api/dashboard/import-dashboard.asciidoc +++ b/docs/api/dashboard/import-dashboard.asciidoc @@ -9,7 +9,7 @@ experimental[] Import dashboards and corresponding saved objects. [[dashboard-api-import-request]] ==== Request -`POST /api/kibana/dashboards/import` +`POST :/api/kibana/dashboards/import` [[dashboard-api-import-params]] ==== Query parameters @@ -40,9 +40,9 @@ Use the complete response body from the <:/api/features` [float] [[features-api-get-codes]] @@ -23,7 +23,7 @@ experimental[] Retrieves all {kib} features. Features are used by spaces and sec The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "discover", diff --git a/docs/api/logstash-configuration-management.asciidoc b/docs/api/logstash-configuration-management.asciidoc index fbb45095c214b..621b6c61dad8a 100644 --- a/docs/api/logstash-configuration-management.asciidoc +++ b/docs/api/logstash-configuration-management.asciidoc @@ -2,9 +2,9 @@ [[logstash-configuration-management-api]] == Logstash configuration management APIs -Programmatically integrate with the Logstash configuration management feature. +Programmatically integrate with Logstash configuration management. -WARNING: Do not directly access the `.logstash` index. The structure of the `.logstash` index is subject to change, which could cause your integration to break. Instead, use the Logstash configuration management APIs. +WARNING: Do not directly access the `.logstash` index. The structure of the `.logstash` index is subject to change, which could cause your integration to break. Instead, use the Logstash configuration management APIs. The following Logstash configuration management APIs are available: @@ -20,5 +20,3 @@ include::logstash-configuration-management/delete-pipeline.asciidoc[] include::logstash-configuration-management/list-pipeline.asciidoc[] include::logstash-configuration-management/create-logstash.asciidoc[] include::logstash-configuration-management/retrieve-pipeline.asciidoc[] - - diff --git a/docs/api/logstash-configuration-management/create-logstash.asciidoc b/docs/api/logstash-configuration-management/create-logstash.asciidoc index 38e0ee12a0ebf..d6ad27fe44603 100644 --- a/docs/api/logstash-configuration-management/create-logstash.asciidoc +++ b/docs/api/logstash-configuration-management/create-logstash.asciidoc @@ -9,7 +9,7 @@ experimental[] Create a centrally-managed Logstash pipeline, or update an existi [[logstash-configuration-management-api-create-request]] ==== Request -`PUT /api/logstash/pipeline/` +`PUT :/api/logstash/pipeline/` [[logstash-configuration-management-api-create-params]] ==== Path parameters @@ -39,9 +39,9 @@ experimental[] Create a centrally-managed Logstash pipeline, or update an existi [[logstash-configuration-management-api-create-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -PUT api/logstash/pipeline/hello-world +$ curl -X PUT "localhost:5601/api/logstash/pipeline/hello-world" { "pipeline": "input { stdin {} } output { stdout {} }", "settings": { diff --git a/docs/api/logstash-configuration-management/delete-pipeline.asciidoc b/docs/api/logstash-configuration-management/delete-pipeline.asciidoc index 15d44034b46fe..e982619ee17f4 100644 --- a/docs/api/logstash-configuration-management/delete-pipeline.asciidoc +++ b/docs/api/logstash-configuration-management/delete-pipeline.asciidoc @@ -9,7 +9,7 @@ experimental[] Delete a centrally-managed Logstash pipeline. [[logstash-configuration-management-api-delete-request]] ==== Request -`DELETE /api/logstash/pipeline/` +`DELETE :/api/logstash/pipeline/` [[logstash-configuration-management-api-delete-params]] ==== Path parameters @@ -26,9 +26,8 @@ experimental[] Delete a centrally-managed Logstash pipeline. [[logstash-configuration-management-api-delete-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -DELETE api/logstash/pipeline/hello-world +$ curl -X DELETE "localhost:5601/api/logstash/pipeline/hello-world" -------------------------------------------------- // KIBANA - diff --git a/docs/api/logstash-configuration-management/list-pipeline.asciidoc b/docs/api/logstash-configuration-management/list-pipeline.asciidoc index 7140c35d89853..d875ea3d95b78 100644 --- a/docs/api/logstash-configuration-management/list-pipeline.asciidoc +++ b/docs/api/logstash-configuration-management/list-pipeline.asciidoc @@ -9,14 +9,14 @@ experimental[] List all centrally-managed Logstash pipelines. [[logstash-configuration-management-api-list-request]] ==== Request -`GET /api/logstash/pipelines` +`GET :/api/logstash/pipelines` [[logstash-configuration-management-api-list-example]] ==== Example The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "pipelines": [ @@ -35,4 +35,4 @@ The API returns the following: } -------------------------------------------------- -<1> The `username` property appears when security is enabled, and depends on when the pipeline was created or last updated. \ No newline at end of file +<1> The `username` property appears when security is enabled, and depends on when the pipeline was created or last updated. diff --git a/docs/api/logstash-configuration-management/retrieve-pipeline.asciidoc b/docs/api/logstash-configuration-management/retrieve-pipeline.asciidoc index 93a1ec3aa1da5..1eb380b71c62a 100644 --- a/docs/api/logstash-configuration-management/retrieve-pipeline.asciidoc +++ b/docs/api/logstash-configuration-management/retrieve-pipeline.asciidoc @@ -9,20 +9,20 @@ experimental[] Retrieve a centrally-managed Logstash pipeline. [[logstash-configuration-management-api-retrieve-request]] ==== Request -`GET /api/logstash/pipeline/` +`GET :/api/logstash/pipeline/` [[logstash-configuration-management-api-retrieve-path-params]] ==== Path parameters `id`:: (Required, string) The pipeline ID. - + [[logstash-configuration-management-api-retrieve-example]] ==== Example The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "hello-world", @@ -33,4 +33,4 @@ The API returns the following: "queue.type": "persistent" } } --------------------------------------------------- \ No newline at end of file +-------------------------------------------------- diff --git a/docs/api/role-management.asciidoc b/docs/api/role-management.asciidoc index 482d1a9b3cdd3..4c4620a23943a 100644 --- a/docs/api/role-management.asciidoc +++ b/docs/api/role-management.asciidoc @@ -2,9 +2,9 @@ [[role-management-api]] == {kib} role management APIs -Manage the roles that grant <>. +Manage the roles that grant <>. -WARNING: Do not use the {ref}/security-api.html#security-role-apis[{es} role management APIs] to manage {kib} roles. +WARNING: Do not use the {ref}/security-api.html#security-role-apis[{es} role management APIs] to manage {kib} roles. The following {kib} role management APIs are available: diff --git a/docs/api/role-management/delete.asciidoc b/docs/api/role-management/delete.asciidoc index acf2e4a3e3f1f..530e1e252ef8f 100644 --- a/docs/api/role-management/delete.asciidoc +++ b/docs/api/role-management/delete.asciidoc @@ -4,26 +4,23 @@ Delete role ++++ -Delete a {kib} role. - -experimental["The underlying mechanism of enforcing role-based access control is stable, but the APIs for managing the roles are experimental."] +experimental[] Delete a {kib} role. [[role-management-api-delete-prereqs]] -==== Prerequisite +==== Prerequisite To use the delete role API, you must have the `manage_security` cluster privilege. [[role-management-api-delete-request-body]] ==== Request -`DELETE /api/security/role/my_admin_role` +`DELETE :/api/security/role/my_admin_role` [[role-management-api-delete-response-codes]] ==== Response codes `204`:: Indicates a successful call. - + `404`:: - Indicates an unsuccessful call. - \ No newline at end of file + Indicates an unsuccessful call. diff --git a/docs/api/role-management/get-all.asciidoc b/docs/api/role-management/get-all.asciidoc index 4a3dbd7734d3a..888bf0c8a137c 100644 --- a/docs/api/role-management/get-all.asciidoc +++ b/docs/api/role-management/get-all.asciidoc @@ -4,32 +4,30 @@ Get all roles ++++ -Retrieve all {kib} roles. - -experimental["The underlying mechanism of enforcing role-based access control is stable, but the APIs for managing the roles are experimental."] +experimental[] Retrieve all {kib} roles. [[role-management-api-get-prereqs]] -==== Prerequisite +==== Prerequisite To use the get role API, you must have the `manage_security` cluster privilege. [[role-management-api-retrieve-all-request-body]] ==== Request -`GET /api/security/role` +`GET :/api/security/role` [[role-management-api-retrieve-all-response-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. - + [[role-management-api-retrieve-all-example]] ==== Example The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- [ { @@ -77,4 +75,4 @@ The API returns the following: "kibana": [ ] } ] --------------------------------------------------- \ No newline at end of file +-------------------------------------------------- diff --git a/docs/api/role-management/get.asciidoc b/docs/api/role-management/get.asciidoc index 44423b01abe5b..d1e9d1e6afa83 100644 --- a/docs/api/role-management/get.asciidoc +++ b/docs/api/role-management/get.asciidoc @@ -4,32 +4,30 @@ Get specific role ++++ -Retrieve a specific role. - -experimental["The underlying mechanism of enforcing role-based access control is stable, but the APIs for managing the roles are experimental."] +experimental[] Retrieve a specific role. [[role-management-specific-api-get-prereqs]] -==== Prerequisite +==== Prerequisite To use the get specific role API, you must have the `manage_security` cluster privilege. [[role-management-specific-api-retrieve-all-request-body]] ===== Request -`GET /api/security/role/my_restricted_kibana_role` +`GET :/api/security/role/my_restricted_kibana_role` [[role-management-specific-api-retrieve-all-response-codes]] ==== Response code -`200`:: +`200`:: Indicates a successful call. - + [[role-management-specific-api-retrieve-all-example]] ===== Example The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "name": "my_restricted_kibana_role", diff --git a/docs/api/role-management/put.asciidoc b/docs/api/role-management/put.asciidoc index a00fedf7e7ac4..59e6bc8d37eec 100644 --- a/docs/api/role-management/put.asciidoc +++ b/docs/api/role-management/put.asciidoc @@ -4,15 +4,13 @@ Create or update role ++++ -Create a new {kib} role, or update the attributes of an existing role. {kib} roles are stored in the +experimental[] Create a new {kib} role, or update the attributes of an existing role. {kib} roles are stored in the {es} native realm. -experimental["The underlying mechanism of enforcing role-based access control is stable, but the APIs for managing the roles are experimental."] - [[role-management-api-put-request]] ==== Request -`PUT /api/security/role/my_kibana_role` +`PUT :/api/security/role/my_kibana_role` [[role-management-api-put-prereqs]] ==== Prerequisite @@ -22,45 +20,45 @@ To use the create or update role API, you must have the `manage_security` cluste [[role-management-api-response-body]] ==== Request body -`metadata`:: +`metadata`:: (Optional, object) In the `metadata` object, keys that begin with `_` are reserved for system usage. -`elasticsearch`:: - (Optional, object) {es} cluster and index privileges. Valid keys include +`elasticsearch`:: + (Optional, object) {es} cluster and index privileges. Valid keys include `cluster`, `indices`, and `run_as`. For more information, see {ref}/defining-roles.html[Defining roles]. -`kibana`:: +`kibana`:: (list) Objects that specify the <> for the role: -`base` ::: +`base` ::: (Optional, list) A base privilege. When specified, the base must be `["all"]` or `["read"]`. When the `base` privilege is specified, you are unable to use the `feature` section. "all" grants read/write access to all {kib} features for the specified spaces. "read" grants read-only access to all {kib} features for the specified spaces. -`feature` ::: +`feature` ::: (object) Contains privileges for specific features. When the `feature` privileges are specified, you are unable to use the `base` section. To retrieve a list of available features, use the <>. -`spaces` ::: +`spaces` ::: (list) The spaces to apply the privileges to. To grant access to all spaces, set to `["*"]`, or omit the value. [[role-management-api-put-response-codes]] ==== Response code -`204`:: +`204`:: Indicates a successful call. ===== Examples Grant access to various features in all spaces: -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/security/role/my_kibana_role +$ curl -X PUT "localhost:5601/api/security/role/my_kibana_role" { "metadata" : { "version" : 1 @@ -127,9 +125,9 @@ PUT /api/security/role/my_kibana_role Grant dashboard-only access to only the Marketing space: -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/security/role/my_kibana_role +$ curl -X PUT "localhost:5601/api/security/role/my_kibana_role" { "metadata" : { "version" : 1 @@ -155,9 +153,9 @@ PUT /api/security/role/my_kibana_role Grant full access to all features in the Default space: -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/security/role/my_kibana_role +$ curl -X PUT "localhost:5601/api/security/role/my_kibana_role" { "metadata" : { "version" : 1 @@ -182,9 +180,9 @@ PUT /api/security/role/my_kibana_role Grant different access to different spaces: -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/security/role/my_kibana_role +$ curl -X PUT "localhost:5601/api/security/role/my_kibana_role" { "metadata" : { "version" : 1 @@ -216,11 +214,11 @@ PUT /api/security/role/my_kibana_role -------------------------------------------------- // KIBANA -Grant access to {kib} and Elasticsearch: +Grant access to {kib} and {es}: -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/security/role/my_kibana_role +$ curl -X PUT "localhost:5601/api/security/role/my_kibana_role" { "metadata" : { "version" : 1 diff --git a/docs/api/saved-objects/bulk_create.asciidoc b/docs/api/saved-objects/bulk_create.asciidoc index d649684bc30f2..9daba224b317c 100644 --- a/docs/api/saved-objects/bulk_create.asciidoc +++ b/docs/api/saved-objects/bulk_create.asciidoc @@ -9,9 +9,9 @@ experimental[] Create multiple {kib} saved objects. [[saved-objects-api-bulk-create-request]] ==== Request -`POST /api/saved_objects/_bulk_create` +`POST :/api/saved_objects/_bulk_create` -`POST /s//api/saved_objects/_bulk_create` +`POST :/s//api/saved_objects/_bulk_create` [[saved-objects-api-bulk-create-path-params]] @@ -63,9 +63,9 @@ Saved objects that are unable to persist are replaced with an error object. Create an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_bulk_create +$ curl -X POST "localhost:5601/api/saved_objects/_bulk_create" [ { "type": "index-pattern", @@ -87,7 +87,7 @@ POST api/saved_objects/_bulk_create The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "saved_objects": [ diff --git a/docs/api/saved-objects/bulk_get.asciidoc b/docs/api/saved-objects/bulk_get.asciidoc index 3ef5823716d79..a6fdeb69ba925 100644 --- a/docs/api/saved-objects/bulk_get.asciidoc +++ b/docs/api/saved-objects/bulk_get.asciidoc @@ -9,9 +9,9 @@ experimental[] Retrieve multiple {kib} saved objects by ID. [[saved-objects-api-bulk-get-request]] ==== Request -`POST /api/saved_objects/_bulk_get` +`POST :/api/saved_objects/_bulk_get` -`POST /s//api/saved_objects/_bulk_get` +`POST :/s//api/saved_objects/_bulk_get` [[saved-objects-api-bulk-get-path-params]] ==== Path parameters @@ -50,9 +50,9 @@ Saved objects that are unable to persist are replaced with an error object. Retrieve an index pattern with the `my-pattern` ID, and a dashboard with the `my-dashboard` ID: -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_bulk_get +$ curl -X POST "localhost:5601/api/saved_objects/_bulk_get" [ { "type": "index-pattern", @@ -68,7 +68,7 @@ POST api/saved_objects/_bulk_get The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "saved_objects": [ diff --git a/docs/api/saved-objects/create.asciidoc b/docs/api/saved-objects/create.asciidoc index 634c71bb4eefe..dc010c80fd012 100644 --- a/docs/api/saved-objects/create.asciidoc +++ b/docs/api/saved-objects/create.asciidoc @@ -9,11 +9,11 @@ experimental[] Create {kib} saved objects. [[saved-objects-api-create-request]] ==== Request -`POST /api/saved_objects/` + +`POST :/api/saved_objects/` + -`POST /api/saved_objects//` +`POST :/api/saved_objects//` -`POST /s//saved_objects/` +`POST :/s//saved_objects/` [[saved-objects-api-create-path-params]] ==== Path parameters @@ -55,9 +55,9 @@ any data that you send to the API is properly formed. [[saved-objects-api-create-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/index-pattern/my-pattern +$ curl -X POST "localhost:5601/api/saved_objects/index-pattern/my-pattern" { "attributes": { "title": "my-pattern-*" @@ -68,7 +68,7 @@ POST api/saved_objects/index-pattern/my-pattern The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "my-pattern", <1> diff --git a/docs/api/saved-objects/delete.asciidoc b/docs/api/saved-objects/delete.asciidoc index c34f9b67dfd22..65c955e15d360 100644 --- a/docs/api/saved-objects/delete.asciidoc +++ b/docs/api/saved-objects/delete.asciidoc @@ -4,16 +4,16 @@ Delete object ++++ -experimental[] Remove {kib} saved objects. +experimental[] Remove {kib} saved objects. WARNING: Once you delete a saved object, _it cannot be recovered_. [[saved-objects-api-delete-request]] ==== Request -`DELETE /api/saved_objects//` +`DELETE :/api/saved_objects//` -`DELETE /s//api/saved_objects//` +`DELETE :/s//api/saved_objects//` [[saved-objects-api-delete-path-params]] ==== Path parameters @@ -33,12 +33,12 @@ WARNING: Once you delete a saved object, _it cannot be recovered_. `200`:: Indicates a successful call. -==== Examples +==== Example Delete an index pattern object with the `my-pattern` ID: -[source,js] +[source,sh] -------------------------------------------------- -DELETE api/saved_objects/index-pattern/my-pattern +$ curl -X DELETE "localhost:5601/api/saved_objects/index-pattern/my-pattern" -------------------------------------------------- // KIBANA diff --git a/docs/api/saved-objects/export.asciidoc b/docs/api/saved-objects/export.asciidoc index 1b4f50dda2ddb..e8c762b9543a1 100644 --- a/docs/api/saved-objects/export.asciidoc +++ b/docs/api/saved-objects/export.asciidoc @@ -9,9 +9,9 @@ experimental[] Retrieve sets of saved objects that you want to import into {kib} [[saved-objects-api-export-request]] ==== Request -`POST /api/saved_objects/_export` +`POST :/api/saved_objects/_export` -`POST /s//api/saved_objects/_export` +`POST :/s//api/saved_objects/_export` [[saved-objects-api-export-path-params]] ==== Path parameters @@ -39,7 +39,7 @@ TIP: You must include `type` or `objects` in the request body. [[saved-objects-api-export-request-response-body]] ==== Response body -The format of the response body is newline delimited JSON. Each exported object is exported as a valid JSON record and separated by the newline character '\n'. +The format of the response body is newline delimited JSON. Each exported object is exported as a valid JSON record and separated by the newline character '\n'. When `excludeExportDetails=false` (the default) we append an export result details record at the end of the file after all the saved object records. The export result details object has the following format: @@ -66,9 +66,9 @@ When `excludeExportDetails=false` (the default) we append an export result detai Export all index pattern saved objects: -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_export +$ curl -X POST "localhost:5601/api/saved_objects/_export" { "type": "index-pattern" } @@ -77,9 +77,9 @@ POST api/saved_objects/_export Export all index pattern saved objects and exclude the export summary from the stream: -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_export +$ curl -X POST "localhost:5601/api/saved_objects/_export" { "type": "index-pattern", "excludeExportDetails": true @@ -89,9 +89,9 @@ POST api/saved_objects/_export Export a specific saved object: -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_export +$ curl -X POST "localhost:5601/api/saved_objects/_export" { "objects": [ { @@ -105,9 +105,9 @@ POST api/saved_objects/_export Export a specific saved object and it's related objects : -[source,js] +[source,sh] -------------------------------------------------- -POST api/saved_objects/_export +$ curl -X POST "localhost:5601/api/saved_objects/_export" { "objects": [ { diff --git a/docs/api/saved-objects/find.asciidoc b/docs/api/saved-objects/find.asciidoc index 955c50922fde7..93e60be5d4923 100644 --- a/docs/api/saved-objects/find.asciidoc +++ b/docs/api/saved-objects/find.asciidoc @@ -9,9 +9,9 @@ experimental[] Retrieve a paginated set of {kib} saved objects by various condit [[saved-objects-api-find-request]] ==== Request -`GET /api/saved_objects/_find` +`GET :/api/saved_objects/_find` -`GET /s//api/saved_objects/_find` +`GET :/s//api/saved_objects/_find` [[saved-objects-api-find-path-params]] ==== Path parameters @@ -67,15 +67,15 @@ change. Use the find API for traditional paginated results, but avoid using it t Find index patterns with titles that start with `my`: -[source,js] +[source,sh] -------------------------------------------------- -GET api/saved_objects/_find?type=index-pattern&search_fields=title&search=my* +$ curl -X GET "localhost:5601/api/saved_objects/_find?type=index-pattern&search_fields=title&search=my*" -------------------------------------------------- // KIBANA The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "total": 1, @@ -95,8 +95,8 @@ The API returns the following: For parameters that accept multiple values (e.g. `fields`), repeat the query parameter for each value: -[source,js] +[source,sh] -------------------------------------------------- -GET api/saved_objects/_find?fields=id&fields=title +$ curl -X GET "localhost:5601/api/saved_objects/_find?fields=id&fields=title" -------------------------------------------------- // KIBANA diff --git a/docs/api/saved-objects/get.asciidoc b/docs/api/saved-objects/get.asciidoc index 29f8ef67e0a83..86b86795b534f 100644 --- a/docs/api/saved-objects/get.asciidoc +++ b/docs/api/saved-objects/get.asciidoc @@ -9,9 +9,9 @@ experimental[] Retrieve a single {kib} saved object by ID. [[saved-objects-api-get-request]] ==== Request -`GET /api/saved_objects//` +`GET :/api/saved_objects//` -`GET /s//api/saved_objects//` +`GET :/s//api/saved_objects//` [[saved-objects-api-get-params]] ==== Path parameters @@ -37,15 +37,15 @@ experimental[] Retrieve a single {kib} saved object by ID. Retrieve the index pattern object with the `my-pattern` ID: -[source,js] +[source,sh] -------------------------------------------------- -GET api/saved_objects/index-pattern/my-pattern +$ curl -X GET "localhost:5601/api/saved_objects/index-pattern/my-pattern" -------------------------------------------------- // KIBANA The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "my-pattern", @@ -57,17 +57,17 @@ The API returns the following: } -------------------------------------------------- -The following example retrieves a dashboard object in the `testspace` by id. +Retrieve a dashboard object in the `testspace` by ID: -[source,js] +[source,sh] -------------------------------------------------- -GET /s/testspace/api/saved_objects/dashboard/7adfa750-4c81-11e8-b3d7-01146121b73d +$ curl -X GET "localhost:5601/s/testspace/api/saved_objects/dashboard/7adfa750-4c81-11e8-b3d7-01146121b73d" -------------------------------------------------- // KIBANA The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "7adfa750-4c81-11e8-b3d7-01146121b73d", diff --git a/docs/api/saved-objects/import.asciidoc b/docs/api/saved-objects/import.asciidoc index 1a380830ed21a..b3e4c48696a17 100644 --- a/docs/api/saved-objects/import.asciidoc +++ b/docs/api/saved-objects/import.asciidoc @@ -9,9 +9,9 @@ experimental[] Create sets of {kib} saved objects from a file created by the exp [[saved-objects-api-import-request]] ==== Request -`POST /api/saved_objects/_import` +`POST :/api/saved_objects/_import` -`POST /s//api/saved_objects/_import` +`POST :/s//api/saved_objects/_import` [[saved-objects-api-import-path-params]] ==== Path parameters @@ -55,14 +55,15 @@ The request body must include the multipart/form-data type. Import an index pattern and dashboard: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_import" -H "kbn-xsrf: true" --form file=@file.ndjson -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"index-pattern","id":"my-pattern","attributes":{"title":"my-pattern-*"}} {"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"}} @@ -70,7 +71,7 @@ The `file.ndjson` file contains the following: The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "success": true, @@ -80,14 +81,15 @@ The API returns the following: Import an index pattern and dashboard that includes a conflict on the index pattern: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_import" -H "kbn-xsrf: true" --form file=@file.ndjson -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"index-pattern","id":"my-pattern","attributes":{"title":"my-pattern-*"}} {"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"}} @@ -95,7 +97,7 @@ The `file.ndjson` file contains the following: The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "success": false, @@ -115,14 +117,15 @@ The API returns the following: Import a visualization and dashboard with an index pattern for the visualization reference that doesn't exist: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_import" -H "kbn-xsrf: true" --form file=@file.ndjson -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"visualization","id":"my-vis","attributes":{"title":"my-vis"},"references":[{"name":"ref_0","type":"index-pattern","id":"my-pattern-*"}]} {"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"},"references":[{"name":"ref_0","type":"visualization","id":"my-vis"}]} @@ -130,7 +133,7 @@ The `file.ndjson` file contains the following: The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- "success": false, "successCount": 0, diff --git a/docs/api/saved-objects/resolve_import_errors.asciidoc b/docs/api/saved-objects/resolve_import_errors.asciidoc index b64e5deb361b2..ec03917390d36 100644 --- a/docs/api/saved-objects/resolve_import_errors.asciidoc +++ b/docs/api/saved-objects/resolve_import_errors.asciidoc @@ -17,9 +17,9 @@ To resolve errors, you can: [[saved-objects-api-resolve-import-errors-request]] ==== Request -`POST /api/saved_objects/_resolve_import_errors` +`POST :/api/saved_objects/_resolve_import_errors` -`POST /s//api/saved_objects/_resolve_import_errors` +`POST :/s//api/saved_objects/_resolve_import_errors` [[saved-objects-api-resolve-import-errors-path-params]] ==== Path parameters @@ -61,21 +61,22 @@ The request body must include the multipart/form-data type. Retry a dashboard import: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_resolve_import_errors" -H "kbn-xsrf: true" --form file=@file.ndjson --form retries='[{"type":"dashboard","id":"my-dashboard"}]' -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"}} -------------------------------------------------- The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "success": true, @@ -85,14 +86,15 @@ The API returns the following: Resolve errors for a dashboard and overwrite the existing saved object: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_resolve_import_errors" -H "kbn-xsrf: true" --form file=@file.ndjson --form retries='[{"type":"dashboard","id":"my-dashboard","overwrite":true}]' -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"index-pattern","id":"my-pattern","attributes":{"title":"my-pattern-*"}} {"type":"dashboard","id":"my-dashboard","attributes":{"title":"Look at my dashboard"}} @@ -100,7 +102,7 @@ The `file.ndjson` file contains the following: The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "success": true, @@ -110,21 +112,22 @@ The API returns the following: Resolve errors for a visualization by replacing the index pattern with another: -[source,js] +[source,sh] -------------------------------------------------- $ curl -X POST "localhost:5601/api/saved_objects/_resolve_import_errors" -H "kbn-xsrf: true" --form file=@file.ndjson --form retries='[{"type":"visualization","id":"my-vis","replaceReferences":[{"type":"index-pattern","from":"missing","to":"existing"}]}]' -------------------------------------------------- +// KIBANA The `file.ndjson` file contains the following: -[source,js] +[source,sh] -------------------------------------------------- {"type":"visualization","id":"my-vis","attributes":{"title":"Look at my visualization"},"references":[{"name":"ref_0","type":"index-pattern","id":"missing"}]} -------------------------------------------------- The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "success": true, diff --git a/docs/api/saved-objects/update.asciidoc b/docs/api/saved-objects/update.asciidoc index 99a9bd4ad15bb..62f4104debc77 100644 --- a/docs/api/saved-objects/update.asciidoc +++ b/docs/api/saved-objects/update.asciidoc @@ -9,9 +9,9 @@ experimental[] Update the attributes for existing {kib} saved objects. [[saved-objects-api-update-request]] ==== Request -`PUT /api/saved_objects//` +`PUT :/api/saved_objects//` -`PUT /s//api/saved_objects//` +`PUT :/s//api/saved_objects//` [[saved-objects-api-update-path-params]] ==== Path parameters @@ -47,9 +47,9 @@ WARNING: When you update, attributes are not validated, which allows you to pass Update an existing index pattern object,`my-pattern`, with a different title: -[source,js] +[source,sh] -------------------------------------------------- -PUT api/saved_objects/index-pattern/my-pattern +$ curl -X PUT "localhost:5601/api/saved_objects/index-pattern/my-pattern" { "attributes": { "title": "some-other-pattern-*" @@ -60,7 +60,7 @@ PUT api/saved_objects/index-pattern/my-pattern The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "my-pattern", diff --git a/docs/api/spaces-management/copy_saved_objects.asciidoc b/docs/api/spaces-management/copy_saved_objects.asciidoc index c07b5f35efe09..e23a137485b2d 100644 --- a/docs/api/spaces-management/copy_saved_objects.asciidoc +++ b/docs/api/spaces-management/copy_saved_objects.asciidoc @@ -5,225 +5,75 @@ Copy saved objects to space ++++ -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] - -//// -Use the appropriate heading levels for your book. -Add anchors for each section. -FYI: The section titles use attributes in case those terms change. -//// - -[[spaces-api-copy-saved-objects-request]] -==== {api-request-title} -//// -This section show the basic endpoint, without the body or optional parameters. -Variables should use <...> syntax. -If an API supports both PUT and POST, include both here. -//// - -`POST /api/spaces/_copy_saved_objects` - -`POST /s//api/spaces/_copy_saved_objects` - - -//// -[[spaces-api-copy-saved-objects-prereqs]] -==== {api-prereq-title} -//// -//// -Optional list of prerequisites. - -For example: - -* A snapshot of an index created in 5.x can be restored to 6.x. You must... -* If the {es} {security-features} are enabled, you must have `write`, `monitor`, -and `manage_follow_index` index privileges... -//// - - -[[spaces-api-copy-saved-objects-desc]] -==== {api-description-title} - -Copy saved objects between spaces. +experimental[] Copy saved objects between spaces. It also allows you to automatically copy related objects, so when you copy a `dashboard`, this can automatically copy over the associated visualizations, index patterns, and saved searches, as required. -You can request to overwrite any objects that already exist in the target space if they share an ID, or you can use the +You can request to overwrite any objects that already exist in the target space if they share an ID, or you can use the <> to do this on a per-object basis. -//// -Add a more detailed description the context. -Link to related APIs if appropriate. +[[spaces-api-copy-saved-objects-request]] +==== {api-request-title} -Guidelines for parameter documentation -*************************************** -* Use a definition list. -* End each definition with a period. -* Include whether the parameter is Optional or Required and the data type. -* Include default values as the last sentence of the first paragraph. -* Include a range of valid values, if applicable. -* If the parameter requires a specific delimiter for multiple values, say so. -* If the parameter supports wildcards, ditto. -* For large or nested objects, consider linking to a separate definition list. -*************************************** -//// +`POST :/api/spaces/_copy_saved_objects` +`POST :/s//api/spaces/_copy_saved_objects` [[spaces-api-copy-saved-objects-path-params]] ==== {api-path-parms-title} -//// -A list of all the parameters within the path of the endpoint (before the query string (?)). -For example: -``:: -(Required, string) Name of the follower index -//// `space_id`:: -(Optional, string) Identifies the source space from which saved objects will be copied. If `space_id` is not specified in the URL, the default space is used. - -//// -[[spaces-api-copy-saved-objects-params]] -==== {api-query-parms-title} -//// -//// -A list of the parameters in the query string of the endpoint (after the ?). - -For example: -`wait_for_active_shards`:: -(Optional, integer) Specifies the number of shards to wait on being active before -responding. A shard must be restored from the leader index being active. -Restoring a follower shard requires transferring all the remote Lucene segment -files to the follower index. The default is `0`, which means waiting on none of -the shards to be active. -//// +(Optional, string) The ID of the space that contains the saved objects you want to copy. When `space_id` is unspecified in the URL, the default space is used. [[spaces-api-copy-saved-objects-request-body]] ==== {api-request-body-title} -//// -A list of the properties you can specify in the body of the request. -For example: -`remote_cluster`:: -(Required, string) The <> that contains -the leader index. +`spaces`:: + (Required, string array) The IDs of the spaces where you want to copy the specified objects. -`leader_index`:: -(Required, string) The name of the index in the leader cluster to follow. -//// -`spaces` :: - (Required, string array) The ids of the spaces the specified object(s) will be copied into. - -`objects` :: +`objects`:: (Required, object array) The saved objects to copy. - `type` ::: + `type`::: (Required, string) The saved object type. - `id` ::: - (Required, string) The saved object id. + `id`::: + (Required, string) The saved object ID. -`includeReferences` :: +`includeReferences`:: (Optional, boolean) When set to `true`, all saved objects related to the specified saved objects will also be copied into the target spaces. The default value is `false`. -`overwrite` :: - (Optional, boolean) When set to `true`, all conflicts will be automatically overidden. If a saved object with a matching `type` and `id` exists in the target space, then that version will be replaced with the version from the source space. The default value is `false`. +`overwrite`:: + (Optional, boolean) When set to `true`, all conflicts are automatically overidden. When a saved object with a matching `type` and `id` exists in the target space, that version is replaced with the version from the source space. The default value is `false`. [[spaces-api-copy-saved-objects-response-body]] ==== {api-response-body-title} -//// -Response body is only required for detailed responses. - -For example: -`auto_follow_stats`:: - (object) An object representing stats for the auto-follow coordinator. This - object consists of the following fields: - -`auto_follow_stats.number_of_successful_follow_indices`::: - (long) the number of indices that the auto-follow coordinator successfully - followed -... - -//// ``:: - (object) Specifies the dynamic keys that are included in the response. An object describing the result of the copy operation for this particular space. + (object) An object that describes the result of the copy operation for the space. Includes the dynamic keys in the response. `success`::: - (boolean) Indicates if the copy operation was successful. Note that some objects may have been copied even if this is set to `false`. Consult the `successCount` and `errors` properties of the response for additional information. + (boolean) The copy operation was successful. When set to `false`, some objects may have been copied. For additional information, refer to the `successCount` and `errors` properties. `successCount`::: - (number) The number of objects that were successfully copied. + (number) The number of objects that successfully copied. `errors`::: - (Optional, array) Collection of any errors that were encountered during the copy operation. If any errors are reported, then the `success` flag will be set to `false`. + (Optional, array) The errors that occurred during the copy operation. When errors are reported, the `success` flag is set to `false`.v `id`:::: - (string) The saved object id which failed to copy. + (string) The saved object ID that failed to copy. `type`:::: - (string) The type of saved object which failed to copy. + (string) The type of saved object that failed to copy. `error`:::: - (object) The error which caused the copy operation to fail. + (object) The error that caused the copy operation to fail. `type`::::: - (string) Indicates the type of error. May be one of: `conflict`, `unsupported_type`, `missing_references`, `unknown`. Errors marked as `conflict` may be resolved by using the <>. - -//// -[[spaces-api-copy-saved-objects-response-codes]] -==== {api-response-codes-title} -//// -//// -Response codes are only required when needed to understand the response body. - -For example: -`200`:: -Indicates all listed indices or index aliases exist. - - `404`:: -Indicates one or more listed indices or index aliases **do not** exist. -//// - + (string) The type of error. For example, `unsupported_type`, `missing_references`, or `unknown`. Errors marked as `conflict` may be resolved by using the <>. [[spaces-api-copy-saved-objects-example]] ==== {api-examples-title} -//// -Optional brief example. -Use an 'Examples' heading if you include multiple examples. +Copy a dashboard with the `my-dashboard` ID, including all references from the `default` space to the `marketing` and `sales` spaces: -[source,js] +[source,sh] ---- -PUT /follower_index/_ccr/follow?wait_for_active_shards=1 -{ - "remote_cluster" : "remote_cluster", - "leader_index" : "leader_index", - "max_read_request_operation_count" : 1024, - "max_outstanding_read_requests" : 16, - "max_read_request_size" : "1024k", - "max_write_request_operation_count" : 32768, - "max_write_request_size" : "16k", - "max_outstanding_write_requests" : 8, - "max_write_buffer_count" : 512, - "max_write_buffer_size" : "512k", - "max_retry_delay" : "10s", - "read_poll_timeout" : "30s" -} ----- -// CONSOLE -// TEST[setup:remote_cluster_and_leader_index] - -The API returns the following result: - -[source,js] ----- -{ - "follow_index_created" : true, - "follow_index_shards_acked" : true, - "index_following_started" : true -} ----- -// TESTRESPONSE -//// - -The following example attempts to copy a dashboard with id `my-dashboard`, including all references from the `default` space to the `marketing` and `sales` spaces. The `marketing` space succeeds, while the `sales` space fails due to a conflict on the underlying index pattern: - -[source,js] ----- -POST /api/spaces/_copy_saved_objects +$ curl -X POST "localhost:5601/api/spaces/_copy_saved_objects" { "objects": [{ "type": "dashboard", @@ -235,9 +85,9 @@ POST /api/spaces/_copy_saved_objects ---- // KIBANA -The API returns the following result: +The API returns the following: -[source,js] +[source,sh] ---- { "marketing": { @@ -258,11 +108,13 @@ The API returns the following result: } ---- -The following example successfully copies a visualization with id `my-viz` from the `marketing` space to the `default` space: +The `marketing` space succeeds, but the `sales` space fails due to a conflict in the index pattern. + +Copy a visualization with the `my-viz` ID from the `marketing` space to the `default` space: -[source,js] +[source,sh] ---- -POST /s/marketing/api/spaces/_copy_saved_objects +$ curl -X POST "localhost:5601/s/marketing/api/spaces/_copy_saved_objects" { "objects": [{ "type": "visualization", @@ -273,9 +125,9 @@ POST /s/marketing/api/spaces/_copy_saved_objects ---- // KIBANA -The API returns the following result: +The API returns the following: -[source,js] +[source,sh] ---- { "default": { diff --git a/docs/api/spaces-management/delete.asciidoc b/docs/api/spaces-management/delete.asciidoc index c66307ea3070f..5b4db78c056dd 100644 --- a/docs/api/spaces-management/delete.asciidoc +++ b/docs/api/spaces-management/delete.asciidoc @@ -4,22 +4,20 @@ Delete space ++++ -Delete a {kib} space. +experimental[] Delete a {kib} space. -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] - -WARNING: When you delete a space, all saved objects that belong to the space are automatically deleted, which is permanent and cannot be undone. +WARNING: When you delete a space, all saved objects that belong to the space are automatically deleted, which is permanent and cannot be undone. [[spaces-api-delete-request]] ==== Request -`DELETE /api/spaces/space/marketing` +`DELETE :/api/spaces/space/marketing` [[spaces-api-delete-errors-codes]] ==== Response codes -`204`:: +`204`:: Indicates a successful call. - + `404`:: Indicates that the request failed. diff --git a/docs/api/spaces-management/get.asciidoc b/docs/api/spaces-management/get.asciidoc index 49119d7602b20..48245b7786604 100644 --- a/docs/api/spaces-management/get.asciidoc +++ b/docs/api/spaces-management/get.asciidoc @@ -4,14 +4,12 @@ Get space ++++ -Retrieve a specified {kib} space. - -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] +experimental[] Retrieve a specified {kib} space. [[spaces-api-get-request]] ==== Request -`GET /api/spaces/space/marketing` +`GET :/api/spaces/space/marketing` [[spaces-api-get-response-codes]] ==== Response code @@ -24,7 +22,7 @@ experimental["The underlying Spaces concepts are stable, but the APIs for managi The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "id": "marketing", @@ -35,4 +33,4 @@ The API returns the following: "disabledFeatures": [], "imageUrl": "" } --------------------------------------------------- \ No newline at end of file +-------------------------------------------------- diff --git a/docs/api/spaces-management/get_all.asciidoc b/docs/api/spaces-management/get_all.asciidoc index f7fb92baa165f..8f7ba86f332de 100644 --- a/docs/api/spaces-management/get_all.asciidoc +++ b/docs/api/spaces-management/get_all.asciidoc @@ -4,14 +4,12 @@ Get all spaces ++++ -Retrieve all {kib} spaces. - -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] +experimental[] Retrieve all {kib} spaces. [[spaces-api-get-all-request]] ==== Request -`GET /api/spaces/space` +`GET :/api/spaces/space` [[spaces-api-get-all-response-codes]] ==== Response code @@ -24,7 +22,7 @@ experimental["The underlying Spaces concepts are stable, but the APIs for managi The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- [ { diff --git a/docs/api/spaces-management/post.asciidoc b/docs/api/spaces-management/post.asciidoc index 4d4627e98899e..b96fbe6364c34 100644 --- a/docs/api/spaces-management/post.asciidoc +++ b/docs/api/spaces-management/post.asciidoc @@ -4,14 +4,12 @@ Create space ++++ -Create a {kib} space. - -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] +experimental[] Create a {kib} space. [[spaces-api-post-request]] ==== Request -`POST /api/spaces/space` +`POST :/api/spaces/space` [[spaces-api-post-request-body]] ==== Request body @@ -29,13 +27,13 @@ experimental["The underlying Spaces concepts are stable, but the APIs for managi (Optional, string array) The list of disabled features for the space. To get a list of available feature IDs, use the <>. `initials`:: - (Optional, string) Specifies the initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters. + (Optional, string) The initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters. `color`:: - (Optional, string) Specifies the hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name. + (Optional, string) The hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name. `imageUrl`:: - (Optional, string) Specifies the data-url encoded image to display in the space avatar. If specified, `initials` will not be displayed, and the `color` will be visible as the background color for transparent images. + (Optional, string) The data-URL encoded image to display in the space avatar. If specified, `initials` will not be displayed, and the `color` will be visible as the background color for transparent images. For best results, your image should be 64x64. Images will not be optimized by this API call, so care should be taken when using custom images. [[spaces-api-post-response-codes]] @@ -47,9 +45,9 @@ experimental["The underlying Spaces concepts are stable, but the APIs for managi [[spaces-api-post-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -POST /api/spaces/space +$ curl -X POST "localhost:5601/api/spaces/space" { "id": "marketing", "name": "Marketing", diff --git a/docs/api/spaces-management/put.asciidoc b/docs/api/spaces-management/put.asciidoc index 586818707c76f..f405d57975a70 100644 --- a/docs/api/spaces-management/put.asciidoc +++ b/docs/api/spaces-management/put.asciidoc @@ -4,37 +4,35 @@ Update space ++++ -Update an existing {kib} space. - -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] +experimental[] Update an existing {kib} space. [[spaces-api-put-api-request]] ==== Request -`PUT /api/spaces/space/` +`PUT :/api/spaces/space/` [[spaces-api-put-request-body]] ==== Request body -`id`:: +`id`:: (Required, string) The space ID that is part of the {kib} URL when inside the space. You are unable to change the ID with the update operation. -`name`:: +`name`:: (Required, string) The display name for the space. -`description`:: +`description`:: (Optional, string) The description for the space. -`disabledFeatures`:: +`disabledFeatures`:: (Optional, string array) The list of disabled features for the space. To get a list of available feature IDs, use the <>. -`initials`:: +`initials`:: (Optional, string) Specifies the initials shown in the space avatar. By default, the initials are automatically generated from the space name. Initials must be 1 or 2 characters. -`color`:: +`color`:: (Optional, string) Specifies the hexadecimal color code used in the space avatar. By default, the color is automatically generated from the space name. -`imageUrl`:: +`imageUrl`:: (Optional, string) Specifies the data-url encoded image to display in the space avatar. If specified, `initials` will not be displayed, and the `color` will be visible as the background color for transparent images. For best results, your image should be 64x64. Images will not be optimized by this API call, so care should be taken when using custom images. @@ -43,13 +41,13 @@ experimental["The underlying Spaces concepts are stable, but the APIs for managi `200`:: Indicates a successful call. - + [[sample-api-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -PUT /api/spaces/space/marketing +$ curl -X PUT "localhost:5601/api/spaces/space/marketing" { "id": "marketing", "name": "Marketing", diff --git a/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc b/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc index 7b52125599c05..8e874bb9f94e5 100644 --- a/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc +++ b/docs/api/spaces-management/resolve_copy_saved_objects_conflicts.asciidoc @@ -5,227 +5,80 @@ Resolve copy to space conflicts ++++ -Overwrite specific saved objects that were returned as errors from the <>. - -experimental["The underlying Spaces concepts are stable, but the APIs for managing Spaces are experimental."] - -//// -Use the appropriate heading levels for your book. -Add anchors for each section. -FYI: The section titles use attributes in case those terms change. -//// +experimental[] Overwrite saved objects that are returned as errors from the <>. [[spaces-api-resolve-copy-saved-objects-conflicts-request]] ==== {api-request-title} -//// -This section show the basic endpoint, without the body or optional parameters. -Variables should use <...> syntax. -If an API supports both PUT and POST, include both here. -//// - -`POST /api/spaces/_resolve_copy_saved_objects_errors` - -`POST /s//api/spaces/_resolve_copy_saved_objects_errors` +`POST :/api/spaces/_resolve_copy_saved_objects_errors` +`POST :/s//api/spaces/_resolve_copy_saved_objects_errors` [[spaces-api-resolve-copy-saved-objects-conflicts-prereqs]] ==== {api-prereq-title} -//// -Optional list of prerequisites. - -For example: - -* A snapshot of an index created in 5.x can be restored to 6.x. You must... -* If the {es} {security-features} are enabled, you must have `write`, `monitor`, -and `manage_follow_index` index privileges... -//// -* Executed the <>, which returned one or more `conflict` errors that you wish to resolve. - -//// -[[spaces-api-resolve-copy-saved-objects-conflicts-desc]] -==== {api-description-title} - -Allows saved objects to be selectively overridden in the target spaces. -//// - -//// -Add a more detailed description the context. -Link to related APIs if appropriate. - -Guidelines for parameter documentation -*************************************** -* Use a definition list. -* End each definition with a period. -* Include whether the parameter is Optional or Required and the data type. -* Include default values as the last sentence of the first paragraph. -* Include a range of valid values, if applicable. -* If the parameter requires a specific delimiter for multiple values, say so. -* If the parameter supports wildcards, ditto. -* For large or nested objects, consider linking to a separate definition list. -*************************************** -//// +Execute the <>, which returns the errors for you to resolve. [[spaces-api-resolve-copy-saved-objects-conflicts-path-params]] ==== {api-path-parms-title} -//// -A list of all the parameters within the path of the endpoint (before the query string (?)). -For example: -``:: -(Required, string) Name of the follower index -//// `space_id`:: -(Optional, string) Identifies the source space from which saved objects will be copied. If `space_id` is not specified in the URL, the default space is used. Must be the same value that was used during the failed <> operation. - -//// -[[spaces-api-resolve-copy-saved-objects-conflicts-request-params]] -==== {api-query-parms-title} -//// -//// -A list of the parameters in the query string of the endpoint (after the ?). - -For example: -`wait_for_active_shards`:: -(Optional, integer) Specifies the number of shards to wait on being active before -responding. A shard must be restored from the leader index being active. -Restoring a follower shard requires transferring all the remote Lucene segment -files to the follower index. The default is `0`, which means waiting on none of -the shards to be active. -//// +(Optional, string) The ID of the space that contains the saved objects you want to copy. When `space_id` is unspecified in the URL, the default space is used. The `space_id` must be the same value used during the failed <> operation. [[spaces-api-resolve-copy-saved-objects-conflicts-request-body]] ==== {api-request-body-title} -//// -A list of the properties you can specify in the body of the request. - -For example: -`remote_cluster`:: -(Required, string) The <> that contains -the leader index. -`leader_index`:: -(Required, string) The name of the index in the leader cluster to follow. -//// -`objects` :: - (Required, object array) The saved objects to copy. Must be the same value that was used during the failed <> operation. - `type` ::: +`objects`:: + (Required, object array) The saved objects to copy. The `objects` must be the same values used during the failed <> operation. + `type`::: (Required, string) The saved object type. - `id` ::: - (Required, string) The saved object id. + `id`::: + (Required, string) The saved object ID. -`includeReferences` :: - (Optional, boolean) When set to `true`, all saved objects related to the specified saved objects will also be copied into the target spaces. You must set this to the same value that you used when executing the <>. The default value is `false`. +`includeReferences`:: + (Optional, boolean) When set to `true`, all saved objects related to the specified saved objects are copied into the target spaces. The `includeReferences` must be the same values used during the failed <> operation. The default value is `false`. `retries`:: - (Required, object) The retry operations to attempt. Object keys represent the target space ids. - `` ::: - (Required, array) The the conflicts to resolve for the indicated ``. - `type` :::: + (Required, object) The retry operations to attempt. Object keys represent the target space IDs. + ``::: + (Required, array) The errors to resolve for the specified ``. + `type`:::: (Required, string) The saved object type. - `id` :::: - (Required, string) The saved object id. - `overwrite` :::: - (Required, boolean) when set to `true`, the saved object from the source space (desigated by the <>) will overwrite the the conflicting object in the destination space. When `false`, this does nothing. + `id`:::: + (Required, string) The saved object ID. + `overwrite`:::: + (Required, boolean) When set to `true`, the saved object from the source space (desigated by the <>) overwrites the conflicting object in the destination space. When set to `false`, this does nothing. [[spaces-api-resolve-copy-saved-objects-conflicts-response-body]] ==== {api-response-body-title} -//// -Response body is only required for detailed responses. - -For example: -`auto_follow_stats`:: - (object) An object representing stats for the auto-follow coordinator. This - object consists of the following fields: - -`auto_follow_stats.number_of_successful_follow_indices`::: - (long) the number of indices that the auto-follow coordinator successfully - followed -... - -//// ``:: - (object) Specifies the dynamic keys that are included in the response. An object describing the result of the copy operation for this particular space. + (object) An object that describes the result of the copy operation for the space. Includes the dynamic keys in the response. `success`::: - (boolean) Indicates if the copy operation was successful. Note that some objects may have been copied even if this is set to `false`. Consult the `successCount` and `errors` properties of the response for additional information. + (boolean) The copy operation was successful. When set to `false`, some objects may have been copied. For additional information, refer to the `successCount` and `errors` properties. `successCount`::: - (number) The number of objects that were successfully copied. + (number) The number of objects that successfully copied. `errors`::: - (Optional, array) Collection of any errors that were encountered during the copy operation. If any errors are reported, then the `success` flag will be set to `false`. + (Optional, array) The errors that occurred during the copy operation. When errors are reported, the `success` flag is set to `false`. `id`:::: - (string) The saved object id which failed to copy. + (string) The saved object ID that failed to copy. `type`:::: - (string) The type of saved object which failed to copy. + (string) The type of saved object that failed to copy. `error`:::: - (object) The error which caused the copy operation to fail. + (object) The error that caused the copy operation to fail. `type`::::: - (string) Indicates the type of error. May be one of: `unsupported_type`, `missing_references`, `unknown`. - -//// -[[spaces-api-resolve-copy-saved-objects-conflicts-response-codes]] -==== {api-response-codes-title} -//// -//// -Response codes are only required when needed to understand the response body. - -For example: -`200`:: -Indicates all listed indices or index aliases exist. - - `404`:: -Indicates one or more listed indices or index aliases **do not** exist. -//// + (string) The type of error. For example, `unsupported_type`, `missing_references`, or `unknown`. [[spaces-api-resolve-copy-saved-objects-conflicts-example]] ==== {api-examples-title} -//// -Optional brief example. -Use an 'Examples' heading if you include multiple examples. - - -[source,js] ----- -PUT /follower_index/_ccr/follow?wait_for_active_shards=1 -{ - "remote_cluster" : "remote_cluster", - "leader_index" : "leader_index", - "max_read_request_operation_count" : 1024, - "max_outstanding_read_requests" : 16, - "max_read_request_size" : "1024k", - "max_write_request_operation_count" : 32768, - "max_write_request_size" : "16k", - "max_outstanding_write_requests" : 8, - "max_write_buffer_count" : 512, - "max_write_buffer_size" : "512k", - "max_retry_delay" : "10s", - "read_poll_timeout" : "30s" -} ----- -// CONSOLE -// TEST[setup:remote_cluster_and_leader_index] - -The API returns the following result: - -[source,js] ----- -{ - "follow_index_created" : true, - "follow_index_shards_acked" : true, - "index_following_started" : true -} ----- -// TESTRESPONSE -//// -The following example overwrites an index pattern in the marketing space, and a visualization in the sales space. +Overwrite an index pattern in the `marketing` space, and a visualization in the `sales` space: -[source,js] +[source,sh] ---- -POST api/spaces/_resolve_copy_saved_objects_errors +$ curl -X POST "localhost:5601/api/spaces/_resolve_copy_saved_objects_errors" { "objects": [{ "type": "dashboard", @@ -248,9 +101,9 @@ POST api/spaces/_resolve_copy_saved_objects_errors ---- // KIBANA -The API returns the following result: +The API returns the following: -[source,js] +[source,sh] ---- { "marketing": { diff --git a/docs/api/upgrade-assistant.asciidoc b/docs/api/upgrade-assistant.asciidoc index b524307c0f273..15d87fbd0dc9d 100644 --- a/docs/api/upgrade-assistant.asciidoc +++ b/docs/api/upgrade-assistant.asciidoc @@ -2,7 +2,7 @@ [[upgrade-assistant-api]] == Upgrade assistant APIs -Check the upgrade status of your Elasticsearch cluster and reindex indices that were created in the previous major version. The assistant helps you prepare for the next major version of Elasticsearch. +Check the upgrade status of your {es} cluster and reindex indices that were created in the previous major version. The assistant helps you prepare for the next major version of {es}. The following upgrade assistant APIs are available: @@ -10,11 +10,17 @@ The following upgrade assistant APIs are available: * <> to start a new reindex or resume a paused reindex +* <> to start or resume multiple reindex tasks + +* <> to check the current reindex batch queue + * <> to check the status of the reindex operation -* <> to cancel reindexes that are waiting for the Elasticsearch reindex task to complete +* <> to cancel reindexes that are waiting for the {es} reindex task to complete include::upgrade-assistant/status.asciidoc[] include::upgrade-assistant/reindexing.asciidoc[] +include::upgrade-assistant/batch_reindexing.asciidoc[] +include::upgrade-assistant/batch_queue.asciidoc[] include::upgrade-assistant/check_reindex_status.asciidoc[] include::upgrade-assistant/cancel_reindex.asciidoc[] diff --git a/docs/api/upgrade-assistant/batch_queue.asciidoc b/docs/api/upgrade-assistant/batch_queue.asciidoc new file mode 100644 index 0000000000000..dcb9b465e4ddc --- /dev/null +++ b/docs/api/upgrade-assistant/batch_queue.asciidoc @@ -0,0 +1,68 @@ +[[batch-reindex-queue]] +=== Batch reindex queue API +++++ +Batch reindex queue +++++ + +experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] + +Check the current reindex batch queue. + +[[batch-reindex-queue-request]] +==== Request + +`GET /api/upgrade_assistant/reindex/batch/queue` + +[[batch-reindex-queue-request-codes]] +==== Response code + +`200`:: + Indicates a successful call. + +[[batch-reindex-queue-example]] +==== Example + +The API returns the following: + +[source,js] +-------------------------------------------------- +{ + "queue": [ <1> + { + "indexName": "index1", + "newIndexName": "reindexed-v8-index2", + "status": 3, + "lastCompletedStep": 0, + "locked": null, + "reindexTaskId": null, + "reindexTaskPercComplete": null, + "errorMessage": null, + "runningReindexCount": null, + "reindexOptions": { + "queueSettings": { + "queuedAt": 1583406985489 + } + } + }, + { + "indexName": "index2", + "newIndexName": "reindexed-v8-index2", + "status": 3, + "lastCompletedStep": 0, + "locked": null, + "reindexTaskId": null, + "reindexTaskPercComplete": null, + "errorMessage": null, + "runningReindexCount": null, + "reindexOptions": { + "queueSettings": { + "queuedAt": 1583406987334 + } + } + } + ] +} +-------------------------------------------------- + +<1> Items in this array indicate reindex tasks at a given point in time and the order in which they will be executed. + diff --git a/docs/api/upgrade-assistant/batch_reindexing.asciidoc b/docs/api/upgrade-assistant/batch_reindexing.asciidoc new file mode 100644 index 0000000000000..40b6d9c816d5c --- /dev/null +++ b/docs/api/upgrade-assistant/batch_reindexing.asciidoc @@ -0,0 +1,81 @@ +[[batch-start-resume-reindex]] +=== Batch start or resume reindex API +++++ +Batch start or resume reindex +++++ + +experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] + +Start or resume multiple reindexing tasks in one request. Additionally, reindexing tasks started or resumed +via the batch endpoint will be placed on a queue and executed one-by-one, which ensures that minimal cluster resources +are consumed over time. + +[[batch-start-resume-reindex-request]] +==== Request + +`POST /api/upgrade_assistant/reindex/batch` + +[[batch-start-resume-reindex-request-body]] +==== Request body + +`indexNames`:: + (Required, array) The list of index names to be reindexed. + +[[batch-start-resume-reindex-codes]] +==== Response code + +`200`:: + Indicates a successful call. + +[[batch-start-resume-example]] +==== Example + +[source,js] +-------------------------------------------------- +POST /api/upgrade_assistant/reindex/batch +{ + "indexNames": [ <1> + "index1", + "index2" + ] +} +-------------------------------------------------- +<1> The order in which the indices are provided here determines the order in which the reindex tasks will be executed. + +Similar to the <>, the API returns the following: + +[source,js] +-------------------------------------------------- +{ + "enqueued": [ <1> + { + "indexName": "index1", + "newIndexName": "reindexed-v8-index1", + "status": 3, + "lastCompletedStep": 0, + "locked": null, + "reindexTaskId": null, + "reindexTaskPercComplete": null, + "errorMessage": null, + "runningReindexCount": null, + "reindexOptions": { <2> + "queueSettings": { + "queuedAt": 1583406985489 <3> + } + } + } + ], + "errors": [ <4> + { + "indexName": "index2", + "message": "Something went wrong!" + } + ] +} +-------------------------------------------------- + +<1> A list of reindex operations created, the order in the array indicates the order in which tasks will be executed. +<2> Presence of this key indicates that the reindex job will occur in the batch. +<3> A Unix timestamp of when the reindex task was placed in the queue. +<4> A list of errors that may have occurred preventing the reindex task from being created. + diff --git a/docs/api/upgrade-assistant/cancel_reindex.asciidoc b/docs/api/upgrade-assistant/cancel_reindex.asciidoc index 8951f235c9265..04ab3bdde35fc 100644 --- a/docs/api/upgrade-assistant/cancel_reindex.asciidoc +++ b/docs/api/upgrade-assistant/cancel_reindex.asciidoc @@ -4,14 +4,14 @@ Cancel reindex ++++ -Cancel reindexes that are waiting for the Elasticsearch reindex task to complete. For example, `lastCompletedStep` set to `40`. +experimental[] Cancel reindexes that are waiting for the {es} reindex task to complete. For example, `lastCompletedStep` set to `40`. -experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] +Cancel reindexes that are waiting for the Elasticsearch reindex task to complete. For example, `lastCompletedStep` set to `40`. [[cancel-reindex-request]] ==== Request -`POST /api/upgrade_assistant/reindex/myIndex/cancel` +`POST :/api/upgrade_assistant/reindex/myIndex/cancel` [[cancel-reindex-response-codes]] ==== Response codes @@ -24,7 +24,7 @@ experimental["The underlying Upgrade Assistant concepts are stable, but the APIs The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "acknowledged": true diff --git a/docs/api/upgrade-assistant/check_reindex_status.asciidoc b/docs/api/upgrade-assistant/check_reindex_status.asciidoc index cb4664baf96b2..00801f201d1e1 100644 --- a/docs/api/upgrade-assistant/check_reindex_status.asciidoc +++ b/docs/api/upgrade-assistant/check_reindex_status.asciidoc @@ -4,27 +4,27 @@ Check reindex status ++++ -Check the status of the reindex operation. +experimental[] Check the status of the reindex operation. -experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] +Check the status of the reindex operation. [[check-reindex-status-request]] ==== Request -`GET /api/upgrade_assistant/reindex/myIndex` +`GET :/api/upgrade_assistant/reindex/myIndex` [[check-reindex-status-response-codes]] ==== Response codes `200`:: Indicates a successful call. - + [[check-reindex-status-example]] ==== Example The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "reindexOp": { @@ -53,59 +53,58 @@ The API returns the following: [[status-code]] ==== Status codes -`0`:: +`0`:: In progress -`1`:: +`1`:: Completed -`2`:: +`2`:: Failed - -`3`:: + +`3`:: Paused NOTE: If the {kib} node that started the reindex is shutdown or restarted, the reindex goes into a paused state after some time. To resume the reindex, you must submit a new POST request to the `/api/upgrade_assistant/reindex/` endpoint. -`4`:: +`4`:: Cancelled [[step-code]] ==== Step codes -`0`:: +`0`:: The reindex operation has been created in Kibana. - -`10`:: + +`10`:: The index group services stopped. Only applies to some system indices. - -`20`:: - The index is set to `readonly`. - -`30`:: + +`20`:: + The index is set to `readonly`. + +`30`:: The new destination index has been created. - -`40`:: + +`40`:: The reindex task in Elasticsearch has started. - -`50`:: + +`50`:: The reindex task in Elasticsearch has completed. - -`60`:: + +`60`:: Aliases were created to point to the new index, and the old index has been deleted. - -`70`:: + +`70`:: The index group services have resumed. Only applies to some system indices. [[warning-code]] ==== Warning codes -`0`:: +`0`:: Specifies to remove the `_all` meta field. - -`1`:: + +`1`:: Specifies to convert any coerced boolean values in the source document. For example, `yes`, `1`, and `off`. - -`2`:: - Specifies to convert documents to support Elastic Common Schema. Only applies to APM indices created in 6.x. +`2`:: + Specifies to convert documents to support Elastic Common Schema. Only applies to APM indices created in 6.x. diff --git a/docs/api/upgrade-assistant/reindexing.asciidoc b/docs/api/upgrade-assistant/reindexing.asciidoc index a6d5d9d0c16ac..ce5670822e5ad 100644 --- a/docs/api/upgrade-assistant/reindexing.asciidoc +++ b/docs/api/upgrade-assistant/reindexing.asciidoc @@ -4,14 +4,14 @@ Start or resume reindex ++++ -Start a new reindex or resume a paused reindex. +experimental[] Start a new reindex or resume a paused reindex. -experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] +Start a new reindex or resume a paused reindex. [[start-resume-reindex-request]] ==== Request -`POST /api/upgrade_assistant/reindex/myIndex` +`POST :/api/upgrade_assistant/reindex/myIndex` [[start-resume-reindex-codes]] ==== Response code @@ -24,7 +24,7 @@ experimental["The underlying Upgrade Assistant concepts are stable, but the APIs The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "indexName": ".ml-state", @@ -37,9 +37,9 @@ The API returns the following: } -------------------------------------------------- -<1> Name of the new index that is being created. -<2> Current status of the reindex. For details, see <>. -<3> Last successfully completed step of the reindex. For details, see <> table. -<4> Task ID of the reindex task in Elasticsearch. Only present if reindexing has started. -<5> Percentage of how far the reindexing task in Elasticsearch has progressed, in decimal from from 0 to 1. -<6> Error that caused the reindex to fail, if it failed. +<1> The name of the new index. +<2> The reindex status. For more information, refer to <>. +<3> The last successfully completed step of the reindex. For more information, refer to <>. +<4> The task ID of the reindex task in {es}. Appears when the reindexing starts. +<5> The progress of the reindexing task in {es}. Appears in decimal form, from 0 to 1. +<6> The error that caused the reindex to fail, if it failed. diff --git a/docs/api/upgrade-assistant/status.asciidoc b/docs/api/upgrade-assistant/status.asciidoc index 9ad77bcabff73..42030061c4289 100644 --- a/docs/api/upgrade-assistant/status.asciidoc +++ b/docs/api/upgrade-assistant/status.asciidoc @@ -4,14 +4,14 @@ Upgrade readiness status ++++ -Check the status of your cluster. +experimental[] Check the status of your cluster. -experimental["The underlying Upgrade Assistant concepts are stable, but the APIs for managing Upgrade Assistant are experimental."] +Check the status of your cluster. [[upgrade-assistant-api-status-request]] ==== Request -`GET /api/upgrade_assistant/status` +`GET :/api/upgrade_assistant/status` [[upgrade-assistant-api-status-response-codes]] ==== Response codes @@ -24,7 +24,7 @@ experimental["The underlying Upgrade Assistant concepts are stable, but the APIs The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "readyForUpgrade": false, diff --git a/docs/api/url-shortening.asciidoc b/docs/api/url-shortening.asciidoc index 8bc701a3d5d12..a62529e11a9ba 100644 --- a/docs/api/url-shortening.asciidoc +++ b/docs/api/url-shortening.asciidoc @@ -12,18 +12,18 @@ Short URLs are designed to make sharing {kib} URLs easier. [[url-shortening-api-request]] ==== Request -`POST /api/shorten_url` +`POST :/api/shorten_url` [[url-shortening-api-request-body]] ==== Request body `url`:: - (Required, string) The {kib} URL that you want to shorten, Relative to `/app/kibana`. + (Required, string) The {kib} URL that you want to shorten, relative to `/app/kibana`. [[url-shortening-api-response-body]] ==== Response body -urlId:: A top level property that contains the shortened URL token for the provided request body. +urlId:: A top-level property that contains the shortened URL token for the provided request body. [[url-shortening-api-codes]] ==== Response code @@ -31,21 +31,21 @@ urlId:: A top level property that contains the shortened URL token for the provi `200`:: Indicates a successful call. -[[url-shortening-api-example]] +[[url-shortening-api-example]] ==== Example -[source,js] +[source,sh] -------------------------------------------------- -POST api/shorten_url +$ curl -X POST "localhost:5601/api/shorten_url" { "url": "/app/kibana#/dashboard?_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(hidePanelTitles:!f,useMargins:!t),panels:!((embeddableConfig:(),gridData:(h:15,i:'1',w:24,x:0,y:0),id:'8f4d0c00-4c86-11e8-b3d7-01146121b73d',panelIndex:'1',type:visualization,version:'7.0.0-alpha1')),query:(language:lucene,query:''),timeRestore:!f,title:'New%20Dashboard',viewMode:edit)" } -------------------------------------------------- // KIBANA -The API returns the following result: +The API returns the following: -[source,js] +[source,sh] -------------------------------------------------- { "urlId": "f73b295ff92718b26bc94edac766d8e3" diff --git a/docs/api/using-api.asciidoc b/docs/api/using-api.asciidoc index 37c5315025dc4..aba65f2e921c2 100644 --- a/docs/api/using-api.asciidoc +++ b/docs/api/using-api.asciidoc @@ -33,6 +33,7 @@ For example, the following `curl` command exports a dashboard: -- curl -X POST -u $USER:$PASSWORD "localhost:5601/api/kibana/dashboards/export?dashboard=942dcef0-b2cd-11e8-ad8e-85441f0c2e5c" -- +// KIBANA [float] [[api-request-headers]] @@ -43,14 +44,14 @@ For all APIs, you must use a request header. The {kib} APIs support the `kbn-xsr `kbn-xsrf: true`:: By default, you must use `kbn-xsrf` for all API calls, except in the following scenarios: -* The API endpoint uses the `GET` or `HEAD` methods +* The API endpoint uses the `GET` or `HEAD` operations * The path is whitelisted using the <> setting * XSRF protections are disabled using the `server.xsrf.disableProtection` setting `Content-Type: application/json`:: - Applicable only when you send a payload in the API request. {kib} API requests and responses use JSON. Typically, if you include the `kbn-xsrf` header, you must also include the `Content-Type` header. + Applicable only when you send a payload in the API request. {kib} API requests and responses use JSON. Typically, if you include the `kbn-xsrf` header, you must also include the `Content-Type` header. Request header example: diff --git a/docs/developer/core/development-functional-tests.asciidoc b/docs/developer/core/development-functional-tests.asciidoc index dcb3d65b8b83f..51b5273851ce7 100644 --- a/docs/developer/core/development-functional-tests.asciidoc +++ b/docs/developer/core/development-functional-tests.asciidoc @@ -178,6 +178,25 @@ To run tests on Firefox locally, use `config.firefox.js`: node scripts/functional_test_runner --config test/functional/config.firefox.js ----------- +[float] +===== Using the test_user service + +Tests should run at the positive security boundry condition, meaning that they should be run with the mimimum privileges required (and documented) and not as the superuser. + This prevents the type of regression where additional privleges accidentally become required to perform the same action. + +The functional UI tests now default to logging in with a user named `test_user` and the roles of this user can be changed dynamically without logging in and out. + +In order to achieve this a new service was introduced called `createTestUserService` (see `test/common/services/security/test_user.ts`). The purpose of this test user service is to create roles defined in the test config files and setRoles() or restoreDefaults(). + +An example of how to set the role like how its defined below: + +`await security.testUser.setRoles(['kibana_user', 'kibana_date_nanos']);` + +Here we are setting the `test_user` to have the `kibana_user` role and also role access to a specific data index (`kibana_date_nanos`). + +Tests should normally setRoles() in the before() and restoreDefaults() in the after(). + + [float] ===== Anatomy of a test file diff --git a/docs/development/core/public/kibana-plugin-core-public.app.mount.md b/docs/development/core/public/kibana-plugin-core-public.app.mount.md index c42f73ced95af..8a9dfd9e2e972 100644 --- a/docs/development/core/public/kibana-plugin-core-public.app.mount.md +++ b/docs/development/core/public/kibana-plugin-core-public.app.mount.md @@ -14,5 +14,5 @@ mount: AppMount | AppMountDeprecated ## Remarks -When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md index e5554be515077..fc99e2208220f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.md @@ -17,5 +17,5 @@ export interface ApplicationSetup | --- | --- | | [register(app)](./kibana-plugin-core-public.applicationsetup.register.md) | Register an mountable application to the system. | | [registerAppUpdater(appUpdater$)](./kibana-plugin-core-public.applicationsetup.registerappupdater.md) | Register an application updater that can be used to change the [AppUpdatableFields](./kibana-plugin-core-public.appupdatablefields.md) fields of all applications at runtime.This is meant to be used by plugins that needs to updates the whole list of applications. To only updates a specific application, use the updater$ property of the registered application instead. | -| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationsetup.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationsetup.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md index 92a7ae1c0deee..1735d5df943ae 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationsetup.registermountcontext.md @@ -8,7 +8,7 @@ > > -Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md index 834411de5d57c..a93bc61bac527 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md @@ -24,5 +24,5 @@ export interface ApplicationStart | --- | --- | | [getUrlForApp(appId, options)](./kibana-plugin-core-public.applicationstart.geturlforapp.md) | Returns an URL to a given app, including the global base path. By default, the URL is relative (/basePath/app/my-app). Use the absolute option to generate an absolute url (http://host:port/basePath/app/my-app)Note that when generating absolute urls, the protocol, host and port are determined from the browser location. | | [navigateToApp(appId, options)](./kibana-plugin-core-public.applicationstart.navigatetoapp.md) | Navigate to a given app | -| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationstart.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationstart.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md index 6e0fbb46e9a1e..11f661c4af2b3 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.registermountcontext.md @@ -8,7 +8,7 @@ > > -Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md b/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md index d0b243859aab0..52a36b0b56f02 100644 --- a/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.appmountcontext.md @@ -8,7 +8,7 @@ > > -The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md b/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md index 130689882495a..66b8a69d84a38 100644 --- a/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md +++ b/docs/development/core/public/kibana-plugin-core-public.appmountdeprecated.md @@ -18,5 +18,5 @@ export declare type AppMountDeprecated = (contex ## Remarks -When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). +When function has two arguments, it will be called with a [context](./kibana-plugin-core-public.appmountcontext.md) as the first argument. This behavior is \*\*deprecated\*\*, and consumers should instead use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md deleted file mode 100644 index 205f863526e22..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md +++ /dev/null @@ -1,17 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [getIsCollapsed$](./kibana-plugin-core-public.chromestart.getiscollapsed_.md) - -## ChromeStart.getIsCollapsed$() method - -Get an observable of the current collapsed state of the chrome. - -Signature: - -```typescript -getIsCollapsed$(): Observable; -``` -Returns: - -`Observable` - diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md new file mode 100644 index 0000000000000..78a4442a651e6 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [getIsNavDrawerLocked$](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) + +## ChromeStart.getIsNavDrawerLocked$() method + +Get an observable of the current locked state of the nav drawer. + +Signature: + +```typescript +getIsNavDrawerLocked$(): Observable; +``` +Returns: + +`Observable` + 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/public/kibana-plugin-core-public.coresetup.getstartservices.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md index 91b906cf83d01..e4fec4eae31b1 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.getstartservices.md @@ -2,16 +2,12 @@ [Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreSetup](./kibana-plugin-core-public.coresetup.md) > [getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md) -## CoreSetup.getStartServices() method +## CoreSetup.getStartServices property -Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed `start`. +[StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) Signature: ```typescript -getStartServices(): Promise<[CoreStart, TPluginsStart]>; +getStartServices: StartServicesAccessor; ``` -Returns: - -`Promise<[CoreStart, TPluginsStart]>` - diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.md index f211b740e84a3..c039bc19348cc 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.md @@ -19,14 +19,9 @@ export interface CoreSetup | [application](./kibana-plugin-core-public.coresetup.application.md) | ApplicationSetup | [ApplicationSetup](./kibana-plugin-core-public.applicationsetup.md) | | [context](./kibana-plugin-core-public.coresetup.context.md) | ContextSetup | [ContextSetup](./kibana-plugin-core-public.contextsetup.md) | | [fatalErrors](./kibana-plugin-core-public.coresetup.fatalerrors.md) | FatalErrorsSetup | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | +| [getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md) | StartServicesAccessor<TPluginsStart> | [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) | | [http](./kibana-plugin-core-public.coresetup.http.md) | HttpSetup | [HttpSetup](./kibana-plugin-core-public.httpsetup.md) | | [injectedMetadata](./kibana-plugin-core-public.coresetup.injectedmetadata.md) | {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
} | exposed temporarily until https://github.com/elastic/kibana/issues/41990 done use \*only\* to retrieve config values. There is no way to set injected values in the new platform. Use the legacy platform API instead. | | [notifications](./kibana-plugin-core-public.coresetup.notifications.md) | NotificationsSetup | [NotificationsSetup](./kibana-plugin-core-public.notificationssetup.md) | | [uiSettings](./kibana-plugin-core-public.coresetup.uisettings.md) | IUiSettingsClient | [IUiSettingsClient](./kibana-plugin-core-public.iuisettingsclient.md) | -## Methods - -| Method | Description | -| --- | --- | -| [getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md) | Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed start. | - diff --git a/docs/development/core/public/kibana-plugin-core-public.errortoastoptions.md b/docs/development/core/public/kibana-plugin-core-public.errortoastoptions.md index cda64018c3f69..dc256e6f5bc06 100644 --- a/docs/development/core/public/kibana-plugin-core-public.errortoastoptions.md +++ b/docs/development/core/public/kibana-plugin-core-public.errortoastoptions.md @@ -4,12 +4,12 @@ ## ErrorToastOptions interface -Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. +Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. Signature: ```typescript -export interface ErrorToastOptions +export interface ErrorToastOptions extends ToastOptions ``` ## Properties diff --git a/docs/development/core/public/kibana-plugin-core-public.itoasts.md b/docs/development/core/public/kibana-plugin-core-public.itoasts.md index 305ed82ea5693..e009c77fe23bc 100644 --- a/docs/development/core/public/kibana-plugin-core-public.itoasts.md +++ b/docs/development/core/public/kibana-plugin-core-public.itoasts.md @@ -9,5 +9,5 @@ Methods for adding and removing global toast messages. See [ToastsApi](./kibana- Signature: ```typescript -export declare type IToasts = Pick; +export declare type IToasts = Pick; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index a9fbaa25ea150..adc87de2b9e7e 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -38,7 +38,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AppLeaveDefaultAction](./kibana-plugin-core-public.appleavedefaultaction.md) | Action to return from a [AppLeaveHandler](./kibana-plugin-core-public.appleavehandler.md) to execute the default behaviour when leaving the application.See | | [ApplicationSetup](./kibana-plugin-core-public.applicationsetup.md) | | | [ApplicationStart](./kibana-plugin-core-public.applicationstart.md) | | -| [AppMountContext](./kibana-plugin-core-public.appmountcontext.md) | The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices()](./kibana-plugin-core-public.coresetup.getstartservices.md). | +| [AppMountContext](./kibana-plugin-core-public.appmountcontext.md) | The context object received when applications are mounted to the DOM. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | | [AppMountParameters](./kibana-plugin-core-public.appmountparameters.md) | | | [Capabilities](./kibana-plugin-core-public.capabilities.md) | The read-only set of capabilities available for the current UI session. Capabilities are simple key-value pairs of (string, boolean), where the string denotes the capability ID, and the boolean is a flag indicating if the capability is enabled or disabled. | | [ChromeBadge](./kibana-plugin-core-public.chromebadge.md) | | @@ -57,7 +57,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [CoreStart](./kibana-plugin-core-public.corestart.md) | Core services exposed to the Plugin start lifecycle | | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | | [EnvironmentMode](./kibana-plugin-core-public.environmentmode.md) | | -| [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. | +| [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. | | [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the message and stack of a fatal Error | | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpFetchOptions](./kibana-plugin-core-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-core-public.httphandler.md). | @@ -115,6 +115,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsUpdateOptions](./kibana-plugin-core-public.savedobjectsupdateoptions.md) | | | [StringValidationRegex](./kibana-plugin-core-public.stringvalidationregex.md) | StringValidation with regex object | | [StringValidationRegexString](./kibana-plugin-core-public.stringvalidationregexstring.md) | StringValidation as regex string | +| [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. | | [UiSettingsParams](./kibana-plugin-core-public.uisettingsparams.md) | UiSettings parameters defined by the plugins. | | [UiSettingsState](./kibana-plugin-core-public.uisettingsstate.md) | | | [UserProvidedValues](./kibana-plugin-core-public.userprovidedvalues.md) | Describes the values explicitly set by user. | @@ -152,6 +153,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectAttribute](./kibana-plugin-core-public.savedobjectattribute.md) | Type definition for a Saved Object attribute value | | [SavedObjectAttributeSingle](./kibana-plugin-core-public.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-core-public.savedobjectattribute.md) | | [SavedObjectsClientContract](./kibana-plugin-core-public.savedobjectsclientcontract.md) | SavedObjectsClientContract as implemented by the [SavedObjectsClient](./kibana-plugin-core-public.savedobjectsclient.md) | +| [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) | Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed start. | | [StringValidation](./kibana-plugin-core-public.stringvalidation.md) | Allows regex objects or a regex string | | [Toast](./kibana-plugin-core-public.toast.md) | | | [ToastInput](./kibana-plugin-core-public.toastinput.md) | Inputs for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. | diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobject.md b/docs/development/core/public/kibana-plugin-core-public.savedobject.md index 9ced619ad4bfe..c6bc13b98bc06 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobject.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobject.md @@ -4,7 +4,6 @@ ## SavedObject interface - Signature: ```typescript diff --git a/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md b/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md new file mode 100644 index 0000000000000..02e896a6b47e5 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.startservicesaccessor.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [StartServicesAccessor](./kibana-plugin-core-public.startservicesaccessor.md) + +## StartServicesAccessor type + +Allows plugins to get access to APIs available in start inside async handlers, such as [App.mount](./kibana-plugin-core-public.app.mount.md). Promise will not resolve until Core and plugin dependencies have completed `start`. + +Signature: + +```typescript +export declare type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.toastoptions.md b/docs/development/core/public/kibana-plugin-core-public.toastoptions.md new file mode 100644 index 0000000000000..0d85c482c2288 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.toastoptions.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ToastOptions](./kibana-plugin-core-public.toastoptions.md) + +## ToastOptions interface + +Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. + +Signature: + +```typescript +export interface ToastOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [toastLifeTimeMs](./kibana-plugin-core-public.toastoptions.toastlifetimems.md) | number | How long should the toast remain on screen. | + diff --git a/docs/development/core/public/kibana-plugin-core-public.toastoptions.toastlifetimems.md b/docs/development/core/public/kibana-plugin-core-public.toastoptions.toastlifetimems.md new file mode 100644 index 0000000000000..bb0e2f9afc83b --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.toastoptions.toastlifetimems.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ToastOptions](./kibana-plugin-core-public.toastoptions.md) > [toastLifeTimeMs](./kibana-plugin-core-public.toastoptions.toastlifetimems.md) + +## ToastOptions.toastLifeTimeMs property + +How long should the toast remain on screen. + +Signature: + +```typescript +toastLifeTimeMs?: number; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.toastsapi.adddanger.md b/docs/development/core/public/kibana-plugin-core-public.toastsapi.adddanger.md index e8cc9ff74e0c4..420100a1209ab 100644 --- a/docs/development/core/public/kibana-plugin-core-public.toastsapi.adddanger.md +++ b/docs/development/core/public/kibana-plugin-core-public.toastsapi.adddanger.md @@ -9,7 +9,7 @@ Adds a new toast pre-configured with the danger color and alert icon. Signature: ```typescript -addDanger(toastOrTitle: ToastInput): Toast; +addDanger(toastOrTitle: ToastInput, options?: ToastOptions): Toast; ``` ## Parameters @@ -17,6 +17,7 @@ addDanger(toastOrTitle: ToastInput): Toast; | Parameter | Type | Description | | --- | --- | --- | | toastOrTitle | ToastInput | a [ToastInput](./kibana-plugin-core-public.toastinput.md) | +| options | ToastOptions | a [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | Returns: diff --git a/docs/development/core/public/kibana-plugin-core-public.toastsapi.addinfo.md b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addinfo.md new file mode 100644 index 0000000000000..76508d26b4ae9 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addinfo.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ToastsApi](./kibana-plugin-core-public.toastsapi.md) > [addInfo](./kibana-plugin-core-public.toastsapi.addinfo.md) + +## ToastsApi.addInfo() method + +Adds a new toast pre-configured with the info color and info icon. + +Signature: + +```typescript +addInfo(toastOrTitle: ToastInput, options?: ToastOptions): Toast; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| toastOrTitle | ToastInput | a [ToastInput](./kibana-plugin-core-public.toastinput.md) | +| options | ToastOptions | a [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | + +Returns: + +`Toast` + +a [Toast](./kibana-plugin-core-public.toast.md) + diff --git a/docs/development/core/public/kibana-plugin-core-public.toastsapi.addsuccess.md b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addsuccess.md index 160cbd4bf6b29..c79f48042514a 100644 --- a/docs/development/core/public/kibana-plugin-core-public.toastsapi.addsuccess.md +++ b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addsuccess.md @@ -9,7 +9,7 @@ Adds a new toast pre-configured with the success color and check icon. Signature: ```typescript -addSuccess(toastOrTitle: ToastInput): Toast; +addSuccess(toastOrTitle: ToastInput, options?: ToastOptions): Toast; ``` ## Parameters @@ -17,6 +17,7 @@ addSuccess(toastOrTitle: ToastInput): Toast; | Parameter | Type | Description | | --- | --- | --- | | toastOrTitle | ToastInput | a [ToastInput](./kibana-plugin-core-public.toastinput.md) | +| options | ToastOptions | a [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | Returns: diff --git a/docs/development/core/public/kibana-plugin-core-public.toastsapi.addwarning.md b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addwarning.md index 17f94cc5b4553..6154af148332d 100644 --- a/docs/development/core/public/kibana-plugin-core-public.toastsapi.addwarning.md +++ b/docs/development/core/public/kibana-plugin-core-public.toastsapi.addwarning.md @@ -9,7 +9,7 @@ Adds a new toast pre-configured with the warning color and help icon. Signature: ```typescript -addWarning(toastOrTitle: ToastInput): Toast; +addWarning(toastOrTitle: ToastInput, options?: ToastOptions): Toast; ``` ## Parameters @@ -17,6 +17,7 @@ addWarning(toastOrTitle: ToastInput): Toast; | Parameter | Type | Description | | --- | --- | --- | | toastOrTitle | ToastInput | a [ToastInput](./kibana-plugin-core-public.toastinput.md) | +| options | ToastOptions | a [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | Returns: diff --git a/docs/development/core/public/kibana-plugin-core-public.toastsapi.md b/docs/development/core/public/kibana-plugin-core-public.toastsapi.md index 4aa240fba0061..ca4c08989128a 100644 --- a/docs/development/core/public/kibana-plugin-core-public.toastsapi.md +++ b/docs/development/core/public/kibana-plugin-core-public.toastsapi.md @@ -23,10 +23,11 @@ export declare class ToastsApi implements IToasts | Method | Modifiers | Description | | --- | --- | --- | | [add(toastOrTitle)](./kibana-plugin-core-public.toastsapi.add.md) | | Adds a new toast to current array of toast. | -| [addDanger(toastOrTitle)](./kibana-plugin-core-public.toastsapi.adddanger.md) | | Adds a new toast pre-configured with the danger color and alert icon. | +| [addDanger(toastOrTitle, options)](./kibana-plugin-core-public.toastsapi.adddanger.md) | | Adds a new toast pre-configured with the danger color and alert icon. | | [addError(error, options)](./kibana-plugin-core-public.toastsapi.adderror.md) | | Adds a new toast that displays an exception message with a button to open the full stacktrace in a modal. | -| [addSuccess(toastOrTitle)](./kibana-plugin-core-public.toastsapi.addsuccess.md) | | Adds a new toast pre-configured with the success color and check icon. | -| [addWarning(toastOrTitle)](./kibana-plugin-core-public.toastsapi.addwarning.md) | | Adds a new toast pre-configured with the warning color and help icon. | +| [addInfo(toastOrTitle, options)](./kibana-plugin-core-public.toastsapi.addinfo.md) | | Adds a new toast pre-configured with the info color and info icon. | +| [addSuccess(toastOrTitle, options)](./kibana-plugin-core-public.toastsapi.addsuccess.md) | | Adds a new toast pre-configured with the success color and check icon. | +| [addWarning(toastOrTitle, options)](./kibana-plugin-core-public.toastsapi.addwarning.md) | | Adds a new toast pre-configured with the warning color and help icon. | | [get$()](./kibana-plugin-core-public.toastsapi.get_.md) | | Observable of the toast messages to show to the user. | | [remove(toastOrId)](./kibana-plugin-core-public.toastsapi.remove.md) | | Removes a toast from the current array of toasts if present. | diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md index 10a656363c0d0..ea8e610ee56de 100644 --- a/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.getstartservices.md @@ -2,16 +2,12 @@ [Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [CoreSetup](./kibana-plugin-core-server.coresetup.md) > [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) -## CoreSetup.getStartServices() method +## CoreSetup.getStartServices property -Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed `start`. This should only be used inside handlers registered during `setup` that will only be executed after `start` lifecycle. +[StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) Signature: ```typescript -getStartServices(): Promise<[CoreStart, TPluginsStart]>; +getStartServices: StartServicesAccessor; ``` -Returns: - -`Promise<[CoreStart, TPluginsStart]>` - diff --git a/docs/development/core/server/kibana-plugin-core-server.coresetup.md b/docs/development/core/server/kibana-plugin-core-server.coresetup.md index 5b5803629cc86..b0eba8ac78063 100644 --- a/docs/development/core/server/kibana-plugin-core-server.coresetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.coresetup.md @@ -19,15 +19,10 @@ export interface CoreSetup | [capabilities](./kibana-plugin-core-server.coresetup.capabilities.md) | CapabilitiesSetup | [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) | | [context](./kibana-plugin-core-server.coresetup.context.md) | ContextSetup | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) | | [elasticsearch](./kibana-plugin-core-server.coresetup.elasticsearch.md) | ElasticsearchServiceSetup | [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) | +| [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) | StartServicesAccessor<TPluginsStart> | [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) | | [http](./kibana-plugin-core-server.coresetup.http.md) | HttpServiceSetup | [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) | | [metrics](./kibana-plugin-core-server.coresetup.metrics.md) | MetricsServiceSetup | [MetricsServiceSetup](./kibana-plugin-core-server.metricsservicesetup.md) | | [savedObjects](./kibana-plugin-core-server.coresetup.savedobjects.md) | SavedObjectsServiceSetup | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) | | [uiSettings](./kibana-plugin-core-server.coresetup.uisettings.md) | UiSettingsServiceSetup | [UiSettingsServiceSetup](./kibana-plugin-core-server.uisettingsservicesetup.md) | | [uuid](./kibana-plugin-core-server.coresetup.uuid.md) | UuidServiceSetup | [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) | -## Methods - -| Method | Description | -| --- | --- | -| [getStartServices()](./kibana-plugin-core-server.coresetup.getstartservices.md) | Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed start. This should only be used inside handlers registered during setup that will only be executed after start lifecycle. | - diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index 54cf496b2d6af..a1158dc853918 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -259,6 +259,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsFieldMapping](./kibana-plugin-core-server.savedobjectsfieldmapping.md) | Describe a [saved object type mapping](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) field.Please refer to [elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html) For the mapping documentation | | [ScopeableRequest](./kibana-plugin-core-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.See [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md). | | [SharedGlobalConfig](./kibana-plugin-core-server.sharedglobalconfig.md) | | +| [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) | Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed start. This should only be used inside handlers registered during setup that will only be executed after start lifecycle. | | [StringValidation](./kibana-plugin-core-server.stringvalidation.md) | Allows regex objects or a regex string | | [UiSettingsType](./kibana-plugin-core-server.uisettingstype.md) | UI element type to represent the settings. | 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/core/server/kibana-plugin-core-server.savedobject.md b/docs/development/core/server/kibana-plugin-core-server.savedobject.md index ebb105c846aff..0df97b0d4221a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobject.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobject.md @@ -4,7 +4,6 @@ ## SavedObject interface - Signature: ```typescript diff --git a/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md b/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md new file mode 100644 index 0000000000000..4de781fc99cc1 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.startservicesaccessor.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) + +## StartServicesAccessor type + +Allows plugins to get access to APIs available in start inside async handlers. Promise will not resolve until Core and plugin dependencies have completed `start`. This should only be used inside handlers registered during `setup` that will only be executed after `start` lifecycle. + +Signature: + +```typescript +export declare type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md new file mode 100644 index 0000000000000..2ef8c797f4054 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) + +## AggConfigOptions.enabled property + +Signature: + +```typescript +enabled?: boolean; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md new file mode 100644 index 0000000000000..8939854ab19ca --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) + +## AggConfigOptions.id property + +Signature: + +```typescript +id?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md new file mode 100644 index 0000000000000..b841d9b04d6a7 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) + +## AggConfigOptions interface + +Signature: + +```typescript +export interface AggConfigOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [enabled](./kibana-plugin-plugins-data-public.aggconfigoptions.enabled.md) | boolean | | +| [id](./kibana-plugin-plugins-data-public.aggconfigoptions.id.md) | string | | +| [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) | Record<string, any> | | +| [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) | string | | +| [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) | IAggType | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md new file mode 100644 index 0000000000000..45219a837cc33 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [params](./kibana-plugin-plugins-data-public.aggconfigoptions.params.md) + +## AggConfigOptions.params property + +Signature: + +```typescript +params?: Record; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md new file mode 100644 index 0000000000000..b2b42eb2e5b4d --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.schema.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [schema](./kibana-plugin-plugins-data-public.aggconfigoptions.schema.md) + +## AggConfigOptions.schema property + +Signature: + +```typescript +schema?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md new file mode 100644 index 0000000000000..866065ce52ba6 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.aggconfigoptions.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) > [type](./kibana-plugin-plugins-data-public.aggconfigoptions.type.md) + +## AggConfigOptions.type property + +Signature: + +```typescript +type: IAggType; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md index e7341caf7b3cd..c5e01715534d1 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | 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/public/kibana-plugin-plugins-data-public.filterbar.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filterbar.md index 016adffd0d7f4..6d8862323792a 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filterbar.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.filterbar.md @@ -7,7 +7,7 @@ Signature: ```typescript -FilterBar: React.ComponentClass, any> & { +FilterBar: React.ComponentClass, any> & { WrappedComponent: React.ComponentType; } ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md index e5ae8ffbd2877..30c3aa946c1ce 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index f8516ec476e88..ea77d6f39389b 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -48,6 +48,7 @@ | Interface | Description | | --- | --- | +| [AggConfigOptions](./kibana-plugin-plugins-data-public.aggconfigoptions.md) | | | [AggParamOption](./kibana-plugin-plugins-data-public.aggparamoption.md) | | | [DataPublicPluginSetup](./kibana-plugin-plugins-data-public.datapublicpluginsetup.md) | | | [DataPublicPluginStart](./kibana-plugin-plugins-data-public.datapublicpluginstart.md) | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md index 58690300b3bd6..d0d4cc491e142 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md @@ -7,5 +7,5 @@ Signature: ```typescript -QueryStringInput: React.FC> +QueryStringInput: React.FC> ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md index 5cdf938a9e47f..a0b879673e553 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.searchbar.md @@ -7,7 +7,7 @@ Signature: ```typescript -SearchBar: React.ComponentClass, "query" | "isLoading" | "indexPatterns" | "filters" | "onQueryChange" | "customSubmitButton" | "screenTitle" | "dataTestSubj" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "refreshInterval" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "onRefresh" | "timeHistory" | "onFiltersUpdated" | "onRefreshChange">, any> & { - WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; +SearchBar: React.ComponentClass, "query" | "isLoading" | "filters" | "indexPatterns" | "refreshInterval" | "screenTitle" | "dataTestSubj" | "customSubmitButton" | "showQueryBar" | "showQueryInput" | "showFilterBar" | "showDatePicker" | "showAutoRefreshOnly" | "isRefreshPaused" | "dateRangeFrom" | "dateRangeTo" | "showSaveQuery" | "savedQuery" | "onQueryChange" | "onQuerySubmit" | "onSaved" | "onSavedQueryUpdated" | "onClearSavedQuery" | "onRefresh" | "timeHistory" | "onFiltersUpdated" | "onRefreshChange">, any> & { + WrappedComponent: React.ComponentType & ReactIntl.InjectedIntlProps>; } ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md index 81a7cbca77c48..d071955f4f522 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.es_field_types.md @@ -30,6 +30,7 @@ export declare enum ES_FIELD_TYPES | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | | HALF\_FLOAT | "half_float" | | +| HISTOGRAM | "histogram" | | | INTEGER | "integer" | | | IP | "ip" | | | KEYWORD | "keyword" | | 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.kbn_field_types.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md index 40b81d2f6ac4d..a0a64190497c8 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.kbn_field_types.md @@ -23,6 +23,7 @@ export declare enum KBN_FIELD_TYPES | DATE | "date" | | | GEO\_POINT | "geo_point" | | | GEO\_SHAPE | "geo_shape" | | +| HISTOGRAM | "histogram" | | | IP | "ip" | | | MURMUR3 | "murmur3" | | | NESTED | "nested" | | 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..e756eb9b72905 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 @@ -67,9 +67,9 @@ | 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) | | +| [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) | | | [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.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/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 71bb7b81ea420..a72c15190840a 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -193,7 +193,7 @@ that feature would not take any effect. `logging.rotate.everyBytes:`:: [experimental] *Default: 10485760* The maximum size of a log file (that is `not an exact` limit). After the limit is reached, a new log file is generated. The default size limit is 10485760 (10 MB) and -this option should be in the range of 102400 (100KB) to 1073741824 (1GB). +this option should be in the range of 1048576 (1 MB) to 1073741824 (1 GB). `logging.rotate.keepFiles:`:: [experimental] *Default: 7* The number of most recent rotated log files to keep on disk. Older files are deleted during log rotation. The default value is 7. The `logging.rotate.keepFiles` @@ -203,7 +203,7 @@ option has to be in the range of 2 to 1024 files. the `logging.rotate.usePolling` is enabled. That option has to be in the range of 5000 to 3600000 milliseconds. `logging.rotate.usePolling:`:: [experimental] *Default: false* By default we try to understand the best way to monitoring -the log file. However, there is some systems where it could not be always accurate. In those cases, if needed, +the log file and warning about it. Please be aware there are some systems where watch api is not accurate. In those cases, in order to get the feature working, the `polling` method could be used enabling that option. `logging.silent:`:: *Default: false* Set the value of this setting to `true` to 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/examples/alerting_example/public/alert_types/index.ts b/examples/alerting_example/public/alert_types/index.ts new file mode 100644 index 0000000000000..96d9c09d15836 --- /dev/null +++ b/examples/alerting_example/public/alert_types/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 { 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'; + +export function registerNavigation(alerting: AlertingSetup) { + // register default navigation + alerting.registerDefaultNavigation( + ALERTING_EXAMPLE_APP_ID, + (alert: SanitizedAlert) => `/alert/${alert.id}` + ); + + 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..e418ed91096eb --- /dev/null +++ b/examples/alerting_example/public/components/view_alert.tsx @@ -0,0 +1,120 @@ +/* + * 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, + BASE_ALERT_API_PATH, +} 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(`${BASE_ALERT_API_PATH}/${id}`).then(setAlert); + } + if (!alertState) { + http.get(`${BASE_ALERT_API_PATH}/${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..296269180dd7b --- /dev/null +++ b/examples/alerting_example/public/components/view_astros_alert.tsx @@ -0,0 +1,127 @@ +/* + * 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, + BASE_ALERT_API_PATH, +} 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(`${BASE_ALERT_API_PATH}/${id}`).then(setAlert); + } + if (!alertState) { + http.get(`${BASE_ALERT_API_PATH}/${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/examples/alerting_example/public/index.ts b/examples/alerting_example/public/index.ts new file mode 100644 index 0000000000000..4a2bfc79903c3 --- /dev/null +++ b/examples/alerting_example/public/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. + */ + +import { AlertingExamplePlugin } from './plugin'; + +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/examples/alerting_example/server/plugin.ts b/examples/alerting_example/server/plugin.ts new file mode 100644 index 0000000000000..b5dabe51e8685 --- /dev/null +++ b/examples/alerting_example/server/plugin.ts @@ -0,0 +1,39 @@ +/* + * 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 } from 'kibana/server'; +import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerting/server'; + +import { alertType as alwaysFiringAlert } from './alert_types/always_firing'; +import { alertType as peopleInSpaceAlert } from './alert_types/astros'; + +// this plugin's dependendencies +export interface AlertingExampleDeps { + alerting: AlertingSetup; +} + +export class AlertingExamplePlugin implements Plugin { + public setup(core: CoreSetup, { alerting }: AlertingExampleDeps) { + alerting.registerType(alwaysFiringAlert); + alerting.registerType(peopleInSpaceAlert); + } + + 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/examples/ui_action_examples/public/plugin.ts b/examples/ui_action_examples/public/plugin.ts index c47746d4b3fd6..d053f7e82862c 100644 --- a/examples/ui_action_examples/public/plugin.ts +++ b/examples/ui_action_examples/public/plugin.ts @@ -46,7 +46,7 @@ export class UiActionExamplesPlugin })); uiActions.registerAction(helloWorldAction); - uiActions.attachAction(helloWorldTrigger.id, helloWorldAction); + uiActions.addTriggerAction(helloWorldTrigger.id, helloWorldAction); } public start() {} diff --git a/examples/ui_actions_explorer/public/app.tsx b/examples/ui_actions_explorer/public/app.tsx index 462f5c3bf88ba..f08b8bb29bdd3 100644 --- a/examples/ui_actions_explorer/public/app.tsx +++ b/examples/ui_actions_explorer/public/app.tsx @@ -95,8 +95,7 @@ const ActionsExplorer = ({ uiActionsApi, openModal }: Props) => { ); }, }); - uiActionsApi.registerAction(dynamicAction); - uiActionsApi.attachAction(HELLO_WORLD_TRIGGER_ID, dynamicAction); + uiActionsApi.addTriggerAction(HELLO_WORLD_TRIGGER_ID, dynamicAction); setConfirmationText( `You've successfully added a new action: ${dynamicAction.getDisplayName( {} diff --git a/examples/ui_actions_explorer/public/plugin.tsx b/examples/ui_actions_explorer/public/plugin.tsx index f1895905a45e1..de86b51aee3a8 100644 --- a/examples/ui_actions_explorer/public/plugin.tsx +++ b/examples/ui_actions_explorer/public/plugin.tsx @@ -79,21 +79,21 @@ export class UiActionsExplorerPlugin implements Plugin (await startServices)[1].uiActions) ); - deps.uiActions.attachAction( + deps.uiActions.addTriggerAction( USER_TRIGGER, createEditUserAction(async () => (await startServices)[0].overlays.openModal) ); - deps.uiActions.attachAction(COUNTRY_TRIGGER, viewInMapsAction); - deps.uiActions.attachAction(COUNTRY_TRIGGER, lookUpWeatherAction); - deps.uiActions.attachAction(COUNTRY_TRIGGER, showcasePluggability); - deps.uiActions.attachAction(PHONE_TRIGGER, makePhoneCallAction); - deps.uiActions.attachAction(PHONE_TRIGGER, showcasePluggability); - deps.uiActions.attachAction(USER_TRIGGER, showcasePluggability); + deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, viewInMapsAction); + deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, lookUpWeatherAction); + deps.uiActions.addTriggerAction(COUNTRY_TRIGGER, showcasePluggability); + deps.uiActions.addTriggerAction(PHONE_TRIGGER, makePhoneCallAction); + deps.uiActions.addTriggerAction(PHONE_TRIGGER, showcasePluggability); + deps.uiActions.addTriggerAction(USER_TRIGGER, showcasePluggability); core.application.register({ id: 'uiActionsExplorer', diff --git a/package.json b/package.json index b3dcfb2aa3b0a..08668730f9a9d 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/*", @@ -117,10 +118,10 @@ "@babel/core": "^7.5.5", "@babel/register": "^7.7.0", "@elastic/apm-rum": "^4.6.0", - "@elastic/charts": "^17.1.1", + "@elastic/charts": "^18.1.0", "@elastic/datemath": "5.0.2", - "@elastic/ems-client": "7.6.0", - "@elastic/eui": "20.0.2", + "@elastic/ems-client": "7.7.0", + "@elastic/eui": "21.0.1", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "2.4.0", @@ -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", @@ -346,10 +348,10 @@ "@types/lru-cache": "^5.1.0", "@types/markdown-it": "^0.0.7", "@types/minimatch": "^2.0.29", - "@types/mocha": "^5.2.7", + "@types/mocha": "^7.0.2", "@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", @@ -454,12 +456,12 @@ "license-checker": "^16.0.0", "listr": "^0.14.1", "load-grunt-config": "^3.0.1", - "mocha": "^6.2.2", + "mocha": "^7.1.1", "mock-http-server": "1.3.0", "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/packages/kbn-ui-shared-deps/monaco.ts b/packages/kbn-ui-shared-deps/monaco.ts index 570aca86c484c..42801c69a3e2c 100644 --- a/packages/kbn-ui-shared-deps/monaco.ts +++ b/packages/kbn-ui-shared-deps/monaco.ts @@ -25,6 +25,8 @@ import 'monaco-editor/esm/vs/base/worker/defaultWorkerFactory'; import 'monaco-editor/esm/vs/editor/browser/controller/coreCommands.js'; import 'monaco-editor/esm/vs/editor/browser/widget/codeEditorWidget.js'; +import 'monaco-editor/esm/vs/editor/contrib/wordOperations/wordOperations.js'; // Needed for word-wise char navigation + import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js'; // Needed for suggestions import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js'; // Needed for hover import 'monaco-editor/esm/vs/editor/contrib/parameterHints/parameterHints.js'; // Needed for signature diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 65fd837ad17c2..1e9ceb42433f0 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -9,9 +9,9 @@ "kbn:watch": "node scripts/build --watch" }, "devDependencies": { - "@elastic/charts": "^17.1.1", + "@elastic/charts": "^18.1.0", "abortcontroller-polyfill": "^1.4.0", - "@elastic/eui": "20.0.2", + "@elastic/eui": "21.0.1", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@kbn/i18n": "1.0.0", diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index 1ca9b63a51d18..0d5d300ec3b79 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1233,11 +1233,11 @@ This table shows where these uiExports have moved to in the New Platform. In mos | `chromeNavControls` | [`core.chrome.navControls.register{Left,Right}`](/docs/development/core/public/kibana-plugin-public.chromenavcontrols.md) | | | `contextMenuActions` | | Should be an API on the devTools plugin. | | `devTools` | | | -| `docViews` | | | +| `docViews` | [`plugins.discover.docViews.addDocView`](./src/plugins/discover/public/doc_views) | Should be an API on the discover plugin. | | `embeddableActions` | | Should be an API on the embeddables plugin. | | `embeddableFactories` | | Should be an API on the embeddables plugin. | -| `fieldFormatEditors` | | | -| `fieldFormats` | [`plugins.data.fieldFormats`](./src/plugins/data/public/field_formats) | | +| `fieldFormatEditors` | | | +| `fieldFormats` | [`plugins.data.fieldFormats`](./src/plugins/data/public/field_formats) | | | `hacks` | n/a | Just run the code in your plugin's `start` method. | | `home` | [`plugins.home.featureCatalogue.register`](./src/plugins/home/public/feature_catalogue) | Must add `home` as a dependency in your kibana.json. | | `indexManagement` | | Should be an API on the indexManagement plugin. | 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/index.ts b/src/core/public/index.ts index 0ff044878afa9..f72e115fd24ff 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -168,6 +168,7 @@ export { ToastInputFields, ToastsSetup, ToastsStart, + ToastOptions, ErrorToastOptions, } from './notifications'; @@ -207,15 +208,21 @@ export interface CoreSetup { injectedMetadata: { getInjectedVar: (name: string, defaultValue?: any) => unknown; }; - - /** - * Allows plugins to get access to APIs available in start inside async - * handlers, such as {@link App.mount}. Promise will not resolve until Core - * and plugin dependencies have completed `start`. - */ - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + /** {@link StartServicesAccessor} */ + getStartServices: StartServicesAccessor; } +/** + * Allows plugins to get access to APIs available in start inside async + * handlers, such as {@link App.mount}. Promise will not resolve until Core + * and plugin dependencies have completed `start`. + * + * @public + */ +export type StartServicesAccessor = () => Promise< + [CoreStart, TPluginsStart] +>; + /** * Core services exposed to the `Plugin` start lifecycle * diff --git a/src/core/public/integrations/moment/moment_service.test.mocks.ts b/src/core/public/integrations/moment/moment_service.test.mocks.ts index 2fa013a6bf132..bb13232157b78 100644 --- a/src/core/public/integrations/moment/moment_service.test.mocks.ts +++ b/src/core/public/integrations/moment/moment_service.test.mocks.ts @@ -21,6 +21,9 @@ export const momentMock = { locale: jest.fn(() => 'default-locale'), tz: { setDefault: jest.fn(), + zone: jest.fn( + z => [{ name: 'tz1' }, { name: 'tz2' }, { name: 'tz3' }].find(f => z === f.name) || null + ), }, weekdays: jest.fn(() => ['dow1', 'dow2', 'dow3']), updateLocale: jest.fn(), diff --git a/src/core/public/integrations/moment/moment_service.test.ts b/src/core/public/integrations/moment/moment_service.test.ts index c9b4479f2f163..bc48ba2a85f63 100644 --- a/src/core/public/integrations/moment/moment_service.test.ts +++ b/src/core/public/integrations/moment/moment_service.test.ts @@ -47,6 +47,26 @@ describe('MomentService', () => { expect(momentMock.updateLocale).toHaveBeenCalledWith('default-locale', { week: { dow: 0 } }); }); + it('does not set unknkown zone', async () => { + const tz$ = new BehaviorSubject('timezone/undefined'); + const uiSettings = uiSettingsServiceMock.createSetupContract(); + uiSettings.get$.mockReturnValueOnce(tz$); + + service.start({ uiSettings }); + await flushPromises(); + expect(momentMock.tz.setDefault).not.toHaveBeenCalled(); + }); + + it('sets timezone when a zone is defined', async () => { + const tz$ = new BehaviorSubject('tz3'); + const uiSettings = uiSettingsServiceMock.createSetupContract(); + uiSettings.get$.mockReturnValueOnce(tz$); + + service.start({ uiSettings }); + await flushPromises(); + expect(momentMock.tz.setDefault).toHaveBeenCalledWith('tz3'); + }); + test('updates moment config', async () => { const tz$ = new BehaviorSubject('tz1'); const dow$ = new BehaviorSubject('dow1'); diff --git a/src/core/public/integrations/moment/moment_service.ts b/src/core/public/integrations/moment/moment_service.ts index 65f2bdea02933..69cc29231d6e4 100644 --- a/src/core/public/integrations/moment/moment_service.ts +++ b/src/core/public/integrations/moment/moment_service.ts @@ -35,7 +35,10 @@ export class MomentService implements CoreService { public async setup() {} public async start({ uiSettings }: StartDeps) { - const setDefaultTimezone = (tz: string) => moment.tz.setDefault(tz); + const setDefaultTimezone = (tz: string) => { + const zone = moment.tz.zone(tz); + if (zone) moment.tz.setDefault(zone.name); + }; const setStartDayOfWeek = (day: string) => { const dow = moment.weekdays().indexOf(day); moment.updateLocale(moment.locale(), { week: { dow } } as any); diff --git a/src/core/public/notifications/index.ts b/src/core/public/notifications/index.ts index 55b64ac375f08..1a5c2cee7ced6 100644 --- a/src/core/public/notifications/index.ts +++ b/src/core/public/notifications/index.ts @@ -19,6 +19,7 @@ export { ErrorToastOptions, + ToastOptions, Toast, ToastInput, IToasts, diff --git a/src/core/public/notifications/toasts/index.ts b/src/core/public/notifications/toasts/index.ts index 6e9de11683364..b259258b8a335 100644 --- a/src/core/public/notifications/toasts/index.ts +++ b/src/core/public/notifications/toasts/index.ts @@ -20,6 +20,7 @@ export { ToastsService, ToastsSetup, ToastsStart } from './toasts_service'; export { ErrorToastOptions, + ToastOptions, ToastsApi, ToastInput, IToasts, diff --git a/src/core/public/notifications/toasts/toasts_api.test.ts b/src/core/public/notifications/toasts/toasts_api.test.ts index a0e419e989657..7c0ef5576256a 100644 --- a/src/core/public/notifications/toasts/toasts_api.test.ts +++ b/src/core/public/notifications/toasts/toasts_api.test.ts @@ -146,6 +146,21 @@ describe('#remove()', () => { }); }); +describe('#addInfo()', () => { + it('adds a info toast', async () => { + const toasts = new ToastsApi(toastDeps()); + expect(toasts.addInfo({})).toHaveProperty('color', 'primary'); + }); + + it('returns the created toast', async () => { + const toasts = new ToastsApi(toastDeps()); + const toast = toasts.addInfo({}, { toastLifeTimeMs: 1 }); + const currentToasts = await getCurrentToasts(toasts); + expect(currentToasts[0].toastLifeTimeMs).toBe(1); + expect(currentToasts[0]).toBe(toast); + }); +}); + describe('#addSuccess()', () => { it('adds a success toast', async () => { const toasts = new ToastsApi(toastDeps()); diff --git a/src/core/public/notifications/toasts/toasts_api.tsx b/src/core/public/notifications/toasts/toasts_api.tsx index 8b1850ff9508f..53717b9c2e174 100644 --- a/src/core/public/notifications/toasts/toasts_api.tsx +++ b/src/core/public/notifications/toasts/toasts_api.tsx @@ -55,7 +55,18 @@ export type ToastInput = string | ToastInputFields; * Options available for {@link IToasts} APIs. * @public */ -export interface ErrorToastOptions { +export interface ToastOptions { + /** + * How long should the toast remain on screen. + */ + toastLifeTimeMs?: number; +} + +/** + * Options available for {@link IToasts} error APIs. + * @public + */ +export interface ErrorToastOptions extends ToastOptions { /** * The title of the toast and the dialog when expanding the message. */ @@ -84,7 +95,7 @@ const normalizeToast = (toastOrTitle: ToastInput): ToastInputFields => { */ export type IToasts = Pick< ToastsApi, - 'get$' | 'add' | 'remove' | 'addSuccess' | 'addWarning' | 'addDanger' | 'addError' + 'get$' | 'add' | 'remove' | 'addSuccess' | 'addWarning' | 'addDanger' | 'addError' | 'addInfo' >; /** @@ -145,17 +156,35 @@ export class ToastsApi implements IToasts { } } + /** + * Adds a new toast pre-configured with the info color and info icon. + * + * @param toastOrTitle - a {@link ToastInput} + * @param options - a {@link ToastOptions} + * @returns a {@link Toast} + */ + public addInfo(toastOrTitle: ToastInput, options?: ToastOptions) { + return this.add({ + color: 'primary', + iconType: 'iInCircle', + ...normalizeToast(toastOrTitle), + ...options, + }); + } + /** * Adds a new toast pre-configured with the success color and check icon. * * @param toastOrTitle - a {@link ToastInput} + * @param options - a {@link ToastOptions} * @returns a {@link Toast} */ - public addSuccess(toastOrTitle: ToastInput) { + public addSuccess(toastOrTitle: ToastInput, options?: ToastOptions) { return this.add({ color: 'success', iconType: 'check', ...normalizeToast(toastOrTitle), + ...options, }); } @@ -163,14 +192,16 @@ export class ToastsApi implements IToasts { * Adds a new toast pre-configured with the warning color and help icon. * * @param toastOrTitle - a {@link ToastInput} + * @param options - a {@link ToastOptions} * @returns a {@link Toast} */ - public addWarning(toastOrTitle: ToastInput) { + public addWarning(toastOrTitle: ToastInput, options?: ToastOptions) { return this.add({ color: 'warning', iconType: 'help', toastLifeTimeMs: this.uiSettings.get('notifications:lifetime:warning'), ...normalizeToast(toastOrTitle), + ...options, }); } @@ -178,14 +209,16 @@ export class ToastsApi implements IToasts { * Adds a new toast pre-configured with the danger color and alert icon. * * @param toastOrTitle - a {@link ToastInput} + * @param options - a {@link ToastOptions} * @returns a {@link Toast} */ - public addDanger(toastOrTitle: ToastInput) { + public addDanger(toastOrTitle: ToastInput, options?: ToastOptions) { return this.add({ color: 'danger', iconType: 'alert', toastLifeTimeMs: this.uiSettings.get('notifications:lifetime:warning'), ...normalizeToast(toastOrTitle), + ...options, }); } @@ -201,7 +234,6 @@ export class ToastsApi implements IToasts { return this.add({ color: 'danger', iconType: 'alert', - title: options.title, toastLifeTimeMs: this.uiSettings.get('notifications:lifetime:error'), text: mountReactNode( this.i18n!.Context} /> ), + ...options, }); } diff --git a/src/core/public/notifications/toasts/toasts_service.mock.ts b/src/core/public/notifications/toasts/toasts_service.mock.ts index f44bd3253048d..2eb9cea7eb5c3 100644 --- a/src/core/public/notifications/toasts/toasts_service.mock.ts +++ b/src/core/public/notifications/toasts/toasts_service.mock.ts @@ -25,6 +25,7 @@ const createToastsApiMock = () => { get$: jest.fn(() => new Observable()), add: jest.fn(), remove: jest.fn(), + addInfo: jest.fn(), addSuccess: jest.fn(), addWarning: jest.fn(), addDanger: jest.fn(), diff --git a/src/core/public/overlays/flyout/flyout_service.tsx b/src/core/public/overlays/flyout/flyout_service.tsx index b609b2ce1d741..444430175d4f2 100644 --- a/src/core/public/overlays/flyout/flyout_service.tsx +++ b/src/core/public/overlays/flyout/flyout_service.tsx @@ -91,6 +91,7 @@ export interface OverlayFlyoutStart { export interface OverlayFlyoutOpenOptions { className?: string; closeButtonAriaLabel?: string; + ownFocus?: boolean; 'data-test-subj'?: string; } diff --git a/src/core/public/overlays/modal/modal_service.tsx b/src/core/public/overlays/modal/modal_service.tsx index 3cf1fe745be8e..f3bbd5c94bdb4 100644 --- a/src/core/public/overlays/modal/modal_service.tsx +++ b/src/core/public/overlays/modal/modal_service.tsx @@ -69,6 +69,7 @@ export interface OverlayModalConfirmOptions { closeButtonAriaLabel?: string; 'data-test-subj'?: string; defaultFocusedButton?: EuiConfirmModalProps['defaultFocusedButton']; + buttonColor?: EuiConfirmModalProps['buttonColor']; } /** diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 46667230edc3b..eec12f2348176 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; } @@ -379,7 +378,8 @@ export interface CoreSetup { context: ContextSetup; // (undocumented) fatalErrors: FatalErrorsSetup; - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + // (undocumented) + getStartServices: StartServicesAccessor; // (undocumented) http: HttpSetup; // @deprecated @@ -562,7 +562,7 @@ export interface EnvironmentMode { } // @public -export interface ErrorToastOptions { +export interface ErrorToastOptions extends ToastOptions { title: string; toastMessage?: string; } @@ -779,7 +779,7 @@ export interface ImageValidation { } // @public -export type IToasts = Pick; +export type IToasts = Pick; // @public export interface IUiSettingsClient { @@ -944,6 +944,8 @@ export type RecursiveReadonly = T extends (...args: any[]) => any ? T : T ext [K in keyof T]: RecursiveReadonly; }> : T; +// Warning: (ae-missing-release-tag) "SavedObject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// // @public (undocumented) export interface SavedObject { attributes: T; @@ -1234,6 +1236,9 @@ export class SimpleSavedObject { _version?: SavedObject['version']; } +// @public +export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; + // @public export type StringValidation = StringValidationRegex | StringValidationRegexString; @@ -1269,16 +1274,22 @@ export type ToastInputFields = Pick; remove(toastOrId: Toast | string): void; // @internal (undocumented) diff --git a/src/core/public/saved_objects/index.ts b/src/core/public/saved_objects/index.ts index 5015a9c3db78e..13b4a12893666 100644 --- a/src/core/public/saved_objects/index.ts +++ b/src/core/public/saved_objects/index.ts @@ -32,11 +32,6 @@ export { export { SimpleSavedObject } from './simple_saved_object'; export { SavedObjectsStart, SavedObjectsService } from './saved_objects_service'; export { - SavedObject, - SavedObjectAttribute, - SavedObjectAttributes, - SavedObjectAttributeSingle, - SavedObjectReference, SavedObjectsBaseOptions, SavedObjectsFindOptions, SavedObjectsMigrationVersion, @@ -48,3 +43,11 @@ export { SavedObjectsImportError, SavedObjectsImportRetry, } from '../../server/types'; + +export { + SavedObject, + SavedObjectAttribute, + SavedObjectAttributes, + SavedObjectAttributeSingle, + SavedObjectReference, +} from '../../types'; 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/index.ts b/src/core/server/index.ts index 89fee92a7ef02..1b436bfd72622 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -352,15 +352,22 @@ export interface CoreSetup { uuid: UuidServiceSetup; /** {@link MetricsServiceSetup} */ metrics: MetricsServiceSetup; - /** - * Allows plugins to get access to APIs available in start inside async handlers. - * Promise will not resolve until Core and plugin dependencies have completed `start`. - * This should only be used inside handlers registered during `setup` that will only be executed - * after `start` lifecycle. - */ - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + /** {@link StartServicesAccessor} */ + getStartServices: StartServicesAccessor; } +/** + * Allows plugins to get access to APIs available in start inside async handlers. + * Promise will not resolve until Core and plugin dependencies have completed `start`. + * This should only be used inside handlers registered during `setup` that will only be executed + * after `start` lifecycle. + * + * @public + */ +export type StartServicesAccessor = () => Promise< + [CoreStart, TPluginsStart] +>; + /** * Context passed to the plugins `start` method. * 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/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 1d927211b43e5..962965a08f8b2 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -35,66 +35,17 @@ export { import { LegacyConfig } from '../legacy'; import { SavedObjectUnsanitizedDoc } from './serialization'; import { SavedObjectsMigrationLogger } from './migrations/core/migration_logger'; +import { SavedObject } from '../../types'; + export { SavedObjectAttributes, SavedObjectAttribute, SavedObjectAttributeSingle, + SavedObject, + SavedObjectReference, + SavedObjectsMigrationVersion, } from '../../types'; -/** - * Information about the migrations that have been applied to this SavedObject. - * When Kibana starts up, KibanaMigrator detects outdated documents and - * migrates them based on this value. For each migration that has been applied, - * the plugin's name is used as a key and the latest migration version as the - * value. - * - * @example - * migrationVersion: { - * dashboard: '7.1.1', - * space: '6.6.6', - * } - * - * @public - */ -export interface SavedObjectsMigrationVersion { - [pluginName: string]: string; -} - -/** - * @public - */ -export interface SavedObject { - /** The ID of this Saved Object, guaranteed to be unique for all objects of the same `type` */ - id: string; - /** The type of Saved Object. Each plugin can define it's own custom Saved Object types. */ - type: string; - /** An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. */ - version?: string; - /** Timestamp of the last time this document had been updated. */ - updated_at?: string; - error?: { - message: string; - statusCode: number; - }; - /** {@inheritdoc SavedObjectAttributes} */ - attributes: T; - /** {@inheritdoc SavedObjectReference} */ - references: SavedObjectReference[]; - /** {@inheritdoc SavedObjectsMigrationVersion} */ - migrationVersion?: SavedObjectsMigrationVersion; -} - -/** - * A reference to another saved object. - * - * @public - */ -export interface SavedObjectReference { - name: string; - type: string; - id: string; -} - /** * * @public diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 84fe081adaae6..6d4181e5e1ab3 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -629,7 +629,8 @@ export interface CoreSetup { context: ContextSetup; // (undocumented) elasticsearch: ElasticsearchServiceSetup; - getStartServices(): Promise<[CoreStart, TPluginsStart]>; + // (undocumented) + getStartServices: StartServicesAccessor; // (undocumented) http: HttpServiceSetup; // (undocumented) @@ -1595,6 +1596,8 @@ export interface RouteValidatorOptions { // @public export type SafeRouteMethod = 'get' | 'options'; +// Warning: (ae-missing-release-tag) "SavedObject" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// // @public (undocumented) export interface SavedObject { attributes: T; @@ -2267,6 +2270,9 @@ export type SharedGlobalConfig = RecursiveReadonly_2<{ path: Pick; }>; +// @public +export type StartServicesAccessor = () => Promise<[CoreStart, TPluginsStart]>; + // @public export type StringValidation = StringValidationRegex | StringValidationRegexString; 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/core/types/saved_objects.ts b/src/core/types/saved_objects.ts index 73eb2db11d62f..d3faab6c557cd 100644 --- a/src/core/types/saved_objects.ts +++ b/src/core/types/saved_objects.ts @@ -46,3 +46,54 @@ export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttri export interface SavedObjectAttributes { [key: string]: SavedObjectAttribute; } + +/** + * A reference to another saved object. + * + * @public + */ +export interface SavedObjectReference { + name: string; + type: string; + id: string; +} + +/** + * Information about the migrations that have been applied to this SavedObject. + * When Kibana starts up, KibanaMigrator detects outdated documents and + * migrates them based on this value. For each migration that has been applied, + * the plugin's name is used as a key and the latest migration version as the + * value. + * + * @example + * migrationVersion: { + * dashboard: '7.1.1', + * space: '6.6.6', + * } + * + * @public + */ +export interface SavedObjectsMigrationVersion { + [pluginName: string]: string; +} + +export interface SavedObject { + /** The ID of this Saved Object, guaranteed to be unique for all objects of the same `type` */ + id: string; + /** The type of Saved Object. Each plugin can define it's own custom Saved Object types. */ + type: string; + /** An opaque version number which changes on each successful write operation. Can be used for implementing optimistic concurrency control. */ + version?: string; + /** Timestamp of the last time this document had been updated. */ + updated_at?: string; + error?: { + message: string; + statusCode: number; + }; + /** {@inheritdoc SavedObjectAttributes} */ + attributes: T; + /** {@inheritdoc SavedObjectReference} */ + references: SavedObjectReference[]; + /** {@inheritdoc SavedObjectsMigrationVersion} */ + migrationVersion?: SavedObjectsMigrationVersion; +} diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 8078c32b10646..a941735c7840e 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -49,8 +49,6 @@ export default { '!packages/kbn-ui-framework/src/services/**/*/index.js', 'src/legacy/core_plugins/**/*.{js,jsx,ts,tsx}', '!src/legacy/core_plugins/**/{__test__,__snapshots__}/**/*', - 'src/legacy/ui/public/{agg_types,vis}/**/*.{ts,tsx}', - '!src/legacy/ui/public/{agg_types,vis}/**/*.d.ts', ], moduleNameMapper: { '@elastic/eui$': '/node_modules/@elastic/eui/test-env', diff --git a/src/dev/run_check_lockfile_symlinks.js b/src/dev/run_check_lockfile_symlinks.js index 54a8cdf638a78..6c6fc54638ee8 100644 --- a/src/dev/run_check_lockfile_symlinks.js +++ b/src/dev/run_check_lockfile_symlinks.js @@ -36,6 +36,8 @@ const IGNORE_FILE_GLOBS = [ '**/*fixtures*/**/*', // cypress isn't used in production, ignore it 'x-pack/legacy/plugins/apm/e2e/*', + // apm scripts aren't used in production, ignore them + 'x-pack/legacy/plugins/apm/scripts/*', ]; run(async ({ log }) => { diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 8ed64f004c9be..370abc120d475 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -18,12 +18,14 @@ */ export const storybookAliases = { + advanced_ui_actions: 'x-pack/plugins/advanced_ui_actions/scripts/storybook.js', apm: 'x-pack/legacy/plugins/apm/scripts/storybook.js', canvas: 'x-pack/legacy/plugins/canvas/scripts/storybook_new.js', codeeditor: 'src/plugins/kibana_react/public/code_editor/scripts/storybook.ts', + dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/scripts/storybook.js', drilldowns: 'x-pack/plugins/drilldowns/scripts/storybook.js', embeddable: 'src/plugins/embeddable/scripts/storybook.js', infra: 'x-pack/legacy/plugins/infra/scripts/storybook.js', siem: 'x-pack/legacy/plugins/siem/scripts/storybook.js', - ui_actions: 'x-pack/plugins/advanced_ui_actions/scripts/storybook.js', + ui_actions: 'src/plugins/ui_actions/scripts/storybook.js', }; diff --git a/src/legacy/core_plugins/application_usage/index.ts b/src/legacy/core_plugins/application_usage/index.ts deleted file mode 100644 index 752d6eaa19bb0..0000000000000 --- a/src/legacy/core_plugins/application_usage/index.ts +++ /dev/null @@ -1,31 +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 { Legacy } from '../../../../kibana'; -import { mappings } from './mappings'; - -// eslint-disable-next-line import/no-default-export -export default function ApplicationUsagePlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'application_usage', - uiExports: { mappings }, // Needed to define the mappings for the SavedObjects - }; - - return new kibana.Plugin(config); -} diff --git a/src/legacy/core_plugins/application_usage/mappings.ts b/src/legacy/core_plugins/application_usage/mappings.ts deleted file mode 100644 index 39adc53f7e9ff..0000000000000 --- a/src/legacy/core_plugins/application_usage/mappings.ts +++ /dev/null @@ -1,36 +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. - */ - -export const mappings = { - application_usage_totals: { - properties: { - appId: { type: 'keyword' }, - numberOfClicks: { type: 'long' }, - minutesOnScreen: { type: 'float' }, - }, - }, - application_usage_transactional: { - properties: { - timestamp: { type: 'date' }, - appId: { type: 'keyword' }, - numberOfClicks: { type: 'long' }, - minutesOnScreen: { type: 'float' }, - }, - }, -}; diff --git a/src/legacy/core_plugins/application_usage/package.json b/src/legacy/core_plugins/application_usage/package.json deleted file mode 100644 index 5ab10a2f8d237..0000000000000 --- a/src/legacy/core_plugins/application_usage/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "application_usage", - "version": "kibana" -} \ No newline at end of file diff --git a/src/legacy/core_plugins/data/index.ts b/src/legacy/core_plugins/data/index.ts deleted file mode 100644 index 10c8cf464b82d..0000000000000 --- a/src/legacy/core_plugins/data/index.ts +++ /dev/null @@ -1,41 +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 { resolve } from 'path'; -import { Legacy } from '../../../../kibana'; - -// eslint-disable-next-line import/no-default-export -export default function DataPlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'data', - require: ['elasticsearch'], - publicDir: resolve(__dirname, 'public'), - config: (Joi: any) => { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - init: (server: Legacy.Server) => ({}), - uiExports: { - injectDefaultVars: () => ({}), - }, - }; - - return new kibana.Plugin(config); -} diff --git a/src/legacy/core_plugins/data/package.json b/src/legacy/core_plugins/data/package.json deleted file mode 100644 index 3f40374650ad7..0000000000000 --- a/src/legacy/core_plugins/data/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "data", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/data/public/index.ts b/src/legacy/core_plugins/data/public/index.ts deleted file mode 100644 index 27a3dd825485d..0000000000000 --- a/src/legacy/core_plugins/data/public/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { DataPlugin as Plugin } from './plugin'; - -export function plugin() { - return new Plugin(); -} - -export { DataSetup, DataStart } from './plugin'; diff --git a/src/legacy/core_plugins/data/public/legacy.ts b/src/legacy/core_plugins/data/public/legacy.ts deleted file mode 100644 index 370b412127db8..0000000000000 --- a/src/legacy/core_plugins/data/public/legacy.ts +++ /dev/null @@ -1,44 +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. - */ - -/** - * New Platform Shim - * - * In this file, we import any legacy dependencies we have, and shim them into - * our plugin by manually constructing the values that the new platform will - * eventually be passing to the `setup` method of our plugin definition. - * - * The idea is that our `plugin.ts` can stay "pure" and not contain any legacy - * world code. Then when it comes time to migrate to the new platform, we can - * simply delete this shim file. - * - * We are also calling `setup` here and exporting our public contract so that - * other legacy plugins are able to import from '../core_plugins/data/legacy' - * and receive the response value of the `setup` contract, mimicking the - * data that will eventually be injected by the new platform. - */ - -import { npSetup, npStart } from 'ui/new_platform'; -import { plugin } from '.'; - -const dataPlugin = plugin(); - -export const setup = dataPlugin.setup(npSetup.core); - -export const start = dataPlugin.start(npStart.core); diff --git a/src/legacy/core_plugins/data/public/plugin.ts b/src/legacy/core_plugins/data/public/plugin.ts deleted file mode 100644 index 76a3d92d20283..0000000000000 --- a/src/legacy/core_plugins/data/public/plugin.ts +++ /dev/null @@ -1,58 +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 { CoreSetup, CoreStart, Plugin } from 'kibana/public'; - -/** - * Interface for this plugin's returned `setup` contract. - * - * @public - */ -export interface DataSetup {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Interface for this plugin's returned `start` contract. - * - * @public - */ -export interface DataStart {} // eslint-disable-line @typescript-eslint/no-empty-interface - -/** - * Data Plugin - public - * - * This is the entry point for the entire client-side public contract of the plugin. - * If something is not explicitly exported here, you can safely assume it is private - * to the plugin and not considered stable. - * - * All stateful contracts will be injected by the platform at runtime, and are defined - * in the setup/start interfaces. The remaining items exported here are either types, - * or static code. - */ - -export class DataPlugin implements Plugin { - public setup(core: CoreSetup) { - return {}; - } - - public start(core: CoreStart): DataStart { - return {}; - } - - public stop() {} -} diff --git a/src/legacy/core_plugins/data/public/setup.ts b/src/legacy/core_plugins/data/public/setup.ts deleted file mode 100644 index a99a2a4d06efe..0000000000000 --- a/src/legacy/core_plugins/data/public/setup.ts +++ /dev/null @@ -1,23 +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 { setup } from './legacy'; - -// for backwards compatibility with 7.3 -export const data = setup; diff --git a/src/legacy/core_plugins/input_control_vis/index.ts b/src/legacy/core_plugins/input_control_vis/index.ts index 8f6178e26126b..d67472ac4b95f 100644 --- a/src/legacy/core_plugins/input_control_vis/index.ts +++ b/src/legacy/core_plugins/input_control_vis/index.ts @@ -25,7 +25,7 @@ import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy const inputControlVisPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ id: 'input_control_vis', - require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter', 'data'], + require: ['kibana', 'elasticsearch', 'visualizations', 'interpreter'], publicDir: resolve(__dirname, 'public'), uiExports: { styleSheetPaths: resolve(__dirname, 'public/index.scss'), diff --git a/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx b/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx index cd3982afd9afd..0cd2a2b331980 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx @@ -19,8 +19,7 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; - -import { ValidatedDualRange } from '../../legacy_imports'; +import { ValidatedDualRange } from '../../../../../../../src/plugins/kibana_react/public'; import { FormRow } from './form_row'; import { RangeControl as RangeControlClass } from '../../control/range_control_factory'; diff --git a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts index dae6c9abb625e..023e6ebb7125c 100644 --- a/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_vis_type.ts @@ -22,7 +22,6 @@ import { i18n } from '@kbn/i18n'; import { createInputControlVisController } from './vis_controller'; import { getControlsTab } from './components/editor/controls_tab'; import { OptionsTab } from './components/editor/options_tab'; -import { Status } from '../../visualizations/public'; import { InputControlVisDependencies } from './plugin'; import { defaultFeedbackMessage } from '../../../../plugins/kibana_utils/common'; @@ -40,7 +39,6 @@ export function createInputControlVisTypeDefinition(deps: InputControlVisDepende defaultMessage: 'Create interactive controls for easy dashboard manipulation.', }), stage: 'experimental', - requiresUpdateStatus: [Status.PARAMS, Status.TIME], feedbackMessage: defaultFeedbackMessage, visualization: InputControlVisController, visConfig: { diff --git a/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts b/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts index b6c4eb28e974f..8c58ac2386da4 100644 --- a/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts +++ b/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts @@ -22,7 +22,5 @@ import { SearchSource as SearchSourceClass, ISearchSource } from '../../../../pl export { SearchSourceFields } from '../../../../plugins/data/public'; -export { ValidatedDualRange } from 'ui/validated_range'; - export type SearchSource = Class; export const SearchSource = SearchSourceClass; diff --git a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx index 624d000dd8d7a..c0ab235c1b9d1 100644 --- a/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/vis_controller.tsx @@ -54,7 +54,7 @@ export const createInputControlVisController = (deps: InputControlVisDependencie .subscribe(this.queryBarUpdateHandler); } - async render(visData: any, visParams: VisParams, status: any) { + async render(visData: any, visParams: VisParams) { this.visParams = visParams; this.controls = []; this.controls = await this.initControls(); diff --git a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js b/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js deleted file mode 100644 index 267ca74c7c42a..0000000000000 --- a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js +++ /dev/null @@ -1,34 +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 expect from '@kbn/expect'; -import { shortenDottedString } from '../shorten_dotted_string'; - -describe('shortenDottedString', () => { - it('Convert a dot.notated.string into a short string', () => { - expect(shortenDottedString('dot.notated.string')).to.equal('d.n.string'); - }); - - 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); - }); -}); diff --git a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js b/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js deleted file mode 100644 index ca76a2a537742..0000000000000 --- a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js +++ /dev/null @@ -1,31 +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. - */ - -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.'); -} diff --git a/src/legacy/core_plugins/kibana/public/.eslintrc.js b/src/legacy/core_plugins/kibana/public/.eslintrc.js index e7171a5291d26..1153706eb8566 100644 --- a/src/legacy/core_plugins/kibana/public/.eslintrc.js +++ b/src/legacy/core_plugins/kibana/public/.eslintrc.js @@ -43,8 +43,6 @@ function buildRestrictedPaths(shimmedPlugins) { 'ui/**/*', 'src/legacy/ui/**/*', 'src/legacy/core_plugins/kibana/public/**/*', - 'src/legacy/core_plugins/data/public/**/*', - '!src/legacy/core_plugins/data/public/index.ts', `!src/legacy/core_plugins/kibana/public/${shimmedPlugin}/**/*`, ], allowSameFolder: false, 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..55e1475fcb03a 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/legacy_imports.ts @@ -25,18 +25,9 @@ */ export { npSetup, npStart } from 'ui/new_platform'; - -export { KbnUrl } from 'ui/url/kbn_url'; -// @ts-ignore -export { KbnUrlProvider, RedirectWhenMissingProvider } from 'ui/url/index'; -export { IInjector } from 'ui/chrome'; export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; export { configureAppAngularModule, - ensureDefaultIndexPattern, - IPrivate, migrateLegacyQuery, - PrivateProvider, - PromiseServiceCreator, subscribeWithScope, } from '../../../../../plugins/kibana_legacy/public'; 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..877ccab99171d 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 @@ -29,14 +29,7 @@ import { PluginInitializerContext, } from 'kibana/public'; import { Storage } from '../../../../../../plugins/kibana_utils/public'; -import { - configureAppAngularModule, - IPrivate, - KbnUrlProvider, - PrivateProvider, - PromiseServiceCreator, - RedirectWhenMissingProvider, -} from '../legacy_imports'; +import { configureAppAngularModule } from '../legacy_imports'; // @ts-ignore import { initDashboardApp } from './legacy_app'; import { EmbeddableStart } from '../../../../../../plugins/embeddable/public'; @@ -117,10 +110,7 @@ function mountDashboardApp(appBasePath: string, element: HTMLElement) { function createLocalAngularModule(core: AppMountContext['core'], navigation: NavigationStart) { createLocalI18nModule(); - createLocalPrivateModule(); - createLocalPromiseModule(); createLocalConfigModule(core); - createLocalKbnUrlModule(); createLocalTopNavModule(navigation); createLocalIconModule(); @@ -128,10 +118,7 @@ function createLocalAngularModule(core: AppMountContext['core'], navigation: Nav ...thirdPartyAngularDependencies, 'app/dashboard/Config', 'app/dashboard/I18n', - 'app/dashboard/Private', 'app/dashboard/TopNav', - 'app/dashboard/KbnUrl', - 'app/dashboard/Promise', 'app/dashboard/icon', ]); return dashboardAngularModule; @@ -143,15 +130,8 @@ function createLocalIconModule() { .directive('icon', reactDirective => reactDirective(EuiIcon)); } -function createLocalKbnUrlModule() { - angular - .module('app/dashboard/KbnUrl', ['app/dashboard/Private', 'ngRoute']) - .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider)) - .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider)); -} - function createLocalConfigModule(core: AppMountContext['core']) { - angular.module('app/dashboard/Config', ['app/dashboard/Private']).provider('config', () => { + angular.module('app/dashboard/Config', []).provider('config', () => { return { $get: () => ({ get: core.uiSettings.get.bind(core.uiSettings), @@ -160,14 +140,6 @@ function createLocalConfigModule(core: AppMountContext['core']) { }); } -function createLocalPromiseModule() { - angular.module('app/dashboard/Promise', []).service('Promise', PromiseServiceCreator); -} - -function createLocalPrivateModule() { - angular.module('app/dashboard/Private', []).provider('Private', PrivateProvider); -} - function createLocalTopNavModule(navigation: NavigationStart) { angular .module('app/dashboard/TopNav', ['react']) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app.tsx b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app.tsx index c0a0693431295..4e9942767186e 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app.tsx @@ -21,8 +21,6 @@ import moment from 'moment'; import { Subscription } from 'rxjs'; import { History } from 'history'; -import { IInjector } from '../legacy_imports'; - import { ViewMode } from '../../../../embeddable_api/public/np_ready/public'; import { SavedObjectDashboard } from '../saved_dashboard/saved_dashboard'; import { DashboardAppState, SavedDashboardPanel } from './types'; @@ -86,28 +84,26 @@ export interface DashboardAppScope extends ng.IScope { } export function initDashboardAppDirective(app: any, deps: RenderDeps) { - app.directive('dashboardApp', function($injector: IInjector) { - return { - restrict: 'E', - controllerAs: 'dashboardApp', - controller: ( - $scope: DashboardAppScope, - $route: any, - $routeParams: { - id?: string; - }, - kbnUrlStateStorage: IKbnUrlStateStorage, - history: History - ) => - new DashboardAppController({ - $route, - $scope, - $routeParams, - indexPatterns: deps.data.indexPatterns, - kbnUrlStateStorage, - history, - ...deps, - }), - }; - }); + app.directive('dashboardApp', () => ({ + restrict: 'E', + controllerAs: 'dashboardApp', + controller: ( + $scope: DashboardAppScope, + $route: any, + $routeParams: { + id?: string; + }, + kbnUrlStateStorage: IKbnUrlStateStorage, + history: History + ) => + new DashboardAppController({ + $route, + $scope, + $routeParams, + indexPatterns: deps.data.indexPatterns, + kbnUrlStateStorage, + history, + ...deps, + }), + })); } diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx index d1e4c9d2d2a0c..f1e1f20de1ce6 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx @@ -754,7 +754,7 @@ export class DashboardAppController { * When de-angularizing this code, please call the underlaying action function * directly and not via the top nav object. **/ - navActions[TopNavIds.ADD](); + navActions[TopNavIds.ADD_EXISTING](); }; $scope.enterEditMode = () => { dashboardStateManager.setFullScreenMode(false); @@ -847,7 +847,8 @@ export class DashboardAppController { showCloneModal(onClone, currentTitle); }; - navActions[TopNavIds.ADD] = () => { + + navActions[TopNavIds.ADD_EXISTING] = () => { if (dashboardContainer && !isErrorEmbeddable(dashboardContainer)) { openAddPanelFlyout({ embeddable: dashboardContainer, diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_state.test.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_state.test.ts index 60ea14dad19e1..08ccc1e0d1e89 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_state.test.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_state.test.ts @@ -25,13 +25,6 @@ import { InputTimeRange, TimefilterContract, TimeRange } from 'src/plugins/data/ import { ViewMode } from 'src/plugins/embeddable/public'; import { createKbnUrlStateStorage } from 'src/plugins/kibana_utils/public'; -jest.mock('ui/agg_types', () => ({ - aggTypes: { - metrics: [], - buckets: [], - }, -})); - describe('DashboardState', function() { let dashboardState: DashboardStateManager; const savedDashboard = getSavedDashboardMock(); 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..dbeaf8a98b461 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 @@ -18,16 +18,18 @@ */ import { i18n } from '@kbn/i18n'; +import { parse } from 'query-string'; 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'; @@ -92,9 +94,8 @@ export function initDashboardApp(app, deps) { .when(DashboardConstants.LANDING_PAGE_PATH, { ...defaults, template: dashboardListingTemplate, - controller($injector, $location, $scope, kbnUrlStateStorage) { + controller($scope, kbnUrlStateStorage, history) { const service = deps.savedDashboards; - const kbnUrl = $injector.get('kbnUrl'); const dashboardConfig = deps.dashboardConfig; // syncs `_g` portion of url with query services @@ -105,13 +106,13 @@ export function initDashboardApp(app, deps) { $scope.listingLimit = deps.uiSettings.get('savedObjects:listingLimit'); $scope.create = () => { - kbnUrl.redirect(DashboardConstants.CREATE_NEW_DASHBOARD_URL); + history.push(DashboardConstants.CREATE_NEW_DASHBOARD_URL); }; $scope.find = search => { return service.find(search, $scope.listingLimit); }; $scope.editItem = ({ id }) => { - kbnUrl.redirect(`${createDashboardEditUrl(id)}?_a=(viewMode:edit)`); + history.push(`${createDashboardEditUrl(id)}?_a=(viewMode:edit)`); }; $scope.getViewUrl = ({ id }) => { return deps.addBasePath(`#${createDashboardEditUrl(id)}`); @@ -120,7 +121,7 @@ export function initDashboardApp(app, deps) { return service.delete(dashboards.map(d => d.id)); }; $scope.hideWriteControls = dashboardConfig.getHideWriteControls(); - $scope.initialFilter = $location.search().filter || EMPTY_FILTER; + $scope.initialFilter = parse(history.location.search).filter || EMPTY_FILTER; deps.chrome.setBreadcrumbs([ { text: i18n.translate('kbn.dashboard.dashboardBreadcrumbsTitle', { @@ -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, 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,8 +207,8 @@ 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); - kbnUrl.redirect(DashboardConstants.LANDING_PAGE_PATH); + deps.core.notifications.toasts.addDanger(error.message); + history.push(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/dashboard/np_ready/top_nav/get_top_nav_config.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts index 7188fab19d6f2..7a3cb4b7dad56 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts @@ -48,9 +48,10 @@ export function getTopNavConfig( ]; case ViewMode.EDIT: return [ + getCreateNewConfig(actions[TopNavIds.VISUALIZE]), getSaveConfig(actions[TopNavIds.SAVE]), getViewConfig(actions[TopNavIds.EXIT_EDIT_MODE]), - getAddConfig(actions[TopNavIds.ADD]), + getAddConfig(actions[TopNavIds.ADD_EXISTING]), getOptionsConfig(actions[TopNavIds.OPTIONS]), getShareConfig(actions[TopNavIds.SHARE]), ]; @@ -161,6 +162,25 @@ function getAddConfig(action: NavAction) { }; } +/** + * @returns {kbnTopNavConfig} + */ +function getCreateNewConfig(action: NavAction) { + return { + emphasize: true, + iconType: 'plusInCircle', + id: 'addNew', + label: i18n.translate('kbn.dashboard.topNave.addNewButtonAriaLabel', { + defaultMessage: 'Create new', + }), + description: i18n.translate('kbn.dashboard.topNave.addNewConfigDescription', { + defaultMessage: 'Create a new panel on this dashboard', + }), + testId: 'dashboardAddNewPanelButton', + run: action, + }; +} + /** * @returns {kbnTopNavConfig} */ diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts index c67d6891c18e7..748bfaaab6141 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts @@ -18,7 +18,6 @@ */ export const TopNavIds = { - ADD: 'add', SHARE: 'share', OPTIONS: 'options', SAVE: 'save', @@ -27,4 +26,5 @@ export const TopNavIds = { CLONE: 'clone', FULL_SCREEN: 'fullScreenMode', VISUALIZE: 'visualize', + ADD_EXISTING: 'addExisting', }; diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js index f74e145865475..47392c541890e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js @@ -73,22 +73,7 @@ describe('discover field chooser directives', function() { beforeEach(() => pluginInstance.initializeServices()); beforeEach(() => pluginInstance.initializeInnerAngular()); - beforeEach( - ngMock.module('app/discover', $provide => { - $provide.decorator('config', $delegate => { - // disable shortDots for these tests - $delegate.get = _.wrap($delegate.get, function(origGet, name) { - if (name === 'shortDots:enable') { - return false; - } else { - return origGet.call(this, name); - } - }); - - return $delegate; - }); - }) - ); + beforeEach(ngMock.module('app/discover')); beforeEach( ngMock.inject(function(Private) { diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/doc_table/lib/rows_headers.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/doc_table/lib/rows_headers.js index c19e033ccb72d..9b63b8cd18f3e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/doc_table/lib/rows_headers.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/doc_table/lib/rows_headers.js @@ -30,7 +30,6 @@ import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logsta describe('Doc Table', function() { let $parentScope; let $scope; - let config; // Stub out a minimal mapping of 4 fields let mapping; @@ -41,8 +40,7 @@ describe('Doc Table', function() { beforeEach(() => pluginInstance.initializeInnerAngular()); beforeEach(ngMock.module('app/discover')); beforeEach( - ngMock.inject(function(_config_, $rootScope, Private) { - config = _config_; + ngMock.inject(function($rootScope, Private) { $parentScope = $rootScope; $parentScope.indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); mapping = $parentScope.indexPattern.fields; @@ -144,12 +142,6 @@ describe('Doc Table', function() { filter: sinon.spy(), maxLength: 50, }); - - // Ignore the metaFields (_id, _type, etc) since we don't have a mapping for them - sinon - .stub(config, 'get') - .withArgs('metaFields') - .returns([]); }); afterEach(function() { destroy(); @@ -215,11 +207,6 @@ describe('Doc Table', function() { maxLength: 50, }); - sinon - .stub(config, 'get') - .withArgs('metaFields') - .returns(['_id']); - // Open the row $scope.toggleRow(); $scope.$digest(); 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..f881eb96e4e81 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, @@ -33,10 +35,13 @@ import { import { DiscoverStartPlugins } from './plugin'; import { SharePluginStart } from '../../../../../plugins/share/public'; -import { DocViewsRegistry } from './np_ready/doc_views/doc_views_registry'; import { ChartsPluginStart } from '../../../../../plugins/charts/public'; import { VisualizationsStart } from '../../../visualizations/public'; -import { createSavedSearchesLoader, SavedSearch } from '../../../../../plugins/discover/public'; +import { + createSavedSearchesLoader, + DocViewerComponent, + SavedSearch, +} from '../../../../../plugins/discover/public'; export interface DiscoverServices { addBasePath: (path: string) => string; @@ -45,7 +50,8 @@ export interface DiscoverServices { core: CoreStart; data: DataPublicPluginStart; docLinks: DocLinksStart; - docViewsRegistry: DocViewsRegistry; + DocViewer: DocViewerComponent; + history: History; theme: ChartsPluginStart['theme']; filterManager: FilterManager; indexPatterns: IndexPatternsContract; @@ -61,8 +67,7 @@ export interface DiscoverServices { } export async function buildServices( core: CoreStart, - plugins: DiscoverStartPlugins, - docViewsRegistry: DocViewsRegistry + plugins: DiscoverStartPlugins ): Promise { const services = { savedObjectsClient: core.savedObjects.client, @@ -78,7 +83,8 @@ export async function buildServices( core, data: plugins.data, docLinks: core.docLinks, - docViewsRegistry, + DocViewer: plugins.discover.docViews.DocViewer, + 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..031e10e99289f 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 @@ -23,11 +23,7 @@ import angular from 'angular'; import { EuiIcon } from '@elastic/eui'; import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; -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 { CoreStart, LegacyCoreStart } from 'kibana/public'; import { DataPublicPluginStart } from '../../../../../plugins/data/public'; import { Storage } from '../../../../../plugins/kibana_utils/public'; import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public'; @@ -61,7 +57,6 @@ import { createRenderCompleteDirective } from './np_ready/angular/directives/ren import { initAngularBootstrap, configureAppAngularModule, - IPrivate, KbnAccessibleClickProvider, PrivateProvider, PromiseServiceCreator, @@ -108,8 +103,6 @@ export function initializeInnerAngularModule( createLocalI18nModule(); createLocalPrivateModule(); createLocalPromiseModule(); - createLocalConfigModule(core.uiSettings); - createLocalKbnUrlModule(); createLocalTopNavModule(navigation); createLocalStorageModule(); createElasticSearchModule(data); @@ -143,7 +136,6 @@ export function initializeInnerAngularModule( 'ngRoute', 'react', 'ui.bootstrap', - 'discoverConfig', 'discoverI18n', 'discoverPrivate', 'discoverPromise', @@ -170,28 +162,6 @@ export function initializeInnerAngularModule( .service('debounce', ['$timeout', DebounceProviderTimeout]); } -function createLocalKbnUrlModule() { - angular - .module('discoverKbnUrl', ['discoverPrivate', 'ngRoute']) - .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider)) - .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider)); -} - -function createLocalConfigModule(uiSettings: IUiSettingsClient) { - angular - .module('discoverConfig', ['discoverPrivate']) - .provider('stateManagementConfig', StateManagementConfigProvider) - .provider('config', () => { - return { - $get: () => ({ - get: (value: string) => { - return uiSettings ? uiSettings.get(value) : undefined; - }, - }), - }; - }); -} - function createLocalPromiseModule() { angular.module('discoverPromise', []).service('Promise', PromiseServiceCreator); } @@ -230,7 +200,7 @@ const createLocalStorageService = function(type: string) { function createElasticSearchModule(data: DataPublicPluginStart) { angular - .module('discoverEs', ['discoverConfig']) + .module('discoverEs', []) // Elasticsearch client used for requesting data. Connects to the /elasticsearch proxy .service('es', () => { return data.search.__LEGACY.esClient; @@ -243,12 +213,7 @@ function createPagerFactoryModule() { function createDocTableModule() { angular - .module('discoverDocTable', [ - 'discoverKbnUrl', - 'discoverConfig', - 'discoverPagerFactory', - 'react', - ]) + .module('discoverDocTable', ['discoverPagerFactory', 'react']) .directive('docTable', createDocTableDirective) .directive('kbnTableHeader', createTableHeaderDirective) .directive('toolBarPagerText', createToolBarPagerTextDirective) 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..7a3a6949baa94 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -52,18 +52,15 @@ export { angular }; 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 @@ -78,7 +75,6 @@ export { EsQuerySortValue, SortDirection, } from '../../../../../plugins/data/public'; -export { ElasticSearchHit } from './np_ready/doc_views/doc_views_types'; export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; // @ts-ignore export { buildPointSeriesData } from 'ui/agg_response/point_series/point_series'; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js index 038f783a0daf1..f8e764cbcbebb 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context.js @@ -66,7 +66,7 @@ getAngularModule().config($routeProvider => { }); }); -function ContextAppRouteController($routeParams, $scope, config, $route) { +function ContextAppRouteController($routeParams, $scope, $route) { const filterManager = getServices().filterManager; const indexPattern = $route.current.locals.indexPattern.ip; const { @@ -77,9 +77,9 @@ function ContextAppRouteController($routeParams, $scope, config, $route) { setFilters, setAppState, } = getState({ - defaultStepSize: config.get('context:defaultSize'), + defaultStepSize: getServices().uiSettings.get('context:defaultSize'), timeFieldName: indexPattern.timeFieldName, - storeInSessionStorage: config.get('state:storeInSessionStorage'), + storeInSessionStorage: getServices().uiSettings.get('state:storeInSessionStorage'), }); this.state = { ...appState.getState() }; this.anchorId = $routeParams.id; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js index 674f40d0186e5..9efddc5275069 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context/query/actions.js @@ -26,7 +26,7 @@ import { fetchAnchorProvider } from '../api/anchor'; import { fetchContextProvider } from '../api/context'; import { getQueryParameterActions } from '../query_parameters'; import { FAILURE_REASONS, LOADING_STATUS } from './constants'; -import { MarkdownSimple } from '../../../../../../../kibana_react/public'; +import { MarkdownSimple } from '../../../../../../../../../plugins/kibana_react/public'; export function QueryActionsProvider(Promise) { const { filterManager, indexPatterns } = getServices(); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js index 345717cafee9a..a6a1de695156d 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js @@ -57,13 +57,13 @@ module.directive('contextApp', function ContextApp() { }; }); -function ContextAppController($scope, config, Private) { - const { filterManager, indexpatterns } = getServices(); +function ContextAppController($scope, Private) { + const { filterManager, indexpatterns, uiSettings } = getServices(); const queryParameterActions = getQueryParameterActions(filterManager, indexpatterns); const queryActions = Private(QueryActionsProvider); this.state = createInitialState( - parseInt(config.get('context:step'), 10), - getFirstSortableField(this.indexPattern, config.get('context:tieBreakerFields')), + parseInt(uiSettings.get('context:step'), 10), + getFirstSortableField(this.indexPattern, uiSettings.get('context:tieBreakerFields')), this.discoverUrl ); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js index 4bc498928be52..47e50f3cc3d4b 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name.js @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { FieldName } from './field_name/field_name'; -import { wrapInI18nContext } from '../../../kibana_services'; +import { FieldName } from '../../../../../../../../plugins/discover/public'; +import { getServices, wrapInI18nContext } from '../../../kibana_services'; -export function FieldNameDirectiveProvider(config, reactDirective) { +export function FieldNameDirectiveProvider(reactDirective) { return reactDirective( wrapInI18nContext(FieldName), [ @@ -29,7 +29,7 @@ export function FieldNameDirectiveProvider(config, reactDirective) { ], { restrict: 'AE' }, { - useShortDots: config.get('shortDots:enable'), + useShortDots: getServices().uiSettings.get('shortDots:enable'), } ); } diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_type_name.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_type_name.ts deleted file mode 100644 index 0cf428ee48b9d..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_type_name.ts +++ /dev/null @@ -1,73 +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 { i18n } from '@kbn/i18n'; - -export function getFieldTypeName(type: string) { - switch (type) { - case 'boolean': - return i18n.translate('kbn.discover.fieldNameIcons.booleanAriaLabel', { - defaultMessage: 'Boolean field', - }); - case 'conflict': - return i18n.translate('kbn.discover.fieldNameIcons.conflictFieldAriaLabel', { - defaultMessage: 'Conflicting field', - }); - case 'date': - return i18n.translate('kbn.discover.fieldNameIcons.dateFieldAriaLabel', { - defaultMessage: 'Date field', - }); - case 'geo_point': - return i18n.translate('kbn.discover.fieldNameIcons.geoPointFieldAriaLabel', { - defaultMessage: 'Geo point field', - }); - case 'geo_shape': - return i18n.translate('kbn.discover.fieldNameIcons.geoShapeFieldAriaLabel', { - defaultMessage: 'Geo shape field', - }); - case 'ip': - return i18n.translate('kbn.discover.fieldNameIcons.ipAddressFieldAriaLabel', { - defaultMessage: 'IP address field', - }); - case 'murmur3': - return i18n.translate('kbn.discover.fieldNameIcons.murmur3FieldAriaLabel', { - defaultMessage: 'Murmur3 field', - }); - case 'number': - return i18n.translate('kbn.discover.fieldNameIcons.numberFieldAriaLabel', { - defaultMessage: 'Number field', - }); - case 'source': - // Note that this type is currently not provided, type for _source is undefined - return i18n.translate('kbn.discover.fieldNameIcons.sourceFieldAriaLabel', { - defaultMessage: 'Source field', - }); - case 'string': - return i18n.translate('kbn.discover.fieldNameIcons.stringFieldAriaLabel', { - defaultMessage: 'String field', - }); - case 'nested': - return i18n.translate('kbn.discover.fieldNameIcons.nestedFieldAriaLabel', { - defaultMessage: 'Nested field', - }); - default: - return i18n.translate('kbn.discover.fieldNameIcons.unknownFieldAriaLabel', { - defaultMessage: 'Unknown field', - }); - } -} diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx index 8db3c77ba0f47..f788347ac016c 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/histogram.tsx @@ -38,12 +38,14 @@ import { TooltipValue, TooltipType, ElementClickListener, + XYChartElementEvent, } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; +import { IUiSettingsClient } from 'kibana/public'; import { EuiChartThemeType } from '@elastic/eui/dist/eui_charts_theme'; import { Subscription } from 'rxjs'; -import { getServices, timezoneProvider } from '../../../kibana_services'; +import { getServices } from '../../../kibana_services'; export interface DiscoverHistogramProps { chartData: any; @@ -85,6 +87,16 @@ function getIntervalInMs( } } +function getTimezone(uiSettings: IUiSettingsClient) { + if (uiSettings.isDefault('dateFormat:tz')) { + const detectedTimezone = moment.tz.guess(); + if (detectedTimezone) return detectedTimezone; + else return moment().format('Z'); + } else { + return uiSettings.get('dateFormat:tz', 'Browser'); + } +} + export function findMinInterval( xValues: number[], esValue: number, @@ -140,7 +152,7 @@ export class DiscoverHistogram extends Component ([elementData]) => { - const startRange = elementData[0].x; + const startRange = (elementData as XYChartElementEvent)[0].x; const range = { from: startRange, @@ -192,7 +204,7 @@ export class DiscoverHistogram extends Component { 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 => { @@ -129,7 +131,7 @@ app.config($routeProvider => { * * @type {State} */ - const id = getIndexPatternId(index, indexPatternList, uiSettings.get('defaultIndex')); + const id = getIndexPatternId(index, indexPatternList, config.get('defaultIndex')); return Promise.props({ list: indexPatternList, loaded: indexPatterns.get(id), @@ -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, }) ), }); @@ -178,8 +184,6 @@ function discoverController( $timeout, $window, Promise, - config, - kbnUrl, localStorage, uiCapabilities ) { @@ -207,6 +211,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 @@ -249,6 +254,15 @@ function discoverController( } }); + // this listener is waiting for such a path http://localhost:5601/app/kibana#/discover + // which could be set through pressing "New" button in top nav or go to "Discover" plugin from the sidebar + // to reload the page in a right way + const unlistenHistoryBasePath = history.listen(({ pathname, search, hash }) => { + if (!search && !hash && pathname === '/discover') { + $route.reload(); + } + }); + $scope.setIndexPattern = async id => { await replaceUrlAppState({ index: id }); $route.reload(); @@ -279,7 +293,7 @@ function discoverController( mode: 'absolute', }); }; - $scope.intervalOptions = intervalOptions; + $scope.intervalOptions = search.aggs.intervalOptions; $scope.minimumVisibleRows = 50; $scope.fetchStatus = fetchStatuses.UNINITIALIZED; $scope.showSaveQuery = uiCapabilities.discover.saveQuery; @@ -304,6 +318,7 @@ function discoverController( stopStateSync(); stopSyncingGlobalStateWithUrl(); stopSyncingQueryAppStateWithStateContainer(); + unlistenHistoryBasePath(); }); const getTopNavLinks = () => { @@ -317,7 +332,7 @@ function discoverController( }), run: function() { $scope.$evalAsync(() => { - kbnUrl.change('/discover'); + history.push('/discover'); }); }, testId: 'discoverNewButton', @@ -385,9 +400,7 @@ function discoverController( testId: 'discoverOpenButton', run: () => { showOpenSearchPanel({ - makeUrl: searchId => { - return kbnUrl.eval('#/discover/{{id}}', { id: searchId }); - }, + makeUrl: searchId => `#/discover/${encodeURIComponent(searchId)}`, I18nContext: core.i18n.Context, }); }, @@ -659,7 +672,7 @@ function discoverController( // no timefield, no vis, nothing to update if (!getTimeField() || !$scope.vis) return; - const buckets = $scope.vis.getAggConfig().byTypeName('buckets'); + const buckets = $scope.vis.data.aggs.byTypeName('buckets'); if (buckets && buckets.length === 1) { $scope.bucketInterval = buckets[0].buckets.getInterval(); @@ -745,7 +758,7 @@ function discoverController( }); if (savedSearch.id !== $route.current.params.id) { - kbnUrl.change('/discover/{{id}}', { id: savedSearch.id }); + history.push(`/discover/${encodeURIComponent(savedSearch.id)}`); } else { // Update defaults so that "reload saved query" functions correctly setAppState(getStateDefaults()); @@ -863,11 +876,11 @@ function discoverController( inspectorRequest.stats(getResponseInspectorStats($scope.searchSource, resp)).ok({ json: resp }); if (getTimeField()) { - const tabifiedData = tabifyAggResponse($scope.vis.aggs, resp); + const tabifiedData = tabifyAggResponse($scope.vis.data.aggs, resp); $scope.searchSource.rawResponse = resp; $scope.histogramData = discoverResponseHandler( tabifiedData, - getDimensions($scope.vis.aggs.aggs, $scope.timeRange) + getDimensions($scope.vis.data.aggs.aggs, $scope.timeRange) ); } @@ -915,11 +928,11 @@ function discoverController( }; $scope.resetQuery = function() { - kbnUrl.change('/discover/{{id}}', { id: $route.current.params.id }); + history.push(`/discover/${encodeURIComponent($route.current.params.id)}`); }; $scope.newQuery = function() { - kbnUrl.change('/discover'); + history.push('/discover'); }; $scope.updateDataSource = () => { @@ -1010,41 +1023,27 @@ function discoverController( }, ]; - if ($scope.vis) { - const visState = $scope.vis.getEnabledState(); - visState.aggs = visStateAggs; - - $scope.vis.setState(visState); - return; - } - - const visSavedObject = { - indexPattern: $scope.indexPattern.id, - visState: { - type: 'histogram', - title: savedSearch.title, - params: { - addLegend: false, - addTimeMarker: true, - }, + $scope.vis = visualizations.createVis('histogram', { + title: savedSearch.title, + params: { + addLegend: false, + addTimeMarker: true, + }, + data: { aggs: visStateAggs, + indexPattern: $scope.searchSource.getField('index').id, + searchSource: $scope.searchSource, }, - }; - - $scope.vis = visualizations.createVis( - $scope.searchSource.getField('index'), - visSavedObject.visState - ); - visSavedObject.vis = $scope.vis; + }); $scope.searchSource.onRequestStart((searchSource, options) => { if (!$scope.vis) return; - return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, options); + return $scope.vis.data.aggs.onSearchRequestStart(searchSource, options); }); $scope.searchSource.setField('aggs', function() { if (!$scope.vis) return; - return $scope.vis.getAggConfig().toDsl(); + return $scope.vis.data.aggs.toDsl(); }); } 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.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts index 32174984c1dfb..84d865fd22a9a 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header.ts @@ -16,11 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -import { IUiSettingsClient } from 'kibana/public'; import { TableHeader } from './table_header/table_header'; -import { wrapInI18nContext } from '../../../../kibana_services'; +import { wrapInI18nContext, getServices } from '../../../../kibana_services'; + +export function createTableHeaderDirective(reactDirective: any) { + const { uiSettings: config } = getServices(); -export function createTableHeaderDirective(reactDirective: any, config: IUiSettingsClient) { return reactDirective( wrapInI18nContext(TableHeader), [ 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/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_row.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_row.ts index 7a090d6b7820c..698bfe7416d42 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_row.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_row.ts @@ -19,7 +19,6 @@ import _ from 'lodash'; import $ from 'jquery'; -import { IUiSettingsClient } from 'kibana/public'; // @ts-ignore import rison from 'rison-node'; import '../../doc_viewer'; @@ -42,12 +41,7 @@ interface LazyScope extends ng.IScope { [key: string]: any; } -export function createTableRowDirective( - $compile: ng.ICompileService, - $httpParamSerializer: any, - kbnUrl: any, - config: IUiSettingsClient -) { +export function createTableRowDirective($compile: ng.ICompileService, $httpParamSerializer: any) { const cellTemplate = _.template(noWhiteSpace(cellTemplateHtml)); const truncateByHeightTemplate = _.template(noWhiteSpace(truncateByHeightTemplateHtml)); @@ -112,10 +106,9 @@ export function createTableRowDirective( }; $scope.getContextAppHref = () => { - const path = kbnUrl.eval('#/discover/context/{{ indexPattern }}/{{ anchorId }}', { - anchorId: $scope.row._id, - indexPattern: $scope.indexPattern.id, - }); + const path = `#/discover/context/${encodeURIComponent( + $scope.indexPattern.id + )}/${encodeURIComponent($scope.row._id)}`; const globalFilters: any = getServices().filterManager.getGlobalFilters(); const appFilters: any = getServices().filterManager.getAppFilters(); const hash = $httpParamSerializer({ @@ -140,7 +133,7 @@ export function createTableRowDirective( const newHtmls = [openRowHtml]; const mapping = indexPattern.fields.getByName; - const hideTimeColumn = config.get('doc_table:hideTimeColumn'); + const hideTimeColumn = getServices().uiSettings.get('doc_table:hideTimeColumn'); if (indexPattern.timeFieldName && !hideTimeColumn) { newHtmls.push( cellTemplate({ diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table.ts index 0ca8286c17081..3cb3a460af649 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/doc_table.ts @@ -17,21 +17,17 @@ * under the License. */ -import { IUiSettingsClient } from 'kibana/public'; import html from './doc_table.html'; import { dispatchRenderComplete } from '../../../../../../../../plugins/kibana_utils/public'; // @ts-ignore import { getLimitedSearchResultsMessage } from './doc_table_strings'; +import { getServices } from '../../../kibana_services'; interface LazyScope extends ng.IScope { [key: string]: any; } -export function createDocTableDirective( - config: IUiSettingsClient, - pagerFactory: any, - $filter: any -) { +export function createDocTableDirective(pagerFactory: any, $filter: any) { return { restrict: 'E', template: html, @@ -68,7 +64,7 @@ export function createDocTableDirective( }; $scope.limitedResultsWarning = getLimitedSearchResultsMessage( - config.get('discover:sampleSize') + getServices().uiSettings.get('discover:sampleSize') ); $scope.addRows = function() { diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts deleted file mode 100644 index 6ba47b839563b..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.ts +++ /dev/null @@ -1,45 +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 { DocViewer } from '../components/doc_viewer/doc_viewer'; - -export function createDocViewerDirective(reactDirective: any) { - return reactDirective( - DocViewer, - [ - 'hit', - ['indexPattern', { watchDepth: 'reference' }], - ['filter', { watchDepth: 'reference' }], - ['columns', { watchDepth: 'collection' }], - ['onAddColumn', { watchDepth: 'reference' }], - ['onRemoveColumn', { watchDepth: 'reference' }], - ], - { - restrict: 'E', - scope: { - hit: '=', - indexPattern: '=', - filter: '=?', - columns: '=?', - onAddColumn: '=?', - onRemoveColumn: '=?', - }, - } - ); -} diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx new file mode 100644 index 0000000000000..90e061ac1aa05 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_viewer.tsx @@ -0,0 +1,49 @@ +/* + * 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 { getServices } from '../../kibana_services'; + +export function createDocViewerDirective(reactDirective: any) { + return reactDirective( + (props: any) => { + const { DocViewer } = getServices(); + return ; + }, + [ + 'hit', + ['indexPattern', { watchDepth: 'reference' }], + ['filter', { watchDepth: 'reference' }], + ['columns', { watchDepth: 'collection' }], + ['onAddColumn', { watchDepth: 'reference' }], + ['onRemoveColumn', { watchDepth: 'reference' }], + ], + { + restrict: 'E', + scope: { + hit: '=', + indexPattern: '=', + filter: '=?', + columns: '=?', + onAddColumn: '=?', + onRemoveColumn: '=?', + }, + } + ); +} diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss index 0491430e5fddd..7161560f8fda4 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/_index.scss @@ -1,3 +1,2 @@ @import 'fetch_error/index'; @import 'field_chooser/index'; -@import 'doc_viewer/index'; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx index 2278b243ecc14..1d19dc112d193 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.test.tsx @@ -24,19 +24,13 @@ import { ReactWrapper } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { Doc, DocProps } from './doc'; -jest.mock('../doc_viewer/doc_viewer', () => ({ - DocViewer: () => null, -})); - jest.mock('../../../kibana_services', () => { return { getServices: () => ({ metadata: { branch: 'test', }, - getDocViewsSorted: () => { - return []; - }, + DocViewer: () => null, }), }; }); diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx index 819eb9df592bd..28a17dbdb67b7 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/doc.tsx @@ -20,9 +20,9 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPageContent } from '@elastic/eui'; import { IndexPatternsContract } from 'src/plugins/data/public'; -import { DocViewer } from '../doc_viewer/doc_viewer'; import { ElasticRequestState, useEsDocSearch } from './use_es_doc_search'; -import { ElasticSearchHit, getServices } from '../../../kibana_services'; +import { getServices } from '../../../kibana_services'; +import { ElasticSearchHit } from '../../../../../../../../plugins/discover/public'; export interface ElasticSearchResult { hits: { @@ -61,6 +61,7 @@ export interface DocProps { } export function Doc(props: DocProps) { + const { DocViewer } = getServices(); const [reqState, hit, indexPattern] = useEsDocSearch(props); return ( diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts index 6cffc2cc533b0..2cd264578a596 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc/use_es_doc_search.ts @@ -17,8 +17,9 @@ * under the License. */ import { useEffect, useState } from 'react'; -import { ElasticSearchHit, IndexPattern } from '../../../kibana_services'; +import { IndexPattern } from '../../../kibana_services'; import { DocProps } from './doc'; +import { ElasticSearchHit } from '../../../../../../../../plugins/discover/public'; export enum ElasticRequestState { Loading, diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc_viewer/doc_viewer.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc_viewer/doc_viewer.tsx deleted file mode 100644 index a177d8c29304c..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/doc_viewer/doc_viewer.tsx +++ /dev/null @@ -1,62 +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 React from 'react'; -import { EuiTabbedContent } from '@elastic/eui'; -import { getServices } from '../../../kibana_services'; -import { DocViewerTab } from './doc_viewer_tab'; -import { DocView, DocViewRenderProps } from '../../doc_views/doc_views_types'; - -/** - * Rendering tabs with different views of 1 Elasticsearch hit in Discover. - * The tabs are provided by the `docs_views` registry. - * A view can contain a React `component`, or any JS framework by using - * a `render` function. - */ -export function DocViewer(renderProps: DocViewRenderProps) { - const { docViewsRegistry } = getServices(); - const tabs = docViewsRegistry - .getDocViewsSorted(renderProps.hit) - .map(({ title, render, component }: DocView, idx: number) => { - return { - id: title, - name: title, - content: ( - - ), - }; - }); - - if (!tabs.length) { - // There there's a minimum of 2 tabs active in Discover. - // This condition takes care of unit tests with 0 tabs. - return null; - } - - return ( -
- -
- ); -} diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js index 4afaafd9bb1cf..398728e51862f 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/components/field_chooser/field_chooser.js @@ -29,8 +29,9 @@ import { KBN_FIELD_TYPES, } from '../../../../../../../../plugins/data/public'; import { getMapsAppUrl, isFieldVisualizable, isMapsAppRegistered } from './lib/visualize_url_utils'; +import { getServices } from '../../../kibana_services'; -export function createFieldChooserDirective($location, config) { +export function createFieldChooserDirective($location) { return { restrict: 'E', scope: { @@ -49,6 +50,7 @@ export function createFieldChooserDirective($location, config) { $scope.showFilter = false; $scope.toggleShowFilter = () => ($scope.showFilter = !$scope.showFilter); $scope.indexPatternList = _.sortBy($scope.indexPatternList, o => o.get('title')); + const config = getServices().uiSettings; const filter = ($scope.filter = { props: ['type', 'aggregatable', 'searchable', 'missing', 'name'], diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts new file mode 100644 index 0000000000000..7196c96989e97 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { shortenDottedString } from './shorten_dotted_string'; diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts new file mode 100644 index 0000000000000..9d78a96784339 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts @@ -0,0 +1,26 @@ +/* + * 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. + */ + +const DOT_PREFIX_RE = /(.).+?\./g; + +/** + * Convert a dot.notated.string into a short + * version (d.n.string) + */ +export const shortenDottedString = (input: string) => input.replace(DOT_PREFIX_RE, '$1.'); diff --git a/src/legacy/core_plugins/kibana/public/discover/plugin.ts b/src/legacy/core_plugins/kibana/public/discover/plugin.ts index ba671a64592a5..d3cdeb49fba71 100644 --- a/src/legacy/core_plugins/kibana/public/discover/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/discover/plugin.ts @@ -19,7 +19,6 @@ import { BehaviorSubject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; -import { i18n } from '@kbn/i18n'; import { AppMountParameters, CoreSetup, CoreStart, Plugin } from 'kibana/public'; import angular, { auto } from 'angular'; import { UiActionsSetup, UiActionsStart } from 'src/plugins/ui_actions/public'; @@ -41,10 +40,7 @@ import { KibanaLegacySetup, AngularRenderedAppUpdater, } from '../../../../../plugins/kibana_legacy/public'; -import { DocViewsRegistry } from './np_ready/doc_views/doc_views_registry'; -import { DocViewInput, DocViewInputFn } from './np_ready/doc_views/doc_views_types'; -import { DocViewTable } from './np_ready/components/table/table'; -import { JsonCodeBlock } from './np_ready/components/json_code_block/json_code_block'; +import { DiscoverSetup, DiscoverStart } from '../../../../../plugins/discover/public'; import { HomePublicPluginSetup } from '../../../../../plugins/home/public'; import { VisualizationsStart, @@ -52,15 +48,6 @@ import { } from '../../../visualizations/public/np_ready/public'; import { createKbnUrlTracker } from '../../../../../plugins/kibana_utils/public'; -/** - * These are the interfaces with your public contracts. You should export these - * for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces. - * @public - */ -export interface DiscoverSetup { - addDocView(docViewRaw: DocViewInput | DocViewInputFn): void; -} -export type DiscoverStart = void; export interface DiscoverSetupPlugins { uiActions: UiActionsSetup; embeddable: EmbeddableSetup; @@ -68,6 +55,7 @@ export interface DiscoverSetupPlugins { home: HomePublicPluginSetup; visualizations: VisualizationsSetup; data: DataPublicPluginSetup; + discover: DiscoverSetup; } export interface DiscoverStartPlugins { uiActions: UiActionsStart; @@ -78,6 +66,7 @@ export interface DiscoverStartPlugins { share: SharePluginStart; inspector: any; visualizations: VisualizationsStart; + discover: DiscoverStart; } const innerAngularName = 'app/discover'; const embeddableAngularName = 'app/discoverEmbeddable'; @@ -87,10 +76,9 @@ const embeddableAngularName = 'app/discoverEmbeddable'; * There are 2 kinds of Angular bootstrapped for rendering, additionally to the main Angular * Discover provides embeddables, those contain a slimmer Angular */ -export class DiscoverPlugin implements Plugin { +export class DiscoverPlugin implements Plugin { private servicesInitialized: boolean = false; private innerAngularInitialized: boolean = false; - private docViewsRegistry: DocViewsRegistry | null = null; private embeddableInjector: auto.IInjectorService | null = null; private getEmbeddableInjector: (() => Promise) | null = null; private appStateUpdater = new BehaviorSubject(() => ({})); @@ -103,7 +91,7 @@ export class DiscoverPlugin implements Plugin { public initializeInnerAngular?: () => void; public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>; - setup(core: CoreSetup, plugins: DiscoverSetupPlugins): DiscoverSetup { + setup(core: CoreSetup, plugins: DiscoverSetupPlugins) { const { appMounted, appUnMounted, stop: stopUrlTracker } = createKbnUrlTracker({ baseUrl: core.http.basePath.prepend('/app/kibana'), defaultSubUrl: '#/discover', @@ -130,21 +118,7 @@ export class DiscoverPlugin implements Plugin { }; this.getEmbeddableInjector = this.getInjector.bind(this); - this.docViewsRegistry = new DocViewsRegistry(this.getEmbeddableInjector); - this.docViewsRegistry.addDocView({ - title: i18n.translate('kbn.discover.docViews.table.tableTitle', { - defaultMessage: 'Table', - }), - order: 10, - component: DocViewTable, - }); - this.docViewsRegistry.addDocView({ - title: i18n.translate('kbn.discover.docViews.json.jsonTitle', { - defaultMessage: 'JSON', - }), - order: 20, - component: JsonCodeBlock, - }); + plugins.discover.docViews.setAngularInjectorGetter(this.getEmbeddableInjector); plugins.kibanaLegacy.registerLegacyApp({ id: 'discover', title: 'Discover', @@ -172,14 +146,10 @@ export class DiscoverPlugin implements Plugin { }, }); registerFeature(plugins.home); - this.registerEmbeddable(core, plugins); - return { - addDocView: this.docViewsRegistry.addDocView.bind(this.docViewsRegistry), - }; } - start(core: CoreStart, plugins: DiscoverStartPlugins): DiscoverStart { + start(core: CoreStart, plugins: DiscoverStartPlugins) { // we need to register the application service at setup, but to render it // there are some start dependencies necessary, for this reason // initializeInnerAngular + initializeServices are assigned at start and used @@ -198,7 +168,7 @@ export class DiscoverPlugin implements Plugin { if (this.servicesInitialized) { return { core, plugins }; } - const services = await buildServices(core, plugins, this.docViewsRegistry!); + const services = await buildServices(core, plugins); setServices(services); this.servicesInitialized = true; diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index 04eaf2cbe2679..df6b08ef76556 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -48,7 +48,6 @@ import './dashboard/legacy'; import './management'; import './dev_tools'; import 'ui/agg_response'; -import 'ui/agg_types'; import { showAppRedirectNotification } from '../../../../plugins/kibana_legacy/public'; import 'leaflet'; import { localApplicationService } from './local_application_service'; diff --git a/src/legacy/core_plugins/kibana/public/management/saved_object_registry.ts b/src/legacy/core_plugins/kibana/public/management/saved_object_registry.ts index 8e73a09480c41..cb9ac0e01bb7f 100644 --- a/src/legacy/core_plugins/kibana/public/management/saved_object_registry.ts +++ b/src/legacy/core_plugins/kibana/public/management/saved_object_registry.ts @@ -35,9 +35,15 @@ interface SavedObjectRegistryEntry { title: string; } +export interface ISavedObjectsManagementRegistry { + register(service: SavedObjectRegistryEntry): void; + all(): SavedObjectRegistryEntry[]; + get(id: string): SavedObjectRegistryEntry | undefined; +} + const registry: SavedObjectRegistryEntry[] = []; -export const savedObjectManagementRegistry = { +export const savedObjectManagementRegistry: ISavedObjectsManagementRegistry = { register: (service: SavedObjectRegistryEntry) => { registry.push(service); }, diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js index e3ab862cd84b7..c5901ca6ee6bf 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/_objects.js @@ -28,7 +28,6 @@ import { ObjectsTable } from './components/objects_table'; import { I18nContext } from 'ui/i18n'; import { get } from 'lodash'; import { npStart } from 'ui/new_platform'; - import { getIndexBreadcrumbs } from './breadcrumbs'; const REACT_OBJECTS_TABLE_DOM_ELEMENT_ID = 'reactSavedObjectsTable'; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.html b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.html index 6efef7b48fa0e..8bce0aabcd64a 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.html +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.html @@ -1,203 +1,5 @@ - - - -
-
-

- -

-
- -
- - - - - - - - -
-
- - -
-
-
- - -
- -
-
- -
- -
- -
-
-
-
- - -
-
-
- - -
- -
-
-
-
-
-
- -
- -
-
- - - - - - - - -
-
-
- - -
- - - -
-
+ + +
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js index d1a8d6a1b14af..a847055b40015 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js @@ -17,26 +17,20 @@ * under the License. */ -import _ from 'lodash'; -import { i18n } from '@kbn/i18n'; -import angular from 'angular'; +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import 'angular'; import 'angular-elastic/elastic'; -import rison from 'rison-node'; -import { savedObjectManagementRegistry } from '../../saved_object_registry'; -import objectViewHTML from './_view.html'; import uiRoutes from 'ui/routes'; import { uiModules } from 'ui/modules'; -import { fatalError, toastNotifications } from 'ui/notify'; -import 'ui/accessibility/kbn_ui_ace_keyboard_mode'; -import { isNumeric } from './lib/numeric'; -import { canViewInApp } from './lib/in_app_url'; +import { I18nContext } from 'ui/i18n'; import { npStart } from 'ui/new_platform'; - -import { castEsToKbnFieldTypeName } from '../../../../../../../plugins/data/public'; - +import objectViewHTML from './_view.html'; import { getViewBreadcrumbs } from './breadcrumbs'; +import { savedObjectManagementRegistry } from '../../saved_object_registry'; +import { SavedObjectEdition } from './saved_object_view'; -const location = 'SavedObject view'; +const REACT_OBJECTS_VIEW_DOM_ELEMENT_ID = 'reactSavedObjectsView'; uiRoutes.when('/management/kibana/objects/:service/:id', { template: objectViewHTML, @@ -44,261 +38,48 @@ uiRoutes.when('/management/kibana/objects/:service/:id', { requireUICapability: 'management.kibana.objects', }); +function createReactView($scope, $routeParams) { + const { service: serviceName, id: objectId, notFound } = $routeParams; + + const { savedObjects, overlays, notifications, application } = npStart.core; + + $scope.$$postDigest(() => { + const node = document.getElementById(REACT_OBJECTS_VIEW_DOM_ELEMENT_ID); + if (!node) { + return; + } + + render( + + + , + node + ); + }); +} + +function destroyReactView() { + const node = document.getElementById(REACT_OBJECTS_VIEW_DOM_ELEMENT_ID); + node && unmountComponentAtNode(node); +} + uiModules .get('apps/management', ['monospaced.elastic']) .directive('kbnManagementObjectsView', function() { return { restrict: 'E', - controller: function($scope, $routeParams, $location, $window, $rootScope, uiCapabilities) { - const serviceObj = savedObjectManagementRegistry.get($routeParams.service); - const service = serviceObj.service; - const savedObjectsClient = npStart.core.savedObjects.client; - const { overlays } = npStart.core; - - /** - * Creates a field definition and pushes it to the memo stack. This function - * is designed to be used in conjunction with _.reduce(). If the - * values is plain object it will recurse through all the keys till it hits - * a string, number or an array. - * - * @param {array} memo The stack of fields - * @param {mixed} value The value of the field - * @param {string} key The key of the field - * @param {object} collection This is a reference the collection being reduced - * @param {array} parents The parent keys to the field - * @returns {array} - */ - const createField = function(memo, val, key, collection, parents) { - if (Array.isArray(parents)) { - parents.push(key); - } else { - parents = [key]; - } - - const field = { type: 'text', name: parents.join('.'), value: val }; - - if (_.isString(field.value)) { - try { - field.value = angular.toJson(JSON.parse(field.value), true); - field.type = 'json'; - } catch (err) { - field.value = field.value; - } - } else if (isNumeric(field.value)) { - field.type = 'number'; - } else if (Array.isArray(field.value)) { - field.type = 'array'; - field.value = angular.toJson(field.value, true); - } else if (_.isBoolean(field.value)) { - field.type = 'boolean'; - field.value = field.value; - } else if (_.isPlainObject(field.value)) { - // do something recursive - return _.reduce(field.value, _.partialRight(createField, parents), memo); - } - - memo.push(field); - - // once the field is added to the object you need to pop the parents - // to remove it since we've hit the end of the branch. - parents.pop(); - return memo; - }; - - const readObjectClass = function(fields, Class) { - const fieldMap = _.indexBy(fields, 'name'); - - _.forOwn(Class.mapping, function(esType, name) { - if (fieldMap[name]) return; - - fields.push({ - name: name, - type: (function() { - switch (castEsToKbnFieldTypeName(esType)) { - case 'string': - return 'text'; - case 'number': - return 'number'; - case 'boolean': - return 'boolean'; - default: - return 'json'; - } - })(), - }); - }); - - if (Class.searchSource && !fieldMap['kibanaSavedObjectMeta.searchSourceJSON']) { - fields.push({ - name: 'kibanaSavedObjectMeta.searchSourceJSON', - type: 'json', - value: '{}', - }); - } - - if (!fieldMap.references) { - fields.push({ - name: 'references', - type: 'array', - value: '[]', - }); - } - }; - - const { edit: canEdit, delete: canDelete } = uiCapabilities.savedObjectsManagement; - $scope.canEdit = canEdit; - $scope.canDelete = canDelete; - $scope.canViewInApp = canViewInApp(uiCapabilities, service.type); - - $scope.notFound = $routeParams.notFound; - - $scope.title = service.type; - - savedObjectsClient - .get(service.type, $routeParams.id) - .then(function(obj) { - $scope.obj = obj; - $scope.link = service.urlFor(obj.id); - - const fields = _.reduce(obj.attributes, createField, []); - // Special handling for references which isn't within "attributes" - createField(fields, obj.references, 'references'); - - if (service.Class) readObjectClass(fields, service.Class); - - // sorts twice since we want numerical sort to prioritize over name, - // and sortBy will do string comparison if trying to match against strings - const nameSortedFields = _.sortBy(fields, 'name'); - $scope.$evalAsync(() => { - $scope.fields = _.sortBy(nameSortedFields, field => { - const orderIndex = service.Class.fieldOrder - ? service.Class.fieldOrder.indexOf(field.name) - : -1; - return orderIndex > -1 ? orderIndex : Infinity; - }); - }); - $scope.$digest(); - }) - .catch(error => fatalError(error, location)); - - // This handles the validation of the Ace Editor. Since we don't have any - // other hooks into the editors to tell us if the content is valid or not - // we need to use the annotations to see if they have any errors. If they - // do then we push the field.name to aceInvalidEditor variable. - // Otherwise we remove it. - const loadedEditors = []; - $scope.aceInvalidEditors = []; - - $scope.aceLoaded = function(editor) { - if (_.contains(loadedEditors, editor)) return; - loadedEditors.push(editor); - - editor.$blockScrolling = Infinity; - - const session = editor.getSession(); - const fieldName = editor.container.id; - - session.setTabSize(2); - session.setUseSoftTabs(true); - session.on('changeAnnotation', function() { - const annotations = session.getAnnotations(); - if (_.some(annotations, { type: 'error' })) { - if (!_.contains($scope.aceInvalidEditors, fieldName)) { - $scope.aceInvalidEditors.push(fieldName); - } - } else { - $scope.aceInvalidEditors = _.without($scope.aceInvalidEditors, fieldName); - } - - if (!$rootScope.$$phase) $scope.$apply(); - }); - }; - - $scope.cancel = function() { - $window.history.back(); - return false; - }; - - /** - * Deletes an object and sets the notification - * @param {type} name description - * @returns {type} description - */ - $scope.delete = function() { - function doDelete() { - savedObjectsClient - .delete(service.type, $routeParams.id) - .then(function() { - return redirectHandler('deleted'); - }) - .catch(error => fatalError(error, location)); - } - const confirmModalOptions = { - confirmButtonText: i18n.translate( - 'kbn.management.objects.confirmModalOptions.deleteButtonLabel', - { - defaultMessage: 'Delete', - } - ), - title: i18n.translate('kbn.management.objects.confirmModalOptions.modalTitle', { - defaultMessage: 'Delete saved Kibana object?', - }), - }; - - overlays - .openConfirm( - i18n.translate('kbn.management.objects.confirmModalOptions.modalDescription', { - defaultMessage: "You can't recover deleted objects", - }), - confirmModalOptions - ) - .then(isConfirmed => { - if (isConfirmed) { - doDelete(); - } - }); - }; - - $scope.submit = function() { - const source = _.cloneDeep($scope.obj.attributes); - - _.each($scope.fields, function(field) { - let value = field.value; - - if (field.type === 'number') { - value = Number(field.value); - } - - if (field.type === 'array') { - value = JSON.parse(field.value); - } - - _.set(source, field.name, value); - }); - - const { references, ...attributes } = source; - - savedObjectsClient - .update(service.type, $routeParams.id, attributes, { references }) - .then(function() { - return redirectHandler('updated'); - }) - .catch(error => fatalError(error, location)); - }; - - function redirectHandler(action) { - $location.path('/management/kibana/objects').search({ - _a: rison.encode({ - tab: serviceObj.title, - }), - }); - - toastNotifications.addSuccess( - `${_.capitalize(action)} '${ - $scope.obj.attributes.title - }' ${$scope.title.toLowerCase()} object` - ); - } + controller: function($scope, $routeParams) { + createReactView($scope, $routeParams); + $scope.$on('$destroy', destroyReactView); }, }; }); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/header.test.tsx.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/header.test.tsx.snap new file mode 100644 index 0000000000000..7e1f7ea12b014 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/header.test.tsx.snap @@ -0,0 +1,165 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Intro component renders correctly 1`] = ` +
+ +
+ +
+ +

+ + Edit search + +

+
+
+
+ +
+ +
+ +
+ + + + + + +
+ + + +
+
+
+ +
+ +
+ +
+`; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/intro.test.tsx.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/intro.test.tsx.snap new file mode 100644 index 0000000000000..812031b4b363c --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/intro.test.tsx.snap @@ -0,0 +1,67 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Intro component renders correctly 1`] = ` + + + } + > +
+
+
+ + +`; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/not_found_errors.test.tsx.snap b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/not_found_errors.test.tsx.snap new file mode 100644 index 0000000000000..ac565a000813e --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/object_view/__snapshots__/not_found_errors.test.tsx.snap @@ -0,0 +1,301 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`NotFoundErrors component renders correctly for index-pattern type 1`] = ` + + + } + > +
+
+
+ + +`; + +exports[`NotFoundErrors component renders correctly for index-pattern-field type 1`] = ` + + + } + > +
+
+
+ + +`; + +exports[`NotFoundErrors component renders correctly for search type 1`] = ` + + + } + > +
+
+
+ + +`; + +exports[`NotFoundErrors component renders correctly for unknown type 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..5342693113bca 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 ( @@ -185,6 +186,7 @@ export class Table extends PureComponent { aria-label={getSavedObjectLabel(type)} type={object.meta.icon || 'apps'} size="s" + data-test-subj="objectType" /> ); @@ -201,6 +203,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 +233,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 +250,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 +378,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/management/sections/objects/lib/create_field_list.test.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/create_field_list.test.ts new file mode 100644 index 0000000000000..345716f91ea88 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/create_field_list.test.ts @@ -0,0 +1,132 @@ +/* + * 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 { SimpleSavedObject, SavedObjectReference } from '../../../../../../../../core/public'; +import { savedObjectsServiceMock } from '../../../../../../../../core/public/mocks'; +import { createFieldList } from './create_field_list'; + +const savedObjectClientMock = savedObjectsServiceMock.createStartContract().client; + +const createObject = ( + attributes: T, + references: SavedObjectReference[] = [] +): SimpleSavedObject => + new SimpleSavedObject(savedObjectClientMock, { + id: 'id', + type: 'type', + migrationVersion: {}, + attributes, + references, + }); + +describe('createFieldList', () => { + it('generate fields based on the object attributes', () => { + const obj = createObject({ + textField: 'some text', + numberField: 12, + boolField: true, + }); + expect(createFieldList(obj)).toMatchInlineSnapshot(` + Array [ + Object { + "name": "textField", + "type": "text", + "value": "some text", + }, + Object { + "name": "numberField", + "type": "number", + "value": 12, + }, + Object { + "name": "boolField", + "type": "boolean", + "value": true, + }, + ] + `); + }); + + it('detects json fields', () => { + const obj = createObject({ + jsonField: `{"data": "value"}`, + }); + expect(createFieldList(obj)).toMatchInlineSnapshot(` + Array [ + Object { + "name": "jsonField", + "type": "json", + "value": "{ + \\"data\\": \\"value\\" + }", + }, + ] + `); + }); + + it('handles array fields', () => { + const obj = createObject({ + someArray: [1, 2, 3], + }); + expect(createFieldList(obj)).toMatchInlineSnapshot(` + Array [ + Object { + "name": "someArray", + "type": "array", + "value": "[ + 1, + 2, + 3 + ]", + }, + ] + `); + }); + + it('recursively collect nested fields', () => { + const obj = createObject({ + firstLevel: { + firstLevelField: 'foo', + secondLevel: { + secondLevelFieldA: 'A', + secondLevelFieldB: 'B', + }, + }, + }); + expect(createFieldList(obj)).toMatchInlineSnapshot(` + Array [ + Object { + "name": "firstLevel.firstLevelField", + "type": "text", + "value": "foo", + }, + Object { + "name": "firstLevel.secondLevel.secondLevelFieldA", + "type": "text", + "value": "A", + }, + Object { + "name": "firstLevel.secondLevel.secondLevelFieldB", + "type": "text", + "value": "B", + }, + ] + `); + }); +}); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/create_field_list.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/create_field_list.ts new file mode 100644 index 0000000000000..88a1184d5d70f --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/create_field_list.ts @@ -0,0 +1,135 @@ +/* + * 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 { forOwn, indexBy, isNumber, isBoolean, isPlainObject, isString } from 'lodash'; +import { SimpleSavedObject } from '../../../../../../../../core/public'; +import { castEsToKbnFieldTypeName } from '../../../../../../../../plugins/data/public'; +import { ObjectField } from '../types'; +import { SavedObjectLoader } from '../../../../../../../../plugins/saved_objects/public'; + +const maxRecursiveIterations = 20; + +export function createFieldList( + object: SimpleSavedObject, + service?: SavedObjectLoader +): ObjectField[] { + const fields = Object.entries(object.attributes as Record).reduce( + (objFields, [key, value]) => { + return [...objFields, ...recursiveCreateFields(key, value)]; + }, + [] as ObjectField[] + ); + if (service && (service as any).Class) { + addFieldsFromClass((service as any).Class, fields); + } + + return fields; +} + +/** + * Creates a field definition and pushes it to the memo stack. This function + * is designed to be used in conjunction with _.reduce(). If the + * values is plain object it will recurse through all the keys till it hits + * a string, number or an array. + * + * @param {string} key The key of the field + * @param {mixed} value The value of the field + * @param {array} parents The parent keys to the field + * @returns {array} + */ +const recursiveCreateFields = (key: string, value: any, parents: string[] = []): ObjectField[] => { + const path = [...parents, key]; + if (path.length > maxRecursiveIterations) { + return []; + } + + const field: ObjectField = { type: 'text', name: path.join('.'), value }; + + if (isString(field.value)) { + try { + field.value = JSON.stringify(JSON.parse(field.value), undefined, 2); + field.type = 'json'; + } catch (err) { + field.type = 'text'; + } + } else if (isNumber(field.value)) { + field.type = 'number'; + } else if (Array.isArray(field.value)) { + field.type = 'array'; + field.value = JSON.stringify(field.value, undefined, 2); + } else if (isBoolean(field.value)) { + field.type = 'boolean'; + } else if (isPlainObject(field.value)) { + let fields: ObjectField[] = []; + forOwn(field.value, (childValue, childKey) => { + fields = [...fields, ...recursiveCreateFields(childKey as string, childValue, path)]; + }); + return fields; + } + + return [field]; +}; + +const addFieldsFromClass = function( + Class: { mapping: Record; searchSource: any }, + fields: ObjectField[] +) { + const fieldMap = indexBy(fields, 'name'); + + _.forOwn(Class.mapping, (esType, name) => { + if (!name || fieldMap[name]) { + return; + } + + const getFieldTypeFromEsType = () => { + switch (castEsToKbnFieldTypeName(esType)) { + case 'string': + return 'text'; + case 'number': + return 'number'; + case 'boolean': + return 'boolean'; + default: + return 'json'; + } + }; + + fields.push({ + name, + type: getFieldTypeFromEsType(), + value: undefined, + }); + }); + + if (Class.searchSource && !fieldMap['kibanaSavedObjectMeta.searchSourceJSON']) { + fields.push({ + name: 'kibanaSavedObjectMeta.searchSourceJSON', + type: 'json', + value: '{}', + }); + } + + if (!fieldMap.references) { + fields.push({ + name: 'references', + type: 'array', + value: '[]', + }); + } +}; diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.js deleted file mode 100644 index 0026154848693..0000000000000 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.js +++ /dev/null @@ -1,38 +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. - */ - -export function canViewInApp(uiCapabilities, type) { - switch (type) { - case 'search': - case 'searches': - return uiCapabilities.discover.show; - case 'visualization': - case 'visualizations': - return uiCapabilities.visualize.show; - case 'index-pattern': - case 'index-patterns': - case 'indexPatterns': - return uiCapabilities.management.kibana.index_patterns; - case 'dashboard': - case 'dashboards': - return uiCapabilities.dashboard.show; - default: - return uiCapabilities[type].show; - } -} diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.ts new file mode 100644 index 0000000000000..82146554afa6f --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/in_app_url.ts @@ -0,0 +1,40 @@ +/* + * 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 { Capabilities } from 'src/core/public'; + +export function canViewInApp(uiCapabilities: Capabilities, type: string): boolean { + switch (type) { + case 'search': + case 'searches': + return uiCapabilities.discover.show as boolean; + case 'visualization': + case 'visualizations': + return uiCapabilities.visualize.show as boolean; + case 'index-pattern': + case 'index-patterns': + case 'indexPatterns': + return uiCapabilities.management.kibana.index_patterns as boolean; + case 'dashboard': + case 'dashboards': + return uiCapabilities.dashboard.show as boolean; + default: + return uiCapabilities[type].show as boolean; + } +} diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/saved_object_view.tsx b/src/legacy/core_plugins/kibana/public/management/sections/objects/saved_object_view.tsx new file mode 100644 index 0000000000000..4984fe3e6d6b8 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/saved_object_view.tsx @@ -0,0 +1,176 @@ +/* + * 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, { Component } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiSpacer, EuiPageContent } from '@elastic/eui'; +import { + Capabilities, + SavedObjectsClientContract, + OverlayStart, + NotificationsStart, + SimpleSavedObject, +} from '../../../../../../../core/public'; +import { ISavedObjectsManagementRegistry } from '../../saved_object_registry'; +import { Header, NotFoundErrors, Intro, Form } from './components/object_view'; +import { canViewInApp } from './lib/in_app_url'; +import { SubmittedFormData } from './types'; + +interface SavedObjectEditionProps { + id: string; + serviceName: string; + serviceRegistry: ISavedObjectsManagementRegistry; + capabilities: Capabilities; + overlays: OverlayStart; + notifications: NotificationsStart; + notFoundType?: string; + savedObjectsClient: SavedObjectsClientContract; +} + +interface SavedObjectEditionState { + type: string; + object?: SimpleSavedObject; +} + +export class SavedObjectEdition extends Component< + SavedObjectEditionProps, + SavedObjectEditionState +> { + constructor(props: SavedObjectEditionProps) { + super(props); + + const { serviceRegistry, serviceName } = props; + const type = serviceRegistry.get(serviceName)!.service.type; + + this.state = { + object: undefined, + type, + }; + } + + componentDidMount() { + const { id, savedObjectsClient } = this.props; + const { type } = this.state; + savedObjectsClient.get(type, id).then(object => { + this.setState({ + object, + }); + }); + } + + render() { + const { + capabilities, + notFoundType, + serviceRegistry, + id, + serviceName, + savedObjectsClient, + } = this.props; + const { type } = this.state; + const { object } = this.state; + const { edit: canEdit, delete: canDelete } = capabilities.savedObjectsManagement as Record< + string, + boolean + >; + const canView = canViewInApp(capabilities, type); + const service = serviceRegistry.get(serviceName)!.service; + + return ( + +
this.delete()} + viewUrl={service.urlFor(id)} + /> + {notFoundType && ( + <> + + + + )} + {canEdit && ( + <> + + + + )} + {object && ( + <> + +
+ + )} + + ); + } + + async delete() { + const { id, savedObjectsClient, overlays, notifications } = this.props; + const { type, object } = this.state; + + const confirmed = await overlays.openConfirm( + i18n.translate('kbn.management.objects.confirmModalOptions.modalDescription', { + defaultMessage: 'This action permanently removes the object from Kibana.', + }), + { + confirmButtonText: i18n.translate( + 'kbn.management.objects.confirmModalOptions.deleteButtonLabel', + { + defaultMessage: 'Delete', + } + ), + title: i18n.translate('kbn.management.objects.confirmModalOptions.modalTitle', { + defaultMessage: `Delete '{title}'?`, + values: { + title: object?.attributes?.title || 'saved Kibana object', + }, + }), + buttonColor: 'danger', + } + ); + if (confirmed) { + await savedObjectsClient.delete(type, id); + notifications.toasts.addSuccess(`Deleted '${object!.attributes.title}' ${type} object`); + this.redirectToListing(); + } + } + + saveChanges = async ({ attributes, references }: SubmittedFormData) => { + const { savedObjectsClient, notifications } = this.props; + const { object, type } = this.state; + + await savedObjectsClient.update(object!.type, object!.id, attributes, { references }); + notifications.toasts.addSuccess(`Updated '${attributes.title}' ${type} object`); + this.redirectToListing(); + }; + + redirectToListing() { + window.location.hash = '/management/kibana/objects'; + } +} diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/types.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/types.ts new file mode 100644 index 0000000000000..32436e96d4829 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/types.ts @@ -0,0 +1,38 @@ +/* + * 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 { SavedObjectReference } from 'src/core/public'; + +export interface ObjectField { + type: FieldType; + name: string; + value: any; +} + +export type FieldType = 'text' | 'number' | 'boolean' | 'array' | 'json'; + +export interface FieldState { + value?: any; + invalid?: boolean; +} + +export interface SubmittedFormData { + attributes: any; + references: SavedObjectReference[]; +} 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..a2e2ba3543104 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts @@ -24,8 +24,6 @@ * directly where they are needed. */ -// @ts-ignore -export { KbnUrlProvider, RedirectWhenMissingProvider } 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,10 +31,6 @@ export { DashboardConstants } from '../dashboard/np_ready/dashboard_constants'; export { VisSavedObject, VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/'; export { configureAppAngularModule, - ensureDefaultIndexPattern, - IPrivate, migrateLegacyQuery, - PrivateProvider, - PromiseServiceCreator, subscribeWithScope, } from '../../../../../plugins/kibana_legacy/public'; 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..241397884c8fe 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 @@ -21,14 +21,7 @@ import angular, { IModule } from 'angular'; import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; import { AppMountContext } from 'kibana/public'; -import { - configureAppAngularModule, - KbnUrlProvider, - RedirectWhenMissingProvider, - IPrivate, - PrivateProvider, - PromiseServiceCreator, -} from '../legacy_imports'; +import { configureAppAngularModule } from '../legacy_imports'; import { NavigationPublicPluginStart as NavigationStart } from '../../../../../../plugins/navigation/public'; import { createTopNavDirective, @@ -83,37 +76,16 @@ function mountVisualizeApp(appBasePath: string, element: HTMLElement) { function createLocalAngularModule(core: AppMountContext['core'], navigation: NavigationStart) { createLocalI18nModule(); - createLocalPrivateModule(); - createLocalPromiseModule(); - createLocalKbnUrlModule(); createLocalTopNavModule(navigation); const visualizeAngularModule: IModule = angular.module(moduleName, [ ...thirdPartyAngularDependencies, 'app/visualize/I18n', - 'app/visualize/Private', 'app/visualize/TopNav', - 'app/visualize/KbnUrl', - 'app/visualize/Promise', ]); return visualizeAngularModule; } -function createLocalKbnUrlModule() { - angular - .module('app/visualize/KbnUrl', ['app/visualize/Private', 'ngRoute']) - .service('kbnUrl', (Private: IPrivate) => Private(KbnUrlProvider)) - .service('redirectWhenMissing', (Private: IPrivate) => Private(RedirectWhenMissingProvider)); -} - -function createLocalPromiseModule() { - angular.module('app/visualize/Promise', []).service('Promise', PromiseServiceCreator); -} - -function createLocalPrivateModule() { - angular.module('app/visualize/Private', []).provider('Private', PrivateProvider); -} - function createLocalTopNavModule(navigation: NavigationStart) { angular .module('app/visualize/TopNav', ['react']) diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts index c334172805b9f..b6a63d50b205b 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/breadcrumbs.ts @@ -69,7 +69,7 @@ export function getEditBreadcrumbs($route: any) { return [ ...getLandingBreadcrumbs(), { - text: $route.current.locals.savedVis.title, + text: $route.current.locals.resolved.savedVis.title, }, ]; } diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html index 28baf21925cbe..0dcacd30fba4e 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/editor.html @@ -69,7 +69,8 @@ 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..c5325ca3108b4 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 @@ -22,6 +22,7 @@ import _ from 'lodash'; import { Subscription } from 'rxjs'; import { map } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; +import { EventEmitter } from 'events'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -30,7 +31,8 @@ import { VisualizeConstants } from '../visualize_constants'; import { getEditBreadcrumbs } from '../breadcrumbs'; import { addHelpMenuToAppChrome } from '../help_menu/help_menu_util'; -import { unhashUrl } from '../../../../../../../plugins/kibana_utils/public'; +import { unhashUrl, removeQueryParam } from '../../../../../../../plugins/kibana_utils/public'; +import { MarkdownSimple, toMountPoint } from '../../../../../../../plugins/kibana_react/public'; import { addFatalError, kbnBaseUrl } from '../../../../../../../plugins/kibana_legacy/public'; import { SavedObjectSaveModal, @@ -68,17 +70,7 @@ export function initEditorDirective(app, deps) { initVisualizationDirective(app, deps); } -function VisualizeAppController( - $scope, - $route, - $window, - $injector, - $timeout, - kbnUrl, - redirectWhenMissing, - kbnUrlStateStorage, - history -) { +function VisualizeAppController($scope, $route, $injector, $timeout, kbnUrlStateStorage, history) { const { indexPatterns, localStorage, @@ -93,6 +85,7 @@ function VisualizeAppController( uiSettings, I18nContext, setActiveUrl, + visualizations, } = getServices(); const { @@ -107,27 +100,63 @@ function VisualizeAppController( ); // Retrieve the resolved SavedVis instance. - const savedVis = $route.current.locals.savedVis; + const { vis, savedVis, savedSearch, embeddableHandler } = $route.current.locals.resolved; + $scope.eventEmitter = new EventEmitter(); const _applyVis = () => { $scope.$apply(); }; // This will trigger a digest cycle. This is needed when vis is updated from a global angular like in visualize_embeddable.js. - savedVis.vis.on('apply', _applyVis); + $scope.eventEmitter.on('apply', _applyVis); // vis is instance of src/legacy/ui/public/vis/vis.js. // SearchSource is a promise-based stream of search results that can inherit from other search sources. - const { vis, searchSource, savedSearch } = savedVis; + const searchSource = vis.data.searchSource; $scope.vis = vis; + $scope.savedSearch = savedSearch; const $appStatus = { dirty: !savedVis.id, }; - vis.on('dirtyStateChange', ({ isDirty }) => { - vis.dirty = isDirty; - $scope.$digest(); + const defaultQuery = { + query: '', + language: + localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), + }; + + const visStateToEditorState = () => { + const savedVisState = visualizations.convertFromSerializedVis(vis.serialize()); + return { + uiState: vis.uiState.toJSON(), + query: vis.data.searchSource.getOwnField('query') || defaultQuery, + filters: vis.data.searchSource.getOwnField('filter') || [], + vis: { ...savedVisState.visState, title: vis.title }, + linked: !!savedVis.savedSearchId, + }; + }; + + const stateDefaults = visStateToEditorState(); + + const { stateContainer, stopStateSync } = useVisualizeAppState({ + stateDefaults, + kbnUrlStateStorage, + }); + + $scope.eventEmitter.on('dirtyStateChange', ({ isDirty }) => { + if (!isDirty) { + stateContainer.transitions.updateVisState(visStateToEditorState().vis); + } + $timeout(() => { + $scope.dirty = isDirty; + }); + }); + + $scope.eventEmitter.on('updateVis', () => { + embeddableHandler.reload(); }); + $scope.embeddableHandler = embeddableHandler; + $scope.topNavMenu = [ ...(visualizeCapabilities.save ? [ @@ -144,10 +173,10 @@ function VisualizeAppController( ), testId: 'visualizeSaveButton', disableButton() { - return Boolean(vis.dirty); + return Boolean($scope.dirty); }, tooltip() { - if (vis.dirty) { + if ($scope.dirty) { return i18n.translate( 'kbn.visualize.topNavMenu.saveVisualizationDisabledButtonTooltip', { @@ -216,7 +245,7 @@ function VisualizeAppController( }), testId: 'shareTopNavButton', run: anchorElement => { - const hasUnappliedChanges = vis.dirty; + const hasUnappliedChanges = $scope.dirty; const hasUnsavedChanges = $appStatus.dirty; share.toggleShareContextMenu({ anchorElement, @@ -242,17 +271,17 @@ function VisualizeAppController( }), testId: 'openInspectorButton', disableButton() { - return !vis.hasInspector || !vis.hasInspector(); + return !embeddableHandler.hasInspector || !embeddableHandler.hasInspector(); }, run() { - const inspectorSession = vis.openInspector(); + const inspectorSession = embeddableHandler.openInspector(); // Close the inspector if this scope is destroyed (e.g. because the user navigates away). const removeWatch = $scope.$on('$destroy', () => inspectorSession.close()); // Remove that watch in case the user closes the inspector session herself. inspectorSession.onClose.finally(removeWatch); }, tooltip() { - if (!vis.hasInspector || !vis.hasInspector()) { + if (!embeddableHandler.hasInspector || !embeddableHandler.hasInspector()) { return i18n.translate('kbn.visualize.topNavMenu.openInspectorDisabledButtonTooltip', { defaultMessage: `This visualization doesn't support any inspectors.`, }); @@ -266,7 +295,7 @@ function VisualizeAppController( defaultMessage: 'Refresh', }), run: function() { - vis.forceReload(); + embeddableHandler.reload(); }, testId: 'visualizeRefreshButton', }, @@ -276,28 +305,6 @@ function VisualizeAppController( chrome.docTitle.change(savedVis.title); } - const defaultQuery = { - query: '', - language: - localStorage.get('kibana.userQueryLanguage') || uiSettings.get('search:queryLanguage'), - }; - - // Extract visualization state with filtered aggs. You can see these filtered aggs in the URL. - // Consists of things like aggs, params, listeners, title, type, etc. - const savedVisState = vis.getState(); - const stateDefaults = { - uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {}, - query: searchSource.getOwnField('query') || defaultQuery, - filters: searchSource.getOwnField('filter') || [], - vis: savedVisState, - linked: !!savedVis.savedSearchId, - }; - - const { stateContainer, stopStateSync } = useVisualizeAppState({ - stateDefaults, - kbnUrlStateStorage, - }); - // sync initial app filters from state to filterManager filterManager.setAppFilters(_.cloneDeep(stateContainer.getState().filters)); // setup syncing of app filters between appState and filterManager @@ -313,16 +320,34 @@ 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', + const { aggs, ...visState } = stateContainer.getState().vis; + vis.setState({ ...visState, data: { aggs } }); + } 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; } } @@ -361,8 +386,8 @@ function VisualizeAppController( }; function init() { - if (vis.indexPattern) { - $scope.indexPattern = vis.indexPattern; + if (vis.data.indexPattern) { + $scope.indexPattern = vis.data.indexPattern; } else { indexPatterns.getDefault().then(defaultIndexPattern => { $scope.indexPattern = defaultIndexPattern; @@ -371,22 +396,14 @@ function VisualizeAppController( const initialState = stateContainer.getState(); - $scope.appState = { - // mock implementation of the legacy appState.save() - // this could be even replaced by passing only "updateAppState" callback - save() { - stateContainer.transitions.updateVisState(vis.getState()); - }, - }; - const handleLinkedSearch = linked => { if (linked && !savedVis.savedSearchId && savedSearch) { savedVis.savedSearchId = savedSearch.id; - vis.savedSearchId = savedSearch.id; + vis.data.savedSearchId = savedSearch.id; searchSource.setParent(savedSearch.searchSource); } else if (!linked && savedVis.savedSearchId) { delete savedVis.savedSearchId; - delete vis.savedSearchId; + delete vis.data.savedSearchId; } }; @@ -395,6 +412,7 @@ function VisualizeAppController( 'uiState', stateContainer ); + vis.uiState = persistedState; $scope.uiState = persistedState; $scope.savedVis = savedVis; $scope.query = initialState.query; @@ -404,7 +422,7 @@ function VisualizeAppController( const addToDashMode = $route.current.params[DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM]; - kbnUrl.removeParam(DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM); + removeQueryParam(history, DashboardConstants.ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM); $scope.isAddToDashMode = () => addToDashMode; @@ -419,7 +437,7 @@ function VisualizeAppController( $scope.showQueryBarTimePicker = () => { // tsvb loads without an indexPattern initially (TODO investigate). // hide timefilter only if timeFieldName is explicitly undefined. - const hasTimeField = vis.indexPattern ? !!vis.indexPattern.timeFieldName : true; + const hasTimeField = vis.data.indexPattern ? !!vis.data.indexPattern.timeFieldName : true; return vis.type.options.showTimePicker && hasTimeField; }; @@ -434,10 +452,24 @@ function VisualizeAppController( updateSavedQueryFromUrl(state.savedQuery); // if the browser history was changed manually we need to reflect changes in the editor - if (!_.isEqual(vis.getState(), state.vis)) { - vis.setState(state.vis); - vis.forceReload(); - vis.emit('updateEditor'); + if ( + !_.isEqual( + { + ...visualizations.convertFromSerializedVis(vis.serialize()).visState, + title: vis.title, + }, + state.vis + ) + ) { + const { aggs, ...visState } = state.vis; + vis.setState({ + ...visState, + data: { + aggs, + }, + }); + embeddableHandler.reload(); + $scope.eventEmitter.emit('updateEditor'); } $appStatus.dirty = true; @@ -490,8 +522,8 @@ function VisualizeAppController( const { query, linked, filters } = stateContainer.getState(); $scope.query = query; handleLinkedSearch(linked); - savedVis.searchSource.setField('query', query); - savedVis.searchSource.setField('filter', filters); + vis.data.searchSource.setField('query', query); + vis.data.searchSource.setField('filter', filters); $scope.$broadcast('render'); }; @@ -525,13 +557,12 @@ function VisualizeAppController( } savedVis.destroy(); subscriptions.unsubscribe(); - $scope.vis.off('apply', _applyVis); + $scope.eventEmitter.off('apply', _applyVis); unsubscribePersisted(); unsubscribeStateUpdates(); - stopStateSync(); - stopSyncingQueryServiceStateWithUrl(); - stopSyncingAppFilters(); + + stopAllSyncing(); }); $timeout(() => { @@ -549,7 +580,7 @@ function VisualizeAppController( // If nothing has changed, trigger the fetch manually, otherwise it will happen as a result of the changes if (!isUpdate) { - $scope.vis.forceReload(); + embeddableHandler.reload(); } }; @@ -598,8 +629,10 @@ function VisualizeAppController( title: savedVis.title, type: savedVis.type || stateContainer.getState().vis.type, }); + savedVis.searchSource.setField('query', stateContainer.getState().query); + savedVis.searchSource.setField('filter', stateContainer.getState().filters); savedVis.visState = stateContainer.getState().vis; - savedVis.uiStateJSON = angular.toJson($scope.uiState.getChanges()); + savedVis.uiStateJSON = angular.toJson($scope.uiState.toJSON()); $appStatus.dirty = false; return savedVis.save(saveOptions).then( @@ -623,10 +656,10 @@ function VisualizeAppController( const savedVisualizationParsedUrl = new KibanaParsedUrl({ basePath: getBasePath(), appId: kbnBaseUrl.slice('/app/'.length), - appPath: kbnUrl.eval(`${VisualizeConstants.EDIT_PATH}/{{id}}`, { id: savedVis.id }), + appPath: `${VisualizeConstants.EDIT_PATH}/${encodeURIComponent(savedVis.id)}`, }); // Manually insert a new url so the back button will open the saved visualization. - $window.history.pushState({}, '', savedVisualizationParsedUrl.getRootRelativePath()); + history.replace(savedVisualizationParsedUrl.appPath); setActiveUrl(savedVisualizationParsedUrl.appPath); const lastDashboardAbsoluteUrl = chrome.navLinks.get('kibana:dashboard').url; @@ -642,7 +675,7 @@ function VisualizeAppController( DashboardConstants.ADD_EMBEDDABLE_ID, savedVis.id ); - kbnUrl.change(dashboardParsedUrl.appPath); + history.push(dashboardParsedUrl.appPath); } else if (savedVis.id === $route.current.params.id) { chrome.docTitle.change(savedVis.lastSavedTitle); chrome.setBreadcrumbs($injector.invoke(getEditBreadcrumbs)); @@ -713,7 +746,7 @@ function VisualizeAppController( ); }; - vis.on('unlinkFromSavedSearch', unlinkFromSavedSearch); + $scope.eventEmitter.on('unlinkFromSavedSearch', unlinkFromSavedSearch); addHelpMenuToAppChrome(chrome, docLinks); 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..fbabd6fc87c98 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 @@ -17,12 +17,12 @@ * under the License. */ -export function initVisualizationDirective(app, deps) { +export function initVisualizationDirective(app) { app.directive('visualizationEmbedded', function($timeout) { return { restrict: 'E', scope: { - savedObj: '=', + embeddableHandler: '=', uiState: '=?', timeRange: '=', filters: '=', @@ -31,24 +31,16 @@ export function initVisualizationDirective(app, deps) { }, link: function($scope, element) { $scope.renderFunction = async () => { - if (!$scope._handler) { - $scope._handler = await deps.embeddable - .getEmbeddableFactory('visualization') - .createFromObject($scope.savedObj, { - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - appState: $scope.appState, - uiState: $scope.uiState, - }); - $scope._handler.render(element[0]); - } else { - $scope._handler.updateInput({ - timeRange: $scope.timeRange, - filters: $scope.filters || [], - query: $scope.query, - }); + if (!$scope.rendered) { + $scope.embeddableHandler.render(element[0]); + $scope.rendered = true; } + + $scope.embeddableHandler.updateInput({ + timeRange: $scope.timeRange, + filters: $scope.filters || [], + query: $scope.query, + }); }; $scope.$on('render', event => { @@ -59,7 +51,9 @@ export function initVisualizationDirective(app, deps) { }); $scope.$on('$destroy', () => { - $scope._handler.destroy(); + if ($scope.embeddableHandler) { + $scope.embeddableHandler.destroy(); + } }); }, }; diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js index f2d9cbe2ad84c..ef174dbaa5865 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js @@ -22,16 +22,23 @@ export function initVisEditorDirective(app, deps) { return { restrict: 'E', scope: { - savedObj: '=', + vis: '=', uiState: '=?', timeRange: '=', filters: '=', query: '=', - appState: '=', + savedSearch: '=', + embeddableHandler: '=', + eventEmitter: '=', }, link: function($scope, element) { - const Editor = $scope.savedObj.vis.type.editor || deps.DefaultVisualizationEditor; - const editor = new Editor(element[0], $scope.savedObj); + const Editor = $scope.vis.type.editor || deps.DefaultVisualizationEditor; + const editor = new Editor( + element[0], + $scope.vis, + $scope.eventEmitter, + $scope.embeddableHandler + ); $scope.renderFunction = () => { editor.render({ @@ -42,8 +49,8 @@ export function initVisEditorDirective(app, deps) { timeRange: $scope.timeRange, filters: $scope.filters, query: $scope.query, - appState: $scope.appState, - linked: !!$scope.savedObj.savedSearchId, + linked: !!$scope.vis.data.savedSearchId, + savedSearch: $scope.savedSearch, }); }; 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..b0b1ae31a02a5 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, @@ -37,6 +40,50 @@ import { getCreateBreadcrumbs, getEditBreadcrumbs, } from './breadcrumbs'; +import { createSavedSearchesLoader } from '../../../../../../plugins/discover/public'; + +const getResolvedResults = deps => { + const { core, data, visualizations } = deps; + + const results = {}; + + return savedVis => { + results.savedVis = savedVis; + return visualizations + .convertToSerializedVis(savedVis) + .then(serializedVis => visualizations.createVis(serializedVis.type, serializedVis)) + .then(vis => { + if (vis.type.setup) { + return vis.type.setup(vis).catch(() => vis); + } + return vis; + }) + .then(vis => { + results.vis = vis; + return deps.embeddable.getEmbeddableFactory('visualization').createFromObject(results.vis, { + timeRange: data.query.timefilter.timefilter.getTime(), + filters: data.query.filterManager.getFilters(), + }); + }) + .then(embeddableHandler => { + results.embeddableHandler = embeddableHandler; + if (results.vis.data.savedSearchId) { + return createSavedSearchesLoader({ + savedObjectsClient: core.savedObjects.client, + indexPatterns: data.indexPatterns, + chrome: core.chrome, + overlays: core.overlays, + }).get(results.vis.data.savedSearchId); + } + }) + .then(savedSearch => { + if (savedSearch) { + results.savedSearch = savedSearch; + } + return results; + }); + }; +}; export function initVisualizeApp(app, deps) { initVisualizeAppDirective(app, deps); @@ -79,8 +126,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 +137,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 +145,8 @@ export function initVisualizeApp(app, deps) { template: editorTemplate, k7Breadcrumbs: getCreateBreadcrumbs, resolve: { - savedVis: function(redirectWhenMissing, $route, $rootScope, kbnUrl) { - const { core, data, savedVisualizations, visualizations } = deps; + resolved: 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,17 +163,14 @@ 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) { - return savedVis.vis.type.setup(savedVis).catch(() => savedVis); - } - return savedVis; - }) + .then(getResolvedResults(deps)) .catch( redirectWhenMissing({ - '*': '/visualize', + history, + mapping: VisualizeConstants.LANDING_PAGE_PATH, + toastNotifications, }) ); }, @@ -139,29 +181,29 @@ 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) + resolved: 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); return savedVis; }) - .then(savedVis => { - if (savedVis.vis.type.setup) { - return savedVis.vis.type.setup(savedVis).catch(() => savedVis); - } - return savedVis; - }) + .then(getResolvedResults(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/kibana/public/visualize/np_ready/listing/visualize_listing.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing.js index 5a479a491395a..6c02afb672e4c 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/listing/visualize_listing.js @@ -34,7 +34,7 @@ export function initListingDirective(app) { ); } -export function VisualizeListingController($injector, $scope, createNewVis, kbnUrlStateStorage) { +export function VisualizeListingController($scope, createNewVis, kbnUrlStateStorage, history) { const { addBasePath, chrome, @@ -46,7 +46,6 @@ export function VisualizeListingController($injector, $scope, createNewVis, kbnU visualizations, core: { docLinks, savedObjects }, } = getServices(); - const kbnUrl = $injector.get('kbnUrl'); // syncs `_g` portion of url with query services const { stop: stopSyncingQueryServiceStateWithUrl } = syncQueryStateWithUrl( @@ -83,7 +82,11 @@ export function VisualizeListingController($injector, $scope, createNewVis, kbnU this.closeNewVisModal = visualizations.showNewVisModal({ onClose: () => { // In case the user came via a URL to this page, change the URL to the regular landing page URL after closing the modal - kbnUrl.changePath(VisualizeConstants.LANDING_PAGE_PATH); + history.push({ + // Should preserve querystring part so the global state is preserved. + ...history.location, + pathname: VisualizeConstants.LANDING_PAGE_PATH, + }); }, }); } diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts index 01ce872aeb679..246a031f05769 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/types.d.ts @@ -29,8 +29,10 @@ import { PersistedState } from 'src/plugins/visualizations/public'; import { LegacyCoreStart } from 'kibana/public'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { VisSavedObject } from '../legacy_imports'; +import { SavedVisState } from '../../../../visualizations/public/np_ready/public/types'; +import { SavedSearch } from '../../../../../../plugins/discover/public'; -export type PureVisState = ReturnType; +export type PureVisState = SavedVisState; export interface VisualizeAppState { filters: Filter[]; @@ -58,14 +60,13 @@ export interface VisualizeAppStateTransitions { } export interface EditorRenderProps { - appState: { save(): void }; core: LegacyCoreStart; data: DataPublicPluginStart; - embeddable: EmbeddableStart; filters: Filter[]; - uiState: PersistedState; timeRange: TimeRange; query?: Query; + savedSearch?: SavedSearch; + uiState: PersistedState; /** * Flag to determine if visualiztion is linked to the saved search */ diff --git a/src/legacy/core_plugins/kibana_react/index.ts b/src/legacy/core_plugins/kibana_react/index.ts deleted file mode 100644 index f4083f3d50c34..0000000000000 --- a/src/legacy/core_plugins/kibana_react/index.ts +++ /dev/null @@ -1,41 +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 { resolve } from 'path'; -import { Legacy } from '../../../../kibana'; - -// eslint-disable-next-line import/no-default-export -export default function DataPlugin(kibana: any) { - const config: Legacy.PluginSpecOptions = { - id: 'kibana_react', - require: [], - config: (Joi: any) => { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - init: (server: Legacy.Server) => ({}), - uiExports: { - injectDefaultVars: () => ({}), - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - }, - }; - - return new kibana.Plugin(config); -} diff --git a/src/legacy/core_plugins/kibana_react/package.json b/src/legacy/core_plugins/kibana_react/package.json deleted file mode 100644 index 3f7cf717a1963..0000000000000 --- a/src/legacy/core_plugins/kibana_react/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "kibana_react", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/kibana_react/public/index.scss b/src/legacy/core_plugins/kibana_react/public/index.scss deleted file mode 100644 index 14b4687c459e1..0000000000000 --- a/src/legacy/core_plugins/kibana_react/public/index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import 'src/legacy/ui/public/styles/styling_constants'; - -@import './markdown/index'; diff --git a/src/legacy/core_plugins/kibana_react/public/index.ts b/src/legacy/core_plugins/kibana_react/public/index.ts deleted file mode 100644 index a6a7cb72a8dee..0000000000000 --- a/src/legacy/core_plugins/kibana_react/public/index.ts +++ /dev/null @@ -1,20 +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. - */ - -export { Markdown, MarkdownSimple } from '../../../../plugins/kibana_react/public'; diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js index 6bdb5d00e67d8..23ca99791e92e 100644 --- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js @@ -21,7 +21,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import ChoroplethLayer from '../choropleth_layer'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import worldJson from './world.json'; import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json'; @@ -38,13 +37,11 @@ import afterdatachangePng from './afterdatachange.png'; import afterdatachangeandresizePng from './afterdatachangeandresize.png'; import aftercolorchangePng from './aftercolorchange.png'; import changestartupPng from './changestartup.png'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createRegionMapVisualization } from '../region_map_visualization'; import { createRegionMapTypeDefinition } from '../region_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; const THRESHOLD = 0.45; const PIXEL_DIFF = 96; @@ -52,7 +49,6 @@ const PIXEL_DIFF = 96; describe('RegionMapsVisualizationTests', function() { let domNode; let RegionMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -115,7 +111,6 @@ describe('RegionMapsVisualizationTests', function() { } RegionMapsVisualization = createRegionMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); ChoroplethLayer.prototype._makeJsonAjaxCall = async function() { //simulate network call @@ -158,7 +153,7 @@ describe('RegionMapsVisualizationTests', function() { imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'region_map', }); diff --git a/src/legacy/core_plugins/region_map/public/region_map_type.js b/src/legacy/core_plugins/region_map/public/region_map_type.js index a03fbe4b291e2..4faa3f92abb5a 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_type.js +++ b/src/legacy/core_plugins/region_map/public/region_map_type.js @@ -18,12 +18,11 @@ */ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { Schemas } from 'ui/agg_types'; import { mapToLayerWithId } from './util'; import { createRegionMapVisualization } from './region_map_visualization'; -import { Status } from '../../visualizations/public'; import { RegionMapOptions } from './components/region_map_options'; import { truncatedColorSchemas } from '../../../../plugins/charts/public'; +import { Schemas } from '../../vis_default_editor/public'; // TODO: reference to TILE_MAP plugin should be removed import { ORIGIN } from '../../tile_map/common/origin'; @@ -55,7 +54,6 @@ provided base maps, or add your own. Darker colors represent higher values.', showAllShapes: true, //still under consideration }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.DATA, Status.UI_STATE], visualization, editorConfig: { optionsTemplate: props => , @@ -100,9 +98,7 @@ provided base maps, or add your own. Darker colors represent higher values.', }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; - + setup: async vis => { const tmsLayers = await serviceSettings.getTMSServices(); vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { @@ -146,7 +142,7 @@ provided base maps, or add your own. Darker colors represent higher values.', vis.params.selectedJoinField = selectedJoinField; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/region_map/public/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/region_map_visualization.js index 8b5812052a395..25641ea76809d 100644 --- a/src/legacy/core_plugins/region_map/public/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/region_map_visualization.js @@ -39,8 +39,8 @@ export function createRegionMapVisualization({ serviceSettings, $injector, uiSet this._choroplethLayer = null; } - async render(esResponse, visParams, status) { - await super.render(esResponse, visParams, status); + async render(esResponse, visParams) { + await super.render(esResponse, visParams); if (this._choroplethLayer) { await this._choroplethLayer.whenDataLoaded(); } diff --git a/src/legacy/core_plugins/telemetry/README.md b/src/legacy/core_plugins/telemetry/README.md deleted file mode 100644 index 830c08f8e8bed..0000000000000 --- a/src/legacy/core_plugins/telemetry/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Kibana Telemetry Service - -Telemetry allows Kibana features to have usage tracked in the wild. The general term "telemetry" refers to multiple things: - -1. Integrating with the telemetry service to express how to collect usage data (Collecting). -2. Sending a payload of usage data up to Elastic's telemetry cluster. -3. Viewing usage data in the Kibana instance of the telemetry cluster (Viewing). - -This plugin is responsible for sending usage data to the telemetry cluster. For collecting usage data, use diff --git a/src/legacy/core_plugins/telemetry/common/constants.ts b/src/legacy/core_plugins/telemetry/common/constants.ts deleted file mode 100644 index b44bf319e6627..0000000000000 --- a/src/legacy/core_plugins/telemetry/common/constants.ts +++ /dev/null @@ -1,83 +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 { i18n } from '@kbn/i18n'; - -/* - * config options opt into telemetry - * @type {string} - */ -export const CONFIG_TELEMETRY = 'telemetry:optIn'; -/* - * config description for opting into telemetry - * @type {string} - */ -export const getConfigTelemetryDesc = () => { - return i18n.translate('telemetry.telemetryConfigDescription', { - defaultMessage: - 'Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.', - }); -}; - -/** - * The amount of time, in milliseconds, to wait between reports when enabled. - * - * Currently 24 hours. - * @type {Number} - */ -export const REPORT_INTERVAL_MS = 86400000; - -/** - * Link to the Elastic Telemetry privacy statement. - */ -export const PRIVACY_STATEMENT_URL = `https://www.elastic.co/legal/privacy-statement`; - -/** - * The type name used within the Monitoring index to publish localization stats. - * @type {string} - */ -export const KIBANA_LOCALIZATION_STATS_TYPE = 'localization'; - -/** - * The type name used to publish telemetry plugin stats. - * @type {string} - */ -export const TELEMETRY_STATS_TYPE = 'telemetry'; - -/** - * UI metric usage type - * @type {string} - */ -export const UI_METRIC_USAGE_TYPE = 'ui_metric'; - -/** - * Application Usage type - */ -export const APPLICATION_USAGE_TYPE = 'application_usage'; - -/** - * Link to Advanced Settings. - */ -export const PATH_TO_ADVANCED_SETTINGS = 'kibana#/management/kibana/settings'; - -/** - * The type name used within the Monitoring index to publish management stats. - * @type {string} - */ -export const KIBANA_STACK_MANAGEMENT_STATS_TYPE = 'stack_management'; diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts deleted file mode 100644 index 1e88e7d65cffd..0000000000000 --- a/src/legacy/core_plugins/telemetry/index.ts +++ /dev/null @@ -1,153 +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 * as Rx from 'rxjs'; -import { resolve } from 'path'; -import JoiNamespace from 'joi'; -import { Server } from 'hapi'; -import { PluginInitializerContext } from 'src/core/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getConfigPath } from '../../../core/server/path'; -// @ts-ignore -import mappings from './mappings.json'; -import { - telemetryPlugin, - replaceTelemetryInjectedVars, - FetcherTask, - PluginsSetup, - handleOldSettings, -} from './server'; - -const ENDPOINT_VERSION = 'v2'; - -const telemetry = (kibana: any) => { - return new kibana.Plugin({ - id: 'telemetry', - configPrefix: 'telemetry', - publicDir: resolve(__dirname, 'public'), - require: ['elasticsearch'], - config(Joi: typeof JoiNamespace) { - return Joi.object({ - enabled: Joi.boolean().default(true), - allowChangingOptInStatus: Joi.boolean().default(true), - optIn: Joi.when('allowChangingOptInStatus', { - is: false, - then: Joi.valid(true).default(true), - otherwise: Joi.boolean().default(true), - }), - // `config` is used internally and not intended to be set - config: Joi.string().default(getConfigPath()), - banner: Joi.boolean().default(true), - url: Joi.when('$dev', { - is: true, - then: Joi.string().default( - `https://telemetry-staging.elastic.co/xpack/${ENDPOINT_VERSION}/send` - ), - otherwise: Joi.string().default( - `https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send` - ), - }), - optInStatusUrl: Joi.when('$dev', { - is: true, - then: Joi.string().default( - `https://telemetry-staging.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` - ), - otherwise: Joi.string().default( - `https://telemetry.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send` - ), - }), - sendUsageFrom: Joi.string() - .allow(['server', 'browser']) - .default('browser'), - }).default(); - }, - uiExports: { - managementSections: ['plugins/telemetry/views/management'], - savedObjectSchemas: { - telemetry: { - isNamespaceAgnostic: true, - }, - }, - async replaceInjectedVars(originalInjectedVars: any, request: any, server: any) { - const telemetryInjectedVars = await replaceTelemetryInjectedVars(request, server); - return Object.assign({}, originalInjectedVars, telemetryInjectedVars); - }, - injectDefaultVars(server: Server) { - const config = server.config(); - return { - telemetryEnabled: config.get('telemetry.enabled'), - telemetryUrl: config.get('telemetry.url'), - telemetryBanner: - config.get('telemetry.allowChangingOptInStatus') !== false && - config.get('telemetry.banner'), - telemetryOptedIn: config.get('telemetry.optIn'), - telemetryOptInStatusUrl: config.get('telemetry.optInStatusUrl'), - allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), - telemetrySendUsageFrom: config.get('telemetry.sendUsageFrom'), - telemetryNotifyUserAboutOptInDefault: false, - }; - }, - mappings, - }, - postInit(server: Server) { - const fetcherTask = new FetcherTask(server); - fetcherTask.start(); - }, - async init(server: Server) { - const { usageCollection } = server.newPlatform.setup.plugins; - const initializerContext = { - env: { - packageInfo: { - version: server.config().get('pkg.version'), - }, - }, - config: { - create() { - const config = server.config(); - return Rx.of({ - enabled: config.get('telemetry.enabled'), - optIn: config.get('telemetry.optIn'), - config: config.get('telemetry.config'), - banner: config.get('telemetry.banner'), - url: config.get('telemetry.url'), - allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'), - }); - }, - }, - } as PluginInitializerContext; - - try { - await handleOldSettings(server); - } catch (err) { - server.log(['warning', 'telemetry'], 'Unable to update legacy telemetry configs.'); - } - - const pluginsSetup: PluginsSetup = { - usageCollection, - }; - - const npPlugin = telemetryPlugin(initializerContext); - await npPlugin.setup(server.newPlatform.setup.core, pluginsSetup, server); - await npPlugin.start(server.newPlatform.start.core); - }, - }); -}; - -// eslint-disable-next-line import/no-default-export -export default telemetry; diff --git a/src/legacy/core_plugins/telemetry/mappings.json b/src/legacy/core_plugins/telemetry/mappings.json deleted file mode 100644 index fa9cc93d6363a..0000000000000 --- a/src/legacy/core_plugins/telemetry/mappings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "telemetry": { - "properties": { - "enabled": { - "type": "boolean" - }, - "sendUsageFrom": { - "ignore_above": 256, - "type": "keyword" - }, - "lastReported": { - "type": "date" - }, - "lastVersionChecked": { - "ignore_above": 256, - "type": "keyword" - }, - "userHasSeenNotice": { - "type": "boolean" - }, - "reportFailureCount": { - "type": "integer" - }, - "reportFailureVersion": { - "ignore_above": 256, - "type": "keyword" - } - } - } -} diff --git a/src/legacy/core_plugins/telemetry/package.json b/src/legacy/core_plugins/telemetry/package.json deleted file mode 100644 index 979e68cce742f..0000000000000 --- a/src/legacy/core_plugins/telemetry/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "telemetry", - "version": "kibana" -} diff --git a/src/legacy/core_plugins/telemetry/public/views/management/index.ts b/src/legacy/core_plugins/telemetry/public/views/management/index.ts deleted file mode 100644 index 2e9f064ec80d8..0000000000000 --- a/src/legacy/core_plugins/telemetry/public/views/management/index.ts +++ /dev/null @@ -1,20 +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 './management'; diff --git a/src/legacy/core_plugins/telemetry/public/views/management/management.tsx b/src/legacy/core_plugins/telemetry/public/views/management/management.tsx deleted file mode 100644 index c8ae410e0aa57..0000000000000 --- a/src/legacy/core_plugins/telemetry/public/views/management/management.tsx +++ /dev/null @@ -1,49 +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 React from 'react'; -import routes from 'ui/routes'; -import { npStart, npSetup } from 'ui/new_platform'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { TelemetryManagementSection } from '../../../../../../plugins/telemetry/public/components'; - -routes.defaults(/\/management/, { - resolve: { - telemetryManagementSection() { - const { telemetry } = npStart.plugins as any; - const { advancedSettings } = npSetup.plugins as any; - - if (telemetry && advancedSettings) { - const componentRegistry = advancedSettings.component; - const Component = (props: any) => ( - - ); - - componentRegistry.register( - componentRegistry.componentType.PAGE_FOOTER_COMPONENT, - Component, - true - ); - } - }, - }, -}); diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts deleted file mode 100644 index 715ca56e290a2..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts +++ /dev/null @@ -1,247 +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 { encryptTelemetry } from './collectors'; -import { CallCluster } from '../../elasticsearch'; -import { UsageCollectionSetup } from '../../../../plugins/usage_collection/server'; -import { ESLicense } from './telemetry_collection/get_local_license'; - -export type EncryptedStatsGetterConfig = { unencrypted: false } & { - server: any; - start: string; - end: string; -}; - -export type UnencryptedStatsGetterConfig = { unencrypted: true } & { - req: any; - start: string; - end: string; -}; - -export interface ClusterDetails { - clusterUuid: string; -} - -export interface StatsCollectionConfig { - usageCollection: UsageCollectionSetup; - callCluster: CallCluster; - server: any; - start: string | number; - end: string | number; -} - -export interface BasicStatsPayload { - timestamp: string; - cluster_uuid: string; - cluster_name: string; - version: string; - cluster_stats: object; - collection?: string; - stack_stats: object; -} - -export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig; -export type ClusterDetailsGetter = (config: StatsCollectionConfig) => Promise; -export type StatsGetter = ( - clustersDetails: ClusterDetails[], - config: StatsCollectionConfig -) => Promise; -export type LicenseGetter = ( - clustersDetails: ClusterDetails[], - config: StatsCollectionConfig -) => Promise<{ [clusterUuid: string]: ESLicense | undefined }>; - -interface CollectionConfig { - title: string; - priority: number; - esCluster: string; - statsGetter: StatsGetter; - clusterDetailsGetter: ClusterDetailsGetter; - licenseGetter: LicenseGetter; -} -interface Collection { - statsGetter: StatsGetter; - licenseGetter: LicenseGetter; - clusterDetailsGetter: ClusterDetailsGetter; - esCluster: string; - title: string; -} - -export class TelemetryCollectionManager { - private usageGetterMethodPriority = -1; - private collections: Collection[] = []; - - public setCollection = (collectionConfig: CollectionConfig) => { - const { - title, - priority, - esCluster, - statsGetter, - clusterDetailsGetter, - licenseGetter, - } = collectionConfig; - - if (typeof priority !== 'number') { - throw new Error('priority must be set.'); - } - if (priority === this.usageGetterMethodPriority) { - throw new Error(`A Usage Getter with the same priority is already set.`); - } - - if (priority > this.usageGetterMethodPriority) { - if (!statsGetter) { - throw Error('Stats getter method not set.'); - } - if (!esCluster) { - throw Error('esCluster name must be set for the getCluster method.'); - } - if (!clusterDetailsGetter) { - throw Error('Cluster UUIds method is not set.'); - } - if (!licenseGetter) { - throw Error('License getter method not set.'); - } - - this.collections.unshift({ - licenseGetter, - statsGetter, - clusterDetailsGetter, - esCluster, - title, - }); - this.usageGetterMethodPriority = priority; - } - }; - - private getStatsCollectionConfig = async ( - collection: Collection, - config: StatsGetterConfig - ): Promise => { - const { start, end } = config; - const server = config.unencrypted ? config.req.server : config.server; - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster( - collection.esCluster - ); - const callCluster = config.unencrypted - ? (...args: any[]) => callWithRequest(config.req, ...args) - : callWithInternalUser; - - const { usageCollection } = server.newPlatform.setup.plugins; - return { server, callCluster, start, end, usageCollection }; - }; - - private getOptInStatsForCollection = async ( - collection: Collection, - optInStatus: boolean, - statsCollectionConfig: StatsCollectionConfig - ) => { - const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); - return clustersDetails.map(({ clusterUuid }) => ({ - cluster_uuid: clusterUuid, - opt_in_status: optInStatus, - })); - }; - - private getUsageForCollection = async ( - collection: Collection, - statsCollectionConfig: StatsCollectionConfig - ) => { - const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig); - - if (clustersDetails.length === 0) { - // don't bother doing a further lookup, try next collection. - return; - } - - const [stats, licenses] = await Promise.all([ - collection.statsGetter(clustersDetails, statsCollectionConfig), - collection.licenseGetter(clustersDetails, statsCollectionConfig), - ]); - - return stats.map(stat => { - const license = licenses[stat.cluster_uuid]; - return { - ...(license ? { license } : {}), - ...stat, - collectionSource: collection.title, - }; - }); - }; - - public getOptInStats = async (optInStatus: boolean, config: StatsGetterConfig) => { - for (const collection of this.collections) { - const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); - try { - const optInStats = await this.getOptInStatsForCollection( - collection, - optInStatus, - statsCollectionConfig - ); - if (optInStats && optInStats.length) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Got Opt In stats using ${collection.title} collection.` - ); - if (config.unencrypted) { - return optInStats; - } - const isDev = statsCollectionConfig.server.config().get('env.dev'); - return encryptTelemetry(optInStats, isDev); - } - } catch (err) { - statsCollectionConfig.server.log( - ['debu', 'telemetry', 'collection'], - `Failed to collect any opt in stats with registered collections.` - ); - // swallow error to try next collection; - } - } - - return []; - }; - public getStats = async (config: StatsGetterConfig) => { - for (const collection of this.collections) { - const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config); - try { - const usageData = await this.getUsageForCollection(collection, statsCollectionConfig); - if (usageData && usageData.length) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Got Usage using ${collection.title} collection.` - ); - if (config.unencrypted) { - return usageData; - } - const isDev = statsCollectionConfig.server.config().get('env.dev'); - return encryptTelemetry(usageData, isDev); - } - } catch (err) { - statsCollectionConfig.server.log( - ['debug', 'telemetry', 'collection'], - `Failed to collect any usage with registered collections.` - ); - // swallow error to try next collection; - } - } - - return []; - }; -} - -export const telemetryCollectionManager = new TelemetryCollectionManager(); diff --git a/src/legacy/core_plugins/telemetry/server/collectors/application_usage/index.test.ts b/src/legacy/core_plugins/telemetry/server/collectors/application_usage/index.test.ts deleted file mode 100644 index 1a64100bda692..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/application_usage/index.test.ts +++ /dev/null @@ -1,146 +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 { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server'; -import { savedObjectsRepositoryMock } from '../../../../../../core/server/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { CollectorOptions } from '../../../../../../plugins/usage_collection/server/collector/collector'; - -import { registerApplicationUsageCollector } from './'; -import { - ROLL_INDICES_INTERVAL, - SAVED_OBJECTS_TOTAL_TYPE, - SAVED_OBJECTS_TRANSACTIONAL_TYPE, -} from './telemetry_application_usage_collector'; - -describe('telemetry_application_usage', () => { - jest.useFakeTimers(); - - let collector: CollectorOptions; - - const usageCollectionMock: jest.Mocked = { - makeUsageCollector: jest.fn().mockImplementation(config => (collector = config)), - registerCollector: jest.fn(), - } as any; - - const getUsageCollector = jest.fn(); - const callCluster = jest.fn(); - - beforeAll(() => registerApplicationUsageCollector(usageCollectionMock, getUsageCollector)); - afterAll(() => jest.clearAllTimers()); - - test('registered collector is set', () => { - expect(collector).not.toBeUndefined(); - }); - - test('if no savedObjectClient initialised, return undefined', async () => { - expect(await collector.fetch(callCluster)).toBeUndefined(); - jest.runTimersToTime(ROLL_INDICES_INTERVAL); - }); - - test('when savedObjectClient is initialised, return something', async () => { - const savedObjectClient = savedObjectsRepositoryMock.create(); - savedObjectClient.find.mockImplementation( - async () => - ({ - saved_objects: [], - total: 0, - } as any) - ); - getUsageCollector.mockImplementation(() => savedObjectClient); - - jest.runTimersToTime(ROLL_INDICES_INTERVAL); // Force rollTotals to run - - expect(await collector.fetch(callCluster)).toStrictEqual({}); - expect(savedObjectClient.bulkCreate).not.toHaveBeenCalled(); - }); - - test('paging in findAll works', async () => { - const savedObjectClient = savedObjectsRepositoryMock.create(); - let total = 201; - savedObjectClient.find.mockImplementation(async opts => { - if (opts.type === SAVED_OBJECTS_TOTAL_TYPE) { - return { - saved_objects: [ - { - id: 'appId', - attributes: { - appId: 'appId', - minutesOnScreen: 10, - numberOfClicks: 10, - }, - }, - ], - total: 1, - } as any; - } - if ((opts.page || 1) > 2) { - return { saved_objects: [], total }; - } - const doc = { - id: 'test-id', - attributes: { - appId: 'appId', - timestamp: new Date().toISOString(), - minutesOnScreen: 1, - numberOfClicks: 1, - }, - }; - const savedObjects = new Array(opts.perPage).fill(doc); - total = savedObjects.length * 2 + 1; - return { saved_objects: savedObjects, total }; - }); - - getUsageCollector.mockImplementation(() => savedObjectClient); - - jest.runTimersToTime(ROLL_INDICES_INTERVAL); // Force rollTotals to run - - expect(await collector.fetch(callCluster)).toStrictEqual({ - appId: { - clicks_total: total - 1 + 10, - clicks_7_days: total - 1, - clicks_30_days: total - 1, - clicks_90_days: total - 1, - minutes_on_screen_total: total - 1 + 10, - minutes_on_screen_7_days: total - 1, - minutes_on_screen_30_days: total - 1, - minutes_on_screen_90_days: total - 1, - }, - }); - expect(savedObjectClient.bulkCreate).toHaveBeenCalledWith( - [ - { - id: 'appId', - type: SAVED_OBJECTS_TOTAL_TYPE, - attributes: { - appId: 'appId', - minutesOnScreen: total - 1 + 10, - numberOfClicks: total - 1 + 10, - }, - }, - ], - { overwrite: true } - ); - expect(savedObjectClient.delete).toHaveBeenCalledTimes(total - 1); - expect(savedObjectClient.delete).toHaveBeenCalledWith( - SAVED_OBJECTS_TRANSACTIONAL_TYPE, - 'test-id' - ); - }); -}); diff --git a/src/legacy/core_plugins/telemetry/server/collectors/index.ts b/src/legacy/core_plugins/telemetry/server/collectors/index.ts deleted file mode 100644 index 6cb7a38b6414f..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export { encryptTelemetry } from './encryption'; -export { registerTelemetryUsageCollector } from './usage'; -export { registerUiMetricUsageCollector } from './ui_metric'; -export { registerLocalizationUsageCollector } from './localization'; -export { registerTelemetryPluginUsageCollector } from './telemetry_plugin'; -export { registerManagementUsageCollector } from './management'; -export { registerApplicationUsageCollector } from './application_usage'; diff --git a/src/legacy/core_plugins/telemetry/server/collectors/localization/telemetry_localization_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/localization/telemetry_localization_collector.ts deleted file mode 100644 index 191565187be14..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/localization/telemetry_localization_collector.ts +++ /dev/null @@ -1,66 +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 { i18nLoader } from '@kbn/i18n'; -import { size } from 'lodash'; -import { getIntegrityHashes, Integrities } from './file_integrity'; -import { KIBANA_LOCALIZATION_STATS_TYPE } from '../../../common/constants'; -import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server'; -export interface UsageStats { - locale: string; - integrities: Integrities; - labelsCount?: number; -} - -export async function getTranslationCount(loader: any, locale: string): Promise { - const translations = await loader.getTranslationsByLocale(locale); - return size(translations.messages); -} - -export function createCollectorFetch(server: any) { - return async function fetchUsageStats(): Promise { - const config = server.config(); - const locale: string = config.get('i18n.locale'); - const translationFilePaths: string[] = server.getTranslationsFilePaths(); - - const [labelsCount, integrities] = await Promise.all([ - getTranslationCount(i18nLoader, locale), - getIntegrityHashes(translationFilePaths), - ]); - - return { - locale, - integrities, - labelsCount, - }; - }; -} - -export function registerLocalizationUsageCollector( - usageCollection: UsageCollectionSetup, - server: any -) { - const collector = usageCollection.makeUsageCollector({ - type: KIBANA_LOCALIZATION_STATS_TYPE, - isReady: () => true, - fetch: createCollectorFetch(server), - }); - - usageCollection.registerCollector(collector); -} diff --git a/src/legacy/core_plugins/telemetry/server/collectors/management/telemetry_management_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/management/telemetry_management_collector.ts deleted file mode 100644 index 481b1e9af2a79..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/management/telemetry_management_collector.ts +++ /dev/null @@ -1,63 +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 { Server } from 'hapi'; -import { size } from 'lodash'; -import { KIBANA_STACK_MANAGEMENT_STATS_TYPE } from '../../../common/constants'; -import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server'; -import { SavedObjectsClient } from '../../../../../../core/server'; - -export type UsageStats = Record; - -export async function getTranslationCount(loader: any, locale: string): Promise { - const translations = await loader.getTranslationsByLocale(locale); - return size(translations.messages); -} - -export function createCollectorFetch(server: Server) { - return async function fetchUsageStats(): Promise { - const internalRepo = server.newPlatform.start.core.savedObjects.createInternalRepository(); - const uiSettingsClient = server.newPlatform.start.core.uiSettings.asScopedToClient( - new SavedObjectsClient(internalRepo) - ); - - const user = await uiSettingsClient.getUserProvided(); - const modifiedEntries = Object.keys(user) - .filter((key: string) => key !== 'buildNum') - .reduce((obj: any, key: string) => { - obj[key] = user[key].userValue; - return obj; - }, {}); - - return modifiedEntries; - }; -} - -export function registerManagementUsageCollector( - usageCollection: UsageCollectionSetup, - server: any -) { - const collector = usageCollection.makeUsageCollector({ - type: KIBANA_STACK_MANAGEMENT_STATS_TYPE, - isReady: () => true, - fetch: createCollectorFetch(server), - }); - - usageCollection.registerCollector(collector); -} diff --git a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts deleted file mode 100644 index 5e25538cbad80..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts +++ /dev/null @@ -1,77 +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 { TELEMETRY_STATS_TYPE } from '../../../common/constants'; -import { getTelemetrySavedObject, TelemetrySavedObject } from '../../telemetry_repository'; -import { getTelemetryOptIn, getTelemetrySendUsageFrom } from '../../telemetry_config'; -import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server'; - -export interface TelemetryUsageStats { - opt_in_status?: boolean | null; - usage_fetcher?: 'browser' | 'server'; - last_reported?: number; -} - -export function createCollectorFetch(server: any) { - return async function fetchUsageStats(): Promise { - const config = server.config(); - const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); - const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); - const configTelemetryOptIn = config.get('telemetry.optIn'); - const currentKibanaVersion = config.get('pkg.version'); - - let telemetrySavedObject: TelemetrySavedObject = {}; - - try { - const { getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - telemetrySavedObject = await getTelemetrySavedObject(internalRepository); - } catch (err) { - // no-op - } - - return { - opt_in_status: getTelemetryOptIn({ - currentKibanaVersion, - telemetrySavedObject, - allowChangingOptInStatus, - configTelemetryOptIn, - }), - last_reported: telemetrySavedObject ? telemetrySavedObject.lastReported : undefined, - usage_fetcher: getTelemetrySendUsageFrom({ - telemetrySavedObject, - configTelemetrySendUsageFrom, - }), - }; - }; -} - -export function registerTelemetryPluginUsageCollector( - usageCollection: UsageCollectionSetup, - server: any -) { - const collector = usageCollection.makeUsageCollector({ - type: TELEMETRY_STATS_TYPE, - isReady: () => true, - fetch: createCollectorFetch(server), - }); - - usageCollection.registerCollector(collector); -} diff --git a/src/legacy/core_plugins/telemetry/server/collectors/ui_metric/index.test.ts b/src/legacy/core_plugins/telemetry/server/collectors/ui_metric/index.test.ts deleted file mode 100644 index ddb58a7d09bbd..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/collectors/ui_metric/index.test.ts +++ /dev/null @@ -1,86 +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 { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/server'; -import { savedObjectsRepositoryMock } from '../../../../../../core/server/mocks'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { CollectorOptions } from '../../../../../../plugins/usage_collection/server/collector/collector'; - -import { registerUiMetricUsageCollector } from './'; - -describe('telemetry_ui_metric', () => { - let collector: CollectorOptions; - - const usageCollectionMock: jest.Mocked = { - makeUsageCollector: jest.fn().mockImplementation(config => (collector = config)), - registerCollector: jest.fn(), - } as any; - - const getUsageCollector = jest.fn(); - const callCluster = jest.fn(); - - beforeAll(() => registerUiMetricUsageCollector(usageCollectionMock, getUsageCollector)); - - test('registered collector is set', () => { - expect(collector).not.toBeUndefined(); - }); - - test('if no savedObjectClient initialised, return undefined', async () => { - expect(await collector.fetch(callCluster)).toBeUndefined(); - }); - - test('when savedObjectClient is initialised, return something', async () => { - const savedObjectClient = savedObjectsRepositoryMock.create(); - savedObjectClient.find.mockImplementation( - async () => - ({ - saved_objects: [], - total: 0, - } as any) - ); - getUsageCollector.mockImplementation(() => savedObjectClient); - - expect(await collector.fetch(callCluster)).toStrictEqual({}); - expect(savedObjectClient.bulkCreate).not.toHaveBeenCalled(); - }); - - test('results grouped by appName', async () => { - const savedObjectClient = savedObjectsRepositoryMock.create(); - savedObjectClient.find.mockImplementation(async () => { - return { - saved_objects: [ - { id: 'testAppName:testKeyName1', attributes: { count: 3 } }, - { id: 'testAppName:testKeyName2', attributes: { count: 5 } }, - { id: 'testAppName2:testKeyName3', attributes: { count: 1 } }, - ], - total: 3, - } as any; - }); - - getUsageCollector.mockImplementation(() => savedObjectClient); - - expect(await collector.fetch(callCluster)).toStrictEqual({ - testAppName: [ - { key: 'testKeyName1', value: 3 }, - { key: 'testKeyName2', value: 5 }, - ], - testAppName2: [{ key: 'testKeyName3', value: 1 }], - }); - }); -}); diff --git a/src/legacy/core_plugins/telemetry/server/fetcher.ts b/src/legacy/core_plugins/telemetry/server/fetcher.ts deleted file mode 100644 index d30ee10066813..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/fetcher.ts +++ /dev/null @@ -1,188 +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 moment from 'moment'; -// @ts-ignore -import fetch from 'node-fetch'; -import { telemetryCollectionManager } from './collection_manager'; -import { - getTelemetryOptIn, - getTelemetrySendUsageFrom, - getTelemetryFailureDetails, -} from './telemetry_config'; -import { getTelemetrySavedObject, updateTelemetrySavedObject } from './telemetry_repository'; -import { REPORT_INTERVAL_MS } from '../common/constants'; - -export class FetcherTask { - private readonly initialCheckDelayMs = 60 * 1000 * 5; - private readonly checkIntervalMs = 60 * 1000 * 60 * 12; - private intervalId?: NodeJS.Timeout; - private lastReported?: number; - private currentVersion: string; - private isSending = false; - private server: any; - - constructor(server: any) { - this.server = server; - this.currentVersion = this.server.config().get('pkg.version'); - } - - private getInternalRepository = () => { - const { getSavedObjectsRepository } = this.server.savedObjects; - const { callWithInternalUser } = this.server.plugins.elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - return internalRepository; - }; - - private getCurrentConfigs = async () => { - const internalRepository = this.getInternalRepository(); - const telemetrySavedObject = await getTelemetrySavedObject(internalRepository); - const config = this.server.config(); - const currentKibanaVersion = config.get('pkg.version'); - const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); - const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); - const configTelemetryOptIn = config.get('telemetry.optIn'); - const telemetryUrl = config.get('telemetry.url') as string; - const { failureCount, failureVersion } = await getTelemetryFailureDetails({ - telemetrySavedObject, - }); - - return { - telemetryOptIn: getTelemetryOptIn({ - currentKibanaVersion, - telemetrySavedObject, - allowChangingOptInStatus, - configTelemetryOptIn, - }), - telemetrySendUsageFrom: getTelemetrySendUsageFrom({ - telemetrySavedObject, - configTelemetrySendUsageFrom, - }), - telemetryUrl, - failureCount, - failureVersion, - }; - }; - - private updateLastReported = async () => { - const internalRepository = this.getInternalRepository(); - this.lastReported = Date.now(); - updateTelemetrySavedObject(internalRepository, { - reportFailureCount: 0, - lastReported: this.lastReported, - }); - }; - - private updateReportFailure = async ({ failureCount }: { failureCount: number }) => { - const internalRepository = this.getInternalRepository(); - - updateTelemetrySavedObject(internalRepository, { - reportFailureCount: failureCount + 1, - reportFailureVersion: this.currentVersion, - }); - }; - - private shouldSendReport = ({ - telemetryOptIn, - telemetrySendUsageFrom, - reportFailureCount, - currentVersion, - reportFailureVersion, - }: any) => { - if (reportFailureCount > 2 && reportFailureVersion === currentVersion) { - return false; - } - - if (telemetryOptIn && telemetrySendUsageFrom === 'server') { - if (!this.lastReported || Date.now() - this.lastReported > REPORT_INTERVAL_MS) { - return true; - } - } - return false; - }; - - private fetchTelemetry = async () => { - return await telemetryCollectionManager.getStats({ - unencrypted: false, - server: this.server, - start: moment() - .subtract(20, 'minutes') - .toISOString(), - end: moment().toISOString(), - }); - }; - - private sendTelemetry = async (url: string, cluster: any): Promise => { - this.server.log(['debug', 'telemetry', 'fetcher'], `Sending usage stats.`); - /** - * send OPTIONS before sending usage data. - * OPTIONS is less intrusive as it does not contain any payload and is used here to check if the endpoint is reachable. - */ - await fetch(url, { - method: 'options', - }); - - await fetch(url, { - method: 'post', - body: cluster, - }); - }; - - private sendIfDue = async () => { - if (this.isSending) { - return; - } - const telemetryConfig = await this.getCurrentConfigs(); - if (!this.shouldSendReport(telemetryConfig)) { - return; - } - - try { - this.isSending = true; - const clusters = await this.fetchTelemetry(); - const { telemetryUrl } = telemetryConfig; - for (const cluster of clusters) { - await this.sendTelemetry(telemetryUrl, cluster); - } - - await this.updateLastReported(); - } catch (err) { - await this.updateReportFailure(telemetryConfig); - - this.server.log( - ['warning', 'telemetry', 'fetcher'], - `Error sending telemetry usage data: ${err}` - ); - } - this.isSending = false; - }; - - public start = () => { - setTimeout(() => { - this.sendIfDue(); - this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); - }, this.initialCheckDelayMs); - }; - - public stop = () => { - if (this.intervalId) { - clearInterval(this.intervalId); - } - }; -} diff --git a/src/legacy/core_plugins/telemetry/server/handle_old_settings/handle_old_settings.ts b/src/legacy/core_plugins/telemetry/server/handle_old_settings/handle_old_settings.ts deleted file mode 100644 index b28a01bffa44d..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/handle_old_settings/handle_old_settings.ts +++ /dev/null @@ -1,59 +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. - */ - -/** - * Clean up any old, deprecated settings and determine if we should continue. - * - * This will update the latest telemetry setting if necessary. - * - * @param {Object} config The advanced settings config object. - * @return {Boolean} {@code true} if the banner should still be displayed. {@code false} if the banner should not be displayed. - */ - -import { Server } from 'hapi'; -import { CONFIG_TELEMETRY } from '../../common/constants'; -import { updateTelemetrySavedObject } from '../telemetry_repository'; - -const CONFIG_ALLOW_REPORT = 'xPackMonitoring:allowReport'; - -export async function handleOldSettings(server: Server) { - const { getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); - const savedObjectsClient = getSavedObjectsRepository(callWithInternalUser); - const uiSettings = server.uiSettingsServiceFactory({ savedObjectsClient }); - - const oldTelemetrySetting = await uiSettings.get(CONFIG_TELEMETRY); - const oldAllowReportSetting = await uiSettings.get(CONFIG_ALLOW_REPORT); - let legacyOptInValue = null; - - if (typeof oldTelemetrySetting === 'boolean') { - legacyOptInValue = oldTelemetrySetting; - } else if ( - typeof oldAllowReportSetting === 'boolean' && - uiSettings.isOverridden(CONFIG_ALLOW_REPORT) - ) { - legacyOptInValue = oldAllowReportSetting; - } - - if (legacyOptInValue !== null) { - await updateTelemetrySavedObject(savedObjectsClient, { - enabled: legacyOptInValue, - }); - } -} diff --git a/src/legacy/core_plugins/telemetry/server/index.ts b/src/legacy/core_plugins/telemetry/server/index.ts deleted file mode 100644 index 85d7d80234ffc..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/index.ts +++ /dev/null @@ -1,31 +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 { PluginInitializerContext } from 'src/core/server'; -import { TelemetryPlugin } from './plugin'; -import * as constants from '../common/constants'; - -export { FetcherTask } from './fetcher'; -export { replaceTelemetryInjectedVars } from './telemetry_config'; -export { handleOldSettings } from './handle_old_settings'; -export { telemetryCollectionManager } from './collection_manager'; -export { PluginsSetup } from './plugin'; -export const telemetryPlugin = (initializerContext: PluginInitializerContext) => - new TelemetryPlugin(initializerContext); -export { constants }; diff --git a/src/legacy/core_plugins/telemetry/server/plugin.ts b/src/legacy/core_plugins/telemetry/server/plugin.ts deleted file mode 100644 index 0b9f0526988c8..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/plugin.ts +++ /dev/null @@ -1,70 +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 { - CoreSetup, - PluginInitializerContext, - ISavedObjectsRepository, - CoreStart, -} from 'src/core/server'; -import { Server } from 'hapi'; -import { registerRoutes } from './routes'; -import { registerCollection } from './telemetry_collection'; -import { UsageCollectionSetup } from '../../../../plugins/usage_collection/server'; -import { - registerUiMetricUsageCollector, - registerTelemetryUsageCollector, - registerLocalizationUsageCollector, - registerTelemetryPluginUsageCollector, - registerManagementUsageCollector, - registerApplicationUsageCollector, -} from './collectors'; - -export interface PluginsSetup { - usageCollection: UsageCollectionSetup; -} - -export class TelemetryPlugin { - private readonly currentKibanaVersion: string; - private savedObjectsClient?: ISavedObjectsRepository; - - constructor(initializerContext: PluginInitializerContext) { - this.currentKibanaVersion = initializerContext.env.packageInfo.version; - } - - public setup(core: CoreSetup, { usageCollection }: PluginsSetup, server: Server) { - const currentKibanaVersion = this.currentKibanaVersion; - - registerCollection(); - registerRoutes({ core, currentKibanaVersion, server }); - - const getSavedObjectsClient = () => this.savedObjectsClient; - - registerTelemetryPluginUsageCollector(usageCollection, server); - registerLocalizationUsageCollector(usageCollection, server); - registerTelemetryUsageCollector(usageCollection, server); - registerUiMetricUsageCollector(usageCollection, getSavedObjectsClient); - registerManagementUsageCollector(usageCollection, server); - registerApplicationUsageCollector(usageCollection, getSavedObjectsClient); - } - - public start({ savedObjects }: CoreStart) { - this.savedObjectsClient = savedObjects.createInternalRepository(); - } -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/index.ts b/src/legacy/core_plugins/telemetry/server/routes/index.ts deleted file mode 100644 index 31ff1682d6806..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/index.ts +++ /dev/null @@ -1,38 +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 { Legacy } from 'kibana'; -import { CoreSetup } from 'src/core/server'; -import { registerTelemetryOptInRoutes } from './telemetry_opt_in'; -import { registerTelemetryUsageStatsRoutes } from './telemetry_usage_stats'; -import { registerTelemetryOptInStatsRoutes } from './telemetry_opt_in_stats'; -import { registerTelemetryUserHasSeenNotice } from './telemetry_user_has_seen_notice'; - -interface RegisterRoutesParams { - core: CoreSetup; - currentKibanaVersion: string; - server: Legacy.Server; -} - -export function registerRoutes({ core, currentKibanaVersion, server }: RegisterRoutesParams) { - registerTelemetryOptInRoutes({ core, currentKibanaVersion, server }); - registerTelemetryUsageStatsRoutes(server); - registerTelemetryOptInStatsRoutes(server); - registerTelemetryUserHasSeenNotice(server); -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts deleted file mode 100644 index ccbc28f6cbadb..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts +++ /dev/null @@ -1,97 +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 Joi from 'joi'; -import moment from 'moment'; -import { boomify } from 'boom'; -import { CoreSetup } from 'src/core/server'; -import { Legacy } from 'kibana'; -import { getTelemetryAllowChangingOptInStatus } from '../telemetry_config'; -import { sendTelemetryOptInStatus } from './telemetry_opt_in_stats'; - -import { - TelemetrySavedObjectAttributes, - updateTelemetrySavedObject, -} from '../telemetry_repository'; - -interface RegisterOptInRoutesParams { - core: CoreSetup; - currentKibanaVersion: string; - server: Legacy.Server; -} - -export function registerTelemetryOptInRoutes({ - server, - currentKibanaVersion, -}: RegisterOptInRoutesParams) { - server.route({ - method: 'POST', - path: '/api/telemetry/v2/optIn', - options: { - validate: { - payload: Joi.object({ - enabled: Joi.bool().required(), - }), - }, - }, - handler: async (req: any, h: any) => { - try { - const newOptInStatus = req.payload.enabled; - const attributes: TelemetrySavedObjectAttributes = { - enabled: newOptInStatus, - lastVersionChecked: currentKibanaVersion, - }; - const config = req.server.config(); - const savedObjectsClient = req.getSavedObjectsClient(); - const configTelemetryAllowChangingOptInStatus = config.get( - 'telemetry.allowChangingOptInStatus' - ); - - const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ - telemetrySavedObject: savedObjectsClient, - configTelemetryAllowChangingOptInStatus, - }); - if (!allowChangingOptInStatus) { - return h.response({ error: 'Not allowed to change Opt-in Status.' }).code(400); - } - - const sendUsageFrom = config.get('telemetry.sendUsageFrom'); - if (sendUsageFrom === 'server') { - const optInStatusUrl = config.get('telemetry.optInStatusUrl'); - await sendTelemetryOptInStatus( - { optInStatusUrl, newOptInStatus }, - { - start: moment() - .subtract(20, 'minutes') - .toISOString(), - end: moment().toISOString(), - server: req.server, - unencrypted: false, - } - ); - } - - await updateTelemetrySavedObject(savedObjectsClient, attributes); - return h.response({}).code(200); - } catch (err) { - return boomify(err); - } - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts deleted file mode 100644 index e64f3f6ff8a94..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts +++ /dev/null @@ -1,85 +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. - */ - -// @ts-ignore -import fetch from 'node-fetch'; -import Joi from 'joi'; -import moment from 'moment'; -import { Legacy } from 'kibana'; -import { telemetryCollectionManager, StatsGetterConfig } from '../collection_manager'; - -interface SendTelemetryOptInStatusConfig { - optInStatusUrl: string; - newOptInStatus: boolean; -} - -export async function sendTelemetryOptInStatus( - config: SendTelemetryOptInStatusConfig, - statsGetterConfig: StatsGetterConfig -) { - const { optInStatusUrl, newOptInStatus } = config; - const optInStatus = await telemetryCollectionManager.getOptInStats( - newOptInStatus, - statsGetterConfig - ); - - await fetch(optInStatusUrl, { - method: 'post', - body: optInStatus, - }); -} - -export function registerTelemetryOptInStatsRoutes(server: Legacy.Server) { - server.route({ - method: 'POST', - path: '/api/telemetry/v2/clusters/_opt_in_stats', - options: { - validate: { - payload: Joi.object({ - enabled: Joi.bool().required(), - unencrypted: Joi.bool().default(true), - }), - }, - }, - handler: async (req: any, h: any) => { - try { - const newOptInStatus = req.payload.enabled; - const unencrypted = req.payload.unencrypted; - const statsGetterConfig = { - start: moment() - .subtract(20, 'minutes') - .toISOString(), - end: moment().toISOString(), - server: req.server, - req, - unencrypted, - }; - - const optInStatus = await telemetryCollectionManager.getOptInStats( - newOptInStatus, - statsGetterConfig - ); - - return h.response(optInStatus).code(200); - } catch (err) { - return h.response([]).code(200); - } - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts deleted file mode 100644 index ee3241b0dc2ea..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts +++ /dev/null @@ -1,67 +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 Joi from 'joi'; -import { boomify } from 'boom'; -import { Legacy } from 'kibana'; -import { telemetryCollectionManager } from '../collection_manager'; - -export function registerTelemetryUsageStatsRoutes(server: Legacy.Server) { - server.route({ - method: 'POST', - path: '/api/telemetry/v2/clusters/_stats', - options: { - validate: { - payload: Joi.object({ - unencrypted: Joi.bool(), - timeRange: Joi.object({ - min: Joi.date().required(), - max: Joi.date().required(), - }).required(), - }), - }, - }, - handler: async (req: any, h: any) => { - const config = req.server.config(); - const start = req.payload.timeRange.min; - const end = req.payload.timeRange.max; - const unencrypted = req.payload.unencrypted; - - try { - return await telemetryCollectionManager.getStats({ - unencrypted, - server, - req, - start, - end, - }); - } catch (err) { - const isDev = config.get('env.dev'); - if (isDev) { - // don't ignore errors when running in dev mode - return boomify(err, { statusCode: err.status || 500 }); - } else { - const statusCode = unencrypted && err.status === 403 ? 403 : 200; - // ignore errors and return empty set - return h.response([]).code(statusCode); - } - } - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts deleted file mode 100644 index 665e6d9aaeb75..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_user_has_seen_notice.ts +++ /dev/null @@ -1,56 +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 { Legacy } from 'kibana'; -import { Request } from 'hapi'; -import { - TelemetrySavedObject, - TelemetrySavedObjectAttributes, - getTelemetrySavedObject, - updateTelemetrySavedObject, -} from '../telemetry_repository'; - -const getInternalRepository = (server: Legacy.Server) => { - const { getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - return internalRepository; -}; - -export function registerTelemetryUserHasSeenNotice(server: Legacy.Server) { - server.route({ - method: 'PUT', - path: '/api/telemetry/v2/userHasSeenNotice', - handler: async (req: Request): Promise => { - const internalRepository = getInternalRepository(server); - const telemetrySavedObject: TelemetrySavedObject = await getTelemetrySavedObject( - internalRepository - ); - - // update the object with a flag stating that the opt-in notice has been seen - const updatedAttributes: TelemetrySavedObjectAttributes = { - ...telemetrySavedObject, - userHasSeenNotice: true, - }; - await updateTelemetrySavedObject(internalRepository, updatedAttributes); - - return updatedAttributes; - }, - }); -} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts deleted file mode 100644 index 9ac94216c21bc..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts +++ /dev/null @@ -1,22 +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. - */ - -export { getLocalStats } from './get_local_stats'; -export { getClusterUuids } from './get_cluster_stats'; -export { registerCollection } from './register_collection'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts deleted file mode 100644 index bf9855ce7538e..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts +++ /dev/null @@ -1,27 +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. - */ - -export { replaceTelemetryInjectedVars } from './replace_injected_vars'; -export { getTelemetryOptIn } from './get_telemetry_opt_in'; -export { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; -export { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; -export { - getTelemetryFailureDetails, - TelemetryFailureDetails, -} from './get_telemetry_failure_details'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts deleted file mode 100644 index f09ee8623afac..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts +++ /dev/null @@ -1,72 +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 { getTelemetrySavedObject } from '../telemetry_repository'; -import { getTelemetryOptIn } from './get_telemetry_opt_in'; -import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; -import { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; -import { getNotifyUserAboutOptInDefault } from './get_telemetry_notify_user_about_optin_default'; - -export async function replaceTelemetryInjectedVars(request: any, server: any) { - const config = server.config(); - const configTelemetrySendUsageFrom = config.get('telemetry.sendUsageFrom'); - const configTelemetryOptIn = config.get('telemetry.optIn'); - const configTelemetryAllowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); - const isRequestingApplication = request.path.startsWith('/app'); - - // Prevent interstitial screens (such as the space selector) from prompting for telemetry - if (!isRequestingApplication) { - return { - telemetryOptedIn: false, - }; - } - - const currentKibanaVersion = config.get('pkg.version'); - const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient(request); - const telemetrySavedObject = await getTelemetrySavedObject(savedObjectsClient); - const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({ - configTelemetryAllowChangingOptInStatus, - telemetrySavedObject, - }); - - const telemetryOptedIn = getTelemetryOptIn({ - configTelemetryOptIn, - allowChangingOptInStatus, - telemetrySavedObject, - currentKibanaVersion, - }); - - const telemetrySendUsageFrom = getTelemetrySendUsageFrom({ - configTelemetrySendUsageFrom, - telemetrySavedObject, - }); - - const telemetryNotifyUserAboutOptInDefault = getNotifyUserAboutOptInDefault({ - telemetrySavedObject, - allowChangingOptInStatus, - configTelemetryOptIn, - telemetryOptedIn, - }); - - return { - telemetryOptedIn, - telemetrySendUsageFrom, - telemetryNotifyUserAboutOptInDefault, - }; -} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts deleted file mode 100644 index f1735d1bb2866..0000000000000 --- a/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts +++ /dev/null @@ -1,32 +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. - */ - -export { getTelemetrySavedObject, TelemetrySavedObject } from './get_telemetry_saved_object'; -export { updateTelemetrySavedObject } from './update_telemetry_saved_object'; - -export interface TelemetrySavedObjectAttributes { - enabled?: boolean | null; - lastVersionChecked?: string; - sendUsageFrom?: 'browser' | 'server'; - lastReported?: number; - telemetryAllowChangingOptInStatus?: boolean; - userHasSeenNotice?: boolean; - reportFailureCount?: number; - reportFailureVersion?: string; -} diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js index 6a08405b5b6a5..3b8a7dfbed313 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { ImageComparator } from 'test_utils/image_comparator'; import dummyESResponse from './dummy_es_response.json'; import initial from './initial.png'; @@ -32,13 +31,11 @@ import EMS_TILES from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_ import EMS_STYLE_ROAD_MAP_BRIGHT from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_bright'; import EMS_STYLE_ROAD_MAP_DESATURATED from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_desaturated'; import EMS_STYLE_DARK_MAP from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_style_dark'; -import { - setup as visualizationsSetup, - start as visualizationsStart, -} from '../../../visualizations/public/np_ready/public/legacy'; +import { setup as visualizationsSetup } from '../../../visualizations/public/np_ready/public/legacy'; import { createTileMapVisualization } from '../tile_map_visualization'; import { createTileMapTypeDefinition } from '../tile_map_type'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; function mockRawData() { const stack = [dummyESResponse]; @@ -67,7 +64,6 @@ let visRegComplete = false; describe('CoordinateMapsVisualizationTest', function() { let domNode; let CoordinateMapsVisualization; - let indexPattern; let vis; let dependencies; @@ -92,7 +88,6 @@ describe('CoordinateMapsVisualizationTest', function() { } CoordinateMapsVisualization = createTileMapVisualization(dependencies); - indexPattern = Private(LogstashIndexPatternStubProvider); getManifestStub = serviceSettings.__debugStubManifestCalls(async url => { //simulate network calls @@ -124,7 +119,7 @@ describe('CoordinateMapsVisualizationTest', function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = new ExprVis({ type: 'tile_map', }); vis.params = { diff --git a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js index ebb0c24243263..d38159c91ef9f 100644 --- a/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/base_maps_visualization.js @@ -63,28 +63,21 @@ export function BaseMapsVisualizationProvider(serviceSettings) { * @param status * @return {Promise} */ - async render(esResponse, visParams, status) { + async render(esResponse, visParams) { if (!this._kibanaMap) { //the visualization has been destroyed; return; } await this._mapIsLoaded; - - if (status.resize) { - this._kibanaMap.resize(); - } - if (status.params || status.aggs) { - this._params = visParams; - await this._updateParams(); - } + this._kibanaMap.resize(); + this._params = visParams; + await this._updateParams(); if (this._hasESResponseChanged(esResponse)) { await this._updateData(esResponse); } - if (status.uiState) { - this._kibanaMap.useUiStateFromVisualization(this.vis); - } + this._kibanaMap.useUiStateFromVisualization(this.vis); await this._whenBaseLayerIsLoaded(); } diff --git a/src/legacy/core_plugins/tile_map/public/tile_map_type.js b/src/legacy/core_plugins/tile_map/public/tile_map_type.js index 544b63abe82c7..39d39a4c8f8fc 100644 --- a/src/legacy/core_plugins/tile_map/public/tile_map_type.js +++ b/src/legacy/core_plugins/tile_map/public/tile_map_type.js @@ -21,9 +21,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; -import { Schemas } from 'ui/agg_types'; -import { Status } from '../../visualizations/public'; +import { Schemas } from '../../vis_default_editor/public'; import { createTileMapVisualization } from './tile_map_visualization'; import { TileMapOptions } from './components/tile_map_options'; import { MapTypes } from './map_types'; @@ -57,7 +56,6 @@ export function createTileMapTypeDefinition(dependencies) { wms: uiSettings.get('visualization:tileMap:WMSdefaults'), }, }, - requiresUpdateStatus: [Status.AGGS, Status.PARAMS, Status.RESIZE, Status.UI_STATE], requiresPartialRows: true, visualization: CoordinateMapsVisualization, responseHandler: convertToGeoJson, @@ -143,21 +141,20 @@ export function createTileMapTypeDefinition(dependencies) { }, ]), }, - setup: async savedVis => { - const vis = savedVis.vis; + setup: async vis => { let tmsLayers; try { tmsLayers = await serviceSettings.getTMSServices(); } catch (e) { - return savedVis; + return vis; } vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { vis.params.wms.selectedTmsLayer = tmsLayers[0]; } - return savedVis; + return vis; }, }; } diff --git a/src/legacy/core_plugins/timelion/index.ts b/src/legacy/core_plugins/timelion/index.ts index 9e2bfd4023bd9..41a15dc4e0186 100644 --- a/src/legacy/core_plugins/timelion/index.ts +++ b/src/legacy/core_plugins/timelion/index.ts @@ -29,7 +29,7 @@ const experimentalLabel = i18n.translate('timelion.uiSettings.experimentalLabel' const timelionPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) => new Plugin({ - require: ['kibana', 'elasticsearch', 'data'], + require: ['kibana', 'elasticsearch'], config(Joi: any) { return Joi.object({ enabled: Joi.boolean().default(true), diff --git a/src/legacy/core_plugins/timelion/public/app.js b/src/legacy/core_plugins/timelion/public/app.js index a9d678cfea79c..a50f8a2cd3e8d 100644 --- a/src/legacy/core_plugins/timelion/public/app.js +++ b/src/legacy/core_plugins/timelion/public/app.js @@ -24,10 +24,10 @@ import { i18n } from '@kbn/i18n'; import { capabilities } from 'ui/capabilities'; import { docTitle } from 'ui/doc_title'; import { fatalError, toastNotifications } from 'ui/notify'; -import { timezoneProvider } from 'ui/vis/lib/timezone'; import { timefilter } from 'ui/timefilter'; import { npStart } from 'ui/new_platform'; import { getSavedSheetBreadcrumbs, getCreateBreadcrumbs } from './breadcrumbs'; +import { getTimezone } from '../../vis_type_timelion/public'; import 'uiExports/savedObjectTypes'; @@ -38,7 +38,6 @@ import 'ui/directives/input_focus'; import './directives/saved_object_finder'; import 'ui/directives/listen'; import './directives/saved_object_save_as_checkbox'; -import '../../data/public/legacy'; import './services/saved_sheet_register'; import rootTemplate from 'plugins/timelion/index.html'; @@ -116,8 +115,7 @@ app.controller('timelion', function( $timeout, AppState, config, - kbnUrl, - Private + kbnUrl ) { // Keeping this at app scope allows us to keep the current page when the user // switches to say, the timepicker. @@ -128,7 +126,7 @@ app.controller('timelion', function( timefilter.enableTimeRangeSelector(); const savedVisualizations = visualizations.savedVisualizationsLoader; - const timezone = Private(timezoneProvider)(); + const timezone = getTimezone(config); const defaultExpression = '.es(*)'; const savedSheet = $route.current.locals.savedSheet; diff --git a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js index 111db0a83ffc4..fb54c36df27d7 100644 --- a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js +++ b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js @@ -21,287 +21,295 @@ import _ from 'lodash'; import rison from 'rison-node'; import { uiModules } from 'ui/modules'; import 'ui/directives/input_focus'; -import 'ui/directives/paginate'; import savedObjectFinderTemplate from './saved_object_finder.html'; import { savedSheetLoader } from '../services/saved_sheets'; import { keyMap } from 'ui/directives/key_map'; +import { + PaginateControlsDirectiveProvider, + PaginateDirectiveProvider, +} from '../../../../../plugins/kibana_legacy/public'; const module = uiModules.get('kibana'); -module.directive('savedObjectFinder', function($location, kbnUrl, Private, config) { - return { - restrict: 'E', - scope: { - type: '@', - // optional make-url attr, sets the userMakeUrl in our scope - userMakeUrl: '=?makeUrl', - // optional on-choose attr, sets the userOnChoose in our scope - userOnChoose: '=?onChoose', - // optional useLocalManagement attr, removes link to management section - useLocalManagement: '=?useLocalManagement', - /** - * @type {function} - an optional function. If supplied an `Add new X` button is shown - * and this function is called when clicked. - */ - onAddNew: '=', - /** - * @{type} boolean - set this to true, if you don't want the search box above the - * table to automatically gain focus once loaded - */ - disableAutoFocus: '=', - }, - template: savedObjectFinderTemplate, - controllerAs: 'finder', - controller: function($scope, $element) { - const self = this; - - // the text input element - const $input = $element.find('input[ng-model=filter]'); - - // The number of items to show in the list - $scope.perPage = config.get('savedObjects:perPage'); - - // the list that will hold the suggestions - const $list = $element.find('ul'); - - // the current filter string, used to check that returned results are still useful - let currentFilter = $scope.filter; - - // the most recently entered search/filter - let prevSearch; - - // the list of hits, used to render display - self.hits = []; - - self.service = savedSheetLoader; - self.properties = self.service.loaderProperties; - - filterResults(); - - /** - * Boolean that keeps track of whether hits are sorted ascending (true) - * or descending (false) by title - * @type {Boolean} - */ - self.isAscending = true; - - /** - * Sorts saved object finder hits either ascending or descending - * @param {Array} hits Array of saved finder object hits - * @return {Array} Array sorted either ascending or descending - */ - self.sortHits = function(hits) { - self.isAscending = !self.isAscending; - self.hits = self.isAscending ? _.sortBy(hits, 'title') : _.sortBy(hits, 'title').reverse(); - }; - - /** - * Passed the hit objects and will determine if the - * hit should have a url in the UI, returns it if so - * @return {string|null} - the url or nothing - */ - self.makeUrl = function(hit) { - if ($scope.userMakeUrl) { - return $scope.userMakeUrl(hit); - } - - if (!$scope.userOnChoose) { - return hit.url; - } +module + .directive('paginate', PaginateDirectiveProvider) + .directive('paginateControls', PaginateControlsDirectiveProvider) + .directive('savedObjectFinder', function($location, kbnUrl, Private, config) { + return { + restrict: 'E', + scope: { + type: '@', + // optional make-url attr, sets the userMakeUrl in our scope + userMakeUrl: '=?makeUrl', + // optional on-choose attr, sets the userOnChoose in our scope + userOnChoose: '=?onChoose', + // optional useLocalManagement attr, removes link to management section + useLocalManagement: '=?useLocalManagement', + /** + * @type {function} - an optional function. If supplied an `Add new X` button is shown + * and this function is called when clicked. + */ + onAddNew: '=', + /** + * @{type} boolean - set this to true, if you don't want the search box above the + * table to automatically gain focus once loaded + */ + disableAutoFocus: '=', + }, + template: savedObjectFinderTemplate, + controllerAs: 'finder', + controller: function($scope, $element) { + const self = this; + + // the text input element + const $input = $element.find('input[ng-model=filter]'); + + // The number of items to show in the list + $scope.perPage = config.get('savedObjects:perPage'); + + // the list that will hold the suggestions + const $list = $element.find('ul'); + + // the current filter string, used to check that returned results are still useful + let currentFilter = $scope.filter; + + // the most recently entered search/filter + let prevSearch; + + // the list of hits, used to render display + self.hits = []; + + self.service = savedSheetLoader; + self.properties = self.service.loaderProperties; - return '#'; - }; + filterResults(); - self.preventClick = function($event) { - $event.preventDefault(); - }; + /** + * Boolean that keeps track of whether hits are sorted ascending (true) + * or descending (false) by title + * @type {Boolean} + */ + self.isAscending = true; + + /** + * Sorts saved object finder hits either ascending or descending + * @param {Array} hits Array of saved finder object hits + * @return {Array} Array sorted either ascending or descending + */ + self.sortHits = function(hits) { + self.isAscending = !self.isAscending; + self.hits = self.isAscending + ? _.sortBy(hits, 'title') + : _.sortBy(hits, 'title').reverse(); + }; + + /** + * Passed the hit objects and will determine if the + * hit should have a url in the UI, returns it if so + * @return {string|null} - the url or nothing + */ + self.makeUrl = function(hit) { + if ($scope.userMakeUrl) { + return $scope.userMakeUrl(hit); + } - /** - * Called when a hit object is clicked, can override the - * url behavior if necessary. - */ - self.onChoose = function(hit, $event) { - if ($scope.userOnChoose) { - $scope.userOnChoose(hit, $event); - } + if (!$scope.userOnChoose) { + return hit.url; + } - const url = self.makeUrl(hit); - if (!url || url === '#' || url.charAt(0) !== '#') return; + return '#'; + }; - $event.preventDefault(); + self.preventClick = function($event) { + $event.preventDefault(); + }; - // we want the '/path', not '#/path' - kbnUrl.change(url.substr(1)); - }; + /** + * Called when a hit object is clicked, can override the + * url behavior if necessary. + */ + self.onChoose = function(hit, $event) { + if ($scope.userOnChoose) { + $scope.userOnChoose(hit, $event); + } - $scope.$watch('filter', function(newFilter) { - // ensure that the currentFilter changes from undefined to '' - // which triggers - currentFilter = newFilter || ''; - filterResults(); - }); - - $scope.pageFirstItem = 0; - $scope.pageLastItem = 0; - $scope.onPageChanged = page => { - $scope.pageFirstItem = page.firstItem; - $scope.pageLastItem = page.lastItem; - }; - - //manages the state of the keyboard selector - self.selector = { - enabled: false, - index: -1, - }; - - self.getLabel = function() { - return _.words(self.properties.nouns) - .map(_.capitalize) - .join(' '); - }; - - //key handler for the filter text box - self.filterKeyDown = function($event) { - switch (keyMap[$event.keyCode]) { - case 'enter': - if (self.hitCount !== 1) return; - - const hit = self.hits[0]; - if (!hit) return; - - self.onChoose(hit, $event); - $event.preventDefault(); - break; - } - }; + const url = self.makeUrl(hit); + if (!url || url === '#' || url.charAt(0) !== '#') return; - //key handler for the list items - self.hitKeyDown = function($event, page, paginate) { - switch (keyMap[$event.keyCode]) { - case 'tab': - if (!self.selector.enabled) break; + $event.preventDefault(); - self.selector.index = -1; - self.selector.enabled = false; + // we want the '/path', not '#/path' + kbnUrl.change(url.substr(1)); + }; - //if the user types shift-tab return to the textbox - //if the user types tab, set the focus to the currently selected hit. - if ($event.shiftKey) { - $input.focus(); - } else { - $list.find('li.active a').focus(); - } + $scope.$watch('filter', function(newFilter) { + // ensure that the currentFilter changes from undefined to '' + // which triggers + currentFilter = newFilter || ''; + filterResults(); + }); - $event.preventDefault(); - break; - case 'down': - if (!self.selector.enabled) break; + $scope.pageFirstItem = 0; + $scope.pageLastItem = 0; + $scope.onPageChanged = page => { + $scope.pageFirstItem = page.firstItem; + $scope.pageLastItem = page.lastItem; + }; + + //manages the state of the keyboard selector + self.selector = { + enabled: false, + index: -1, + }; + + self.getLabel = function() { + return _.words(self.properties.nouns) + .map(_.capitalize) + .join(' '); + }; + + //key handler for the filter text box + self.filterKeyDown = function($event) { + switch (keyMap[$event.keyCode]) { + case 'enter': + if (self.hitCount !== 1) return; + + const hit = self.hits[0]; + if (!hit) return; + + self.onChoose(hit, $event); + $event.preventDefault(); + break; + } + }; + + //key handler for the list items + self.hitKeyDown = function($event, page, paginate) { + switch (keyMap[$event.keyCode]) { + case 'tab': + if (!self.selector.enabled) break; + + self.selector.index = -1; + self.selector.enabled = false; + + //if the user types shift-tab return to the textbox + //if the user types tab, set the focus to the currently selected hit. + if ($event.shiftKey) { + $input.focus(); + } else { + $list.find('li.active a').focus(); + } + + $event.preventDefault(); + break; + case 'down': + if (!self.selector.enabled) break; + + if (self.selector.index + 1 < page.length) { + self.selector.index += 1; + } + $event.preventDefault(); + break; + case 'up': + if (!self.selector.enabled) break; + + if (self.selector.index > 0) { + self.selector.index -= 1; + } + $event.preventDefault(); + break; + case 'right': + if (!self.selector.enabled) break; + + if (page.number < page.count) { + paginate.goToPage(page.number + 1); + self.selector.index = 0; + selectTopHit(); + } + $event.preventDefault(); + break; + case 'left': + if (!self.selector.enabled) break; + + if (page.number > 1) { + paginate.goToPage(page.number - 1); + self.selector.index = 0; + selectTopHit(); + } + $event.preventDefault(); + break; + case 'escape': + if (!self.selector.enabled) break; - if (self.selector.index + 1 < page.length) { - self.selector.index += 1; - } - $event.preventDefault(); - break; - case 'up': - if (!self.selector.enabled) break; + $input.focus(); + $event.preventDefault(); + break; + case 'enter': + if (!self.selector.enabled) break; + + const hitIndex = (page.number - 1) * paginate.perPage + self.selector.index; + const hit = self.hits[hitIndex]; + if (!hit) break; + + self.onChoose(hit, $event); + $event.preventDefault(); + break; + case 'shift': + break; + default: + $input.focus(); + break; + } + }; + + self.hitBlur = function() { + self.selector.index = -1; + self.selector.enabled = false; + }; + + self.manageObjects = function(type) { + $location.url('/management/kibana/objects?_a=' + rison.encode({ tab: type })); + }; + + self.hitCountNoun = function() { + return (self.hitCount === 1 ? self.properties.noun : self.properties.nouns).toLowerCase(); + }; + + function selectTopHit() { + setTimeout(function() { + //triggering a focus event kicks off a new angular digest cycle. + $list.find('a:first').focus(); + }, 0); + } - if (self.selector.index > 0) { - self.selector.index -= 1; - } - $event.preventDefault(); - break; - case 'right': - if (!self.selector.enabled) break; - - if (page.number < page.count) { - paginate.goToPage(page.number + 1); - self.selector.index = 0; - selectTopHit(); - } - $event.preventDefault(); - break; - case 'left': - if (!self.selector.enabled) break; - - if (page.number > 1) { - paginate.goToPage(page.number - 1); - self.selector.index = 0; - selectTopHit(); + function filterResults() { + if (!self.service) return; + if (!self.properties) return; + + // track the filter that we use for this search, + // but ensure that we don't search for the same + // thing twice. This is called from multiple places + // and needs to be smart about when it actually searches + const filter = currentFilter; + if (prevSearch === filter) return; + + prevSearch = filter; + + const isLabsEnabled = config.get('visualize:enableLabs'); + self.service.find(filter).then(function(hits) { + hits.hits = hits.hits.filter( + hit => isLabsEnabled || _.get(hit, 'type.stage') !== 'experimental' + ); + hits.total = hits.hits.length; + + // ensure that we don't display old results + // as we can't really cancel requests + if (currentFilter === filter) { + self.hitCount = hits.total; + self.hits = _.sortBy(hits.hits, 'title'); } - $event.preventDefault(); - break; - case 'escape': - if (!self.selector.enabled) break; - - $input.focus(); - $event.preventDefault(); - break; - case 'enter': - if (!self.selector.enabled) break; - - const hitIndex = (page.number - 1) * paginate.perPage + self.selector.index; - const hit = self.hits[hitIndex]; - if (!hit) break; - - self.onChoose(hit, $event); - $event.preventDefault(); - break; - case 'shift': - break; - default: - $input.focus(); - break; + }); } - }; - - self.hitBlur = function() { - self.selector.index = -1; - self.selector.enabled = false; - }; - - self.manageObjects = function(type) { - $location.url('/management/kibana/objects?_a=' + rison.encode({ tab: type })); - }; - - self.hitCountNoun = function() { - return (self.hitCount === 1 ? self.properties.noun : self.properties.nouns).toLowerCase(); - }; - - function selectTopHit() { - setTimeout(function() { - //triggering a focus event kicks off a new angular digest cycle. - $list.find('a:first').focus(); - }, 0); - } - - function filterResults() { - if (!self.service) return; - if (!self.properties) return; - - // track the filter that we use for this search, - // but ensure that we don't search for the same - // thing twice. This is called from multiple places - // and needs to be smart about when it actually searches - const filter = currentFilter; - if (prevSearch === filter) return; - - prevSearch = filter; - - const isLabsEnabled = config.get('visualize:enableLabs'); - self.service.find(filter).then(function(hits) { - hits.hits = hits.hits.filter( - hit => isLabsEnabled || _.get(hit, 'type.stage') !== 'experimental' - ); - hits.total = hits.hits.length; - - // ensure that we don't display old results - // as we can't really cancel requests - if (currentFilter === filter) { - self.hitCount = hits.total; - self.hits = _.sortBy(hits.hits, 'title'); - } - }); - } - }, - }; -}); + }, + }; + }); diff --git a/src/legacy/core_plugins/ui_metric/index.ts b/src/legacy/core_plugins/ui_metric/index.ts index 5a4a0ebf1a632..2e5be3d7b0a39 100644 --- a/src/legacy/core_plugins/ui_metric/index.ts +++ b/src/legacy/core_plugins/ui_metric/index.ts @@ -25,9 +25,6 @@ export default function(kibana: any) { id: 'ui_metric', require: ['kibana', 'elasticsearch'], publicDir: resolve(__dirname, 'public'), - uiExports: { - mappings: require('./mappings.json'), - }, init() {}, }); } diff --git a/src/legacy/core_plugins/ui_metric/mappings.json b/src/legacy/core_plugins/ui_metric/mappings.json deleted file mode 100644 index 113e37e60e48b..0000000000000 --- a/src/legacy/core_plugins/ui_metric/mappings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ui-metric": { - "properties": { - "count": { - "type": "integer" - } - } - } -} diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap b/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap index ba5f2ae975cbe..5200fee45d6b3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap +++ b/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap @@ -3,6 +3,7 @@ exports[`DefaultEditorAgg component should init with the default set of props 1`] = ` diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg_params.test.tsx.snap b/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg_params.test.tsx.snap deleted file mode 100644 index 028d0b8016693..0000000000000 --- a/src/legacy/core_plugins/vis_default_editor/public/components/__snapshots__/agg_params.test.tsx.snap +++ /dev/null @@ -1,70 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DefaultEditorAggParams component should init with the default set of params 1`] = ` - - - - - - - - - -`; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx index 22e0ebb3d30dc..feb5b3caa023b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg.test.tsx @@ -21,16 +21,13 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { IndexPattern } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; +import { IndexPattern, IAggType, AggGroupNames } from 'src/plugins/data/public'; -import { IAggType, AggGroupNames } from '../legacy_imports'; import { DefaultEditorAgg, DefaultEditorAggProps } from './agg'; import { DefaultEditorAggParams } from './agg_params'; import { AGGS_ACTION_KEYS } from './agg_group_state'; import { Schema } from '../schemas'; - -jest.mock('ui/new_platform'); +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('./agg_params', () => ({ DefaultEditorAggParams: () => null, @@ -70,7 +67,7 @@ describe('DefaultEditorAgg component', () => { isLastBucket: false, isRemovable: false, metricAggs: [], - state: { params: {} } as VisState, + state: { params: {} } as EditorVisState, setAggParamValue, setStateParamValue, onAggTypeChange: () => {}, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx index 30ccd4f0b6cae..2a45273207623 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg.tsx @@ -28,7 +28,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IAggConfig } from '../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { DefaultEditorAggParams } from './agg_params'; import { DefaultEditorAggCommonProps } from './agg_common_props'; import { AGGS_ACTION_KEYS, AggsAction } from './agg_group_state'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx index 24cb83498d4d0..9df4ea58e0f07 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_add.tsx @@ -29,7 +29,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { IAggConfig, AggGroupNames } from '../legacy_imports'; +import { IAggConfig, AggGroupNames } from '../../../../../plugins/data/public'; import { Schema } from '../schemas'; interface DefaultEditorAggAddProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts index 1a97cc5c4d967..3aae10879138a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_common_props.ts @@ -17,9 +17,10 @@ * under the License. */ -import { VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggType, IAggConfig, IAggGroupNames } from '../legacy_imports'; +import { VisParams } from 'src/legacy/core_plugins/visualizations/public'; +import { IAggType, IAggConfig, IAggGroupNames } from 'src/plugins/data/public'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; type AggId = IAggConfig['id']; type AggParams = IAggConfig['params']; @@ -31,7 +32,7 @@ export interface DefaultEditorCommonProps { formIsTouched: boolean; groupName: IAggGroupNames; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; setAggParamValue: ( aggId: AggId, paramName: T, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx index ec467480539ab..5d02f0a2c759e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { act } from 'react-dom/test-utils'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfigs, IAggConfig } from '../legacy_imports'; +import { IAggConfigs, IAggConfig } from 'src/plugins/data/public'; import { DefaultEditorAggGroup, DefaultEditorAggGroupProps } from './agg_group'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('@elastic/eui', () => ({ EuiTitle: 'eui-title', @@ -36,17 +36,6 @@ jest.mock('@elastic/eui', () => ({ EuiPanel: 'eui-panel', })); -jest.mock('../legacy_imports', () => ({ - aggGroupNamesMap: () => ({ - metrics: 'Metrics', - buckets: 'Buckets', - }), - AggGroupNames: { - Metrics: 'metrics', - Buckets: 'buckets', - }, -})); - jest.mock('./agg', () => ({ DefaultEditorAgg: () =>
, })); @@ -104,8 +93,8 @@ describe('DefaultEditorAgg component', () => { metricAggs: [], groupName: 'metrics', state: { - aggs, - } as VisState, + data: { aggs }, + } as EditorVisState, schemas: [ { name: 'metrics', @@ -158,8 +147,8 @@ describe('DefaultEditorAgg component', () => { }); expect(reorderAggs).toHaveBeenCalledWith( - defaultProps.state.aggs.aggs[0], - defaultProps.state.aggs.aggs[1] + defaultProps.state.data.aggs!.aggs[0], + defaultProps.state.data.aggs!.aggs[1] ); }); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx index a15a98d4983ce..08b69ef37f528 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group.tsx @@ -30,7 +30,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IAggConfig, aggGroupNamesMap, AggGroupNames } from '../legacy_imports'; +import { AggGroupNames, search, IAggConfig } from '../../../../../plugins/data/public'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from './agg_common_props'; @@ -68,14 +68,15 @@ function DefaultEditorAggGroup({ setTouched, setValidity, }: DefaultEditorAggGroupProps) { - const groupNameLabel = (aggGroupNamesMap() as any)[groupName]; + const groupNameLabel = (search.aggs.aggGroupNamesMap() as any)[groupName]; // e.g. buckets can have no aggs const schemaNames = getSchemasByGroup(schemas, groupName).map(s => s.name); const group: IAggConfig[] = useMemo( () => - state.aggs.aggs.filter((agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema)) || - [], - [state.aggs.aggs, schemaNames] + state.data.aggs!.aggs.filter( + (agg: IAggConfig) => agg.schema && schemaNames.includes(agg.schema) + ) || [], + [state.data.aggs, schemaNames] ); const stats = { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts index aebece29e7ae6..3693f1b1e3091 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { IAggConfig } from '../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { isAggRemovable, calcAggIsTooLow, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx index 0a8c5c3077ada..9a4cca940baea 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_helper.tsx @@ -18,7 +18,7 @@ */ import { findIndex, isEmpty } from 'lodash'; -import { IAggConfig } from '../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { AggsState } from './agg_group_state'; import { Schema, getSchemaByName } from '../schemas'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx index d022297ae72b3..bfd5bec339b1f 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_group_state.tsx @@ -17,7 +17,7 @@ * under the License. */ -import { IAggConfig } from '../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; export enum AGGS_ACTION_KEYS { TOUCHED = 'aggsTouched', diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts index cdc5a4c8f8a77..aec332e8674d7 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts @@ -17,12 +17,11 @@ * under the License. */ -import { IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfig, AggParam } from '../legacy_imports'; +import { IAggConfig, AggParam, IndexPatternField } from 'src/plugins/data/public'; import { ComboBoxGroupedOptions } from '../utils'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; // NOTE: we cannot export the interface with export { InterfaceName } // as there is currently a bug on babel typescript transform plugin for it @@ -36,7 +35,7 @@ export interface AggParamCommonProps { formIsTouched: boolean; indexedFields?: ComboBoxGroupedOptions; showValidation: boolean; - state: VisState; + state: EditorVisState; value?: T; metricAggs: IAggConfig[]; schemas: Schema[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx index d2821566fcb37..1c49ebf40640e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx @@ -18,12 +18,16 @@ */ import React from 'react'; -import { mount, shallow } from 'enzyme'; +import { mount } from 'enzyme'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { IndexPattern } from 'src/plugins/data/public'; -import { DefaultEditorAggParams, DefaultEditorAggParamsProps } from './agg_params'; -import { IAggConfig, AggGroupNames } from '../legacy_imports'; +import { IndexPattern, IAggConfig, AggGroupNames } from 'src/plugins/data/public'; +import { + DefaultEditorAggParams as PureDefaultEditorAggParams, + DefaultEditorAggParamsProps, +} from './agg_params'; +import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public'; +import { dataPluginMock } from '../../../../../plugins/data/public/mocks'; +import { EditorVisState } from './sidebar/state/reducers'; const mockEditorConfig = { useNormalizedEsInterval: { hidden: false, fixedValue: false }, @@ -34,8 +38,12 @@ const mockEditorConfig = { timeBase: '1m', }, }; +const DefaultEditorAggParams = (props: DefaultEditorAggParamsProps) => ( + + + +); -jest.mock('ui/new_platform'); jest.mock('./utils', () => ({ getEditorConfig: jest.fn(() => mockEditorConfig), })); @@ -100,7 +108,7 @@ describe('DefaultEditorAggParams component', () => { formIsTouched: false, indexPattern: {} as IndexPattern, metricAggs: [], - state: {} as VisState, + state: {} as EditorVisState, setAggParamValue, onAggTypeChange, setTouched, @@ -109,12 +117,6 @@ describe('DefaultEditorAggParams component', () => { }; }); - it('should init with the default set of params', () => { - const comp = shallow(); - - expect(comp).toMatchSnapshot(); - }); - it('should reset the validity to true when destroyed', () => { const comp = mount(); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx index 510c21af95da1..b1555b76500d0 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx @@ -22,8 +22,7 @@ import { EuiForm, EuiAccordion, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import useUnmount from 'react-use/lib/useUnmount'; -import { IndexPattern } from 'src/plugins/data/public'; -import { IAggConfig, AggGroupNames } from '../legacy_imports'; +import { IAggConfig, IndexPattern, AggGroupNames } from '../../../../../plugins/data/public'; import { DefaultEditorAggSelect } from './agg_select'; import { DefaultEditorAggParam } from './agg_param'; @@ -41,6 +40,8 @@ import { import { DefaultEditorCommonProps } from './agg_common_props'; import { EditorParamConfig, TimeIntervalParam, FixedParam, getEditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; +import { useKibana } from '../../../../../plugins/kibana_react/public'; +import { VisDefaultEditorKibanaServices } from '../types'; const FIXED_VALUE_PROP = 'fixedValue'; const DEFAULT_PROP = 'default'; @@ -83,18 +84,24 @@ function DefaultEditorAggParams({ allowedAggs = [], hideCustomLabel = false, }: DefaultEditorAggParamsProps) { - const schema = getSchemaByName(schemas, agg.schema); - const { title } = schema; - const aggFilter = [...allowedAggs, ...(schema.aggFilter || [])]; + const schema = useMemo(() => getSchemaByName(schemas, agg.schema), [agg.schema, schemas]); + const aggFilter = useMemo(() => [...allowedAggs, ...(schema.aggFilter || [])], [ + allowedAggs, + schema.aggFilter, + ]); + const { services } = useKibana(); + const aggTypes = useMemo(() => services.data.search.aggs.types.getAll(), [ + services.data.search.aggs.types, + ]); const groupedAggTypeOptions = useMemo( - () => getAggTypeOptions(agg, indexPattern, groupName, aggFilter), - [agg, indexPattern, groupName, aggFilter] + () => getAggTypeOptions(aggTypes, agg, indexPattern, groupName, aggFilter), + [aggTypes, agg, indexPattern, groupName, aggFilter] ); const error = aggIsTooLow ? i18n.translate('visDefaultEditor.aggParams.errors.aggWrongRunOrderErrorMessage', { defaultMessage: '"{schema}" aggs must run before all other buckets!', - values: { schema: title }, + values: { schema: schema.title }, }) : ''; const aggTypeName = agg.type?.name; @@ -105,8 +112,20 @@ function DefaultEditorAggParams({ fieldName, ]); const params = useMemo( - () => getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas, hideCustomLabel }), - [agg, editorConfig, metricAggs, state, schemas, hideCustomLabel] + () => + getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas, hideCustomLabel }, + services.data.search.__LEGACY.aggTypeFieldFilters + ), + [ + agg, + editorConfig, + metricAggs, + state, + schemas, + hideCustomLabel, + services.data.search.__LEGACY.aggTypeFieldFilters, + ] ); const allParams = [...params.basic, ...params.advanced]; const [paramsState, onChangeParamsState] = useReducer( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts index 047467750794b..bed2561341737 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts @@ -17,9 +17,14 @@ * under the License. */ -import { IndexPattern } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfig, IAggType, AggGroupNames, BUCKET_TYPES } from '../legacy_imports'; +import { + AggGroupNames, + BUCKET_TYPES, + IAggConfig, + IAggType, + IndexPattern, + IndexPatternField, +} from 'src/plugins/data/public'; import { getAggParamsToRender, getAggTypeOptions, @@ -28,12 +33,17 @@ import { import { FieldParamEditor, OrderByParamEditor } from './controls'; import { EditorConfig } from './utils'; import { Schema } from '../schemas'; +import { EditorVisState } from './sidebar/state/reducers'; jest.mock('../utils', () => ({ groupAndSortBy: jest.fn(() => ['indexedFields']), })); -jest.mock('ui/new_platform'); +const mockFilter: any = { + filter(fields: IndexPatternField[]): IndexPatternField[] { + return fields; + }, +}; describe('DefaultEditorAggParams helpers', () => { describe('getAggParamsToRender', () => { @@ -48,7 +58,7 @@ describe('DefaultEditorAggParams helpers', () => { hideCustomLabel: true, } as Schema, ]; - const state = {} as VisState; + const state = {} as EditorVisState; const metricAggs: IAggConfig[] = []; const emptyParams = { basic: [], @@ -62,14 +72,20 @@ describe('DefaultEditorAggParams helpers', () => { }, schema: 'metric', } as IAggConfig; - const params = getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas }); + const params = getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas }, + mockFilter + ); expect(params).toEqual(emptyParams); }); it('should not create any param if there is no agg type', () => { agg = { schema: 'metric' } as IAggConfig; - const params = getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas }); + const params = getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas }, + mockFilter + ); expect(params).toEqual(emptyParams); }); @@ -85,7 +101,10 @@ describe('DefaultEditorAggParams helpers', () => { hidden: true, }, }; - const params = getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas }); + const params = getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas }, + mockFilter + ); expect(params).toEqual(emptyParams); }); @@ -97,7 +116,10 @@ describe('DefaultEditorAggParams helpers', () => { }, schema: 'metric2', } as any) as IAggConfig; - const params = getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas }); + const params = getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas }, + mockFilter + ); expect(params).toEqual(emptyParams); }); @@ -136,7 +158,10 @@ describe('DefaultEditorAggParams helpers', () => { field: 'field', }, } as any) as IAggConfig; - const params = getAggParamsToRender({ agg, editorConfig, metricAggs, state, schemas }); + const params = getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas }, + mockFilter + ); expect(params).toEqual({ basic: [ @@ -172,7 +197,13 @@ describe('DefaultEditorAggParams helpers', () => { describe('getAggTypeOptions', () => { it('should return agg type options grouped by subtype', () => { const indexPattern = {} as IndexPattern; - const aggs = getAggTypeOptions({} as IAggConfig, indexPattern, 'metrics', []); + const aggs = getAggTypeOptions( + { metrics: [] }, + {} as IAggConfig, + indexPattern, + 'metrics', + [] + ); expect(aggs).toEqual(['indexedFields']); }); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts index 520ff6ffc5ff5..10590e1a59f4a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -19,29 +19,29 @@ import { get, isEmpty } from 'lodash'; -import { IndexPattern, IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { groupAndSortBy, ComboBoxGroupedOptions } from '../utils'; -import { AggTypeState, AggParamsState } from './agg_params_state'; -import { AggParamEditorProps } from './agg_param_props'; -import { aggParamsMap } from './agg_params_map'; import { - aggTypeFilters, - aggTypeFieldFilters, - aggTypes, + AggTypeFieldFilters, IAggConfig, AggParam, IFieldParamType, IAggType, -} from '../legacy_imports'; + IndexPattern, + IndexPatternField, +} from 'src/plugins/data/public'; +import { groupAndSortBy, ComboBoxGroupedOptions } from '../utils'; +import { AggTypeState, AggParamsState } from './agg_params_state'; +import { AggParamEditorProps } from './agg_param_props'; +import { aggParamsMap } from './agg_params_map'; import { EditorConfig } from './utils'; import { Schema, getSchemaByName } from '../schemas'; +import { search } from '../../../../../plugins/data/public'; +import { EditorVisState } from './sidebar/state/reducers'; interface ParamInstanceBase { agg: IAggConfig; editorConfig: EditorConfig; metricAggs: IAggConfig[]; - state: VisState; + state: EditorVisState; schemas: Schema[]; hideCustomLabel?: boolean; } @@ -53,14 +53,10 @@ export interface ParamInstance extends ParamInstanceBase { value: unknown; } -function getAggParamsToRender({ - agg, - editorConfig, - metricAggs, - state, - schemas, - hideCustomLabel, -}: ParamInstanceBase) { +function getAggParamsToRender( + { agg, editorConfig, metricAggs, state, schemas, hideCustomLabel }: ParamInstanceBase, + aggTypeFieldFilters: AggTypeFieldFilters +) { const params = { basic: [] as ParamInstance[], advanced: [] as ParamInstance[], @@ -136,13 +132,14 @@ function getAggParamsToRender({ } function getAggTypeOptions( + aggTypes: any, agg: IAggConfig, indexPattern: IndexPattern, groupName: string, allowedAggs: string[] ): ComboBoxGroupedOptions { - const aggTypeOptions = aggTypeFilters.filter( - (aggTypes as any)[groupName], + const aggTypeOptions = search.aggs.aggTypeFilters.filter( + aggTypes[groupName], indexPattern, agg, allowedAggs diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts index 7caa775dd4fa4..4517313b6fd6e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_map.ts @@ -22,11 +22,12 @@ import { AggGroupNames, BUCKET_TYPES, METRIC_TYPES, - siblingPipelineType, - parentPipelineType, -} from '../legacy_imports'; + search, +} from '../../../../../plugins/data/public'; import { wrapWithInlineComp } from './controls/utils'; +const { siblingPipelineType, parentPipelineType } = search.aggs; + const buckets = { [BUCKET_TYPES.DATE_HISTOGRAM]: { scaleMetricValues: controls.ScaleMetricsParamEditor, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx index 4d969a2d8ec6c..7ee432946f3c8 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_select.tsx @@ -23,9 +23,8 @@ import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow, EuiLink, EuiText } fr import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { IndexPattern } from 'src/plugins/data/public'; +import { IAggType, IndexPattern } from 'src/plugins/data/public'; import { useKibana } from '../../../../../plugins/kibana_react/public'; -import { IAggType } from '../legacy_imports'; import { ComboBoxGroupedOptions } from '../utils'; import { AGG_TYPE_ACTION_KEYS, AggTypeAction } from './agg_params_state'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx index 7f04b851902de..98540d3414f2d 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_control_props.tsx @@ -18,7 +18,7 @@ */ import { VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfig } from '../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { DefaultEditorAggCommonProps } from '../agg_common_props'; export interface AggControlProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx index 0b847e3747b30..0c1e93bc1e646 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/agg_utils.test.tsx @@ -20,7 +20,7 @@ import React, { FunctionComponent } from 'react'; import { mount, ReactWrapper } from 'enzyme'; -import { IAggConfig } from '../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { safeMakeLabel, useAvailableOptions, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx index 625b09b05d28f..f6edecbbcbd70 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/components/mask_list.tsx @@ -22,7 +22,7 @@ import { EuiFieldText, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { InputList, InputListConfig, InputObject, InputModel, InputItem } from './input_list'; -import { CidrMask } from '../../../legacy_imports'; +import { search } from '../../../../../../../plugins/data/public'; const EMPTY_STRING = ''; @@ -47,7 +47,7 @@ function MaskList({ showValidation, onBlur, ...rest }: MaskListProps) { defaultValue: { mask: { model: '0.0.0.0/1', value: '0.0.0.0/1', isInvalid: false }, }, - validateClass: CidrMask, + validateClass: search.aggs.CidrMask, getModelValue: (item: MaskObject = {}) => ({ mask: { model: item.mask || EMPTY_STRING, diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx index 186738d0f551c..b33149dc51a19 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.test.tsx @@ -22,11 +22,10 @@ import { act } from 'react-dom/test-utils'; import { mount, shallow, ReactWrapper } from 'enzyme'; import { EuiComboBoxProps, EuiComboBox } from '@elastic/eui'; -import { IndexPatternField } from 'src/plugins/data/public'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; +import { IAggConfig, IndexPatternField } from 'src/plugins/data/public'; import { ComboBoxGroupedOptions } from '../../utils'; import { FieldParamEditor, FieldParamEditorProps } from './field'; -import { IAggConfig } from '../../legacy_imports'; +import { EditorVisState } from '../sidebar/state/reducers'; function callComboBoxOnChange(comp: ReactWrapper, value: any = []) { const comboBoxProps = comp.find(EuiComboBox).props() as EuiComboBoxProps; @@ -79,7 +78,7 @@ describe('FieldParamEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx index 0ec00ab6f20f0..59642ae4c25f7 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/field.tsx @@ -23,8 +23,7 @@ import React, { useEffect, useState, useCallback } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IndexPatternField } from 'src/plugins/data/public'; -import { AggParam, IAggConfig, IFieldParamType } from '../../legacy_imports'; +import { AggParam, IAggConfig, IFieldParamType, IndexPatternField } from 'src/plugins/data/public'; import { formatListAsProse, parseCommaSeparatedList, useValidation } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { ComboBoxGroupedOptions } from '../../utils'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx index 3622b27bad403..e2e7c2895093e 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/filter.tsx @@ -21,8 +21,7 @@ import React, { useState } from 'react'; import { EuiForm, EuiButtonIcon, EuiFieldText, EuiFormRow, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { Query, QueryStringInput } from '../../../../../../plugins/data/public'; -import { IAggConfig } from '../../legacy_imports'; +import { IAggConfig, Query, QueryStringInput } from '../../../../../../plugins/data/public'; interface FilterRowProps { id: string; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx index 416f925da8c1e..90b7cb03b7a5b 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/has_extended_bounds.tsx @@ -20,10 +20,12 @@ import React, { useEffect } from 'react'; import { i18n } from '@kbn/i18n'; +import { search } from '../../../../../../plugins/data/public'; import { SwitchParamEditor } from './switch'; -import { isType } from '../../legacy_imports'; import { AggParamEditorProps } from '../agg_param_props'; +const { isType } = search.aggs; + function HasExtendedBoundsParamEditor(props: AggParamEditorProps) { useEffect(() => { props.setValue(props.value && props.agg.params.min_doc_count); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx index cf7af1aa5cb3a..c53e7a8beb831 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/metric_agg.test.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; -import { IAggConfig } from '../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { DEFAULT_OPTIONS, aggFilter, MetricAggParamEditor } from './metric_agg'; jest.mock('./utils', () => ({ diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx index 8d22ab283f3a1..7010f0d53e569 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/missing_bucket.tsx @@ -21,11 +21,11 @@ import React, { useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { SwitchParamEditor } from './switch'; -import { isStringType } from '../../legacy_imports'; +import { search } from '../../../../../../plugins/data/public'; import { AggParamEditorProps } from '../agg_param_props'; function MissingBucketParamEditor(props: AggParamEditorProps) { - const fieldTypeIsNotString = !isStringType(props.agg); + const fieldTypeIsNotString = !search.aggs.isStringType(props.agg); useEffect(() => { if (fieldTypeIsNotString) { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx index f40143251e46a..8f63662d928c1 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order.tsx @@ -21,7 +21,7 @@ import React, { useEffect } from 'react'; import { EuiFormRow, EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { OptionedValueProp, OptionedParamEditorProps } from '../../legacy_imports'; +import { OptionedValueProp, OptionedParamEditorProps } from 'src/plugins/data/public'; import { AggParamEditorProps } from '../agg_param_props'; function OrderParamEditor({ diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx index 01f5ed9b6a2f1..4c843791153b0 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.test.tsx @@ -21,8 +21,6 @@ import React from 'react'; import { mount } from 'enzyme'; import { OrderByParamEditor } from './order_by'; -jest.mock('ui/new_platform'); - describe('OrderAggParamEditor component', () => { let setValue: jest.Mock; let setValidity: jest.Mock; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx index 8c020c668b3c6..41672bc192fab 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_agg.tsx @@ -20,7 +20,7 @@ import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../legacy_imports'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx index c0391358ec6e2..9f1aaa54a8ca3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/order_by.tsx @@ -28,8 +28,9 @@ import { useValidation, } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; -import { termsAggFilter } from '../../legacy_imports'; +import { search } from '../../../../../../plugins/data/public'; +const { termsAggFilter } = search.aggs; const DEFAULT_VALUE = '_key'; const DEFAULT_OPTIONS = [ { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx index 0eaf9bcc987c1..82166440cf8e8 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/percentiles.test.tsx @@ -19,10 +19,10 @@ import React from 'react'; import { AggParamEditorProps } from '../agg_param_props'; -import { IAggConfig } from '../../legacy_imports'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; +import { IAggConfig } from 'src/plugins/data/public'; import { mount } from 'enzyme'; import { PercentilesEditor } from './percentiles'; +import { EditorVisState } from '../sidebar/state/reducers'; describe('PercentilesEditor component', () => { let setValue: jest.Mock; @@ -45,7 +45,7 @@ describe('PercentilesEditor component', () => { setValue, setValidity, setTouched, - state: {} as VisState, + state: {} as EditorVisState, metricAggs: [] as IAggConfig[], schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx index 5bc94bd4af226..c9f53a68b3e83 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_agg.tsx @@ -20,7 +20,7 @@ import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../legacy_imports'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx index 9d48b1c964a27..ead3f8bb00623 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/sub_metric.tsx @@ -21,7 +21,7 @@ import React, { useEffect } from 'react'; import { EuiFormLabel, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { AggParamType, IAggConfig, AggGroupNames } from '../../legacy_imports'; +import { AggParamType, IAggConfig, AggGroupNames } from '../../../../../../plugins/data/public'; import { useSubAggParamsHandlers } from './utils'; import { AggParamEditorProps } from '../agg_param_props'; import { DefaultEditorAggParams } from '../agg_params'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts index 8a21114999cd6..7c7431015d175 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts @@ -17,9 +17,9 @@ * under the License. */ -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfig, AggParam } from '../../legacy_imports'; +import { IAggConfig, AggParam } from 'src/plugins/data/public'; import { EditorConfig } from '../utils'; +import { EditorVisState } from '../sidebar/state/reducers'; export const aggParamCommonPropsMock = { agg: {} as IAggConfig, @@ -27,7 +27,7 @@ export const aggParamCommonPropsMock = { editorConfig: {} as EditorConfig, formIsTouched: false, metricAggs: [] as IAggConfig[], - state: {} as VisState, + state: {} as EditorVisState, showValidation: false, schemas: [], }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx index ee3666b2ed441..de0059f5467ad 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx @@ -23,7 +23,7 @@ import { EuiFormRow, EuiIconTip, EuiComboBox, EuiComboBoxOptionOption } from '@e import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { isValidInterval, AggParamOption } from '../../legacy_imports'; +import { search, AggParamOption } from '../../../../../../plugins/data/public'; import { AggParamEditorProps } from '../agg_param_props'; interface ComboBoxOption extends EuiComboBoxOptionOption { @@ -59,7 +59,7 @@ function TimeIntervalParamEditor({ if (value) { definedOption = find(options, { key: value }); selectedOptions = definedOption ? [definedOption] : [{ label: value, key: 'custom' }]; - isValid = !!(definedOption || isValidInterval(value, timeBase)); + isValid = !!(definedOption || search.aggs.isValidInterval(value, timeBase)); } const interval = get(agg, 'buckets.getInterval') && (agg as any).buckets.getInterval(); @@ -100,7 +100,7 @@ function TimeIntervalParamEditor({ const normalizedCustomValue = customValue.trim(); setValue(normalizedCustomValue); - if (normalizedCustomValue && isValidInterval(normalizedCustomValue, timeBase)) { + if (normalizedCustomValue && search.aggs.isValidInterval(normalizedCustomValue, timeBase)) { agg.write(); } }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.test.tsx index 4ce0712040bd5..74dab1a3b551a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.test.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.test.tsx @@ -25,7 +25,7 @@ import { TopAggregateParamEditorProps, } from './top_aggregate'; import { aggParamCommonPropsMock } from './test_utils'; -import { IAggConfig } from '../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; describe('TopAggregateParamEditor', () => { let agg: IAggConfig; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.tsx index 346dfc0156f07..bab20d18c8fc0 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/top_aggregate.tsx @@ -28,7 +28,7 @@ import { OptionedValueProp, OptionedParamEditorProps, OptionedParamType, -} from '../../legacy_imports'; +} from 'src/plugins/data/public'; import { AggParamEditorProps } from '../agg_param_props'; export interface AggregateValueProp extends OptionedValueProp { diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts index 8aeae488942cd..f4c0814748ebc 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/agg_utils.ts @@ -20,7 +20,7 @@ import { useEffect, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { IAggConfig } from '../../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; type AggFilter = string[]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts index c7816d5a9d305..4dadef79b1204 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/utils/use_handlers.ts @@ -19,7 +19,7 @@ import { useCallback } from 'react'; -import { IAggConfig, AggParamType } from '../../../legacy_imports'; +import { IAggConfig, AggParamType } from 'src/plugins/data/public'; type SetValue = (value?: IAggConfig) => void; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx index 1c1f9d57d8b90..a6a1980210be4 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/data_tab.tsx @@ -21,13 +21,12 @@ import React, { useMemo, useCallback } from 'react'; import { findLast } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; -import { VisState } from 'src/legacy/core_plugins/visualizations/public'; import { - IAggConfig, AggGroupNames, - parentPipelineType, + IAggConfig, IMetricAggType, -} from '../../legacy_imports'; + search, +} from '../../../../../../plugins/data/public'; import { DefaultEditorAggGroup } from '../agg_group'; import { EditorAction, @@ -40,6 +39,7 @@ import { } from './state'; import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from '../agg_common_props'; import { ISchemas } from '../../schemas'; +import { EditorVisState } from './state/reducers'; export interface DefaultEditorDataTabProps { dispatch: React.Dispatch; @@ -47,7 +47,7 @@ export interface DefaultEditorDataTabProps { isTabSelected: boolean; metricAggs: IAggConfig[]; schemas: ISchemas; - state: VisState; + state: EditorVisState; setTouched(isTouched: boolean): void; setValidity(modelName: string, value: boolean): void; setStateValue: DefaultEditorAggCommonProps['setStateParamValue']; @@ -67,7 +67,7 @@ function DefaultEditorDataTab({ () => findLast( metricAggs, - ({ type }: { type: IMetricAggType }) => type.subtype === parentPipelineType + ({ type }: { type: IMetricAggType }) => type.subtype === search.aggs.parentPipelineType ), [metricAggs] ); diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index 1efd8dae8178b..04c931f593e5a 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -21,9 +21,9 @@ import React, { useMemo, useState, useCallback, KeyboardEventHandler, useEffect import { get, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; import { keyCodes, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { EventEmitter } from 'events'; import { Vis } from 'src/legacy/core_plugins/visualizations/public'; -import { AggGroupNames } from '../../legacy_imports'; import { DefaultEditorNavBar, OptionTab } from './navbar'; import { DefaultEditorControls } from './controls'; import { setStateParamValue, useEditorReducer, useEditorFormState, discardChanges } from './state'; @@ -31,6 +31,7 @@ import { DefaultEditorAggCommonProps } from '../agg_common_props'; import { SidebarTitle } from './sidebar_title'; import { PersistedState } from '../../../../../../plugins/visualizations/public'; import { SavedSearch } from '../../../../../../plugins/discover/public'; +import { AggGroupNames } from '../../../../../../plugins/data/public'; import { getSchemasByGroup } from '../../schemas'; interface DefaultEditorSideBarProps { @@ -40,6 +41,7 @@ interface DefaultEditorSideBarProps { uiState: PersistedState; vis: Vis; isLinkedSearch: boolean; + eventEmitter: EventEmitter; savedSearch?: SavedSearch; } @@ -50,14 +52,17 @@ function DefaultEditorSideBar({ uiState, vis, isLinkedSearch, + eventEmitter, savedSearch, }: DefaultEditorSideBarProps) { const [selectedTab, setSelectedTab] = useState(optionTabs[0].name); const [isDirty, setDirty] = useState(false); - const [state, dispatch] = useEditorReducer(vis); + const [state, dispatch] = useEditorReducer(vis, eventEmitter); const { formState, setTouched, setValidity, resetValidity } = useEditorFormState(); - const responseAggs = useMemo(() => state.aggs.getResponseAggs(), [state.aggs]); + const responseAggs = useMemo(() => (state.data.aggs ? state.data.aggs.getResponseAggs() : []), [ + state.data.aggs, + ]); const metricSchemas = getSchemasByGroup(vis.type.schemas.all || [], AggGroupNames.Metrics).map( s => s.name ); @@ -90,17 +95,20 @@ function DefaultEditorSideBar({ const applyChanges = useCallback(() => { if (formState.invalid || !isDirty) { setTouched(true); - return; } - vis.setCurrentState(state); - vis.updateState(); - vis.emit('dirtyStateChange', { + vis.setState({ + ...vis.serialize(), + params: state.params, + data: { aggs: state.data.aggs ? (state.data.aggs.aggs.map(agg => agg.toJSON()) as any) : [] }, + }); + eventEmitter.emit('updateVis'); + eventEmitter.emit('dirtyStateChange', { isDirty: false, }); setTouched(false); - }, [vis, state, formState.invalid, setTouched, isDirty]); + }, [vis, state, formState.invalid, setTouched, isDirty, eventEmitter]); const onSubmit: KeyboardEventHandler = useCallback( event => { @@ -122,18 +130,22 @@ function DefaultEditorSideBar({ resetValidity(); } }; - vis.on('dirtyStateChange', changeHandler); + eventEmitter.on('dirtyStateChange', changeHandler); - return () => vis.off('dirtyStateChange', changeHandler); - }, [resetValidity, vis]); + return () => { + eventEmitter.off('dirtyStateChange', changeHandler); + }; + }, [resetValidity, eventEmitter]); // subscribe on external vis changes using browser history, for example press back button useEffect(() => { const resetHandler = () => dispatch(discardChanges(vis)); - vis.on('updateEditor', resetHandler); + eventEmitter.on('updateEditor', resetHandler); - return () => vis.off('updateEditor', resetHandler); - }, [dispatch, vis]); + return () => { + eventEmitter.off('updateEditor', resetHandler); + }; + }, [dispatch, vis, eventEmitter]); const dataTabProps = { dispatch, @@ -147,7 +159,7 @@ function DefaultEditorSideBar({ }; const optionTabProps = { - aggs: state.aggs, + aggs: state.data.aggs!, hasHistogramAgg, stateParams: state.params, vis, @@ -173,7 +185,12 @@ function DefaultEditorSideBar({ onKeyDownCapture={onSubmit} > {vis.type.requiresSearch && ( - + )} {optionTabs.length > 1 && ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx index 876404851aed4..575ad5ae2a95c 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/sidebar_title.tsx @@ -18,6 +18,7 @@ */ import React, { useCallback, useState } from 'react'; +import { EventEmitter } from 'events'; import { EuiButton, EuiButtonEmpty, @@ -39,23 +40,24 @@ import { SavedSearch } from '../../../../../../plugins/discover/public'; interface LinkedSearchProps { savedSearch: SavedSearch; - vis: Vis; + eventEmitter: EventEmitter; } interface SidebarTitleProps { isLinkedSearch: boolean; savedSearch?: SavedSearch; vis: Vis; + eventEmitter: EventEmitter; } -export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { +export function LinkedSearch({ savedSearch, eventEmitter }: LinkedSearchProps) { const [showPopover, setShowPopover] = useState(false); const closePopover = useCallback(() => setShowPopover(false), []); const onClickButtonLink = useCallback(() => setShowPopover(v => !v), []); const onClickUnlikFromSavedSearch = useCallback(() => { setShowPopover(false); - vis.emit('unlinkFromSavedSearch'); - }, [vis]); + eventEmitter.emit('unlinkFromSavedSearch'); + }, [eventEmitter]); const linkButtonAriaLabel = i18n.translate( 'visDefaultEditor.sidebar.savedSearch.linkButtonAriaLabel', @@ -151,20 +153,20 @@ export function LinkedSearch({ savedSearch, vis }: LinkedSearchProps) { ); } -function SidebarTitle({ savedSearch, vis, isLinkedSearch }: SidebarTitleProps) { +function SidebarTitle({ savedSearch, vis, isLinkedSearch, eventEmitter }: SidebarTitleProps) { return isLinkedSearch && savedSearch ? ( - + ) : vis.type.options.showIndexSelection ? (

- {vis.indexPattern.title} + {vis.data.indexPattern!.title}

) : ( diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts index f9915bedc8878..e3577218b7e25 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/actions.ts @@ -18,7 +18,7 @@ */ import { Vis, VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { IAggConfig } from '../../../legacy_imports'; +import { IAggConfig } from 'src/plugins/data/public'; import { EditorStateActionTypes } from './constants'; import { Schema } from '../../../schemas'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts index df5ba3f6121c7..11cbc3f93e9d3 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/index.ts @@ -17,42 +17,39 @@ * under the License. */ -import { useEffect, useReducer, useCallback } from 'react'; -import { isEqual } from 'lodash'; +import { useReducer, useCallback } from 'react'; +import { EventEmitter } from 'events'; -import { Vis, VisState, VisParams } from 'src/legacy/core_plugins/visualizations/public'; -import { editorStateReducer, initEditorState } from './reducers'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; +import { createEditorStateReducer, initEditorState, EditorVisState } from './reducers'; import { EditorStateActionTypes } from './constants'; -import { EditorAction, updateStateParams } from './actions'; +import { EditorAction } from './actions'; +import { useKibana } from '../../../../../../../plugins/kibana_react/public'; +import { VisDefaultEditorKibanaServices } from '../../../types'; export * from './editor_form_state'; export * from './actions'; -export function useEditorReducer(vis: Vis): [VisState, React.Dispatch] { - const [state, dispatch] = useReducer(editorStateReducer, vis, initEditorState); - - useEffect(() => { - const handleVisUpdate = (params: VisParams) => { - if (!isEqual(params, state.params)) { - dispatch(updateStateParams(params)); - } - }; - - // fires when visualization state changes, and we need to copy changes to editorState - vis.on('updateEditorStateParams', handleVisUpdate); - - return () => vis.off('updateEditorStateParams', handleVisUpdate); - }, [vis, state.params]); +export function useEditorReducer( + vis: Vis, + eventEmitter: EventEmitter +): [EditorVisState, React.Dispatch] { + const { services } = useKibana(); + const [state, dispatch] = useReducer( + createEditorStateReducer(services.data.search), + vis, + initEditorState + ); const wrappedDispatch = useCallback( (action: EditorAction) => { dispatch(action); - vis.emit('dirtyStateChange', { + eventEmitter.emit('dirtyStateChange', { isDirty: action.type !== EditorStateActionTypes.DISCARD_CHANGES, }); }, - [vis] + [eventEmitter] ); return [state, wrappedDispatch]; diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts index 73675e75cbe36..6e5bec7c69c90 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/components/sidebar/state/reducers.ts @@ -19,33 +19,45 @@ import { cloneDeep } from 'lodash'; -import { Vis, VisState } from 'src/legacy/core_plugins/visualizations/public'; -import { createAggConfigs, AggGroupNames } from '../../../legacy_imports'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public'; +import { AggGroupNames, DataPublicPluginStart } from '../../../../../../../plugins/data/public'; import { EditorStateActionTypes } from './constants'; import { getEnabledMetricAggsCount } from '../../agg_group_helper'; import { EditorAction } from './actions'; function initEditorState(vis: Vis) { - return vis.copyCurrentState(true); + return { + ...vis.clone(), + }; } -function editorStateReducer(state: VisState, action: EditorAction): VisState { +export type EditorVisState = Pick; + +const createEditorStateReducer = ({ + aggs: { createAggConfigs }, +}: DataPublicPluginStart['search']) => ( + state: EditorVisState, + action: EditorAction +): EditorVisState => { switch (action.type) { case EditorStateActionTypes.ADD_NEW_AGG: { const { schema } = action.payload; const defaultConfig = - !state.aggs.aggs.find(agg => agg.schema === schema.name) && schema.defaults + !state.data.aggs!.aggs.find(agg => agg.schema === schema.name) && schema.defaults ? (schema as any).defaults.slice(0, schema.max) : { schema: schema.name }; - const aggConfig = state.aggs.createAggConfig(defaultConfig, { + const aggConfig = state.data.aggs!.createAggConfig(defaultConfig, { addToAggConfigs: false, }); aggConfig.brandNew = true; - const newAggs = [...state.aggs.aggs, aggConfig]; + const newAggs = [...state.data.aggs!.aggs, aggConfig]; return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -56,7 +68,7 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { case EditorStateActionTypes.CHANGE_AGG_TYPE: { const { aggId, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { agg.type = value; @@ -68,14 +80,17 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.SET_AGG_PARAM_VALUE: { const { aggId, paramName, value } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -93,7 +108,10 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -111,7 +129,7 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { case EditorStateActionTypes.REMOVE_AGG: { let isMetric = false; - const newAggs = state.aggs.aggs.filter(({ id, schema }) => { + const newAggs = state.data.aggs!.aggs.filter(({ id, schema }) => { if (id === action.payload.aggId) { const schemaDef = action.payload.schemas.find(s => s.name === schema); if (schemaDef && schemaDef.group === AggGroupNames.Metrics) { @@ -134,26 +152,36 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.REORDER_AGGS: { const { sourceAgg, destinationAgg } = action.payload; - const destinationIndex = state.aggs.aggs.indexOf(destinationAgg); - const newAggs = [...state.aggs.aggs]; - newAggs.splice(destinationIndex, 0, newAggs.splice(state.aggs.aggs.indexOf(sourceAgg), 1)[0]); + const destinationIndex = state.data.aggs!.aggs.indexOf(destinationAgg); + const newAggs = [...state.data.aggs!.aggs]; + newAggs.splice( + destinationIndex, + 0, + newAggs.splice(state.data.aggs!.aggs.indexOf(sourceAgg), 1)[0] + ); return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } case EditorStateActionTypes.TOGGLE_ENABLED_AGG: { const { aggId, enabled } = action.payload; - const newAggs = state.aggs.aggs.map(agg => { + const newAggs = state.data.aggs!.aggs.map(agg => { if (agg.id === aggId) { const parsedAgg = agg.toJSON(); @@ -168,7 +196,10 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { return { ...state, - aggs: createAggConfigs(state.aggs.indexPattern, newAggs), + data: { + ...state.data, + aggs: createAggConfigs(state.data.indexPattern!, newAggs), + }, }; } @@ -181,6 +212,6 @@ function editorStateReducer(state: VisState, action: EditorAction): VisState { }; } } -} +}; -export { editorStateReducer, initEditorState }; +export { createEditorStateReducer, initEditorState }; diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx index fa3213d244e7e..b504dfd6a55e9 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx @@ -20,10 +20,6 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; import { EditorRenderProps } from '../../kibana/public/visualize/np_ready/types'; -import { - VisualizeEmbeddableContract as VisualizeEmbeddable, - VisualizeEmbeddableFactoryContract as VisualizeEmbeddableFactory, -} from '../../visualizations/public/'; import { PanelsContainer, Panel } from '../../../../plugins/kibana_react/public'; import './vis_type_agg_filter'; @@ -32,68 +28,44 @@ import { DefaultEditorControllerState } from './default_editor_controller'; import { getInitialWidth } from './editor_size'; function DefaultEditor({ - embeddable, - savedObj, + vis, uiState, timeRange, filters, - appState, optionTabs, query, + embeddableHandler, + eventEmitter, linked, + savedSearch, }: DefaultEditorControllerState & Omit) { const visRef = useRef(null); - const visHandler = useRef(null); const [isCollapsed, setIsCollapsed] = useState(false); - const [factory, setFactory] = useState(null); - const { vis, savedSearch } = savedObj; const onClickCollapse = useCallback(() => { setIsCollapsed(value => !value); }, []); useEffect(() => { - async function visualize() { - if (!visRef.current || (!visHandler.current && factory)) { - return; - } - - if (!visHandler.current) { - const embeddableFactory = embeddable.getEmbeddableFactory( - 'visualization' - ) as VisualizeEmbeddableFactory; - setFactory(embeddableFactory); - - visHandler.current = (await embeddableFactory.createFromObject(savedObj, { - // should be look through createFromObject interface again because of "id" param - id: '', - uiState, - appState, - timeRange, - filters, - query, - })) as VisualizeEmbeddable; - - visHandler.current.render(visRef.current); - } else { - visHandler.current.updateInput({ - timeRange, - filters, - query, - }); - } + if (!visRef.current) { + return; } - visualize(); - }, [uiState, savedObj, timeRange, filters, appState, query, factory, embeddable]); + embeddableHandler.render(visRef.current); + setTimeout(() => { + eventEmitter.emit('apply'); + }); + + return () => embeddableHandler.destroy(); + }, [embeddableHandler, eventEmitter]); useEffect(() => { - return () => { - if (visHandler.current) { - visHandler.current.destroy(); - } - }; - }, []); + embeddableHandler.updateInput({ + timeRange, + filters, + query, + }); + }, [embeddableHandler, timeRange, filters, query]); const editorInitialWidth = getInitialWidth(vis.type.editorConfig.defaultSize); @@ -120,6 +92,7 @@ function DefaultEditor({ uiState={uiState} isLinkedSearch={linked} savedSearch={savedSearch} + eventEmitter={eventEmitter} /> diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx index db910604eddd1..13fcabd799959 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx @@ -21,18 +21,22 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; +import { EventEmitter } from 'events'; import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; -import { VisSavedObject } from 'src/legacy/core_plugins/visualizations/public/'; +import { Vis } from 'src/legacy/core_plugins/visualizations/public/'; import { Storage } from '../../../../plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; import { DefaultEditor } from './default_editor'; import { DefaultEditorDataTab, OptionTab } from './components/sidebar'; +import { VisualizeEmbeddable } from '../../visualizations/public/np_ready/public/embeddable'; const localStorage = new Storage(window.localStorage); export interface DefaultEditorControllerState { - savedObj: VisSavedObject; + vis: Vis; + eventEmitter: EventEmitter; + embeddableHandler: VisualizeEmbeddable; optionTabs: OptionTab[]; } @@ -40,9 +44,9 @@ class DefaultEditorController { private el: HTMLElement; private state: DefaultEditorControllerState; - constructor(el: HTMLElement, savedObj: VisSavedObject) { + constructor(el: HTMLElement, vis: Vis, eventEmitter: EventEmitter, embeddableHandler: any) { this.el = el; - const { type: visType } = savedObj.vis; + const { type: visType } = vis; const optionTabs = [ ...(visType.schemas.buckets || visType.schemas.metrics @@ -71,8 +75,10 @@ class DefaultEditorController { ]; this.state = { - savedObj, + vis, optionTabs, + eventEmitter, + embeddableHandler, }; } diff --git a/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts b/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts deleted file mode 100644 index 50028d8c970f4..0000000000000 --- a/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts +++ /dev/null @@ -1,47 +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. - */ - -/* `ui/agg_types` dependencies */ -export { BUCKET_TYPES, METRIC_TYPES } from '../../../../plugins/data/public'; -export { - AggGroupNames, - aggGroupNamesMap, - AggParam, - AggParamType, - AggType, - aggTypes, - createAggConfigs, - FieldParamType, - IAggConfig, - IAggConfigs, - IAggGroupNames, - IAggType, - IFieldParamType, - termsAggFilter, -} from 'ui/agg_types'; -export { aggTypeFilters, propFilter } from 'ui/agg_types'; -export { aggTypeFieldFilters } from 'ui/agg_types'; -export { MetricAggType, IMetricAggType } from 'ui/agg_types'; -export { parentPipelineType } from 'ui/agg_types'; -export { siblingPipelineType } from 'ui/agg_types'; -export { isType, isStringType } from 'ui/agg_types'; -export { OptionedValueProp, OptionedParamEditorProps, OptionedParamType } from 'ui/agg_types'; -export { isValidInterval } from 'ui/agg_types'; -export { AggParamOption } from 'ui/agg_types'; -export { CidrMask } from 'ui/agg_types'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/types.ts b/src/legacy/core_plugins/vis_default_editor/public/types.ts new file mode 100644 index 0000000000000..22fc24005994d --- /dev/null +++ b/src/legacy/core_plugins/vis_default_editor/public/types.ts @@ -0,0 +1,24 @@ +/* + * 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 { DataPublicPluginStart } from 'src/plugins/data/public'; + +export interface VisDefaultEditorKibanaServices { + data: DataPublicPluginStart; +} diff --git a/src/legacy/core_plugins/vis_default_editor/public/utils.test.ts b/src/legacy/core_plugins/vis_default_editor/public/utils.test.ts index b050979b7b338..f3912450ba670 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/utils.test.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/utils.test.ts @@ -18,9 +18,7 @@ */ import { groupAndSortBy } from './utils'; -import { AggGroupNames } from './legacy_imports'; - -jest.mock('ui/new_platform'); +import { AggGroupNames } from 'src/plugins/data/public'; const aggs = [ { diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx index 18fbba1b039b5..3239e871a2465 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/vis_options_props.tsx @@ -17,8 +17,8 @@ * under the License. */ -import { PersistedState } from '../../../../plugins/visualizations/public'; -import { IAggConfigs } from './legacy_imports'; +import { PersistedState } from 'src/plugins/visualizations/public'; +import { IAggConfigs } from 'src/plugins/data/public'; import { Vis } from '../../visualizations/public'; export interface VisOptionsProps { diff --git a/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts b/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts index fcb06f73513b0..3ff212c43e6e8 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts +++ b/src/legacy/core_plugins/vis_default_editor/public/vis_type_agg_filter.ts @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { IndexPattern } from 'src/plugins/data/public'; -import { IAggType, IAggConfig, aggTypeFilters, propFilter } from './legacy_imports'; +import { IAggType, IAggConfig, IndexPattern, search } from '../../../../plugins/data/public'; +const { aggTypeFilters, propFilter } = search.aggs; const filterByName = propFilter('name'); /** diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 5bcb2961c42de..103879cb6e6df 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -21,11 +21,6 @@ import React from 'react'; import { render, mount } from 'enzyme'; import { MarkdownVisWrapper } from './markdown_vis_controller'; -// We need Markdown to do these tests, so mock data plugin -jest.mock('../../data/public/legacy', () => { - return {}; -}); - describe('markdown vis controller', () => { it('should set html from markdown params', () => { const vis = { diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.tsx b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.tsx index 4e77bb196b713..3260e9f7d8091 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.tsx +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_vis_controller.tsx @@ -18,7 +18,7 @@ */ import React from 'react'; -import { Markdown } from '../../kibana_react/public'; +import { Markdown } from '../../../../plugins/kibana_react/public'; import { MarkdownVisParams } from './types'; interface MarkdownVisComponentProps extends MarkdownVisParams { diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx index 6a466c9cd0211..7ba4fe017522d 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.test.tsx @@ -20,12 +20,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { Vis } from 'src/legacy/core_plugins/visualizations/public'; import { MetricVisComponent, MetricVisComponentProps } from './metric_vis_component'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { npStart } from 'ui/new_platform'; import { fieldFormats } from '../../../../../plugins/data/public'; import { identity } from 'lodash'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; jest.mock('ui/new_platform'); @@ -37,7 +37,7 @@ const baseVisData = { } as any; describe('MetricVisComponent', function() { - const vis: Vis = { + const vis: ExprVis = { params: { metric: { colorSchema: 'Green to Red', @@ -57,7 +57,7 @@ describe('MetricVisComponent', function() { const getComponent = (propOverrides: Partial = {} as Partial) => { const props: Props = { vis, - visParams: vis.params, + visParams: vis.params as any, visData: baseVisData, renderComplete: jest.fn(), ...propOverrides, diff --git a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx index a93bb618da31f..175458497a05e 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx +++ b/src/legacy/core_plugins/vis_type_metric/public/components/metric_vis_component.tsx @@ -27,12 +27,13 @@ import { FieldFormatsContentType, IFieldFormat } from '../../../../../plugins/da import { KibanaDatatable } from '../../../../../plugins/expressions/public'; import { getHeatmapColors } from '../../../../../plugins/charts/public'; import { VisParams, MetricVisMetric } from '../types'; -import { SchemaConfig, Vis } from '../../../visualizations/public'; +import { SchemaConfig } from '../../../visualizations/public'; +import { ExprVis } from '../../../visualizations/public/np_ready/public/expressions/vis'; export interface MetricVisComponentProps { visParams: VisParams; visData: Input; - vis: Vis; + vis: ExprVis; renderComplete: () => void; } diff --git a/src/legacy/core_plugins/vis_type_metric/public/legacy_imports.ts b/src/legacy/core_plugins/vis_type_metric/public/legacy_imports.ts index b769030a04fb1..cd7a8e740d85d 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/legacy_imports.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/legacy_imports.ts @@ -18,4 +18,3 @@ */ export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; -export { AggGroupNames, Schemas } from 'ui/agg_types'; diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts index 3bddc94929cf5..22c32895d6803 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_fn.test.ts @@ -23,21 +23,8 @@ import { functionWrapper } from '../../../../plugins/expressions/common/expressi jest.mock('ui/new_platform'); -jest.mock('../../vis_default_editor/public/legacy_imports', () => ({ - propFilter: jest.fn(), - AggGroupNames: { - Buckets: 'buckets', - Metrics: 'metrics', - }, - aggTypeFilters: { - addFilter: jest.fn(), - }, - BUCKET_TYPES: { - DATE_HISTOGRAM: 'date_histogram', - }, - METRIC_TYPES: { - TOP_HITS: 'top_hits', - }, +jest.mock('../../vis_default_editor/public', () => ({ + Schemas: class {}, })); describe('interpreter/functions#metric', () => { diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts index 5813465cc3f00..c0bfa47bff502 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.test.ts @@ -36,21 +36,8 @@ import { createMetricVisTypeDefinition } from './metric_vis_type'; jest.mock('ui/new_platform'); -jest.mock('../../vis_default_editor/public/legacy_imports', () => ({ - propFilter: jest.fn(), - AggGroupNames: { - Buckets: 'buckets', - Metrics: 'metrics', - }, - aggTypeFilters: { - addFilter: jest.fn(), - }, - BUCKET_TYPES: { - DATE_HISTOGRAM: 'date_histogram', - }, - METRIC_TYPES: { - TOP_HITS: 'top_hits', - }, +jest.mock('../../vis_default_editor/public', () => ({ + Schemas: class {}, })); describe('metric_vis - createMetricVisTypeDefinition', () => { @@ -74,11 +61,22 @@ describe('metric_vis - createMetricVisTypeDefinition', () => { labelTemplate: 'ip[{{value}}]', }); + const searchSource = { + getField: (name: string) => { + if (name === 'index') { + return stubIndexPattern; + } + }, + }; + // TODO: remove when Vis is converted to typescript. Only importing Vis as type // @ts-ignore - vis = visualizationsStart.createVis(stubIndexPattern, { + vis = visualizationsStart.createVis('metric', { type: 'metric', - aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + data: { + searchSource, + aggs: [{ id: '1', type: 'top_hits', schema: 'metric', params: { field: 'ip' } }], + }, }); vis.params.dimensions = { diff --git a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts index 0b8d9b17659f4..f29164f7e540d 100644 --- a/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_metric/public/metric_vis_type.ts @@ -22,8 +22,9 @@ import { i18n } from '@kbn/i18n'; import { MetricVisComponent } from './components/metric_vis_component'; import { MetricVisOptions } from './components/metric_vis_options'; import { ColorModes } from '../../vis_type_vislib/public'; -import { Schemas, AggGroupNames } from './legacy_imports'; import { ColorSchemas, colorSchemas } from '../../../../plugins/charts/public'; +import { AggGroupNames } from '../../../../plugins/data/public'; +import { Schemas } from '../../vis_default_editor/public'; export const createMetricVisTypeDefinition = () => ({ name: 'metric', diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js index 91581923b05cb..211b79e915038 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js @@ -27,7 +27,8 @@ import { oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative, } from 'fixtures/fake_hierarchical_data'; import sinon from 'sinon'; -import { tabifyAggResponse, npStart } from '../../legacy_imports'; +import { npStart } from '../../legacy_imports'; +import { search } from '../../../../../../plugins/data/public'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { round } from 'lodash'; import { tableVisTypeDefinition } from '../../table_vis_type'; @@ -39,6 +40,8 @@ import { getAngularModule } from '../../get_inner_angular'; import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; import { tableVisResponseHandler } from '../../table_vis_response_handler'; +const { tabifyAggResponse } = search; + describe('Table Vis - AggTable Directive', function() { let $rootScope; let $compile; @@ -47,57 +50,73 @@ describe('Table Vis - AggTable Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('table', { type: 'table', params: { showMetricsAtAllLevels: true, }, - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { type: 'terms', schema: 'bucket', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'bucket', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets, { + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets, { metricsAtAllLevels: true, }); - const vis3 = visualizationsStart.createVis(indexPattern, { + const vis3 = visualizationsStart.createVis('table', { type: 'table', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, - { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, - { - type: 'date_histogram', - schema: 'bucket', - params: { field: '@timestamp', interval: 'd' }, - }, - { - type: 'derivative', - schema: 'metric', - params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, - }, - { - type: 'top_hits', - schema: 'metric', - params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, - }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'min', schema: 'metric', params: { field: '@timestamp' } }, + { type: 'terms', schema: 'bucket', params: { field: 'extension' } }, + { + type: 'date_histogram', + schema: 'bucket', + params: { field: '@timestamp', interval: 'd' }, + }, + { + type: 'derivative', + schema: 'metric', + params: { metricAgg: 'custom', customMetric: { id: '5-orderAgg', type: 'count' } }, + }, + { + type: 'top_hits', + schema: 'metric', + params: { field: 'bytes', aggregate: { val: 'min' }, size: 1 }, + }, + ], + searchSource, + }, }); - vis3.aggs.aggs.forEach(function(agg, i) { + vis3.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); tabifiedData.oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative = tabifyAggResponse( - vis3.aggs, + vis3.data.aggs, oneTermOneHistogramBucketWithTwoMetricsOneTopHitOneDerivative ); }; diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js index 4d62551dcf396..77f817e44ba79 100644 --- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js +++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js @@ -21,13 +21,16 @@ import $ from 'jquery'; import ngMock from 'ng_mock'; import expect from '@kbn/expect'; import { metricOnly, threeTermBuckets } from 'fixtures/fake_hierarchical_data'; -import { tabifyAggResponse, npStart } from '../../legacy_imports'; +import { npStart } from '../../legacy_imports'; +import { search } from '../../../../../../plugins/data/public'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { getAngularModule } from '../../get_inner_angular'; import { initTableVisLegacyModule } from '../../table_vis_legacy_module'; import { tableVisResponseHandler } from '../../table_vis_response_handler'; import { start as visualizationsStart } from '../../../../visualizations/public/np_ready/public/legacy'; +const { tabifyAggResponse } = search; + describe('Table Vis - AggTableGroup Directive', function() { let $rootScope; let $compile; @@ -35,22 +38,35 @@ describe('Table Vis - AggTableGroup Directive', function() { const tabifiedData = {}; const init = () => { - const vis1 = visualizationsStart.createVis(indexPattern, 'table'); - tabifiedData.metricOnly = tabifyAggResponse(vis1.aggs, metricOnly); + const searchSource = { + getField: name => { + if (name === 'index') { + return indexPattern; + } + }, + }; + const vis1 = visualizationsStart.createVis('table', { + type: 'table', + data: { searchSource, aggs: [] }, + }); + tabifiedData.metricOnly = tabifyAggResponse(vis1.data.aggs, metricOnly); - const vis2 = visualizationsStart.createVis(indexPattern, { + const vis2 = visualizationsStart.createVis('pie', { type: 'pie', - aggs: [ - { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, - { type: 'terms', schema: 'split', params: { field: 'extension' } }, - { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, - { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, - ], + data: { + aggs: [ + { type: 'avg', schema: 'metric', params: { field: 'bytes' } }, + { type: 'terms', schema: 'split', params: { field: 'extension' } }, + { type: 'terms', schema: 'segment', params: { field: 'geo.src' } }, + { type: 'terms', schema: 'segment', params: { field: 'machine.os' } }, + ], + searchSource, + }, }); - vis2.aggs.aggs.forEach(function(agg, i) { + vis2.data.aggs.aggs.forEach(function(agg, i) { agg.id = 'agg_' + (i + 1); }); - tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.aggs, threeTermBuckets); + tabifiedData.threeTermBuckets = tabifyAggResponse(vis2.data.aggs, threeTermBuckets); }; const initLocalAngular = () => { diff --git a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx index 8cc0ca2456867..30a9526273166 100644 --- a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx @@ -24,11 +24,13 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { VisOptionsProps } from 'src/legacy/core_plugins/vis_default_editor/public'; -import { tabifyGetColumns } from '../legacy_imports'; +import { search } from '../../../../../plugins/data/public'; import { NumberInputOption, SwitchOption, SelectOption } from '../../../vis_type_vislib/public'; import { TableVisParams } from '../types'; import { totalAggregations } from './utils'; +const { tabifyGetColumns } = search; + function TableOptions({ aggs, stateParams, diff --git a/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts b/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts index 6fb5658d8e815..6208e358b4184 100644 --- a/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts +++ b/src/legacy/core_plugins/vis_type_table/public/get_inner_angular.ts @@ -25,14 +25,14 @@ import 'angular-recursion'; import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; import { CoreStart, LegacyCoreStart, IUiSettingsClient } from 'kibana/public'; import { - PrivateProvider, + initAngularBootstrap, PaginateDirectiveProvider, PaginateControlsDirectiveProvider, + PrivateProvider, watchMultiDecorator, KbnAccessibleClickProvider, configureAppAngularModule, -} from './legacy_imports'; -import { initAngularBootstrap } from '../../../../plugins/kibana_legacy/public'; +} from '../../../../plugins/kibana_legacy/public'; initAngularBootstrap(); diff --git a/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts b/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts index 7b584f8069338..287b6c172ffd9 100644 --- a/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts +++ b/src/legacy/core_plugins/vis_type_table/public/legacy_imports.ts @@ -19,16 +19,3 @@ export { npSetup, npStart } from 'ui/new_platform'; export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; -export { IAggConfig, AggGroupNames, Schemas } from 'ui/agg_types'; -// @ts-ignore -export { PaginateDirectiveProvider } from 'ui/directives/paginate'; -// @ts-ignore -export { PaginateControlsDirectiveProvider } from 'ui/directives/paginate'; -import { search } from '../../../../plugins/data/public'; -export const { tabifyAggResponse, tabifyGetColumns } = search; -export { - configureAppAngularModule, - KbnAccessibleClickProvider, - PrivateProvider, - watchMultiDecorator, -} from '../../../../plugins/kibana_legacy/public'; diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts index 6d4e94c6292a6..ad56607e9296c 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_controller.test.ts @@ -34,8 +34,13 @@ import { stubFields } from '../../../../plugins/data/public/stubs'; import { tableVisResponseHandler } from './table_vis_response_handler'; import { coreMock } from '../../../../core/public/mocks'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { createAggConfigs } from 'ui/agg_types'; -import { tabifyAggResponse, IAggConfig } from './legacy_imports'; +import { npStart } from './legacy_imports'; +import { IAggConfig, search } from '../../../../plugins/data/public'; + +// should be mocked once get rid of 'ui/new_platform' legacy imports +const { createAggConfigs } = npStart.plugins.data.search.aggs; + +const { tabifyAggResponse } = search; jest.mock('ui/new_platform'); jest.mock('../../../../plugins/kibana_legacy/public/angular/angular_config', () => ({ @@ -113,20 +118,22 @@ describe('Table Vis - Controller', () => { return ({ type: tableVisTypeDefinition, params: Object.assign({}, tableVisTypeDefinition.visConfig.defaults, params), - aggs: createAggConfigs(stubIndexPattern, [ - { type: 'count', schema: 'metric' }, - { - type: 'range', - schema: 'bucket', - params: { - field: 'bytes', - ranges: [ - { from: 0, to: 1000 }, - { from: 1000, to: 2000 }, - ], + data: { + aggs: createAggConfigs(stubIndexPattern, [ + { type: 'count', schema: 'metric' }, + { + type: 'range', + schema: 'bucket', + params: { + field: 'bytes', + ranges: [ + { from: 0, to: 1000 }, + { from: 1000, to: 2000 }, + ], + }, }, - }, - ]), + ]), + }, } as unknown) as Vis; } @@ -146,11 +153,11 @@ describe('Table Vis - Controller', () => { // basically a parameterized beforeEach function initController(vis: Vis) { - vis.aggs.aggs.forEach((agg: IAggConfig, i: number) => { + vis.data.aggs!.aggs.forEach((agg: IAggConfig, i: number) => { agg.id = 'agg_' + (i + 1); }); - tabifiedResponse = tabifyAggResponse(vis.aggs, oneRangeBucket); + tabifiedResponse = tabifyAggResponse(vis.data.aggs!, oneRangeBucket); $rootScope.vis = vis; $rootScope.visParams = vis.params; $rootScope.uiState = { diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts index 970bf1ba7ce64..e70b09904253f 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts @@ -18,7 +18,8 @@ */ import { i18n } from '@kbn/i18n'; -import { AggGroupNames, Schemas } from './legacy_imports'; +import { AggGroupNames } from '../../../../plugins/data/public'; +import { Schemas } from '../../vis_default_editor/public'; import { Vis } from '../../visualizations/public'; import { tableVisResponseHandler } from './table_vis_response_handler'; // @ts-ignore diff --git a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts index 2d27a99bdd8af..2feaad9f4e6b6 100644 --- a/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts +++ b/src/legacy/core_plugins/vis_type_table/public/vis_controller.ts @@ -19,12 +19,12 @@ import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; import $ from 'jquery'; -import { isEqual } from 'lodash'; -import { Vis, VisParams } from '../../visualizations/public'; +import { VisParams } from '../../visualizations/public'; import { npStart } from './legacy_imports'; import { getAngularModule } from './get_inner_angular'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; +import { ExprVis } from '../../visualizations/public/np_ready/public/expressions/vis'; const innerAngularName = 'kibana/table_vis'; @@ -32,12 +32,12 @@ export class TableVisualizationController { private tableVisModule: IModule | undefined; private injector: auto.IInjectorService | undefined; el: JQuery; - vis: Vis; + vis: ExprVis; $rootScope: IRootScopeService | null = null; $scope: (IScope & { [key: string]: any }) | undefined; $compile: ICompileService | undefined; - constructor(domeElement: Element, vis: Vis) { + constructor(domeElement: Element, vis: ExprVis) { this.el = $(domeElement); this.vis = vis; } @@ -60,7 +60,7 @@ export class TableVisualizationController { } } - async render(esResponse: object, visParams: VisParams, status: { [key: string]: boolean }) { + async render(esResponse: object, visParams: VisParams) { this.initLocalAngular(); return new Promise(async (resolve, reject) => { @@ -77,15 +77,10 @@ export class TableVisualizationController { this.$scope.visState = { params: visParams }; this.$scope.esResponse = esResponse; - if (!isEqual(this.$scope.visParams, visParams)) { - this.vis.emit('updateEditorStateParams', visParams); - } - this.$scope.visParams = visParams; this.$scope.renderComplete = resolve; this.$scope.renderFailed = reject; this.$scope.resize = Date.now(); - this.$scope.updateStatus = status; this.$scope.$apply(); }; @@ -93,7 +88,7 @@ export class TableVisualizationController { this.$scope = this.$rootScope.$new(); this.$scope.uiState = this.vis.getUiState(); updateScope(); - this.el.find('div').append(this.$compile(this.vis.type.visConfig.template)(this.$scope)); + this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope)); this.$scope.$apply(); } else { updateScope(); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js index 3091b3340cd6d..6f54744a2f508 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js @@ -19,7 +19,6 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import { start as visualizationsStart } from '../../../../../core_plugins/visualizations/public/np_ready/public/legacy'; import { ImageComparator } from 'test_utils/image_comparator'; import { createTagCloudVisualization } from '../tag_cloud_visualization'; @@ -36,7 +35,6 @@ const PIXEL_DIFF = 64; describe('TagCloudVisualizationTest', function() { let domNode; - let indexPattern; let vis; let imageComparator; @@ -66,22 +64,18 @@ describe('TagCloudVisualizationTest', function() { }); beforeEach(ngMock.module('kibana')); - beforeEach( - ngMock.inject(Private => { - indexPattern = Private(LogstashIndexPatternStubProvider); - }) - ); describe('TagCloudVisualization - basics', function() { beforeEach(async function() { setupDOM('512px', '512px'); imageComparator = new ImageComparator(); - vis = visualizationsStart.createVis(indexPattern, { + vis = visualizationsStart.createVis('tagcloud', { type: 'tagcloud', params: { bucket: { accessor: 0, format: {} }, metric: { accessor: 0, format: {} }, }, + data: {}, }); }); diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx index ab7c2cd980c42..a9e816f70cf53 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx @@ -20,11 +20,10 @@ import React from 'react'; import { EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; - +import { ValidatedDualRange } from '../../../../../../src/plugins/kibana_react/public'; import { VisOptionsProps } from '../../../vis_default_editor/public'; import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public'; import { TagCloudVisParams } from '../types'; -import { ValidatedDualRange } from '../legacy_imports'; function TagCloudOptions({ stateParams, setValue, vis }: VisOptionsProps) { const handleFontSizeChange = ([minFontSize, maxFontSize]: [string | number, string | number]) => { diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js index 114643c9a74e0..04f447bf78d50 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_visualization.js @@ -79,17 +79,10 @@ export function createTagCloudVisualization({ colors }) { render(