diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml
index 1d3ea8c5dd4d0..c10bf18e5e917 100644
--- a/.buildkite/ftr_configs.yml
+++ b/.buildkite/ftr_configs.yml
@@ -151,6 +151,7 @@ enabled:
- x-pack/test/functional_synthetics/config.js
- x-pack/test/functional_with_es_ssl/config.ts
- x-pack/test/functional/apps/advanced_settings/config.ts
+ - x-pack/test/functional/apps/aiops/config.ts
- x-pack/test/functional/apps/api_keys/config.ts
- x-pack/test/functional/apps/apm/config.ts
- x-pack/test/functional/apps/canvas/config.ts
@@ -249,6 +250,7 @@ enabled:
- x-pack/test/security_functional/oidc.config.ts
- x-pack/test/security_functional/saml.config.ts
- x-pack/test/security_functional/insecure_cluster_warning.config.ts
+ - x-pack/test/security_functional/user_profiles.config.ts
- x-pack/test/security_solution_endpoint_api_int/config.ts
- x-pack/test/security_solution_endpoint/config.ts
- x-pack/test/session_view/basic/config.ts
diff --git a/.buildkite/pipelines/bazel_cache.yml b/.buildkite/pipelines/bazel_cache.yml
index 9aa961bcddbd2..030443d1e005b 100644
--- a/.buildkite/pipelines/bazel_cache.yml
+++ b/.buildkite/pipelines/bazel_cache.yml
@@ -26,10 +26,18 @@ steps:
concurrency_group: bazel_macos
concurrency: 1
concurrency_method: eager
+ retry:
+ automatic:
+ - exit_status: '*'
+ limit: 1
- command: .buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh
label: Bootstrap (MacOS ARM)
priority: $${PRIORITY}
agents:
queue: macos-arm
timeout_in_minutes: 60
+ retry:
+ automatic:
+ - exit_status: '*'
+ limit: 1
YAML
diff --git a/.buildkite/scripts/bootstrap.sh b/.buildkite/scripts/bootstrap.sh
index b4ec748b863e2..4646da7600ecf 100755
--- a/.buildkite/scripts/bootstrap.sh
+++ b/.buildkite/scripts/bootstrap.sh
@@ -7,6 +7,11 @@ source .buildkite/scripts/common/setup_bazel.sh
echo "--- yarn install and bootstrap"
+BOOTSTRAP_PARAMS=()
+if [[ "${BOOTSTRAP_ALWAYS_FORCE_INSTALL:-}" ]]; then
+ BOOTSTRAP_PARAMS+=(--force-install)
+fi
+
# Use the node_modules that is baked into the agent image, if it exists, as a cache
# But only for agents not mounting the workspace on a local ssd or in memory
# It actually ends up being slower to move all of the tiny files between the disks vs extracting archives from the yarn cache
@@ -15,7 +20,7 @@ if [[ -d ~/.kibana/node_modules && "$(pwd)" != *"/local-ssd/"* && "$(pwd)" != "/
mv ~/.kibana/node_modules ./
fi
-if ! yarn kbn bootstrap; then
+if ! yarn kbn bootstrap "${BOOTSTRAP_PARAMS[@]}"; then
echo "bootstrap failed, trying again in 15 seconds"
sleep 15
diff --git a/.buildkite/scripts/build_kibana.sh b/.buildkite/scripts/build_kibana.sh
index 54e5273eb4c68..90f9da8ac8de4 100755
--- a/.buildkite/scripts/build_kibana.sh
+++ b/.buildkite/scripts/build_kibana.sh
@@ -9,17 +9,12 @@ export KBN_NP_PLUGINS_BUILT=true
echo "--- Build Kibana Distribution"
BUILD_ARGS=""
-if is_pr_with_label "ci:build-all-platforms"; then
- BUILD_ARGS="--all-platforms --skip-os-packages"
-fi
-if is_pr_with_label "ci:build-os-packages"; then
- BUILD_ARGS="--all-platforms --docker-cross-compile"
-fi
-if ! is_pr_with_label "ci:build-canvas-shareable-runtime"; then
- BUILD_ARGS="$BUILD_ARGS --skip-canvas-shareable-runtime"
-fi
-
-node scripts/build "$BUILD_ARGS"
+is_pr_with_label "ci:build-all-platforms" && BUILD_ARGS="--all-platforms"
+is_pr_with_label "ci:build-docker-cross-compile" && BUILD_ARG="$BUILD_ARGS --docker-cross-compile"
+is_pr_with_label "ci:build-os-packages" || BUILD_ARGS="$BUILD_ARGS --skip-os-packages"
+is_pr_with_label "ci:build-canvas-shareable-runtime" || BUILD_ARGS="$BUILD_ARGS --skip-canvas-shareable-runtime"
+is_pr_with_label "ci:build-docker-contexts" || BUILD_ARGS="$BUILD_ARGS --skip-docker-contexts"
+node scripts/build $BUILD_ARGS
if is_pr_with_label "ci:build-cloud-image"; then
echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co
diff --git a/.buildkite/scripts/build_kibana_plugins.sh b/.buildkite/scripts/build_kibana_plugins.sh
index fafd68d86a65d..4e566008b3351 100755
--- a/.buildkite/scripts/build_kibana_plugins.sh
+++ b/.buildkite/scripts/build_kibana_plugins.sh
@@ -3,4 +3,5 @@
set -euo pipefail
echo "--- Build Platform Plugins"
-node scripts/build_kibana_platform_plugins --examples --test-plugins
+THREADS=$(grep -c ^processor /proc/cpuinfo)
+node scripts/build_kibana_platform_plugins --examples --test-plugins --workers "$THREADS" --no-inspect-workers --no-progress
diff --git a/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh b/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh
index ab642ec431486..91886c855402d 100755
--- a/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh
+++ b/.buildkite/scripts/steps/bazel_cache/bootstrap_mac.sh
@@ -7,6 +7,9 @@ source .buildkite/scripts/common/util.sh
export BAZEL_CACHE_MODE=populate-local-gcs
export DISABLE_BOOTSTRAP_VALIDATION=true
+# Because we're manually deleting node_modules and bazel directories in-between runs, we need to --force-install
+export BOOTSTRAP_ALWAYS_FORCE_INSTALL=true
+
# Clear out bazel cache between runs to make sure that any artifacts that don't exist in the cache are uploaded
rm -rf ~/.bazel-cache
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index c51571ebaece6..19d2f1cdb27ef 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -85,6 +85,7 @@
/x-pack/plugins/runtime_fields @elastic/kibana-app-services
/x-pack/test/search_sessions_integration/ @elastic/kibana-app-services
/src/plugins/dashboard/public/application/embeddable/viewport/print_media @elastic/kibana-app-services
+x-pack/plugins/files @elastic/kibana-app-services
### Observability Plugins
diff --git a/STYLEGUIDE.mdx b/STYLEGUIDE.mdx
index b06cfa44a4973..8e043cba92249 100644
--- a/STYLEGUIDE.mdx
+++ b/STYLEGUIDE.mdx
@@ -2,7 +2,7 @@
id: kibStyleGuide
slug: /kibana-dev-docs/contributing/styleguide
title: Style Guide
-summary: JavaScript/TypeScript styleguide.
+description: JavaScript/TypeScript styleguide.
date: 2021-05-06
tags: ['kibana', 'onboarding', 'dev', 'styleguide', 'typescript', 'javascript']
---
diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx
index c1274e9de8d53..f282d76f832a9 100644
--- a/api_docs/actions.mdx
+++ b/api_docs/actions.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibActionsPluginApi
slug: /kibana-dev-docs/api/actions
title: "actions"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the actions plugin
-date: 2022-08-10
+description: API docs for the actions plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import actionsObj from './actions.devdocs.json';
diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx
index 6b898e269d87e..d2ceaab33973d 100644
--- a/api_docs/advanced_settings.mdx
+++ b/api_docs/advanced_settings.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibAdvancedSettingsPluginApi
slug: /kibana-dev-docs/api/advancedSettings
title: "advancedSettings"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the advancedSettings plugin
-date: 2022-08-10
+description: API docs for the advancedSettings plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import advancedSettingsObj from './advanced_settings.devdocs.json';
diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx
index 1612fec6b3e97..187f9343d71c4 100644
--- a/api_docs/aiops.mdx
+++ b/api_docs/aiops.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibAiopsPluginApi
slug: /kibana-dev-docs/api/aiops
title: "aiops"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the aiops plugin
-date: 2022-08-10
+description: API docs for the aiops plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import aiopsObj from './aiops.devdocs.json';
diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx
index f0d87090462c6..dc6b0afa761ed 100644
--- a/api_docs/alerting.mdx
+++ b/api_docs/alerting.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibAlertingPluginApi
slug: /kibana-dev-docs/api/alerting
title: "alerting"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the alerting plugin
-date: 2022-08-10
+description: API docs for the alerting plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import alertingObj from './alerting.devdocs.json';
diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx
index a997550a52c4f..7300c7c4e6e79 100644
--- a/api_docs/apm.mdx
+++ b/api_docs/apm.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibApmPluginApi
slug: /kibana-dev-docs/api/apm
title: "apm"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the apm plugin
-date: 2022-08-10
+description: API docs for the apm plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import apmObj from './apm.devdocs.json';
diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx
index c230845985c7b..0b0ed7407957d 100644
--- a/api_docs/banners.mdx
+++ b/api_docs/banners.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibBannersPluginApi
slug: /kibana-dev-docs/api/banners
title: "banners"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the banners plugin
-date: 2022-08-10
+description: API docs for the banners plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import bannersObj from './banners.devdocs.json';
diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx
index 73e3f00fe1e78..d69a594d888e1 100644
--- a/api_docs/bfetch.mdx
+++ b/api_docs/bfetch.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibBfetchPluginApi
slug: /kibana-dev-docs/api/bfetch
title: "bfetch"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the bfetch plugin
-date: 2022-08-10
+description: API docs for the bfetch plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import bfetchObj from './bfetch.devdocs.json';
diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx
index 95ec1ae2cbe63..e7815d47682ee 100644
--- a/api_docs/canvas.mdx
+++ b/api_docs/canvas.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCanvasPluginApi
slug: /kibana-dev-docs/api/canvas
title: "canvas"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the canvas plugin
-date: 2022-08-10
+description: API docs for the canvas plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import canvasObj from './canvas.devdocs.json';
diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx
index 8aa1a1c9687c5..303a1b51161d5 100644
--- a/api_docs/cases.mdx
+++ b/api_docs/cases.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCasesPluginApi
slug: /kibana-dev-docs/api/cases
title: "cases"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the cases plugin
-date: 2022-08-10
+description: API docs for the cases plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import casesObj from './cases.devdocs.json';
diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx
index a019fbfd8f7cc..2f719228ffca3 100644
--- a/api_docs/charts.mdx
+++ b/api_docs/charts.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibChartsPluginApi
slug: /kibana-dev-docs/api/charts
title: "charts"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the charts plugin
-date: 2022-08-10
+description: API docs for the charts plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import chartsObj from './charts.devdocs.json';
diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx
index aef9a98b87d14..92fb236da4dfe 100644
--- a/api_docs/cloud.mdx
+++ b/api_docs/cloud.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCloudPluginApi
slug: /kibana-dev-docs/api/cloud
title: "cloud"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the cloud plugin
-date: 2022-08-10
+description: API docs for the cloud plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import cloudObj from './cloud.devdocs.json';
diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx
index cdff3aa52f2fa..3187f3c79b136 100644
--- a/api_docs/cloud_security_posture.mdx
+++ b/api_docs/cloud_security_posture.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCloudSecurityPosturePluginApi
slug: /kibana-dev-docs/api/cloudSecurityPosture
title: "cloudSecurityPosture"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the cloudSecurityPosture plugin
-date: 2022-08-10
+description: API docs for the cloudSecurityPosture plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json';
diff --git a/api_docs/console.mdx b/api_docs/console.mdx
index 94d35af8f5f82..c8fa214ebb827 100644
--- a/api_docs/console.mdx
+++ b/api_docs/console.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibConsolePluginApi
slug: /kibana-dev-docs/api/console
title: "console"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the console plugin
-date: 2022-08-10
+description: API docs for the console plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import consoleObj from './console.devdocs.json';
diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx
index 09460acd1b129..3bf15c15f0ecf 100644
--- a/api_docs/controls.mdx
+++ b/api_docs/controls.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibControlsPluginApi
slug: /kibana-dev-docs/api/controls
title: "controls"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the controls plugin
-date: 2022-08-10
+description: API docs for the controls plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import controlsObj from './controls.devdocs.json';
diff --git a/api_docs/core.mdx b/api_docs/core.mdx
index 2f8691e5706b4..3574957c8e0fc 100644
--- a/api_docs/core.mdx
+++ b/api_docs/core.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCorePluginApi
slug: /kibana-dev-docs/api/core
title: "core"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the core plugin
-date: 2022-08-10
+description: API docs for the core plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import coreObj from './core.devdocs.json';
diff --git a/api_docs/core_application.mdx b/api_docs/core_application.mdx
index 351723d723c6b..c3589c46a0469 100644
--- a/api_docs/core_application.mdx
+++ b/api_docs/core_application.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCoreApplicationPluginApi
slug: /kibana-dev-docs/api/core-application
title: "core.application"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the core.application plugin
-date: 2022-08-10
+description: API docs for the core.application plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.application']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import coreApplicationObj from './core_application.devdocs.json';
diff --git a/api_docs/core_chrome.mdx b/api_docs/core_chrome.mdx
index abfb4f3cda316..7bace2a507a6c 100644
--- a/api_docs/core_chrome.mdx
+++ b/api_docs/core_chrome.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCoreChromePluginApi
slug: /kibana-dev-docs/api/core-chrome
title: "core.chrome"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the core.chrome plugin
-date: 2022-08-10
+description: API docs for the core.chrome plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.chrome']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import coreChromeObj from './core_chrome.devdocs.json';
diff --git a/api_docs/core_saved_objects.mdx b/api_docs/core_saved_objects.mdx
index d84d7af14c1ee..6fcd60f4851a4 100644
--- a/api_docs/core_saved_objects.mdx
+++ b/api_docs/core_saved_objects.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCoreSavedObjectsPluginApi
slug: /kibana-dev-docs/api/core-savedObjects
title: "core.savedObjects"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the core.savedObjects plugin
-date: 2022-08-10
+description: API docs for the core.savedObjects plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.savedObjects']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import coreSavedObjectsObj from './core_saved_objects.devdocs.json';
diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx
index 86a28528ef9ef..43bfe0acae309 100644
--- a/api_docs/custom_integrations.mdx
+++ b/api_docs/custom_integrations.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibCustomIntegrationsPluginApi
slug: /kibana-dev-docs/api/customIntegrations
title: "customIntegrations"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the customIntegrations plugin
-date: 2022-08-10
+description: API docs for the customIntegrations plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import customIntegrationsObj from './custom_integrations.devdocs.json';
diff --git a/api_docs/dashboard.devdocs.json b/api_docs/dashboard.devdocs.json
index cf48ab9df40cd..01decee7cd29b 100644
--- a/api_docs/dashboard.devdocs.json
+++ b/api_docs/dashboard.devdocs.json
@@ -81,6 +81,82 @@
"path": "src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx",
"deprecated": false
},
+ {
+ "parentPluginId": "dashboard",
+ "id": "def-public.DashboardContainer.getAllDataViews",
+ "type": "Function",
+ "tags": [],
+ "label": "getAllDataViews",
+ "description": [
+ "\nGets all the dataviews that are actively being used in the dashboard"
+ ],
+ "signature": [
+ "() => ",
+ {
+ "pluginId": "dataViews",
+ "scope": "common",
+ "docId": "kibDataViewsPluginApi",
+ "section": "def-common.DataView",
+ "text": "DataView"
+ },
+ "[]"
+ ],
+ "path": "src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx",
+ "deprecated": false,
+ "children": [],
+ "returnComment": [
+ "An array of dataviews"
+ ]
+ },
+ {
+ "parentPluginId": "dashboard",
+ "id": "def-public.DashboardContainer.setAllDataViews",
+ "type": "Function",
+ "tags": [],
+ "label": "setAllDataViews",
+ "description": [
+ "\nUse this to set the dataviews that are used in the dashboard when they change/update"
+ ],
+ "signature": [
+ "(newDataViews: ",
+ {
+ "pluginId": "dataViews",
+ "scope": "common",
+ "docId": "kibDataViewsPluginApi",
+ "section": "def-common.DataView",
+ "text": "DataView"
+ },
+ "[]) => void"
+ ],
+ "path": "src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "dashboard",
+ "id": "def-public.DashboardContainer.setAllDataViews.$1",
+ "type": "Array",
+ "tags": [],
+ "label": "newDataViews",
+ "description": [
+ "The new array of dataviews that will overwrite the old dataviews array"
+ ],
+ "signature": [
+ {
+ "pluginId": "dataViews",
+ "scope": "common",
+ "docId": "kibDataViewsPluginApi",
+ "section": "def-common.DataView",
+ "text": "DataView"
+ },
+ "[]"
+ ],
+ "path": "src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx",
+ "deprecated": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": []
+ },
{
"parentPluginId": "dashboard",
"id": "def-public.DashboardContainer.getPanelCount",
diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx
index 0850ff066d082..e9b89abcc6115 100644
--- a/api_docs/dashboard.mdx
+++ b/api_docs/dashboard.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDashboardPluginApi
slug: /kibana-dev-docs/api/dashboard
title: "dashboard"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dashboard plugin
-date: 2022-08-10
+description: API docs for the dashboard plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dashboardObj from './dashboard.devdocs.json';
@@ -18,7 +21,7 @@ Contact [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-prese
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 143 | 0 | 141 | 12 |
+| 146 | 0 | 141 | 12 |
## Client
diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx
index 9a4d938edfb2d..9e9e9022ad468 100644
--- a/api_docs/dashboard_enhanced.mdx
+++ b/api_docs/dashboard_enhanced.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDashboardEnhancedPluginApi
slug: /kibana-dev-docs/api/dashboardEnhanced
title: "dashboardEnhanced"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dashboardEnhanced plugin
-date: 2022-08-10
+description: API docs for the dashboardEnhanced plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json';
diff --git a/api_docs/data.mdx b/api_docs/data.mdx
index f9674f514c206..e99dae2e55978 100644
--- a/api_docs/data.mdx
+++ b/api_docs/data.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataPluginApi
slug: /kibana-dev-docs/api/data
title: "data"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the data plugin
-date: 2022-08-10
+description: API docs for the data plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataObj from './data.devdocs.json';
diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx
index 29460e1bd559d..e42c8927f3847 100644
--- a/api_docs/data_query.mdx
+++ b/api_docs/data_query.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataQueryPluginApi
slug: /kibana-dev-docs/api/data-query
title: "data.query"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the data.query plugin
-date: 2022-08-10
+description: API docs for the data.query plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataQueryObj from './data_query.devdocs.json';
diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx
index d2f2f7bc0829b..01c72585f1aa3 100644
--- a/api_docs/data_search.mdx
+++ b/api_docs/data_search.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataSearchPluginApi
slug: /kibana-dev-docs/api/data-search
title: "data.search"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the data.search plugin
-date: 2022-08-10
+description: API docs for the data.search plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataSearchObj from './data_search.devdocs.json';
diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx
index 2ad5853bb2f40..1e6e529149989 100644
--- a/api_docs/data_view_editor.mdx
+++ b/api_docs/data_view_editor.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataViewEditorPluginApi
slug: /kibana-dev-docs/api/dataViewEditor
title: "dataViewEditor"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dataViewEditor plugin
-date: 2022-08-10
+description: API docs for the dataViewEditor plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataViewEditorObj from './data_view_editor.devdocs.json';
diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx
index 5a4e3653b0aea..b2581e4f92242 100644
--- a/api_docs/data_view_field_editor.mdx
+++ b/api_docs/data_view_field_editor.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataViewFieldEditorPluginApi
slug: /kibana-dev-docs/api/dataViewFieldEditor
title: "dataViewFieldEditor"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dataViewFieldEditor plugin
-date: 2022-08-10
+description: API docs for the dataViewFieldEditor plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json';
diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx
index 942deac343a77..8d9911745c4d3 100644
--- a/api_docs/data_view_management.mdx
+++ b/api_docs/data_view_management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataViewManagementPluginApi
slug: /kibana-dev-docs/api/dataViewManagement
title: "dataViewManagement"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dataViewManagement plugin
-date: 2022-08-10
+description: API docs for the dataViewManagement plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataViewManagementObj from './data_view_management.devdocs.json';
diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx
index d129adeffd608..6bb7f9213f889 100644
--- a/api_docs/data_views.mdx
+++ b/api_docs/data_views.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataViewsPluginApi
slug: /kibana-dev-docs/api/dataViews
title: "dataViews"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dataViews plugin
-date: 2022-08-10
+description: API docs for the dataViews plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataViewsObj from './data_views.devdocs.json';
diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx
index 926edb474e954..c779357745331 100644
--- a/api_docs/data_visualizer.mdx
+++ b/api_docs/data_visualizer.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDataVisualizerPluginApi
slug: /kibana-dev-docs/api/dataVisualizer
title: "dataVisualizer"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the dataVisualizer plugin
-date: 2022-08-10
+description: API docs for the dataVisualizer plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import dataVisualizerObj from './data_visualizer.devdocs.json';
diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx
index 153eae57516ff..aa4ecef1c0dad 100644
--- a/api_docs/deprecations_by_api.mdx
+++ b/api_docs/deprecations_by_api.mdx
@@ -1,11 +1,14 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDevDocsDeprecationsByApi
slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api
title: Deprecated API usage by API
-summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
-date: 2022-08-10
+description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
## Referenced deprecated APIs
@@ -96,7 +99,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
This is relied on by the reporting feature, and should be removed once reporting
migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/issues/19914 |
-
+
## Unreferenced deprecated APIs
diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx
index e58b5ba0a4aa2..40935bd3a4ec6 100644
--- a/api_docs/deprecations_by_plugin.mdx
+++ b/api_docs/deprecations_by_plugin.mdx
@@ -1,11 +1,14 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDevDocsDeprecationsByPlugin
slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin
title: Deprecated API usage by plugin
-summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
-date: 2022-08-10
+description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx
index 86c110b553d6b..55fe21009f1a0 100644
--- a/api_docs/deprecations_by_team.mdx
+++ b/api_docs/deprecations_by_team.mdx
@@ -1,11 +1,14 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDevDocsDeprecationsDueByTeam
slug: /kibana-dev-docs/api-meta/deprecations-due-by-team
title: Deprecated APIs due to be removed, by team
-summary: Lists the teams that are referencing deprecated APIs with a remove by date.
-date: 2022-08-10
+description: Lists the teams that are referencing deprecated APIs with a remove by date.
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx
index 8d0eb77ba41c5..13dad9769e26a 100644
--- a/api_docs/dev_tools.mdx
+++ b/api_docs/dev_tools.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDevToolsPluginApi
slug: /kibana-dev-docs/api/devTools
title: "devTools"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the devTools plugin
-date: 2022-08-10
+description: API docs for the devTools plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import devToolsObj from './dev_tools.devdocs.json';
diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx
index b9ca0d5091db0..d95e7b4b4ec07 100644
--- a/api_docs/discover.mdx
+++ b/api_docs/discover.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDiscoverPluginApi
slug: /kibana-dev-docs/api/discover
title: "discover"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the discover plugin
-date: 2022-08-10
+description: API docs for the discover plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import discoverObj from './discover.devdocs.json';
diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx
index b50a8b5a34fcc..37520938fdd5a 100644
--- a/api_docs/discover_enhanced.mdx
+++ b/api_docs/discover_enhanced.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDiscoverEnhancedPluginApi
slug: /kibana-dev-docs/api/discoverEnhanced
title: "discoverEnhanced"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the discoverEnhanced plugin
-date: 2022-08-10
+description: API docs for the discoverEnhanced plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import discoverEnhancedObj from './discover_enhanced.devdocs.json';
diff --git a/api_docs/elastic_apm_synthtrace.mdx b/api_docs/elastic_apm_synthtrace.mdx
index 4c82dfcb262a8..513b14bbf25b0 100644
--- a/api_docs/elastic_apm_synthtrace.mdx
+++ b/api_docs/elastic_apm_synthtrace.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibElasticApmSynthtracePluginApi
slug: /kibana-dev-docs/api/elastic-apm-synthtrace
title: "@elastic/apm-synthtrace"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @elastic/apm-synthtrace plugin
-date: 2022-08-10
+description: API docs for the @elastic/apm-synthtrace plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-synthtrace']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import elasticApmSynthtraceObj from './elastic_apm_synthtrace.devdocs.json';
diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json
index ed0bc94fae658..15b274a52b3c1 100644
--- a/api_docs/embeddable.devdocs.json
+++ b/api_docs/embeddable.devdocs.json
@@ -4798,6 +4798,43 @@
"returnComment": [],
"initialIsOpen": false
},
+ {
+ "parentPluginId": "embeddable",
+ "id": "def-public.isFilterableEmbeddable",
+ "type": "Function",
+ "tags": [],
+ "label": "isFilterableEmbeddable",
+ "description": [
+ "\nEnsure that embeddable supports filtering/querying"
+ ],
+ "signature": [
+ "(incoming: unknown) => boolean"
+ ],
+ "path": "src/plugins/embeddable/public/lib/filterable_embeddable/types.ts",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "embeddable",
+ "id": "def-public.isFilterableEmbeddable.$1",
+ "type": "Unknown",
+ "tags": [],
+ "label": "incoming",
+ "description": [
+ "Embeddable that is being tested to check if it is a FilterableEmbeddable"
+ ],
+ "signature": [
+ "unknown"
+ ],
+ "path": "src/plugins/embeddable/public/lib/filterable_embeddable/types.ts",
+ "deprecated": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": [
+ "true if the incoming embeddable is a FilterableEmbeddable, false if it is not"
+ ],
+ "initialIsOpen": false
+ },
{
"parentPluginId": "embeddable",
"id": "def-public.isRangeSelectTriggerContext",
@@ -7430,6 +7467,61 @@
],
"initialIsOpen": false
},
+ {
+ "parentPluginId": "embeddable",
+ "id": "def-public.FilterableEmbeddable",
+ "type": "Interface",
+ "tags": [],
+ "label": "FilterableEmbeddable",
+ "description": [
+ "\nAll embeddables that implement this interface should support being filtered\nand/or queried via the top navigation bar"
+ ],
+ "path": "src/plugins/embeddable/public/lib/filterable_embeddable/types.ts",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "embeddable",
+ "id": "def-public.FilterableEmbeddable.getFilters",
+ "type": "Function",
+ "tags": [],
+ "label": "getFilters",
+ "description": [
+ "\nGets the embeddable's local filters"
+ ],
+ "signature": [
+ "() => Promise<",
+ "Filter",
+ "[]>"
+ ],
+ "path": "src/plugins/embeddable/public/lib/filterable_embeddable/types.ts",
+ "deprecated": false,
+ "children": [],
+ "returnComment": []
+ },
+ {
+ "parentPluginId": "embeddable",
+ "id": "def-public.FilterableEmbeddable.getQuery",
+ "type": "Function",
+ "tags": [],
+ "label": "getQuery",
+ "description": [
+ "\nGets the embeddable's local query"
+ ],
+ "signature": [
+ "() => Promise<",
+ "Query",
+ " | ",
+ "AggregateQuery",
+ " | undefined>"
+ ],
+ "path": "src/plugins/embeddable/public/lib/filterable_embeddable/types.ts",
+ "deprecated": false,
+ "children": [],
+ "returnComment": []
+ }
+ ],
+ "initialIsOpen": false
+ },
{
"parentPluginId": "embeddable",
"id": "def-public.IContainer",
diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx
index ed91daaafbb5a..c2980c7c90f92 100644
--- a/api_docs/embeddable.mdx
+++ b/api_docs/embeddable.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEmbeddablePluginApi
slug: /kibana-dev-docs/api/embeddable
title: "embeddable"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the embeddable plugin
-date: 2022-08-10
+description: API docs for the embeddable plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import embeddableObj from './embeddable.devdocs.json';
@@ -18,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 507 | 0 | 413 | 4 |
+| 512 | 0 | 413 | 4 |
## Client
diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx
index 91e5f95beee98..4953a59facca6 100644
--- a/api_docs/embeddable_enhanced.mdx
+++ b/api_docs/embeddable_enhanced.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEmbeddableEnhancedPluginApi
slug: /kibana-dev-docs/api/embeddableEnhanced
title: "embeddableEnhanced"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the embeddableEnhanced plugin
-date: 2022-08-10
+description: API docs for the embeddableEnhanced plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json';
diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx
index 1d7d67c0a6928..82db857f64353 100644
--- a/api_docs/encrypted_saved_objects.mdx
+++ b/api_docs/encrypted_saved_objects.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEncryptedSavedObjectsPluginApi
slug: /kibana-dev-docs/api/encryptedSavedObjects
title: "encryptedSavedObjects"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the encryptedSavedObjects plugin
-date: 2022-08-10
+description: API docs for the encryptedSavedObjects plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json';
diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx
index a544cb6aeda42..be1cc389b67f2 100644
--- a/api_docs/enterprise_search.mdx
+++ b/api_docs/enterprise_search.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEnterpriseSearchPluginApi
slug: /kibana-dev-docs/api/enterpriseSearch
title: "enterpriseSearch"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the enterpriseSearch plugin
-date: 2022-08-10
+description: API docs for the enterpriseSearch plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import enterpriseSearchObj from './enterprise_search.devdocs.json';
diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx
index 152bbc8e6a05c..5985f4ac49506 100644
--- a/api_docs/es_ui_shared.mdx
+++ b/api_docs/es_ui_shared.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEsUiSharedPluginApi
slug: /kibana-dev-docs/api/esUiShared
title: "esUiShared"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the esUiShared plugin
-date: 2022-08-10
+description: API docs for the esUiShared plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import esUiSharedObj from './es_ui_shared.devdocs.json';
diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx
index 4ae46dc78dddc..882ec361bdb70 100644
--- a/api_docs/event_annotation.mdx
+++ b/api_docs/event_annotation.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEventAnnotationPluginApi
slug: /kibana-dev-docs/api/eventAnnotation
title: "eventAnnotation"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the eventAnnotation plugin
-date: 2022-08-10
+description: API docs for the eventAnnotation plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import eventAnnotationObj from './event_annotation.devdocs.json';
diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx
index 810257e6bd754..169240a4e31f1 100644
--- a/api_docs/event_log.mdx
+++ b/api_docs/event_log.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibEventLogPluginApi
slug: /kibana-dev-docs/api/eventLog
title: "eventLog"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the eventLog plugin
-date: 2022-08-10
+description: API docs for the eventLog plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import eventLogObj from './event_log.devdocs.json';
diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx
index 14425f584cf13..c26dd9d602518 100644
--- a/api_docs/expression_error.mdx
+++ b/api_docs/expression_error.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionErrorPluginApi
slug: /kibana-dev-docs/api/expressionError
title: "expressionError"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionError plugin
-date: 2022-08-10
+description: API docs for the expressionError plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionErrorObj from './expression_error.devdocs.json';
diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx
index 20a1cf38142fc..805db130b3635 100644
--- a/api_docs/expression_gauge.mdx
+++ b/api_docs/expression_gauge.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionGaugePluginApi
slug: /kibana-dev-docs/api/expressionGauge
title: "expressionGauge"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionGauge plugin
-date: 2022-08-10
+description: API docs for the expressionGauge plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionGaugeObj from './expression_gauge.devdocs.json';
diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx
index 7b6c454387525..6d4d4c5bc3797 100644
--- a/api_docs/expression_heatmap.mdx
+++ b/api_docs/expression_heatmap.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionHeatmapPluginApi
slug: /kibana-dev-docs/api/expressionHeatmap
title: "expressionHeatmap"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionHeatmap plugin
-date: 2022-08-10
+description: API docs for the expressionHeatmap plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionHeatmapObj from './expression_heatmap.devdocs.json';
diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx
index 6e44f7e1925bd..ccb91e5f51b84 100644
--- a/api_docs/expression_image.mdx
+++ b/api_docs/expression_image.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionImagePluginApi
slug: /kibana-dev-docs/api/expressionImage
title: "expressionImage"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionImage plugin
-date: 2022-08-10
+description: API docs for the expressionImage plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionImageObj from './expression_image.devdocs.json';
diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx
index 66f01446ec898..827dfeb0783b1 100644
--- a/api_docs/expression_legacy_metric_vis.mdx
+++ b/api_docs/expression_legacy_metric_vis.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionLegacyMetricVisPluginApi
slug: /kibana-dev-docs/api/expressionLegacyMetricVis
title: "expressionLegacyMetricVis"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionLegacyMetricVis plugin
-date: 2022-08-10
+description: API docs for the expressionLegacyMetricVis plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json';
diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx
index c84e3ebe07e28..0fc049cd34fd8 100644
--- a/api_docs/expression_metric.mdx
+++ b/api_docs/expression_metric.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionMetricPluginApi
slug: /kibana-dev-docs/api/expressionMetric
title: "expressionMetric"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionMetric plugin
-date: 2022-08-10
+description: API docs for the expressionMetric plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionMetricObj from './expression_metric.devdocs.json';
diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx
index fe81d139d71e6..d865c607d2a79 100644
--- a/api_docs/expression_metric_vis.mdx
+++ b/api_docs/expression_metric_vis.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionMetricVisPluginApi
slug: /kibana-dev-docs/api/expressionMetricVis
title: "expressionMetricVis"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionMetricVis plugin
-date: 2022-08-10
+description: API docs for the expressionMetricVis plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionMetricVisObj from './expression_metric_vis.devdocs.json';
diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx
index 1e14f753c20ef..f376d7efbd3c0 100644
--- a/api_docs/expression_partition_vis.mdx
+++ b/api_docs/expression_partition_vis.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionPartitionVisPluginApi
slug: /kibana-dev-docs/api/expressionPartitionVis
title: "expressionPartitionVis"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionPartitionVis plugin
-date: 2022-08-10
+description: API docs for the expressionPartitionVis plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionPartitionVisObj from './expression_partition_vis.devdocs.json';
diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx
index c1a77887e01bc..35cadf9482078 100644
--- a/api_docs/expression_repeat_image.mdx
+++ b/api_docs/expression_repeat_image.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionRepeatImagePluginApi
slug: /kibana-dev-docs/api/expressionRepeatImage
title: "expressionRepeatImage"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionRepeatImage plugin
-date: 2022-08-10
+description: API docs for the expressionRepeatImage plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionRepeatImageObj from './expression_repeat_image.devdocs.json';
diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx
index ffe31cd906521..c4093b827de57 100644
--- a/api_docs/expression_reveal_image.mdx
+++ b/api_docs/expression_reveal_image.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionRevealImagePluginApi
slug: /kibana-dev-docs/api/expressionRevealImage
title: "expressionRevealImage"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionRevealImage plugin
-date: 2022-08-10
+description: API docs for the expressionRevealImage plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionRevealImageObj from './expression_reveal_image.devdocs.json';
diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx
index 22ac6f5aa8f4c..91c67dcaabba9 100644
--- a/api_docs/expression_shape.mdx
+++ b/api_docs/expression_shape.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionShapePluginApi
slug: /kibana-dev-docs/api/expressionShape
title: "expressionShape"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionShape plugin
-date: 2022-08-10
+description: API docs for the expressionShape plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionShapeObj from './expression_shape.devdocs.json';
diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx
index ae2e7c6c172b1..44b99db0d35e3 100644
--- a/api_docs/expression_tagcloud.mdx
+++ b/api_docs/expression_tagcloud.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionTagcloudPluginApi
slug: /kibana-dev-docs/api/expressionTagcloud
title: "expressionTagcloud"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionTagcloud plugin
-date: 2022-08-10
+description: API docs for the expressionTagcloud plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionTagcloudObj from './expression_tagcloud.devdocs.json';
diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx
index abef8921098c4..dffc294756819 100644
--- a/api_docs/expression_x_y.mdx
+++ b/api_docs/expression_x_y.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionXYPluginApi
slug: /kibana-dev-docs/api/expressionXY
title: "expressionXY"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressionXY plugin
-date: 2022-08-10
+description: API docs for the expressionXY plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionXYObj from './expression_x_y.devdocs.json';
diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx
index 8265dab8d0b62..5ce386f8a2f49 100644
--- a/api_docs/expressions.mdx
+++ b/api_docs/expressions.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibExpressionsPluginApi
slug: /kibana-dev-docs/api/expressions
title: "expressions"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the expressions plugin
-date: 2022-08-10
+description: API docs for the expressions plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import expressionsObj from './expressions.devdocs.json';
diff --git a/api_docs/features.mdx b/api_docs/features.mdx
index 4dbf73d2e9894..2393f30a5b9a0 100644
--- a/api_docs/features.mdx
+++ b/api_docs/features.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibFeaturesPluginApi
slug: /kibana-dev-docs/api/features
title: "features"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the features plugin
-date: 2022-08-10
+description: API docs for the features plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import featuresObj from './features.devdocs.json';
diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx
index 1ed0f87b87f7c..b90819ea8f5aa 100644
--- a/api_docs/field_formats.mdx
+++ b/api_docs/field_formats.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibFieldFormatsPluginApi
slug: /kibana-dev-docs/api/fieldFormats
title: "fieldFormats"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the fieldFormats plugin
-date: 2022-08-10
+description: API docs for the fieldFormats plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import fieldFormatsObj from './field_formats.devdocs.json';
diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx
index 23ef42b26d43d..9d9e0eb35894c 100644
--- a/api_docs/file_upload.mdx
+++ b/api_docs/file_upload.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibFileUploadPluginApi
slug: /kibana-dev-docs/api/fileUpload
title: "fileUpload"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the fileUpload plugin
-date: 2022-08-10
+description: API docs for the fileUpload plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import fileUploadObj from './file_upload.devdocs.json';
diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx
index 80b0f42943529..9bb727824c189 100644
--- a/api_docs/fleet.mdx
+++ b/api_docs/fleet.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibFleetPluginApi
slug: /kibana-dev-docs/api/fleet
title: "fleet"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the fleet plugin
-date: 2022-08-10
+description: API docs for the fleet plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import fleetObj from './fleet.devdocs.json';
diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx
index fc2c49c06221c..33748702b61b8 100644
--- a/api_docs/global_search.mdx
+++ b/api_docs/global_search.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibGlobalSearchPluginApi
slug: /kibana-dev-docs/api/globalSearch
title: "globalSearch"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the globalSearch plugin
-date: 2022-08-10
+description: API docs for the globalSearch plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import globalSearchObj from './global_search.devdocs.json';
diff --git a/api_docs/home.mdx b/api_docs/home.mdx
index 89c35468ff05d..cd3147cc301bd 100644
--- a/api_docs/home.mdx
+++ b/api_docs/home.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibHomePluginApi
slug: /kibana-dev-docs/api/home
title: "home"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the home plugin
-date: 2022-08-10
+description: API docs for the home plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import homeObj from './home.devdocs.json';
diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx
index a0569cdca5081..e828742670e19 100644
--- a/api_docs/index_lifecycle_management.mdx
+++ b/api_docs/index_lifecycle_management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibIndexLifecycleManagementPluginApi
slug: /kibana-dev-docs/api/indexLifecycleManagement
title: "indexLifecycleManagement"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the indexLifecycleManagement plugin
-date: 2022-08-10
+description: API docs for the indexLifecycleManagement plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json';
diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx
index eb738f4c646d3..c4d0c091519f7 100644
--- a/api_docs/index_management.mdx
+++ b/api_docs/index_management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibIndexManagementPluginApi
slug: /kibana-dev-docs/api/indexManagement
title: "indexManagement"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the indexManagement plugin
-date: 2022-08-10
+description: API docs for the indexManagement plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import indexManagementObj from './index_management.devdocs.json';
diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx
index 7723a94c95620..58f393c23bc6f 100644
--- a/api_docs/infra.mdx
+++ b/api_docs/infra.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibInfraPluginApi
slug: /kibana-dev-docs/api/infra
title: "infra"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the infra plugin
-date: 2022-08-10
+description: API docs for the infra plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import infraObj from './infra.devdocs.json';
diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx
index 9d1b8650276ba..5b5f9f42f9bdc 100644
--- a/api_docs/inspector.mdx
+++ b/api_docs/inspector.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibInspectorPluginApi
slug: /kibana-dev-docs/api/inspector
title: "inspector"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the inspector plugin
-date: 2022-08-10
+description: API docs for the inspector plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import inspectorObj from './inspector.devdocs.json';
diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx
index d08e8b4873224..76159a88a4046 100644
--- a/api_docs/interactive_setup.mdx
+++ b/api_docs/interactive_setup.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibInteractiveSetupPluginApi
slug: /kibana-dev-docs/api/interactiveSetup
title: "interactiveSetup"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the interactiveSetup plugin
-date: 2022-08-10
+description: API docs for the interactiveSetup plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import interactiveSetupObj from './interactive_setup.devdocs.json';
diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx
index 059821a6ee8b6..ad13f5ee9c2d0 100644
--- a/api_docs/kbn_ace.mdx
+++ b/api_docs/kbn_ace.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAcePluginApi
slug: /kibana-dev-docs/api/kbn-ace
title: "@kbn/ace"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ace plugin
-date: 2022-08-10
+description: API docs for the @kbn/ace plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAceObj from './kbn_ace.devdocs.json';
diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx
index 4c1649eb8c953..d52a5f6b909c3 100644
--- a/api_docs/kbn_aiops_components.mdx
+++ b/api_docs/kbn_aiops_components.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAiopsComponentsPluginApi
slug: /kibana-dev-docs/api/kbn-aiops-components
title: "@kbn/aiops-components"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/aiops-components plugin
-date: 2022-08-10
+description: API docs for the @kbn/aiops-components plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json';
diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx
index 97da08a9e054e..149c07f9a6653 100644
--- a/api_docs/kbn_aiops_utils.mdx
+++ b/api_docs/kbn_aiops_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAiopsUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-aiops-utils
title: "@kbn/aiops-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/aiops-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/aiops-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json';
diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx
index 712f797450c93..4e3fd64430fe4 100644
--- a/api_docs/kbn_alerts.mdx
+++ b/api_docs/kbn_alerts.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAlertsPluginApi
slug: /kibana-dev-docs/api/kbn-alerts
title: "@kbn/alerts"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/alerts plugin
-date: 2022-08-10
+description: API docs for the @kbn/alerts plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAlertsObj from './kbn_alerts.devdocs.json';
diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx
index 0871cfe033afe..441f3eb3db741 100644
--- a/api_docs/kbn_analytics.mdx
+++ b/api_docs/kbn_analytics.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsPluginApi
slug: /kibana-dev-docs/api/kbn-analytics
title: "@kbn/analytics"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsObj from './kbn_analytics.devdocs.json';
diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx
index b7cd57c8cb350..c1f06d561d044 100644
--- a/api_docs/kbn_analytics_client.mdx
+++ b/api_docs/kbn_analytics_client.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsClientPluginApi
slug: /kibana-dev-docs/api/kbn-analytics-client
title: "@kbn/analytics-client"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics-client plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics-client plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json';
diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx
index 12c7c41b9010d..d9fab71d98594 100644
--- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx
+++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsShippersElasticV3BrowserPluginApi
slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser
title: "@kbn/analytics-shippers-elastic-v3-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json';
diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx
index 673437126d94f..2201f02c57558 100644
--- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx
+++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsShippersElasticV3CommonPluginApi
slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common
title: "@kbn/analytics-shippers-elastic-v3-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json';
diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx
index 52b8887fae27f..8e48be19e49b8 100644
--- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx
+++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsShippersElasticV3ServerPluginApi
slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server
title: "@kbn/analytics-shippers-elastic-v3-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json';
diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx
index b00cba99dc65d..0f8b6675aa3b3 100644
--- a/api_docs/kbn_analytics_shippers_fullstory.mdx
+++ b/api_docs/kbn_analytics_shippers_fullstory.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAnalyticsShippersFullstoryPluginApi
slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory
title: "@kbn/analytics-shippers-fullstory"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/analytics-shippers-fullstory plugin
-date: 2022-08-10
+description: API docs for the @kbn/analytics-shippers-fullstory plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json';
diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx
index e4d53e0bacfd8..6ee6654bca627 100644
--- a/api_docs/kbn_apm_config_loader.mdx
+++ b/api_docs/kbn_apm_config_loader.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnApmConfigLoaderPluginApi
slug: /kibana-dev-docs/api/kbn-apm-config-loader
title: "@kbn/apm-config-loader"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/apm-config-loader plugin
-date: 2022-08-10
+description: API docs for the @kbn/apm-config-loader plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json';
diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx
index f0709c01d5522..552bd53fc9230 100644
--- a/api_docs/kbn_apm_utils.mdx
+++ b/api_docs/kbn_apm_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnApmUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-apm-utils
title: "@kbn/apm-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/apm-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/apm-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json';
diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx
index 34dec7bb8b7c2..5511c5405411f 100644
--- a/api_docs/kbn_axe_config.mdx
+++ b/api_docs/kbn_axe_config.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnAxeConfigPluginApi
slug: /kibana-dev-docs/api/kbn-axe-config
title: "@kbn/axe-config"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/axe-config plugin
-date: 2022-08-10
+description: API docs for the @kbn/axe-config plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnAxeConfigObj from './kbn_axe_config.devdocs.json';
diff --git a/api_docs/kbn_bazel_packages.mdx b/api_docs/kbn_bazel_packages.mdx
index 85685f06c59dd..3f72ba8df808a 100644
--- a/api_docs/kbn_bazel_packages.mdx
+++ b/api_docs/kbn_bazel_packages.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnBazelPackagesPluginApi
slug: /kibana-dev-docs/api/kbn-bazel-packages
title: "@kbn/bazel-packages"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/bazel-packages plugin
-date: 2022-08-10
+description: API docs for the @kbn/bazel-packages plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-packages']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnBazelPackagesObj from './kbn_bazel_packages.devdocs.json';
diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx
index 465efbdb066c1..e000823006bae 100644
--- a/api_docs/kbn_ci_stats_core.mdx
+++ b/api_docs/kbn_ci_stats_core.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCiStatsCorePluginApi
slug: /kibana-dev-docs/api/kbn-ci-stats-core
title: "@kbn/ci-stats-core"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ci-stats-core plugin
-date: 2022-08-10
+description: API docs for the @kbn/ci-stats-core plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json';
diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx
index 10c1ee15848e9..b4c7822027657 100644
--- a/api_docs/kbn_ci_stats_performance_metrics.mdx
+++ b/api_docs/kbn_ci_stats_performance_metrics.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCiStatsPerformanceMetricsPluginApi
slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics
title: "@kbn/ci-stats-performance-metrics"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ci-stats-performance-metrics plugin
-date: 2022-08-10
+description: API docs for the @kbn/ci-stats-performance-metrics plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json';
diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx
index 1fe469a2f2b76..124fdda39cd95 100644
--- a/api_docs/kbn_ci_stats_reporter.mdx
+++ b/api_docs/kbn_ci_stats_reporter.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCiStatsReporterPluginApi
slug: /kibana-dev-docs/api/kbn-ci-stats-reporter
title: "@kbn/ci-stats-reporter"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ci-stats-reporter plugin
-date: 2022-08-10
+description: API docs for the @kbn/ci-stats-reporter plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json';
diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx
index c41826cdf11a7..a4432f832ef5e 100644
--- a/api_docs/kbn_cli_dev_mode.mdx
+++ b/api_docs/kbn_cli_dev_mode.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCliDevModePluginApi
slug: /kibana-dev-docs/api/kbn-cli-dev-mode
title: "@kbn/cli-dev-mode"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/cli-dev-mode plugin
-date: 2022-08-10
+description: API docs for the @kbn/cli-dev-mode plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json';
diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx
index dbd9ea19feb48..ae5cd47cda816 100644
--- a/api_docs/kbn_coloring.mdx
+++ b/api_docs/kbn_coloring.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnColoringPluginApi
slug: /kibana-dev-docs/api/kbn-coloring
title: "@kbn/coloring"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/coloring plugin
-date: 2022-08-10
+description: API docs for the @kbn/coloring plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnColoringObj from './kbn_coloring.devdocs.json';
diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx
index 49894b0045255..2d89d9f9d3d27 100644
--- a/api_docs/kbn_config.mdx
+++ b/api_docs/kbn_config.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnConfigPluginApi
slug: /kibana-dev-docs/api/kbn-config
title: "@kbn/config"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/config plugin
-date: 2022-08-10
+description: API docs for the @kbn/config plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnConfigObj from './kbn_config.devdocs.json';
diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx
index ea43e0d405a1c..fc93f0c95c25d 100644
--- a/api_docs/kbn_config_mocks.mdx
+++ b/api_docs/kbn_config_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnConfigMocksPluginApi
slug: /kibana-dev-docs/api/kbn-config-mocks
title: "@kbn/config-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/config-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/config-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json';
diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx
index 82ecdab7f4247..3f692e8c39e74 100644
--- a/api_docs/kbn_config_schema.mdx
+++ b/api_docs/kbn_config_schema.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnConfigSchemaPluginApi
slug: /kibana-dev-docs/api/kbn-config-schema
title: "@kbn/config-schema"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/config-schema plugin
-date: 2022-08-10
+description: API docs for the @kbn/config-schema plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx
index c09a2f9778701..dc25d37e8dcb6 100644
--- a/api_docs/kbn_core_analytics_browser.mdx
+++ b/api_docs/kbn_core_analytics_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-browser
title: "@kbn/core-analytics-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx
index 11b8af9ab3439..6ed61554c64dc 100644
--- a/api_docs/kbn_core_analytics_browser_internal.mdx
+++ b/api_docs/kbn_core_analytics_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal
title: "@kbn/core-analytics-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx
index c7fa438af7585..083459d82e734 100644
--- a/api_docs/kbn_core_analytics_browser_mocks.mdx
+++ b/api_docs/kbn_core_analytics_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks
title: "@kbn/core-analytics-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx
index f00aad80106be..eabbc9e824460 100644
--- a/api_docs/kbn_core_analytics_server.mdx
+++ b/api_docs/kbn_core_analytics_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-server
title: "@kbn/core-analytics-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx
index 5cda27736f13c..e85565987a37e 100644
--- a/api_docs/kbn_core_analytics_server_internal.mdx
+++ b/api_docs/kbn_core_analytics_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal
title: "@kbn/core-analytics-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx
index ed0fd75a17ea1..2e7d30f0d0fbf 100644
--- a/api_docs/kbn_core_analytics_server_mocks.mdx
+++ b/api_docs/kbn_core_analytics_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreAnalyticsServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks
title: "@kbn/core-analytics-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-analytics-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-analytics-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx
index 4cf38273b434e..34de7d4b8e06a 100644
--- a/api_docs/kbn_core_base_browser_mocks.mdx
+++ b/api_docs/kbn_core_base_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreBaseBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks
title: "@kbn/core-base-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-base-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-base-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx
index f998c3986fa42..573b7df56d3c3 100644
--- a/api_docs/kbn_core_base_common.mdx
+++ b/api_docs/kbn_core_base_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreBaseCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-base-common
title: "@kbn/core-base-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-base-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-base-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json';
diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx
index 7196db6502636..18e83415fc77b 100644
--- a/api_docs/kbn_core_base_server_internal.mdx
+++ b/api_docs/kbn_core_base_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreBaseServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-base-server-internal
title: "@kbn/core-base-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-base-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-base-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx
index e0fe87f10560e..90308821b1602 100644
--- a/api_docs/kbn_core_base_server_mocks.mdx
+++ b/api_docs/kbn_core_base_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreBaseServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-base-server-mocks
title: "@kbn/core-base-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-base-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-base-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx
index 4fe41d98f95e1..5c9813c841e93 100644
--- a/api_docs/kbn_core_capabilities_common.mdx
+++ b/api_docs/kbn_core_capabilities_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreCapabilitiesCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-capabilities-common
title: "@kbn/core-capabilities-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-capabilities-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-capabilities-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json';
diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx
index 8dd31e759d375..2d74140d25d5b 100644
--- a/api_docs/kbn_core_capabilities_server.mdx
+++ b/api_docs/kbn_core_capabilities_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreCapabilitiesServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-capabilities-server
title: "@kbn/core-capabilities-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-capabilities-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-capabilities-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json';
diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx
index ea93ab2a728a3..5864db03de071 100644
--- a/api_docs/kbn_core_capabilities_server_mocks.mdx
+++ b/api_docs/kbn_core_capabilities_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreCapabilitiesServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks
title: "@kbn/core-capabilities-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-capabilities-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-capabilities-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx
index 2022112d0f968..980aeb7e5eafd 100644
--- a/api_docs/kbn_core_config_server_internal.mdx
+++ b/api_docs/kbn_core_config_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreConfigServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-config-server-internal
title: "@kbn/core-config-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-config-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-config-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx
index 6b3592a5106a8..c7b4f1f1db12e 100644
--- a/api_docs/kbn_core_deprecations_browser.mdx
+++ b/api_docs/kbn_core_deprecations_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDeprecationsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-deprecations-browser
title: "@kbn/core-deprecations-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-deprecations-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-deprecations-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json';
diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx
index c653204a2efa7..b51f5542dcac5 100644
--- a/api_docs/kbn_core_deprecations_browser_internal.mdx
+++ b/api_docs/kbn_core_deprecations_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDeprecationsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal
title: "@kbn/core-deprecations-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-deprecations-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-deprecations-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx
index 5de45a3e441d2..ae1d2d010d9ce 100644
--- a/api_docs/kbn_core_deprecations_browser_mocks.mdx
+++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDeprecationsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks
title: "@kbn/core-deprecations-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-deprecations-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-deprecations-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx
index 9ec6d2b8e7de6..ef822626f6f33 100644
--- a/api_docs/kbn_core_deprecations_common.mdx
+++ b/api_docs/kbn_core_deprecations_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDeprecationsCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-deprecations-common
title: "@kbn/core-deprecations-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-deprecations-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-deprecations-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json';
diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx
index 575fa27be8fc7..5b70ecb032151 100644
--- a/api_docs/kbn_core_doc_links_browser.mdx
+++ b/api_docs/kbn_core_doc_links_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDocLinksBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-doc-links-browser
title: "@kbn/core-doc-links-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-doc-links-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-doc-links-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json';
diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx
index 979b7c9e29a0e..c153294c409c3 100644
--- a/api_docs/kbn_core_doc_links_browser_mocks.mdx
+++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDocLinksBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks
title: "@kbn/core-doc-links-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-doc-links-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-doc-links-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx
index 1d8883729bc08..5bb7687740ecf 100644
--- a/api_docs/kbn_core_doc_links_server.mdx
+++ b/api_docs/kbn_core_doc_links_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDocLinksServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-doc-links-server
title: "@kbn/core-doc-links-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-doc-links-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-doc-links-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json';
diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx
index 9d377f03024cf..2cd86fe9ad73b 100644
--- a/api_docs/kbn_core_doc_links_server_mocks.mdx
+++ b/api_docs/kbn_core_doc_links_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreDocLinksServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks
title: "@kbn/core-doc-links-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-doc-links-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-doc-links-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx
index 71a70374fdcec..ed0b4b1c9bcfd 100644
--- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx
+++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreElasticsearchClientServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal
title: "@kbn/core-elasticsearch-client-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-elasticsearch-client-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx
index e30a930a510c2..2bb6fd38a5486 100644
--- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx
+++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreElasticsearchClientServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks
title: "@kbn/core-elasticsearch-client-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx
index 3e4d5ea1eff1e..f5f44e819ce92 100644
--- a/api_docs/kbn_core_elasticsearch_server.mdx
+++ b/api_docs/kbn_core_elasticsearch_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreElasticsearchServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server
title: "@kbn/core-elasticsearch-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-elasticsearch-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-elasticsearch-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json';
diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx
index d2c0ac6db57f5..fcb6bee1f95ca 100644
--- a/api_docs/kbn_core_elasticsearch_server_internal.mdx
+++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreElasticsearchServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal
title: "@kbn/core-elasticsearch-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-elasticsearch-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-elasticsearch-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx
index 4c7e3c5963d2d..0b46995435694 100644
--- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx
+++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreElasticsearchServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks
title: "@kbn/core-elasticsearch-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-elasticsearch-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-elasticsearch-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx
index 661d4f2ed8405..10f74250c8dd0 100644
--- a/api_docs/kbn_core_environment_server_internal.mdx
+++ b/api_docs/kbn_core_environment_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreEnvironmentServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-environment-server-internal
title: "@kbn/core-environment-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-environment-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-environment-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx
index 4f5e63161fb70..b84b68e017374 100644
--- a/api_docs/kbn_core_environment_server_mocks.mdx
+++ b/api_docs/kbn_core_environment_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreEnvironmentServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks
title: "@kbn/core-environment-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-environment-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-environment-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx
index 64da2a1842348..1f6edae3523a8 100644
--- a/api_docs/kbn_core_execution_context_browser.mdx
+++ b/api_docs/kbn_core_execution_context_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-browser
title: "@kbn/core-execution-context-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx
index 699750f0ccda9..400b5a8cd8d61 100644
--- a/api_docs/kbn_core_execution_context_browser_internal.mdx
+++ b/api_docs/kbn_core_execution_context_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal
title: "@kbn/core-execution-context-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx
index f9da7f78d662a..5756f10d51000 100644
--- a/api_docs/kbn_core_execution_context_browser_mocks.mdx
+++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks
title: "@kbn/core-execution-context-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx
index 1164f75874838..1775cf95424b5 100644
--- a/api_docs/kbn_core_execution_context_common.mdx
+++ b/api_docs/kbn_core_execution_context_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-common
title: "@kbn/core-execution-context-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx
index 4709b3b984eb0..0fbd1783b6c31 100644
--- a/api_docs/kbn_core_execution_context_server.mdx
+++ b/api_docs/kbn_core_execution_context_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-server
title: "@kbn/core-execution-context-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx
index 1041572776e69..b80f7f7829f3f 100644
--- a/api_docs/kbn_core_execution_context_server_internal.mdx
+++ b/api_docs/kbn_core_execution_context_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal
title: "@kbn/core-execution-context-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx
index bf92cf8086388..5894717106f89 100644
--- a/api_docs/kbn_core_execution_context_server_mocks.mdx
+++ b/api_docs/kbn_core_execution_context_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreExecutionContextServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks
title: "@kbn/core-execution-context-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-execution-context-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-execution-context-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx
index 66fa9fd0d119e..788d6e2d1202f 100644
--- a/api_docs/kbn_core_fatal_errors_browser.mdx
+++ b/api_docs/kbn_core_fatal_errors_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreFatalErrorsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser
title: "@kbn/core-fatal-errors-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-fatal-errors-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-fatal-errors-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json';
diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx
index 93e50050c1827..b21295fde28b6 100644
--- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx
+++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreFatalErrorsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks
title: "@kbn/core-fatal-errors-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-fatal-errors-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx
index 7d478e7661cf2..4c0375f75ef49 100644
--- a/api_docs/kbn_core_http_browser.mdx
+++ b/api_docs/kbn_core_http_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-browser
title: "@kbn/core-http-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json';
diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx
index 0196916c49af4..741b7b15181ed 100644
--- a/api_docs/kbn_core_http_browser_internal.mdx
+++ b/api_docs/kbn_core_http_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-browser-internal
title: "@kbn/core-http-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx
index 36e36ebcb79b9..7a748adae2e2b 100644
--- a/api_docs/kbn_core_http_browser_mocks.mdx
+++ b/api_docs/kbn_core_http_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks
title: "@kbn/core-http-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx
index 0ce137eaaf25b..c2ced4707e7e2 100644
--- a/api_docs/kbn_core_http_common.mdx
+++ b/api_docs/kbn_core_http_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-common
title: "@kbn/core-http-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json';
diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx
index 7468336058974..a450f828cc24b 100644
--- a/api_docs/kbn_core_http_context_server_mocks.mdx
+++ b/api_docs/kbn_core_http_context_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpContextServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks
title: "@kbn/core-http-context-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-context-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-context-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx
index a6333f53e2076..660e16aaa2334 100644
--- a/api_docs/kbn_core_http_router_server_internal.mdx
+++ b/api_docs/kbn_core_http_router_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpRouterServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal
title: "@kbn/core-http-router-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-router-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-router-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx
index 7566ee9119d10..281c9400435f2 100644
--- a/api_docs/kbn_core_http_router_server_mocks.mdx
+++ b/api_docs/kbn_core_http_router_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpRouterServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks
title: "@kbn/core-http-router-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-router-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-router-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx
index 29e742f2350f8..6736f3e83167d 100644
--- a/api_docs/kbn_core_http_server.mdx
+++ b/api_docs/kbn_core_http_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-server
title: "@kbn/core-http-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json';
diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx
index 1254401ee5426..c82bdcaec983f 100644
--- a/api_docs/kbn_core_http_server_internal.mdx
+++ b/api_docs/kbn_core_http_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-server-internal
title: "@kbn/core-http-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx
index 8d66b2eda38ee..dc7f6893d7397 100644
--- a/api_docs/kbn_core_http_server_mocks.mdx
+++ b/api_docs/kbn_core_http_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreHttpServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-http-server-mocks
title: "@kbn/core-http-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-http-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-http-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx
index e7173c6deaab5..29a450346c446 100644
--- a/api_docs/kbn_core_i18n_browser.mdx
+++ b/api_docs/kbn_core_i18n_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreI18nBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-i18n-browser
title: "@kbn/core-i18n-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-i18n-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-i18n-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json';
diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx
index ac518d3fba884..0345e27a252c4 100644
--- a/api_docs/kbn_core_i18n_browser_mocks.mdx
+++ b/api_docs/kbn_core_i18n_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreI18nBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks
title: "@kbn/core-i18n-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-i18n-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-i18n-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx
index 33b9777c89da1..104d153f003fe 100644
--- a/api_docs/kbn_core_injected_metadata_browser.mdx
+++ b/api_docs/kbn_core_injected_metadata_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreInjectedMetadataBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser
title: "@kbn/core-injected-metadata-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-injected-metadata-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-injected-metadata-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json';
diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx
index 1b950e8fe9490..23d3b5fd4460e 100644
--- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx
+++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreInjectedMetadataBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks
title: "@kbn/core-injected-metadata-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-injected-metadata-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx
index 91b4acc9cadc8..8f36ee7e2ce4d 100644
--- a/api_docs/kbn_core_integrations_browser_internal.mdx
+++ b/api_docs/kbn_core_integrations_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreIntegrationsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal
title: "@kbn/core-integrations-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-integrations-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-integrations-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx
index 3c46e98f755c9..8569ab0f0bb05 100644
--- a/api_docs/kbn_core_integrations_browser_mocks.mdx
+++ b/api_docs/kbn_core_integrations_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreIntegrationsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks
title: "@kbn/core-integrations-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-integrations-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-integrations-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx
index 8febbac2aba38..ca4ceef547462 100644
--- a/api_docs/kbn_core_logging_server.mdx
+++ b/api_docs/kbn_core_logging_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreLoggingServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-logging-server
title: "@kbn/core-logging-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-logging-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-logging-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json';
diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx
index 6a56cc215c2d2..aacfe4c584c29 100644
--- a/api_docs/kbn_core_logging_server_internal.mdx
+++ b/api_docs/kbn_core_logging_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreLoggingServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-logging-server-internal
title: "@kbn/core-logging-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-logging-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-logging-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx
index d694c5c983d20..39dbbf64c899a 100644
--- a/api_docs/kbn_core_logging_server_mocks.mdx
+++ b/api_docs/kbn_core_logging_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreLoggingServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks
title: "@kbn/core-logging-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-logging-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-logging-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx
index c713d338cfd26..1362bd713e36e 100644
--- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx
+++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMetricsCollectorsServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal
title: "@kbn/core-metrics-collectors-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-metrics-collectors-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-metrics-collectors-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx
index 7782767b072c5..71bc6f3a3f04a 100644
--- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx
+++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMetricsCollectorsServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks
title: "@kbn/core-metrics-collectors-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-metrics-collectors-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx
index d3ba6875eb993..041ef87b42952 100644
--- a/api_docs/kbn_core_metrics_server.mdx
+++ b/api_docs/kbn_core_metrics_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMetricsServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-metrics-server
title: "@kbn/core-metrics-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-metrics-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-metrics-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json';
diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx
index 1f4fa49cf81ed..ae16ec053bb11 100644
--- a/api_docs/kbn_core_metrics_server_internal.mdx
+++ b/api_docs/kbn_core_metrics_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMetricsServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal
title: "@kbn/core-metrics-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-metrics-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-metrics-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx
index 44ef913936687..b4a898c163d5a 100644
--- a/api_docs/kbn_core_metrics_server_mocks.mdx
+++ b/api_docs/kbn_core_metrics_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMetricsServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks
title: "@kbn/core-metrics-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-metrics-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-metrics-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx
index cd1db61a8b29d..ae5b022c353d8 100644
--- a/api_docs/kbn_core_mount_utils_browser.mdx
+++ b/api_docs/kbn_core_mount_utils_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMountUtilsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser
title: "@kbn/core-mount-utils-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-mount-utils-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-mount-utils-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json';
diff --git a/api_docs/kbn_core_mount_utils_browser_internal.mdx b/api_docs/kbn_core_mount_utils_browser_internal.mdx
index 2d690a6065357..31eef32ff122d 100644
--- a/api_docs/kbn_core_mount_utils_browser_internal.mdx
+++ b/api_docs/kbn_core_mount_utils_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreMountUtilsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser-internal
title: "@kbn/core-mount-utils-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-mount-utils-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-mount-utils-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreMountUtilsBrowserInternalObj from './kbn_core_mount_utils_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx
index 620d527e9dfec..46bc2f98e711d 100644
--- a/api_docs/kbn_core_node_server.mdx
+++ b/api_docs/kbn_core_node_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNodeServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-node-server
title: "@kbn/core-node-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-node-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-node-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json';
diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx
index 5dc70b4e434d5..32bdf17e3702d 100644
--- a/api_docs/kbn_core_node_server_internal.mdx
+++ b/api_docs/kbn_core_node_server_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNodeServerInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-node-server-internal
title: "@kbn/core-node-server-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-node-server-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-node-server-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json';
diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx
index a1c7f0518037e..1c237f65329ec 100644
--- a/api_docs/kbn_core_node_server_mocks.mdx
+++ b/api_docs/kbn_core_node_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNodeServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-node-server-mocks
title: "@kbn/core-node-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-node-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-node-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx
index 9b73ce6f2af07..2f29364b23a43 100644
--- a/api_docs/kbn_core_notifications_browser.mdx
+++ b/api_docs/kbn_core_notifications_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNotificationsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-notifications-browser
title: "@kbn/core-notifications-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-notifications-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-notifications-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json';
diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx
index e26ac823e3a64..7616c2e3e5d19 100644
--- a/api_docs/kbn_core_notifications_browser_internal.mdx
+++ b/api_docs/kbn_core_notifications_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNotificationsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal
title: "@kbn/core-notifications-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-notifications-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-notifications-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx
index 8defd47de4067..0fcdf7624cf5b 100644
--- a/api_docs/kbn_core_notifications_browser_mocks.mdx
+++ b/api_docs/kbn_core_notifications_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreNotificationsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks
title: "@kbn/core-notifications-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-notifications-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-notifications-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx
index 2ba9f8a19a050..453c38659a5e4 100644
--- a/api_docs/kbn_core_overlays_browser.mdx
+++ b/api_docs/kbn_core_overlays_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreOverlaysBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-overlays-browser
title: "@kbn/core-overlays-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-overlays-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-overlays-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json';
diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx
index 6f0a29e468045..a34142a2fae29 100644
--- a/api_docs/kbn_core_overlays_browser_internal.mdx
+++ b/api_docs/kbn_core_overlays_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreOverlaysBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal
title: "@kbn/core-overlays-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-overlays-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-overlays-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx
index 866132ba10c92..37408d1a0c8e0 100644
--- a/api_docs/kbn_core_overlays_browser_mocks.mdx
+++ b/api_docs/kbn_core_overlays_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreOverlaysBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks
title: "@kbn/core-overlays-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-overlays-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-overlays-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx
index cbbf027250fe0..9a7c7a1edce55 100644
--- a/api_docs/kbn_core_preboot_server.mdx
+++ b/api_docs/kbn_core_preboot_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCorePrebootServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-preboot-server
title: "@kbn/core-preboot-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-preboot-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-preboot-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json';
diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx
index a07a0853de6ae..0afd2e4c96dea 100644
--- a/api_docs/kbn_core_preboot_server_mocks.mdx
+++ b/api_docs/kbn_core_preboot_server_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCorePrebootServerMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks
title: "@kbn/core-preboot-server-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-preboot-server-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-preboot-server-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx
index 4083b402a8042..f4c2d6f9ccc42 100644
--- a/api_docs/kbn_core_saved_objects_api_browser.mdx
+++ b/api_docs/kbn_core_saved_objects_api_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsApiBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser
title: "@kbn/core-saved-objects-api-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-api-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-api-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx
index 3db45c8be52f9..8fc0b694aa6c1 100644
--- a/api_docs/kbn_core_saved_objects_api_server.mdx
+++ b/api_docs/kbn_core_saved_objects_api_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsApiServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server
title: "@kbn/core-saved-objects-api-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-api-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-api-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx
index 7a311807c8358..24b3e5da37fbb 100644
--- a/api_docs/kbn_core_saved_objects_browser.mdx
+++ b/api_docs/kbn_core_saved_objects_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser
title: "@kbn/core-saved-objects-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx
index 9967e10cdc76d..032339de4038f 100644
--- a/api_docs/kbn_core_saved_objects_browser_internal.mdx
+++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal
title: "@kbn/core-saved-objects-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx
index 54dfcdbd7459a..038b770a93bac 100644
--- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx
+++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks
title: "@kbn/core-saved-objects-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx
index dc3a1986e550d..1d5aaa4650348 100644
--- a/api_docs/kbn_core_saved_objects_common.mdx
+++ b/api_docs/kbn_core_saved_objects_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-common
title: "@kbn/core-saved-objects-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json';
diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx
index 4f50d19daef66..52b21777a4436 100644
--- a/api_docs/kbn_core_saved_objects_server.mdx
+++ b/api_docs/kbn_core_saved_objects_server.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreSavedObjectsServerPluginApi
slug: /kibana-dev-docs/api/kbn-core-saved-objects-server
title: "@kbn/core-saved-objects-server"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-saved-objects-server plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-saved-objects-server plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json';
diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx
index fe65a7e89048c..787255afdcef6 100644
--- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx
+++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreTestHelpersDeprecationsGettersPluginApi
slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters
title: "@kbn/core-test-helpers-deprecations-getters"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-test-helpers-deprecations-getters plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json';
diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx
index 99655563b1296..5324e74eaddf4 100644
--- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx
+++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreTestHelpersHttpSetupBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser
title: "@kbn/core-test-helpers-http-setup-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-test-helpers-http-setup-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json';
diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx
index cf31e74dce003..607691e3099a3 100644
--- a/api_docs/kbn_core_theme_browser.mdx
+++ b/api_docs/kbn_core_theme_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreThemeBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-theme-browser
title: "@kbn/core-theme-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-theme-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-theme-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json';
diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx
index eb88aa7a05bbd..d2d25970198fa 100644
--- a/api_docs/kbn_core_theme_browser_internal.mdx
+++ b/api_docs/kbn_core_theme_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreThemeBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal
title: "@kbn/core-theme-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-theme-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-theme-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx
index 92d27f90b7cf8..dd78cb97c9b73 100644
--- a/api_docs/kbn_core_theme_browser_mocks.mdx
+++ b/api_docs/kbn_core_theme_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreThemeBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks
title: "@kbn/core-theme-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-theme-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-theme-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx
index 64f78476c8eef..319ea1a3816db 100644
--- a/api_docs/kbn_core_ui_settings_browser.mdx
+++ b/api_docs/kbn_core_ui_settings_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreUiSettingsBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser
title: "@kbn/core-ui-settings-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-ui-settings-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-ui-settings-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json';
diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx
index 25c030f47a1e0..dbf6c57f3a902 100644
--- a/api_docs/kbn_core_ui_settings_browser_internal.mdx
+++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreUiSettingsBrowserInternalPluginApi
slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal
title: "@kbn/core-ui-settings-browser-internal"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-ui-settings-browser-internal plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-ui-settings-browser-internal plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json';
diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx
index 637c39c488705..6cd8019246435 100644
--- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx
+++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreUiSettingsBrowserMocksPluginApi
slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks
title: "@kbn/core-ui-settings-browser-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-ui-settings-browser-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-ui-settings-browser-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json';
diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx
index b93086e6d5a6e..23df6c2264954 100644
--- a/api_docs/kbn_core_ui_settings_common.mdx
+++ b/api_docs/kbn_core_ui_settings_common.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCoreUiSettingsCommonPluginApi
slug: /kibana-dev-docs/api/kbn-core-ui-settings-common
title: "@kbn/core-ui-settings-common"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/core-ui-settings-common plugin
-date: 2022-08-10
+description: API docs for the @kbn/core-ui-settings-common plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json';
diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx
index f9dd8733c5c49..7d308692aa3d3 100644
--- a/api_docs/kbn_crypto.mdx
+++ b/api_docs/kbn_crypto.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCryptoPluginApi
slug: /kibana-dev-docs/api/kbn-crypto
title: "@kbn/crypto"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/crypto plugin
-date: 2022-08-10
+description: API docs for the @kbn/crypto plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCryptoObj from './kbn_crypto.devdocs.json';
diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx
index cb5d48578bd36..2880bdaed08ba 100644
--- a/api_docs/kbn_crypto_browser.mdx
+++ b/api_docs/kbn_crypto_browser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnCryptoBrowserPluginApi
slug: /kibana-dev-docs/api/kbn-crypto-browser
title: "@kbn/crypto-browser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/crypto-browser plugin
-date: 2022-08-10
+description: API docs for the @kbn/crypto-browser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json';
diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx
index d91f60d78e108..b72576e13c035 100644
--- a/api_docs/kbn_datemath.mdx
+++ b/api_docs/kbn_datemath.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDatemathPluginApi
slug: /kibana-dev-docs/api/kbn-datemath
title: "@kbn/datemath"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/datemath plugin
-date: 2022-08-10
+description: API docs for the @kbn/datemath plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDatemathObj from './kbn_datemath.devdocs.json';
diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx
index 46bd0d8207f2f..d55689dd7adfa 100644
--- a/api_docs/kbn_dev_cli_errors.mdx
+++ b/api_docs/kbn_dev_cli_errors.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDevCliErrorsPluginApi
slug: /kibana-dev-docs/api/kbn-dev-cli-errors
title: "@kbn/dev-cli-errors"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/dev-cli-errors plugin
-date: 2022-08-10
+description: API docs for the @kbn/dev-cli-errors plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json';
diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx
index 7cb93cffe8c9d..e2a3d8828c9de 100644
--- a/api_docs/kbn_dev_cli_runner.mdx
+++ b/api_docs/kbn_dev_cli_runner.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDevCliRunnerPluginApi
slug: /kibana-dev-docs/api/kbn-dev-cli-runner
title: "@kbn/dev-cli-runner"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/dev-cli-runner plugin
-date: 2022-08-10
+description: API docs for the @kbn/dev-cli-runner plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json';
diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx
index 771e5cecdf43d..43f9f57f37548 100644
--- a/api_docs/kbn_dev_proc_runner.mdx
+++ b/api_docs/kbn_dev_proc_runner.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDevProcRunnerPluginApi
slug: /kibana-dev-docs/api/kbn-dev-proc-runner
title: "@kbn/dev-proc-runner"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/dev-proc-runner plugin
-date: 2022-08-10
+description: API docs for the @kbn/dev-proc-runner plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json';
diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx
index 5342c7bfa04d9..e92051ab7b1df 100644
--- a/api_docs/kbn_dev_utils.mdx
+++ b/api_docs/kbn_dev_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDevUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-dev-utils
title: "@kbn/dev-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/dev-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/dev-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json';
diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx
index c371b30eb3338..c0c47f70125cd 100644
--- a/api_docs/kbn_doc_links.mdx
+++ b/api_docs/kbn_doc_links.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDocLinksPluginApi
slug: /kibana-dev-docs/api/kbn-doc-links
title: "@kbn/doc-links"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/doc-links plugin
-date: 2022-08-10
+description: API docs for the @kbn/doc-links plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDocLinksObj from './kbn_doc_links.devdocs.json';
diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx
index 7665daea7144c..7d67005ca5e99 100644
--- a/api_docs/kbn_docs_utils.mdx
+++ b/api_docs/kbn_docs_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnDocsUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-docs-utils
title: "@kbn/docs-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/docs-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/docs-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json';
diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx
index 63353d14673c9..baed6476694f0 100644
--- a/api_docs/kbn_ebt_tools.mdx
+++ b/api_docs/kbn_ebt_tools.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnEbtToolsPluginApi
slug: /kibana-dev-docs/api/kbn-ebt-tools
title: "@kbn/ebt-tools"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ebt-tools plugin
-date: 2022-08-10
+description: API docs for the @kbn/ebt-tools plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json';
diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx
index e48c751e54b5c..fb0b15352818b 100644
--- a/api_docs/kbn_es_archiver.mdx
+++ b/api_docs/kbn_es_archiver.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnEsArchiverPluginApi
slug: /kibana-dev-docs/api/kbn-es-archiver
title: "@kbn/es-archiver"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/es-archiver plugin
-date: 2022-08-10
+description: API docs for the @kbn/es-archiver plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json';
diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx
index 46ac654c9d5e7..3484f1a6ada51 100644
--- a/api_docs/kbn_es_errors.mdx
+++ b/api_docs/kbn_es_errors.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnEsErrorsPluginApi
slug: /kibana-dev-docs/api/kbn-es-errors
title: "@kbn/es-errors"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/es-errors plugin
-date: 2022-08-10
+description: API docs for the @kbn/es-errors plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnEsErrorsObj from './kbn_es_errors.devdocs.json';
diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx
index 5f6deb9a2917c..eade19c03aa86 100644
--- a/api_docs/kbn_es_query.mdx
+++ b/api_docs/kbn_es_query.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnEsQueryPluginApi
slug: /kibana-dev-docs/api/kbn-es-query
title: "@kbn/es-query"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/es-query plugin
-date: 2022-08-10
+description: API docs for the @kbn/es-query plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnEsQueryObj from './kbn_es_query.devdocs.json';
diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx
index 4fb658ae8fe6b..9a7b139bc2a52 100644
--- a/api_docs/kbn_eslint_plugin_imports.mdx
+++ b/api_docs/kbn_eslint_plugin_imports.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnEslintPluginImportsPluginApi
slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports
title: "@kbn/eslint-plugin-imports"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/eslint-plugin-imports plugin
-date: 2022-08-10
+description: API docs for the @kbn/eslint-plugin-imports plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json';
diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx
index 40554b64f05ac..e31c681e7ba4d 100644
--- a/api_docs/kbn_field_types.mdx
+++ b/api_docs/kbn_field_types.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnFieldTypesPluginApi
slug: /kibana-dev-docs/api/kbn-field-types
title: "@kbn/field-types"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/field-types plugin
-date: 2022-08-10
+description: API docs for the @kbn/field-types plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnFieldTypesObj from './kbn_field_types.devdocs.json';
diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx
index b857ce8b6e4f7..188031bf41fcc 100644
--- a/api_docs/kbn_find_used_node_modules.mdx
+++ b/api_docs/kbn_find_used_node_modules.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnFindUsedNodeModulesPluginApi
slug: /kibana-dev-docs/api/kbn-find-used-node-modules
title: "@kbn/find-used-node-modules"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/find-used-node-modules plugin
-date: 2022-08-10
+description: API docs for the @kbn/find-used-node-modules plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json';
diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx
index 1cbaea812812d..a77e974d22f04 100644
--- a/api_docs/kbn_generate.mdx
+++ b/api_docs/kbn_generate.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnGeneratePluginApi
slug: /kibana-dev-docs/api/kbn-generate
title: "@kbn/generate"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/generate plugin
-date: 2022-08-10
+description: API docs for the @kbn/generate plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnGenerateObj from './kbn_generate.devdocs.json';
diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx
index 710252ce3a5c7..8e464bd8f0012 100644
--- a/api_docs/kbn_get_repo_files.mdx
+++ b/api_docs/kbn_get_repo_files.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnGetRepoFilesPluginApi
slug: /kibana-dev-docs/api/kbn-get-repo-files
title: "@kbn/get-repo-files"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/get-repo-files plugin
-date: 2022-08-10
+description: API docs for the @kbn/get-repo-files plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json';
diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx
index 0c1c5162e78a6..72a4fe984177f 100644
--- a/api_docs/kbn_handlebars.mdx
+++ b/api_docs/kbn_handlebars.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnHandlebarsPluginApi
slug: /kibana-dev-docs/api/kbn-handlebars
title: "@kbn/handlebars"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/handlebars plugin
-date: 2022-08-10
+description: API docs for the @kbn/handlebars plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnHandlebarsObj from './kbn_handlebars.devdocs.json';
diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx
index 8347122ac841d..2c309c2f64a28 100644
--- a/api_docs/kbn_hapi_mocks.mdx
+++ b/api_docs/kbn_hapi_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnHapiMocksPluginApi
slug: /kibana-dev-docs/api/kbn-hapi-mocks
title: "@kbn/hapi-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/hapi-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/hapi-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json';
diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx
index 488d44e113ae8..889d0c17237d9 100644
--- a/api_docs/kbn_home_sample_data_card.mdx
+++ b/api_docs/kbn_home_sample_data_card.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnHomeSampleDataCardPluginApi
slug: /kibana-dev-docs/api/kbn-home-sample-data-card
title: "@kbn/home-sample-data-card"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/home-sample-data-card plugin
-date: 2022-08-10
+description: API docs for the @kbn/home-sample-data-card plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json';
diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx
index 1eb25f2d0aabe..956443176eec3 100644
--- a/api_docs/kbn_home_sample_data_tab.mdx
+++ b/api_docs/kbn_home_sample_data_tab.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnHomeSampleDataTabPluginApi
slug: /kibana-dev-docs/api/kbn-home-sample-data-tab
title: "@kbn/home-sample-data-tab"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/home-sample-data-tab plugin
-date: 2022-08-10
+description: API docs for the @kbn/home-sample-data-tab plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json';
diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx
index a142e7e1a75e4..3b55fb665b773 100644
--- a/api_docs/kbn_i18n.mdx
+++ b/api_docs/kbn_i18n.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnI18nPluginApi
slug: /kibana-dev-docs/api/kbn-i18n
title: "@kbn/i18n"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/i18n plugin
-date: 2022-08-10
+description: API docs for the @kbn/i18n plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnI18nObj from './kbn_i18n.devdocs.json';
diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx
index d89fbe0f1c21f..18cedf5f5e4f8 100644
--- a/api_docs/kbn_import_resolver.mdx
+++ b/api_docs/kbn_import_resolver.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnImportResolverPluginApi
slug: /kibana-dev-docs/api/kbn-import-resolver
title: "@kbn/import-resolver"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/import-resolver plugin
-date: 2022-08-10
+description: API docs for the @kbn/import-resolver plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnImportResolverObj from './kbn_import_resolver.devdocs.json';
diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx
index 5b2e1825b0446..09163c26a680d 100644
--- a/api_docs/kbn_interpreter.mdx
+++ b/api_docs/kbn_interpreter.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnInterpreterPluginApi
slug: /kibana-dev-docs/api/kbn-interpreter
title: "@kbn/interpreter"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/interpreter plugin
-date: 2022-08-10
+description: API docs for the @kbn/interpreter plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnInterpreterObj from './kbn_interpreter.devdocs.json';
diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx
index a2504a4c32db6..bb1c0bedada86 100644
--- a/api_docs/kbn_io_ts_utils.mdx
+++ b/api_docs/kbn_io_ts_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnIoTsUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-io-ts-utils
title: "@kbn/io-ts-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/io-ts-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/io-ts-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json';
diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx
index 74a3f649a904a..20a4d28a0221e 100644
--- a/api_docs/kbn_jest_serializers.mdx
+++ b/api_docs/kbn_jest_serializers.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnJestSerializersPluginApi
slug: /kibana-dev-docs/api/kbn-jest-serializers
title: "@kbn/jest-serializers"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/jest-serializers plugin
-date: 2022-08-10
+description: API docs for the @kbn/jest-serializers plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json';
diff --git a/api_docs/kbn_kibana_manifest_parser.mdx b/api_docs/kbn_kibana_manifest_parser.mdx
index cb8e3e9e4ab23..8d12a00d7354a 100644
--- a/api_docs/kbn_kibana_manifest_parser.mdx
+++ b/api_docs/kbn_kibana_manifest_parser.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnKibanaManifestParserPluginApi
slug: /kibana-dev-docs/api/kbn-kibana-manifest-parser
title: "@kbn/kibana-manifest-parser"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/kibana-manifest-parser plugin
-date: 2022-08-10
+description: API docs for the @kbn/kibana-manifest-parser plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-parser']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnKibanaManifestParserObj from './kbn_kibana_manifest_parser.devdocs.json';
diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx
index ce71c1b8b75f0..5f16371077c03 100644
--- a/api_docs/kbn_kibana_manifest_schema.mdx
+++ b/api_docs/kbn_kibana_manifest_schema.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnKibanaManifestSchemaPluginApi
slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema
title: "@kbn/kibana-manifest-schema"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/kibana-manifest-schema plugin
-date: 2022-08-10
+description: API docs for the @kbn/kibana-manifest-schema plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json';
diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx
index 1151120643d1a..48d05d099c986 100644
--- a/api_docs/kbn_logging.mdx
+++ b/api_docs/kbn_logging.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnLoggingPluginApi
slug: /kibana-dev-docs/api/kbn-logging
title: "@kbn/logging"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/logging plugin
-date: 2022-08-10
+description: API docs for the @kbn/logging plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnLoggingObj from './kbn_logging.devdocs.json';
diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx
index 3b7ee97c52ae1..f3e37ddd2f799 100644
--- a/api_docs/kbn_logging_mocks.mdx
+++ b/api_docs/kbn_logging_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnLoggingMocksPluginApi
slug: /kibana-dev-docs/api/kbn-logging-mocks
title: "@kbn/logging-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/logging-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/logging-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json';
diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx
index ed6376e9553e1..cdcc007bda547 100644
--- a/api_docs/kbn_managed_vscode_config.mdx
+++ b/api_docs/kbn_managed_vscode_config.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnManagedVscodeConfigPluginApi
slug: /kibana-dev-docs/api/kbn-managed-vscode-config
title: "@kbn/managed-vscode-config"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/managed-vscode-config plugin
-date: 2022-08-10
+description: API docs for the @kbn/managed-vscode-config plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json';
diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx
index 8d6dba65ead91..71af48ec9a4dd 100644
--- a/api_docs/kbn_mapbox_gl.mdx
+++ b/api_docs/kbn_mapbox_gl.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnMapboxGlPluginApi
slug: /kibana-dev-docs/api/kbn-mapbox-gl
title: "@kbn/mapbox-gl"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/mapbox-gl plugin
-date: 2022-08-10
+description: API docs for the @kbn/mapbox-gl plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json';
diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx
index 7cb8d90cfa235..4f3afabcbdf20 100644
--- a/api_docs/kbn_ml_agg_utils.mdx
+++ b/api_docs/kbn_ml_agg_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnMlAggUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-ml-agg-utils
title: "@kbn/ml-agg-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ml-agg-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/ml-agg-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json';
diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx
index 6d72343154bdc..fd25d71911ac4 100644
--- a/api_docs/kbn_ml_is_populated_object.mdx
+++ b/api_docs/kbn_ml_is_populated_object.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnMlIsPopulatedObjectPluginApi
slug: /kibana-dev-docs/api/kbn-ml-is-populated-object
title: "@kbn/ml-is-populated-object"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ml-is-populated-object plugin
-date: 2022-08-10
+description: API docs for the @kbn/ml-is-populated-object plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json';
diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx
index fe74228ef2800..84f80a8557221 100644
--- a/api_docs/kbn_ml_string_hash.mdx
+++ b/api_docs/kbn_ml_string_hash.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnMlStringHashPluginApi
slug: /kibana-dev-docs/api/kbn-ml-string-hash
title: "@kbn/ml-string-hash"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ml-string-hash plugin
-date: 2022-08-10
+description: API docs for the @kbn/ml-string-hash plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json';
diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx
index 5ad15805a570f..2c037730f69ef 100644
--- a/api_docs/kbn_monaco.mdx
+++ b/api_docs/kbn_monaco.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnMonacoPluginApi
slug: /kibana-dev-docs/api/kbn-monaco
title: "@kbn/monaco"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/monaco plugin
-date: 2022-08-10
+description: API docs for the @kbn/monaco plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnMonacoObj from './kbn_monaco.devdocs.json';
diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx
index 5ceffe10c2355..99c81b283e5eb 100644
--- a/api_docs/kbn_optimizer.mdx
+++ b/api_docs/kbn_optimizer.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnOptimizerPluginApi
slug: /kibana-dev-docs/api/kbn-optimizer
title: "@kbn/optimizer"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/optimizer plugin
-date: 2022-08-10
+description: API docs for the @kbn/optimizer plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnOptimizerObj from './kbn_optimizer.devdocs.json';
diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx
index e87a7556a2f4d..500fd91a654e3 100644
--- a/api_docs/kbn_optimizer_webpack_helpers.mdx
+++ b/api_docs/kbn_optimizer_webpack_helpers.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnOptimizerWebpackHelpersPluginApi
slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers
title: "@kbn/optimizer-webpack-helpers"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/optimizer-webpack-helpers plugin
-date: 2022-08-10
+description: API docs for the @kbn/optimizer-webpack-helpers plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json';
diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx
index e783b89afa935..84fe13cd647f3 100644
--- a/api_docs/kbn_performance_testing_dataset_extractor.mdx
+++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnPerformanceTestingDatasetExtractorPluginApi
slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor
title: "@kbn/performance-testing-dataset-extractor"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/performance-testing-dataset-extractor plugin
-date: 2022-08-10
+description: API docs for the @kbn/performance-testing-dataset-extractor plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json';
diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx
index 8528d35bdbf2d..7a4b18b12d6f8 100644
--- a/api_docs/kbn_plugin_generator.mdx
+++ b/api_docs/kbn_plugin_generator.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnPluginGeneratorPluginApi
slug: /kibana-dev-docs/api/kbn-plugin-generator
title: "@kbn/plugin-generator"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/plugin-generator plugin
-date: 2022-08-10
+description: API docs for the @kbn/plugin-generator plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json';
diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx
index d7c4a8b24e619..8fef2ea69e8fa 100644
--- a/api_docs/kbn_plugin_helpers.mdx
+++ b/api_docs/kbn_plugin_helpers.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnPluginHelpersPluginApi
slug: /kibana-dev-docs/api/kbn-plugin-helpers
title: "@kbn/plugin-helpers"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/plugin-helpers plugin
-date: 2022-08-10
+description: API docs for the @kbn/plugin-helpers plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json';
diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx
index f6b280b0f03db..b03dc56faba87 100644
--- a/api_docs/kbn_react_field.mdx
+++ b/api_docs/kbn_react_field.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnReactFieldPluginApi
slug: /kibana-dev-docs/api/kbn-react-field
title: "@kbn/react-field"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/react-field plugin
-date: 2022-08-10
+description: API docs for the @kbn/react-field plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnReactFieldObj from './kbn_react_field.devdocs.json';
diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx
index 40d5b8ffa349e..55d597dc0f2a9 100644
--- a/api_docs/kbn_repo_source_classifier.mdx
+++ b/api_docs/kbn_repo_source_classifier.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnRepoSourceClassifierPluginApi
slug: /kibana-dev-docs/api/kbn-repo-source-classifier
title: "@kbn/repo-source-classifier"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/repo-source-classifier plugin
-date: 2022-08-10
+description: API docs for the @kbn/repo-source-classifier plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json';
diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx
index 443b445f4d402..65475404e3908 100644
--- a/api_docs/kbn_rule_data_utils.mdx
+++ b/api_docs/kbn_rule_data_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnRuleDataUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-rule-data-utils
title: "@kbn/rule-data-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/rule-data-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/rule-data-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx
index 7bed67d2eaf32..0eb3286920244 100644
--- a/api_docs/kbn_securitysolution_autocomplete.mdx
+++ b/api_docs/kbn_securitysolution_autocomplete.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionAutocompletePluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete
title: "@kbn/securitysolution-autocomplete"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-autocomplete plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-autocomplete plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx
index 5191717a2b4f6..3fd73ca86c922 100644
--- a/api_docs/kbn_securitysolution_es_utils.mdx
+++ b/api_docs/kbn_securitysolution_es_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionEsUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils
title: "@kbn/securitysolution-es-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-es-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-es-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx
index 168432db590ca..059651e0c5a5a 100644
--- a/api_docs/kbn_securitysolution_hook_utils.mdx
+++ b/api_docs/kbn_securitysolution_hook_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionHookUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils
title: "@kbn/securitysolution-hook-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-hook-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-hook-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx
index dde361045dfca..7f4324a0e1772 100644
--- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx
+++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionIoTsAlertingTypesPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types
title: "@kbn/securitysolution-io-ts-alerting-types"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx
index 2e9052ebcb51a..985ca5901286b 100644
--- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx
+++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionIoTsListTypesPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types
title: "@kbn/securitysolution-io-ts-list-types"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-io-ts-list-types plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-io-ts-list-types plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx
index 912260c4b7f99..4afc55fb373ba 100644
--- a/api_docs/kbn_securitysolution_io_ts_types.mdx
+++ b/api_docs/kbn_securitysolution_io_ts_types.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionIoTsTypesPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types
title: "@kbn/securitysolution-io-ts-types"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-io-ts-types plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-io-ts-types plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx
index 17c3de5b2ef01..5c756ed317cae 100644
--- a/api_docs/kbn_securitysolution_io_ts_utils.mdx
+++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionIoTsUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils
title: "@kbn/securitysolution-io-ts-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-io-ts-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-io-ts-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_list_api.devdocs.json b/api_docs/kbn_securitysolution_list_api.devdocs.json
index f644bd3bfab69..79b6b26e9f098 100644
--- a/api_docs/kbn_securitysolution_list_api.devdocs.json
+++ b/api_docs/kbn_securitysolution_list_api.devdocs.json
@@ -496,7 +496,7 @@
"label": "findListsWithValidation",
"description": [],
"signature": [
- "({ cursor, http, pageIndex, pageSize, signal, }: ",
+ "({ cursor, http, pageIndex, pageSize, signal, sortField, sortOrder, }: ",
{
"pluginId": "@kbn/securitysolution-list-api",
"scope": "common",
@@ -514,7 +514,7 @@
"id": "def-common.findListsWithValidation.$1",
"type": "Object",
"tags": [],
- "label": "{\n cursor,\n http,\n pageIndex,\n pageSize,\n signal,\n}",
+ "label": "{\n cursor,\n http,\n pageIndex,\n pageSize,\n signal,\n sortField,\n sortOrder,\n}",
"description": [],
"signature": [
{
@@ -1011,6 +1011,32 @@
],
"path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts",
"deprecated": false
+ },
+ {
+ "parentPluginId": "@kbn/securitysolution-list-api",
+ "id": "def-common.FindListsParams.sortOrder",
+ "type": "CompoundType",
+ "tags": [],
+ "label": "sortOrder",
+ "description": [],
+ "signature": [
+ "\"asc\" | \"desc\" | undefined"
+ ],
+ "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "@kbn/securitysolution-list-api",
+ "id": "def-common.FindListsParams.sortField",
+ "type": "string",
+ "tags": [],
+ "label": "sortField",
+ "description": [],
+ "signature": [
+ "string | undefined"
+ ],
+ "path": "packages/kbn-securitysolution-list-api/src/list_api/types.ts",
+ "deprecated": false
}
],
"initialIsOpen": false
diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx
index 949bf45c71f1d..cfdfd9a6568c6 100644
--- a/api_docs/kbn_securitysolution_list_api.mdx
+++ b/api_docs/kbn_securitysolution_list_api.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionListApiPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-list-api
title: "@kbn/securitysolution-list-api"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-list-api plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-list-api plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json';
@@ -18,7 +21,7 @@ Contact [Owner missing] for questions regarding this plugin.
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 59 | 0 | 58 | 0 |
+| 61 | 0 | 60 | 0 |
## Common
diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx
index f0dbd8a1e3a59..f2c6e31617cf8 100644
--- a/api_docs/kbn_securitysolution_list_constants.mdx
+++ b/api_docs/kbn_securitysolution_list_constants.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionListConstantsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants
title: "@kbn/securitysolution-list-constants"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-list-constants plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-list-constants plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx
index 8d5a2429c99af..b25c0b1deb60d 100644
--- a/api_docs/kbn_securitysolution_list_hooks.mdx
+++ b/api_docs/kbn_securitysolution_list_hooks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionListHooksPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks
title: "@kbn/securitysolution-list-hooks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-list-hooks plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-list-hooks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx
index 2c061d5bbeec7..fcbcb384848c2 100644
--- a/api_docs/kbn_securitysolution_list_utils.mdx
+++ b/api_docs/kbn_securitysolution_list_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionListUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils
title: "@kbn/securitysolution-list-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-list-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-list-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx
index a638dc939e2fe..558fcb7778dc3 100644
--- a/api_docs/kbn_securitysolution_rules.mdx
+++ b/api_docs/kbn_securitysolution_rules.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionRulesPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-rules
title: "@kbn/securitysolution-rules"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-rules plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-rules plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx
index 623e10d8a0e4a..8d8bebe8fc200 100644
--- a/api_docs/kbn_securitysolution_t_grid.mdx
+++ b/api_docs/kbn_securitysolution_t_grid.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionTGridPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid
title: "@kbn/securitysolution-t-grid"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-t-grid plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-t-grid plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json';
diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx
index 3979cc1743954..98a042e1ed233 100644
--- a/api_docs/kbn_securitysolution_utils.mdx
+++ b/api_docs/kbn_securitysolution_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSecuritysolutionUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-securitysolution-utils
title: "@kbn/securitysolution-utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/securitysolution-utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/securitysolution-utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json';
diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx
index c3668e264b8e4..a1ba58192aaa9 100644
--- a/api_docs/kbn_server_http_tools.mdx
+++ b/api_docs/kbn_server_http_tools.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnServerHttpToolsPluginApi
slug: /kibana-dev-docs/api/kbn-server-http-tools
title: "@kbn/server-http-tools"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/server-http-tools plugin
-date: 2022-08-10
+description: API docs for the @kbn/server-http-tools plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json';
diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx
index 72a014f25ba22..bce8de0772e48 100644
--- a/api_docs/kbn_server_route_repository.mdx
+++ b/api_docs/kbn_server_route_repository.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnServerRouteRepositoryPluginApi
slug: /kibana-dev-docs/api/kbn-server-route-repository
title: "@kbn/server-route-repository"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/server-route-repository plugin
-date: 2022-08-10
+description: API docs for the @kbn/server-route-repository plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json';
diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx
index 0fde3962a5f48..602b7900da2ca 100644
--- a/api_docs/kbn_shared_svg.mdx
+++ b/api_docs/kbn_shared_svg.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedSvgPluginApi
slug: /kibana-dev-docs/api/kbn-shared-svg
title: "@kbn/shared-svg"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-svg plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-svg plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx
index edecab3bd00f2..36fa3bff8a056 100644
--- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx
+++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxButtonExitFullScreenMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks
title: "@kbn/shared-ux-button-exit-full-screen-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx
index a4371e47e72f2..5900fcefa5a23 100644
--- a/api_docs/kbn_shared_ux_button_toolbar.mdx
+++ b/api_docs/kbn_shared_ux_button_toolbar.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxButtonToolbarPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar
title: "@kbn/shared-ux-button-toolbar"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-button-toolbar plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-button-toolbar plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx
index 8393837ce0d48..f9f761e93c106 100644
--- a/api_docs/kbn_shared_ux_card_no_data.mdx
+++ b/api_docs/kbn_shared_ux_card_no_data.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxCardNoDataPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data
title: "@kbn/shared-ux-card-no-data"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-card-no-data plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-card-no-data plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx
index 84f7b5feb8e5f..4b4a6a247c8b8 100644
--- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx
+++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxCardNoDataMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks
title: "@kbn/shared-ux-card-no-data-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-card-no-data-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_components.mdx b/api_docs/kbn_shared_ux_components.mdx
index 4dd9cb49f5f6f..d69138c6435ae 100644
--- a/api_docs/kbn_shared_ux_components.mdx
+++ b/api_docs/kbn_shared_ux_components.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxComponentsPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-components
title: "@kbn/shared-ux-components"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-components plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-components plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-components']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxComponentsObj from './kbn_shared_ux_components.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx
index c9247266d2047..a4cc2d4b26bb1 100644
--- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx
+++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxLinkRedirectAppMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks
title: "@kbn/shared-ux-link-redirect-app-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx
index e259334407430..25689321f7f8c 100644
--- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx
+++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPageAnalyticsNoDataPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data
title: "@kbn/shared-ux-page-analytics-no-data"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-page-analytics-no-data plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx
index d27d9840a5b1f..6fd9be7b546a0 100644
--- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx
+++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPageAnalyticsNoDataMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks
title: "@kbn/shared-ux-page-analytics-no-data-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx
index 3644d7acad093..5c4f74b5ad4fa 100644
--- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx
+++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPageKibanaNoDataPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data
title: "@kbn/shared-ux-page-kibana-no-data"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-page-kibana-no-data plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx
index d019b15d67759..70ab9a10e9435 100644
--- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx
+++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPageKibanaNoDataMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks
title: "@kbn/shared-ux-page-kibana-no-data-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx
index 29b118a38656b..bf61fc483d6c5 100644
--- a/api_docs/kbn_shared_ux_page_solution_nav.mdx
+++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPageSolutionNavPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav
title: "@kbn/shared-ux-page-solution-nav"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-page-solution-nav plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-page-solution-nav plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx
index fda31d8d34910..8a24fe051e71a 100644
--- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx
+++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPromptNoDataViewsPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views
title: "@kbn/shared-ux-prompt-no-data-views"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-prompt-no-data-views plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx
index 25bd1af3c2ed3..bb254d68a98c3 100644
--- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx
+++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxPromptNoDataViewsMocksPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks
title: "@kbn/shared-ux-prompt-no-data-views-mocks"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_services.mdx b/api_docs/kbn_shared_ux_services.mdx
index c22a7771b5198..bd1958f97749e 100644
--- a/api_docs/kbn_shared_ux_services.mdx
+++ b/api_docs/kbn_shared_ux_services.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxServicesPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-services
title: "@kbn/shared-ux-services"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-services plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-services plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-services']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxServicesObj from './kbn_shared_ux_services.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_storybook.mdx b/api_docs/kbn_shared_ux_storybook.mdx
index fc045d20ddf3a..a13e4cceb4d0c 100644
--- a/api_docs/kbn_shared_ux_storybook.mdx
+++ b/api_docs/kbn_shared_ux_storybook.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxStorybookPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-storybook
title: "@kbn/shared-ux-storybook"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-storybook plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-storybook plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxStorybookObj from './kbn_shared_ux_storybook.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx
index 3595f0ef8c6b6..49725a3f13e47 100644
--- a/api_docs/kbn_shared_ux_storybook_mock.mdx
+++ b/api_docs/kbn_shared_ux_storybook_mock.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxStorybookMockPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock
title: "@kbn/shared-ux-storybook-mock"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-storybook-mock plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-storybook-mock plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json';
diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx
index 9b65d143ab654..364e61e82fd8a 100644
--- a/api_docs/kbn_shared_ux_utility.mdx
+++ b/api_docs/kbn_shared_ux_utility.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSharedUxUtilityPluginApi
slug: /kibana-dev-docs/api/kbn-shared-ux-utility
title: "@kbn/shared-ux-utility"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/shared-ux-utility plugin
-date: 2022-08-10
+description: API docs for the @kbn/shared-ux-utility plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json';
diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx
index 2051d3395ffa1..7f40f129763d0 100644
--- a/api_docs/kbn_some_dev_log.mdx
+++ b/api_docs/kbn_some_dev_log.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSomeDevLogPluginApi
slug: /kibana-dev-docs/api/kbn-some-dev-log
title: "@kbn/some-dev-log"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/some-dev-log plugin
-date: 2022-08-10
+description: API docs for the @kbn/some-dev-log plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json';
diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx
index c4befb85d9af4..825cbae993202 100644
--- a/api_docs/kbn_sort_package_json.mdx
+++ b/api_docs/kbn_sort_package_json.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnSortPackageJsonPluginApi
slug: /kibana-dev-docs/api/kbn-sort-package-json
title: "@kbn/sort-package-json"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/sort-package-json plugin
-date: 2022-08-10
+description: API docs for the @kbn/sort-package-json plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json';
diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx
index 2b6c2b5320fde..6bbc561c4830f 100644
--- a/api_docs/kbn_std.mdx
+++ b/api_docs/kbn_std.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnStdPluginApi
slug: /kibana-dev-docs/api/kbn-std
title: "@kbn/std"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/std plugin
-date: 2022-08-10
+description: API docs for the @kbn/std plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnStdObj from './kbn_std.devdocs.json';
diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx
index 657bbdc0e9f4e..1f6b56839503a 100644
--- a/api_docs/kbn_stdio_dev_helpers.mdx
+++ b/api_docs/kbn_stdio_dev_helpers.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnStdioDevHelpersPluginApi
slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers
title: "@kbn/stdio-dev-helpers"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/stdio-dev-helpers plugin
-date: 2022-08-10
+description: API docs for the @kbn/stdio-dev-helpers plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json';
diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx
index 30c0da2b24cb7..d5c5ecd971061 100644
--- a/api_docs/kbn_storybook.mdx
+++ b/api_docs/kbn_storybook.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnStorybookPluginApi
slug: /kibana-dev-docs/api/kbn-storybook
title: "@kbn/storybook"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/storybook plugin
-date: 2022-08-10
+description: API docs for the @kbn/storybook plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnStorybookObj from './kbn_storybook.devdocs.json';
diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx
index 95f4d0a0c39d6..eb842010913da 100644
--- a/api_docs/kbn_telemetry_tools.mdx
+++ b/api_docs/kbn_telemetry_tools.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTelemetryToolsPluginApi
slug: /kibana-dev-docs/api/kbn-telemetry-tools
title: "@kbn/telemetry-tools"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/telemetry-tools plugin
-date: 2022-08-10
+description: API docs for the @kbn/telemetry-tools plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json';
diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx
index 54dc3daf11382..81468659ef8d1 100644
--- a/api_docs/kbn_test.mdx
+++ b/api_docs/kbn_test.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTestPluginApi
slug: /kibana-dev-docs/api/kbn-test
title: "@kbn/test"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/test plugin
-date: 2022-08-10
+description: API docs for the @kbn/test plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTestObj from './kbn_test.devdocs.json';
diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx
index 0555066353d71..218032a0205ce 100644
--- a/api_docs/kbn_test_jest_helpers.mdx
+++ b/api_docs/kbn_test_jest_helpers.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTestJestHelpersPluginApi
slug: /kibana-dev-docs/api/kbn-test-jest-helpers
title: "@kbn/test-jest-helpers"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/test-jest-helpers plugin
-date: 2022-08-10
+description: API docs for the @kbn/test-jest-helpers plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json';
diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx
index 2c50d575b67c2..e04ac886039e9 100644
--- a/api_docs/kbn_tooling_log.mdx
+++ b/api_docs/kbn_tooling_log.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnToolingLogPluginApi
slug: /kibana-dev-docs/api/kbn-tooling-log
title: "@kbn/tooling-log"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/tooling-log plugin
-date: 2022-08-10
+description: API docs for the @kbn/tooling-log plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnToolingLogObj from './kbn_tooling_log.devdocs.json';
diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx
index 5f9161ddc8121..b93458fcfd6f3 100644
--- a/api_docs/kbn_type_summarizer.mdx
+++ b/api_docs/kbn_type_summarizer.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTypeSummarizerPluginApi
slug: /kibana-dev-docs/api/kbn-type-summarizer
title: "@kbn/type-summarizer"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/type-summarizer plugin
-date: 2022-08-10
+description: API docs for the @kbn/type-summarizer plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json';
diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx
index c2213c413022c..09973a0355c1a 100644
--- a/api_docs/kbn_type_summarizer_core.mdx
+++ b/api_docs/kbn_type_summarizer_core.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTypeSummarizerCorePluginApi
slug: /kibana-dev-docs/api/kbn-type-summarizer-core
title: "@kbn/type-summarizer-core"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/type-summarizer-core plugin
-date: 2022-08-10
+description: API docs for the @kbn/type-summarizer-core plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json';
diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx
index 7401bb90b53be..fc803c91fe227 100644
--- a/api_docs/kbn_typed_react_router_config.mdx
+++ b/api_docs/kbn_typed_react_router_config.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnTypedReactRouterConfigPluginApi
slug: /kibana-dev-docs/api/kbn-typed-react-router-config
title: "@kbn/typed-react-router-config"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/typed-react-router-config plugin
-date: 2022-08-10
+description: API docs for the @kbn/typed-react-router-config plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json';
diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx
index 4ad76a0b2cce5..0b8adb42b2510 100644
--- a/api_docs/kbn_ui_theme.mdx
+++ b/api_docs/kbn_ui_theme.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnUiThemePluginApi
slug: /kibana-dev-docs/api/kbn-ui-theme
title: "@kbn/ui-theme"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/ui-theme plugin
-date: 2022-08-10
+description: API docs for the @kbn/ui-theme plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnUiThemeObj from './kbn_ui_theme.devdocs.json';
diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx
index 315320ec12199..49b6b5b49565d 100644
--- a/api_docs/kbn_user_profile_components.mdx
+++ b/api_docs/kbn_user_profile_components.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnUserProfileComponentsPluginApi
slug: /kibana-dev-docs/api/kbn-user-profile-components
title: "@kbn/user-profile-components"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/user-profile-components plugin
-date: 2022-08-10
+description: API docs for the @kbn/user-profile-components plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json';
diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx
index b5f9fc136eb24..53d0fa73d9ee0 100644
--- a/api_docs/kbn_utility_types.mdx
+++ b/api_docs/kbn_utility_types.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnUtilityTypesPluginApi
slug: /kibana-dev-docs/api/kbn-utility-types
title: "@kbn/utility-types"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/utility-types plugin
-date: 2022-08-10
+description: API docs for the @kbn/utility-types plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json';
diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx
index 820eaf6f617ee..bdecfc73f4ebc 100644
--- a/api_docs/kbn_utility_types_jest.mdx
+++ b/api_docs/kbn_utility_types_jest.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnUtilityTypesJestPluginApi
slug: /kibana-dev-docs/api/kbn-utility-types-jest
title: "@kbn/utility-types-jest"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/utility-types-jest plugin
-date: 2022-08-10
+description: API docs for the @kbn/utility-types-jest plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json';
diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx
index 731bba5581005..b546f76fbb408 100644
--- a/api_docs/kbn_utils.mdx
+++ b/api_docs/kbn_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnUtilsPluginApi
slug: /kibana-dev-docs/api/kbn-utils
title: "@kbn/utils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/utils plugin
-date: 2022-08-10
+description: API docs for the @kbn/utils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnUtilsObj from './kbn_utils.devdocs.json';
diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx
index 02a3897d7c631..7b193b75ddcbc 100644
--- a/api_docs/kbn_yarn_lock_validator.mdx
+++ b/api_docs/kbn_yarn_lock_validator.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKbnYarnLockValidatorPluginApi
slug: /kibana-dev-docs/api/kbn-yarn-lock-validator
title: "@kbn/yarn-lock-validator"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the @kbn/yarn-lock-validator plugin
-date: 2022-08-10
+description: API docs for the @kbn/yarn-lock-validator plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json';
diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx
index a8020229ae902..9b707bb0c7dcf 100644
--- a/api_docs/kibana_overview.mdx
+++ b/api_docs/kibana_overview.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKibanaOverviewPluginApi
slug: /kibana-dev-docs/api/kibanaOverview
title: "kibanaOverview"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the kibanaOverview plugin
-date: 2022-08-10
+description: API docs for the kibanaOverview plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kibanaOverviewObj from './kibana_overview.devdocs.json';
diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx
index a6184ddccc580..8c7f62aba1414 100644
--- a/api_docs/kibana_react.mdx
+++ b/api_docs/kibana_react.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKibanaReactPluginApi
slug: /kibana-dev-docs/api/kibanaReact
title: "kibanaReact"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the kibanaReact plugin
-date: 2022-08-10
+description: API docs for the kibanaReact plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kibanaReactObj from './kibana_react.devdocs.json';
diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx
index dc2050c831113..e56406b94b4c5 100644
--- a/api_docs/kibana_utils.mdx
+++ b/api_docs/kibana_utils.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKibanaUtilsPluginApi
slug: /kibana-dev-docs/api/kibanaUtils
title: "kibanaUtils"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the kibanaUtils plugin
-date: 2022-08-10
+description: API docs for the kibanaUtils plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kibanaUtilsObj from './kibana_utils.devdocs.json';
diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx
index 16b4fb5cb5919..48713acc4b59a 100644
--- a/api_docs/kubernetes_security.mdx
+++ b/api_docs/kubernetes_security.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibKubernetesSecurityPluginApi
slug: /kibana-dev-docs/api/kubernetesSecurity
title: "kubernetesSecurity"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the kubernetesSecurity plugin
-date: 2022-08-10
+description: API docs for the kubernetesSecurity plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import kubernetesSecurityObj from './kubernetes_security.devdocs.json';
diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json
index 7f8e68796b1bc..ec3a260fc858e 100644
--- a/api_docs/lens.devdocs.json
+++ b/api_docs/lens.devdocs.json
@@ -54,6 +54,14 @@
"docId": "kibEmbeddablePluginApi",
"section": "def-public.SelfStyledEmbeddable",
"text": "SelfStyledEmbeddable"
+ },
+ ",",
+ {
+ "pluginId": "embeddable",
+ "scope": "public",
+ "docId": "kibEmbeddablePluginApi",
+ "section": "def-public.FilterableEmbeddable",
+ "text": "FilterableEmbeddable"
}
],
"path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx",
@@ -593,6 +601,48 @@
"children": [],
"returnComment": []
},
+ {
+ "parentPluginId": "lens",
+ "id": "def-public.Embeddable.getFilters",
+ "type": "Function",
+ "tags": [],
+ "label": "getFilters",
+ "description": [
+ "\nGets the Lens embeddable's local filters"
+ ],
+ "signature": [
+ "() => Promise<",
+ "Filter",
+ "[]>"
+ ],
+ "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx",
+ "deprecated": false,
+ "children": [],
+ "returnComment": [
+ "Local/panel-level array of filters for Lens embeddable"
+ ]
+ },
+ {
+ "parentPluginId": "lens",
+ "id": "def-public.Embeddable.getQuery",
+ "type": "Function",
+ "tags": [],
+ "label": "getQuery",
+ "description": [
+ "\nGets the Lens embeddable's local query"
+ ],
+ "signature": [
+ "() => Promise<",
+ "Query",
+ " | undefined>"
+ ],
+ "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx",
+ "deprecated": false,
+ "children": [],
+ "returnComment": [
+ "Local/panel-level query for Lens embeddable"
+ ]
+ },
{
"parentPluginId": "lens",
"id": "def-public.Embeddable.getSavedVis",
diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx
index 00fb0f1fbca99..79cab2a0c391b 100644
--- a/api_docs/lens.mdx
+++ b/api_docs/lens.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibLensPluginApi
slug: /kibana-dev-docs/api/lens
title: "lens"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the lens plugin
-date: 2022-08-10
+description: API docs for the lens plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import lensObj from './lens.devdocs.json';
@@ -18,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors)
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 611 | 0 | 529 | 40 |
+| 613 | 0 | 529 | 40 |
## Client
diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx
index fe15f80ede6f7..aba6b167cae5a 100644
--- a/api_docs/license_api_guard.mdx
+++ b/api_docs/license_api_guard.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibLicenseApiGuardPluginApi
slug: /kibana-dev-docs/api/licenseApiGuard
title: "licenseApiGuard"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the licenseApiGuard plugin
-date: 2022-08-10
+description: API docs for the licenseApiGuard plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import licenseApiGuardObj from './license_api_guard.devdocs.json';
diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx
index 4f3ca21b59ae6..812fddd90eaa4 100644
--- a/api_docs/license_management.mdx
+++ b/api_docs/license_management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibLicenseManagementPluginApi
slug: /kibana-dev-docs/api/licenseManagement
title: "licenseManagement"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the licenseManagement plugin
-date: 2022-08-10
+description: API docs for the licenseManagement plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import licenseManagementObj from './license_management.devdocs.json';
diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx
index 67265e266c821..5e24095c695cf 100644
--- a/api_docs/licensing.mdx
+++ b/api_docs/licensing.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibLicensingPluginApi
slug: /kibana-dev-docs/api/licensing
title: "licensing"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the licensing plugin
-date: 2022-08-10
+description: API docs for the licensing plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import licensingObj from './licensing.devdocs.json';
diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx
index 0979a5b708ff8..650ae2c402952 100644
--- a/api_docs/lists.mdx
+++ b/api_docs/lists.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibListsPluginApi
slug: /kibana-dev-docs/api/lists
title: "lists"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the lists plugin
-date: 2022-08-10
+description: API docs for the lists plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import listsObj from './lists.devdocs.json';
diff --git a/api_docs/management.mdx b/api_docs/management.mdx
index 0ed65db0d4f12..bd6c4e20be181 100644
--- a/api_docs/management.mdx
+++ b/api_docs/management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibManagementPluginApi
slug: /kibana-dev-docs/api/management
title: "management"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the management plugin
-date: 2022-08-10
+description: API docs for the management plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import managementObj from './management.devdocs.json';
diff --git a/api_docs/maps.devdocs.json b/api_docs/maps.devdocs.json
index adf14e6907d43..26f459392cbd9 100644
--- a/api_docs/maps.devdocs.json
+++ b/api_docs/maps.devdocs.json
@@ -202,7 +202,14 @@
"MapByValueInput",
", ",
"MapByReferenceInput",
- ">"
+ ">,",
+ {
+ "pluginId": "embeddable",
+ "scope": "public",
+ "docId": "kibEmbeddablePluginApi",
+ "section": "def-public.FilterableEmbeddable",
+ "text": "FilterableEmbeddable"
+ }
],
"path": "x-pack/plugins/maps/public/embeddable/map_embeddable.tsx",
"deprecated": false,
@@ -453,6 +460,44 @@
"children": [],
"returnComment": []
},
+ {
+ "parentPluginId": "maps",
+ "id": "def-public.MapEmbeddable.getFilters",
+ "type": "Function",
+ "tags": [],
+ "label": "getFilters",
+ "description": [
+ "\nTODO: Implement this function once https://github.com/elastic/kibana/issues/91282 is resolved"
+ ],
+ "signature": [
+ "() => Promise"
+ ],
+ "path": "x-pack/plugins/maps/public/embeddable/map_embeddable.tsx",
+ "deprecated": false,
+ "children": [],
+ "returnComment": [
+ "[]"
+ ]
+ },
+ {
+ "parentPluginId": "maps",
+ "id": "def-public.MapEmbeddable.getQuery",
+ "type": "Function",
+ "tags": [],
+ "label": "getQuery",
+ "description": [
+ "\nTODO: Implement this function once https://github.com/elastic/kibana/issues/91282 is resolved"
+ ],
+ "signature": [
+ "() => Promise"
+ ],
+ "path": "x-pack/plugins/maps/public/embeddable/map_embeddable.tsx",
+ "deprecated": false,
+ "children": [],
+ "returnComment": [
+ "undefined"
+ ]
+ },
{
"parentPluginId": "maps",
"id": "def-public.MapEmbeddable.supportedTriggers",
diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx
index 6829a216fe116..3b773461df244 100644
--- a/api_docs/maps.mdx
+++ b/api_docs/maps.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibMapsPluginApi
slug: /kibana-dev-docs/api/maps
title: "maps"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the maps plugin
-date: 2022-08-10
+description: API docs for the maps plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import mapsObj from './maps.devdocs.json';
@@ -18,7 +21,7 @@ Contact [GIS](https://github.com/orgs/elastic/teams/kibana-gis) for questions re
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 253 | 0 | 252 | 25 |
+| 255 | 0 | 252 | 25 |
## Client
diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx
index d7a63f3d34ee7..70e163489b0a0 100644
--- a/api_docs/maps_ems.mdx
+++ b/api_docs/maps_ems.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibMapsEmsPluginApi
slug: /kibana-dev-docs/api/mapsEms
title: "mapsEms"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the mapsEms plugin
-date: 2022-08-10
+description: API docs for the mapsEms plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import mapsEmsObj from './maps_ems.devdocs.json';
diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx
index 9516946b4ce9e..8e72f2881a7b4 100644
--- a/api_docs/ml.mdx
+++ b/api_docs/ml.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibMlPluginApi
slug: /kibana-dev-docs/api/ml
title: "ml"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the ml plugin
-date: 2022-08-10
+description: API docs for the ml plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import mlObj from './ml.devdocs.json';
diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx
index 92a65a43a0659..35d5950e9aa09 100644
--- a/api_docs/monitoring.mdx
+++ b/api_docs/monitoring.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibMonitoringPluginApi
slug: /kibana-dev-docs/api/monitoring
title: "monitoring"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the monitoring plugin
-date: 2022-08-10
+description: API docs for the monitoring plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import monitoringObj from './monitoring.devdocs.json';
diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx
index 164e2cf2e4552..99444b3ab8c4f 100644
--- a/api_docs/monitoring_collection.mdx
+++ b/api_docs/monitoring_collection.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibMonitoringCollectionPluginApi
slug: /kibana-dev-docs/api/monitoringCollection
title: "monitoringCollection"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the monitoringCollection plugin
-date: 2022-08-10
+description: API docs for the monitoringCollection plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import monitoringCollectionObj from './monitoring_collection.devdocs.json';
diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx
index 88649fac25726..3e6e703b2627f 100644
--- a/api_docs/navigation.mdx
+++ b/api_docs/navigation.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibNavigationPluginApi
slug: /kibana-dev-docs/api/navigation
title: "navigation"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the navigation plugin
-date: 2022-08-10
+description: API docs for the navigation plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import navigationObj from './navigation.devdocs.json';
diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx
index e3d0f4030217b..4c27826c7d70d 100644
--- a/api_docs/newsfeed.mdx
+++ b/api_docs/newsfeed.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibNewsfeedPluginApi
slug: /kibana-dev-docs/api/newsfeed
title: "newsfeed"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the newsfeed plugin
-date: 2022-08-10
+description: API docs for the newsfeed plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import newsfeedObj from './newsfeed.devdocs.json';
diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx
index 2fef46534e32c..beb1f8ed4ce00 100644
--- a/api_docs/observability.mdx
+++ b/api_docs/observability.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibObservabilityPluginApi
slug: /kibana-dev-docs/api/observability
title: "observability"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the observability plugin
-date: 2022-08-10
+description: API docs for the observability plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import observabilityObj from './observability.devdocs.json';
diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx
index 0662d95a4578d..932943299b4d5 100644
--- a/api_docs/osquery.mdx
+++ b/api_docs/osquery.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibOsqueryPluginApi
slug: /kibana-dev-docs/api/osquery
title: "osquery"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the osquery plugin
-date: 2022-08-10
+description: API docs for the osquery plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import osqueryObj from './osquery.devdocs.json';
diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx
index 8739896158d98..5edc8ff33896b 100644
--- a/api_docs/plugin_directory.mdx
+++ b/api_docs/plugin_directory.mdx
@@ -1,28 +1,31 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibDevDocsPluginDirectory
slug: /kibana-dev-docs/api-meta/plugin-api-directory
title: Directory
-summary: Directory of public APIs available through plugins or packages.
-date: 2022-08-10
+description: Directory of public APIs available through plugins or packages.
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
### Overall stats
-| Count | Plugins or Packages with a
public API | Number of teams |
+| Count | Plugins or Packages with a
public API | Number of teams |
|--------------|----------|------------------------|
| 401 | 335 | 36 |
### Public API health stats
-| API Count | Any Count | Missing comments | Missing exports |
+| API Count | Any Count | Missing comments | Missing exports |
|--------------|----------|-----------------|--------|
-| 28869 | 175 | 19603 | 911 |
+| 28894 | 175 | 19605 | 911 |
## Plugin Directory
-| Plugin name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
+| Plugin name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 266 | 0 | 261 | 19 |
| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 23 | 0 | 19 | 1 |
@@ -41,7 +44,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2524 | 2 | 296 | 6 |
| crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 102 | 0 | 83 | 1 |
-| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 143 | 0 | 141 | 12 |
+| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 146 | 0 | 141 | 12 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3100 | 34 | 2421 | 22 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 15 | 0 | 7 | 0 |
@@ -52,7 +55,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 |
| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 84 | 0 | 68 | 7 |
| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 |
-| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 507 | 0 | 413 | 4 |
+| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 512 | 0 | 413 | 4 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 |
| | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 42 | 0 |
| | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 6 | 0 | 6 | 0 |
@@ -95,14 +98,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 420 | 9 |
| | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 |
-| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 611 | 0 | 529 | 40 |
+| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 613 | 0 | 529 | 40 |
| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 |
| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 |
| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 |
| | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 202 | 0 | 90 | 49 |
| logstash | [Logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 |
| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 41 | 0 | 41 | 6 |
-| | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 253 | 0 | 252 | 25 |
+| | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 255 | 0 | 252 | 25 |
| | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 |
| | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 244 | 9 | 71 | 30 |
| | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 11 | 0 | 9 | 1 |
@@ -146,7 +149,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 428 | 0 | 407 | 46 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 130 | 0 | 91 | 11 |
| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 205 | 0 | 142 | 9 |
-| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 97 | 2 | 84 | 16 |
+| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 108 | 2 | 84 | 16 |
| upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| urlDrilldown | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds drilldown implementations to Kibana | 0 | 0 | 0 | 0 |
| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 12 | 0 | 12 | 0 |
@@ -170,7 +173,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
## Package Directory
-| Package name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
+| Package name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
| | [Owner missing] | Elastic APM trace data generator | 74 | 0 | 74 | 11 |
| | [Owner missing] | - | 11 | 5 | 11 | 0 |
@@ -338,7 +341,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 458 | 1 | 446 | 0 |
| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 61 | 0 | 32 | 0 |
| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 28 | 0 | 21 | 0 |
-| | [Owner missing] | security solution list REST API | 59 | 0 | 58 | 0 |
+| | [Owner missing] | security solution list REST API | 61 | 0 | 60 | 0 |
| | [Owner missing] | security solution list constants to use across plugins such lists, security_solution, cases, etc... | 26 | 0 | 12 | 0 |
| | [Owner missing] | Security solution list ReactJS hooks | 56 | 0 | 44 | 0 |
| | [Owner missing] | security solution list utilities | 235 | 0 | 187 | 0 |
diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx
index 3aa8398b740c4..4941daae32dd9 100644
--- a/api_docs/presentation_util.mdx
+++ b/api_docs/presentation_util.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibPresentationUtilPluginApi
slug: /kibana-dev-docs/api/presentationUtil
title: "presentationUtil"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the presentationUtil plugin
-date: 2022-08-10
+description: API docs for the presentationUtil plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import presentationUtilObj from './presentation_util.devdocs.json';
diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx
index 6f0cd82e1a78e..8d4396be9bf19 100644
--- a/api_docs/remote_clusters.mdx
+++ b/api_docs/remote_clusters.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibRemoteClustersPluginApi
slug: /kibana-dev-docs/api/remoteClusters
title: "remoteClusters"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the remoteClusters plugin
-date: 2022-08-10
+description: API docs for the remoteClusters plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import remoteClustersObj from './remote_clusters.devdocs.json';
diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx
index 5afca34982f27..6aee86e0fdf60 100644
--- a/api_docs/reporting.mdx
+++ b/api_docs/reporting.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibReportingPluginApi
slug: /kibana-dev-docs/api/reporting
title: "reporting"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the reporting plugin
-date: 2022-08-10
+description: API docs for the reporting plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import reportingObj from './reporting.devdocs.json';
diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx
index bc77cfd91dcbb..023133740bb35 100644
--- a/api_docs/rollup.mdx
+++ b/api_docs/rollup.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibRollupPluginApi
slug: /kibana-dev-docs/api/rollup
title: "rollup"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the rollup plugin
-date: 2022-08-10
+description: API docs for the rollup plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import rollupObj from './rollup.devdocs.json';
diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx
index 6c8d83bc98738..932775d59d1f8 100644
--- a/api_docs/rule_registry.mdx
+++ b/api_docs/rule_registry.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibRuleRegistryPluginApi
slug: /kibana-dev-docs/api/ruleRegistry
title: "ruleRegistry"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the ruleRegistry plugin
-date: 2022-08-10
+description: API docs for the ruleRegistry plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import ruleRegistryObj from './rule_registry.devdocs.json';
diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx
index a5ee7c49d1451..c8f4bbb7cfd54 100644
--- a/api_docs/runtime_fields.mdx
+++ b/api_docs/runtime_fields.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibRuntimeFieldsPluginApi
slug: /kibana-dev-docs/api/runtimeFields
title: "runtimeFields"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the runtimeFields plugin
-date: 2022-08-10
+description: API docs for the runtimeFields plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import runtimeFieldsObj from './runtime_fields.devdocs.json';
diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx
index 130c38292d30b..2a45acec975d7 100644
--- a/api_docs/saved_objects.mdx
+++ b/api_docs/saved_objects.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSavedObjectsPluginApi
slug: /kibana-dev-docs/api/savedObjects
title: "savedObjects"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the savedObjects plugin
-date: 2022-08-10
+description: API docs for the savedObjects plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import savedObjectsObj from './saved_objects.devdocs.json';
diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx
index 668ccd3daae20..5aedc341f2015 100644
--- a/api_docs/saved_objects_management.mdx
+++ b/api_docs/saved_objects_management.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSavedObjectsManagementPluginApi
slug: /kibana-dev-docs/api/savedObjectsManagement
title: "savedObjectsManagement"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the savedObjectsManagement plugin
-date: 2022-08-10
+description: API docs for the savedObjectsManagement plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import savedObjectsManagementObj from './saved_objects_management.devdocs.json';
diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx
index 4685825e7a6cd..fcdc28e190291 100644
--- a/api_docs/saved_objects_tagging.mdx
+++ b/api_docs/saved_objects_tagging.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSavedObjectsTaggingPluginApi
slug: /kibana-dev-docs/api/savedObjectsTagging
title: "savedObjectsTagging"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the savedObjectsTagging plugin
-date: 2022-08-10
+description: API docs for the savedObjectsTagging plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json';
diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx
index 76f90c0802efc..b20c324fc1752 100644
--- a/api_docs/saved_objects_tagging_oss.mdx
+++ b/api_docs/saved_objects_tagging_oss.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSavedObjectsTaggingOssPluginApi
slug: /kibana-dev-docs/api/savedObjectsTaggingOss
title: "savedObjectsTaggingOss"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the savedObjectsTaggingOss plugin
-date: 2022-08-10
+description: API docs for the savedObjectsTaggingOss plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json';
diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx
index 16d10745203e9..33de999c00487 100644
--- a/api_docs/screenshot_mode.mdx
+++ b/api_docs/screenshot_mode.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibScreenshotModePluginApi
slug: /kibana-dev-docs/api/screenshotMode
title: "screenshotMode"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the screenshotMode plugin
-date: 2022-08-10
+description: API docs for the screenshotMode plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import screenshotModeObj from './screenshot_mode.devdocs.json';
diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx
index 86e79999b384d..8d5a646481901 100644
--- a/api_docs/screenshotting.mdx
+++ b/api_docs/screenshotting.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibScreenshottingPluginApi
slug: /kibana-dev-docs/api/screenshotting
title: "screenshotting"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the screenshotting plugin
-date: 2022-08-10
+description: API docs for the screenshotting plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import screenshottingObj from './screenshotting.devdocs.json';
diff --git a/api_docs/security.mdx b/api_docs/security.mdx
index f8511044a4fca..706e8aac91546 100644
--- a/api_docs/security.mdx
+++ b/api_docs/security.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSecurityPluginApi
slug: /kibana-dev-docs/api/security
title: "security"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the security plugin
-date: 2022-08-10
+description: API docs for the security plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import securityObj from './security.devdocs.json';
diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx
index c7482d78f41f7..21c98900020f0 100644
--- a/api_docs/security_solution.mdx
+++ b/api_docs/security_solution.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSecuritySolutionPluginApi
slug: /kibana-dev-docs/api/securitySolution
title: "securitySolution"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the securitySolution plugin
-date: 2022-08-10
+description: API docs for the securitySolution plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import securitySolutionObj from './security_solution.devdocs.json';
diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx
index 4ca297f594c7a..68180e9038995 100644
--- a/api_docs/session_view.mdx
+++ b/api_docs/session_view.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSessionViewPluginApi
slug: /kibana-dev-docs/api/sessionView
title: "sessionView"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the sessionView plugin
-date: 2022-08-10
+description: API docs for the sessionView plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import sessionViewObj from './session_view.devdocs.json';
diff --git a/api_docs/share.mdx b/api_docs/share.mdx
index b753451bb6e4b..b573d28030c72 100644
--- a/api_docs/share.mdx
+++ b/api_docs/share.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSharePluginApi
slug: /kibana-dev-docs/api/share
title: "share"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the share plugin
-date: 2022-08-10
+description: API docs for the share plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import shareObj from './share.devdocs.json';
diff --git a/api_docs/shared_u_x.mdx b/api_docs/shared_u_x.mdx
index 8a6d39f05d426..d6cfa15485188 100644
--- a/api_docs/shared_u_x.mdx
+++ b/api_docs/shared_u_x.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSharedUXPluginApi
slug: /kibana-dev-docs/api/sharedUX
title: "sharedUX"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the sharedUX plugin
-date: 2022-08-10
+description: API docs for the sharedUX plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sharedUX']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import sharedUXObj from './shared_u_x.devdocs.json';
diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx
index caeac63ee507a..d3d5e104f4526 100644
--- a/api_docs/snapshot_restore.mdx
+++ b/api_docs/snapshot_restore.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSnapshotRestorePluginApi
slug: /kibana-dev-docs/api/snapshotRestore
title: "snapshotRestore"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the snapshotRestore plugin
-date: 2022-08-10
+description: API docs for the snapshotRestore plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import snapshotRestoreObj from './snapshot_restore.devdocs.json';
diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx
index f5ebf550fc41b..9038d2eacc908 100644
--- a/api_docs/spaces.mdx
+++ b/api_docs/spaces.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibSpacesPluginApi
slug: /kibana-dev-docs/api/spaces
title: "spaces"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the spaces plugin
-date: 2022-08-10
+description: API docs for the spaces plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import spacesObj from './spaces.devdocs.json';
diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx
index 10fa21f771ae1..dcdba1552f10a 100644
--- a/api_docs/stack_alerts.mdx
+++ b/api_docs/stack_alerts.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibStackAlertsPluginApi
slug: /kibana-dev-docs/api/stackAlerts
title: "stackAlerts"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the stackAlerts plugin
-date: 2022-08-10
+description: API docs for the stackAlerts plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import stackAlertsObj from './stack_alerts.devdocs.json';
diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx
index de967da0a364b..ce359ca4fd7b9 100644
--- a/api_docs/task_manager.mdx
+++ b/api_docs/task_manager.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTaskManagerPluginApi
slug: /kibana-dev-docs/api/taskManager
title: "taskManager"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the taskManager plugin
-date: 2022-08-10
+description: API docs for the taskManager plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import taskManagerObj from './task_manager.devdocs.json';
diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx
index c60df09c546fb..89a01c83122b2 100644
--- a/api_docs/telemetry.mdx
+++ b/api_docs/telemetry.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTelemetryPluginApi
slug: /kibana-dev-docs/api/telemetry
title: "telemetry"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the telemetry plugin
-date: 2022-08-10
+description: API docs for the telemetry plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import telemetryObj from './telemetry.devdocs.json';
diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx
index cf79719b39296..865e7be0c9551 100644
--- a/api_docs/telemetry_collection_manager.mdx
+++ b/api_docs/telemetry_collection_manager.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTelemetryCollectionManagerPluginApi
slug: /kibana-dev-docs/api/telemetryCollectionManager
title: "telemetryCollectionManager"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the telemetryCollectionManager plugin
-date: 2022-08-10
+description: API docs for the telemetryCollectionManager plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json';
diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx
index ecd2f8c6086e3..b4fa569dbc78b 100644
--- a/api_docs/telemetry_collection_xpack.mdx
+++ b/api_docs/telemetry_collection_xpack.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTelemetryCollectionXpackPluginApi
slug: /kibana-dev-docs/api/telemetryCollectionXpack
title: "telemetryCollectionXpack"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the telemetryCollectionXpack plugin
-date: 2022-08-10
+description: API docs for the telemetryCollectionXpack plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json';
diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx
index 1a53259103f89..486de1a4c8432 100644
--- a/api_docs/telemetry_management_section.mdx
+++ b/api_docs/telemetry_management_section.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTelemetryManagementSectionPluginApi
slug: /kibana-dev-docs/api/telemetryManagementSection
title: "telemetryManagementSection"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the telemetryManagementSection plugin
-date: 2022-08-10
+description: API docs for the telemetryManagementSection plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json';
diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx
index cfc255dfe62c6..f147d268825a2 100644
--- a/api_docs/threat_intelligence.mdx
+++ b/api_docs/threat_intelligence.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibThreatIntelligencePluginApi
slug: /kibana-dev-docs/api/threatIntelligence
title: "threatIntelligence"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the threatIntelligence plugin
-date: 2022-08-10
+description: API docs for the threatIntelligence plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import threatIntelligenceObj from './threat_intelligence.devdocs.json';
diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx
index 85bb399795ea7..b955620c88ff3 100644
--- a/api_docs/timelines.mdx
+++ b/api_docs/timelines.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTimelinesPluginApi
slug: /kibana-dev-docs/api/timelines
title: "timelines"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the timelines plugin
-date: 2022-08-10
+description: API docs for the timelines plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import timelinesObj from './timelines.devdocs.json';
diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx
index 0a2bf3dbb972d..5f6c713dc50d3 100644
--- a/api_docs/transform.mdx
+++ b/api_docs/transform.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTransformPluginApi
slug: /kibana-dev-docs/api/transform
title: "transform"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the transform plugin
-date: 2022-08-10
+description: API docs for the transform plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import transformObj from './transform.devdocs.json';
diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx
index d8516da231894..d55719923df33 100644
--- a/api_docs/triggers_actions_ui.mdx
+++ b/api_docs/triggers_actions_ui.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibTriggersActionsUiPluginApi
slug: /kibana-dev-docs/api/triggersActionsUi
title: "triggersActionsUi"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the triggersActionsUi plugin
-date: 2022-08-10
+description: API docs for the triggersActionsUi plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import triggersActionsUiObj from './triggers_actions_ui.devdocs.json';
diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx
index 0af35abc19f93..375718734c27e 100644
--- a/api_docs/ui_actions.mdx
+++ b/api_docs/ui_actions.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUiActionsPluginApi
slug: /kibana-dev-docs/api/uiActions
title: "uiActions"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the uiActions plugin
-date: 2022-08-10
+description: API docs for the uiActions plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import uiActionsObj from './ui_actions.devdocs.json';
diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx
index 922a3ab74839d..e651863ed5962 100644
--- a/api_docs/ui_actions_enhanced.mdx
+++ b/api_docs/ui_actions_enhanced.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUiActionsEnhancedPluginApi
slug: /kibana-dev-docs/api/uiActionsEnhanced
title: "uiActionsEnhanced"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the uiActionsEnhanced plugin
-date: 2022-08-10
+description: API docs for the uiActionsEnhanced plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json';
diff --git a/api_docs/unified_search.devdocs.json b/api_docs/unified_search.devdocs.json
index 42f2de80c7812..756a40fd1398a 100644
--- a/api_docs/unified_search.devdocs.json
+++ b/api_docs/unified_search.devdocs.json
@@ -75,7 +75,9 @@
"type": "Function",
"tags": [],
"label": "FilterItem",
- "description": [],
+ "description": [
+ "\nRenders a single filter pill"
+ ],
"signature": [
"(props: ",
"FilterItemProps",
@@ -102,13 +104,80 @@
"returnComment": [],
"initialIsOpen": false
},
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItems",
+ "type": "Function",
+ "tags": [],
+ "label": "FilterItems",
+ "description": [
+ "\nRenders a group of filter pills"
+ ],
+ "signature": [
+ "(props: Pick<",
+ {
+ "pluginId": "unifiedSearch",
+ "scope": "public",
+ "docId": "kibUnifiedSearchPluginApi",
+ "section": "def-public.FilterItemsProps",
+ "text": "FilterItemsProps"
+ },
+ ", \"filters\" | \"indexPatterns\" | \"readOnly\" | \"onFiltersUpdated\" | \"hiddenPanelOptions\" | \"timeRangeForSuggestionsOverride\"> & React.RefAttributes, any, any>>) => JSX.Element"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/index.tsx",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItems.$1",
+ "type": "CompoundType",
+ "tags": [],
+ "label": "props",
+ "description": [],
+ "signature": [
+ "Pick<",
+ {
+ "pluginId": "unifiedSearch",
+ "scope": "public",
+ "docId": "kibUnifiedSearchPluginApi",
+ "section": "def-public.FilterItemsProps",
+ "text": "FilterItemsProps"
+ },
+ ", \"filters\" | \"indexPatterns\" | \"readOnly\" | \"onFiltersUpdated\" | \"hiddenPanelOptions\" | \"timeRangeForSuggestionsOverride\"> & React.RefAttributes, any, any>>"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/index.tsx",
+ "deprecated": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": [],
+ "initialIsOpen": false
+ },
{
"parentPluginId": "unifiedSearch",
"id": "def-public.FilterLabel",
"type": "Function",
"tags": [],
"label": "FilterLabel",
- "description": [],
+ "description": [
+ "\nRenders the label for a single filter pill"
+ ],
"signature": [
"(props: ",
"FilterLabelProps",
@@ -555,6 +624,155 @@
],
"initialIsOpen": false
},
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps",
+ "type": "Interface",
+ "tags": [],
+ "label": "FilterItemsProps",
+ "description": [
+ "\nProperties for the filter items component, which will render a single filter pill for every filter that is sent in\nas part of the `Filter[]` property."
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.filters",
+ "type": "Array",
+ "tags": [],
+ "label": "filters",
+ "description": [
+ "Array of filters that will be rendered as filter pills"
+ ],
+ "signature": [
+ "Filter",
+ "[]"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.readOnly",
+ "type": "CompoundType",
+ "tags": [],
+ "label": "readOnly",
+ "description": [
+ "Optional property that controls whether or not clicking the filter pill opens a popover *and* whether\nor not the `x` button to remove the filter is rendered."
+ ],
+ "signature": [
+ "boolean | undefined"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.onFiltersUpdated",
+ "type": "Function",
+ "tags": [],
+ "label": "onFiltersUpdated",
+ "description": [
+ "If not read only, this is called whenever a filter is removed and/or updated"
+ ],
+ "signature": [
+ "((filters: ",
+ "Filter",
+ "[]) => void) | undefined"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false,
+ "children": [
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.onFiltersUpdated.$1",
+ "type": "Array",
+ "tags": [],
+ "label": "filters",
+ "description": [],
+ "signature": [
+ "Filter",
+ "[]"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": []
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.indexPatterns",
+ "type": "Array",
+ "tags": [],
+ "label": "indexPatterns",
+ "description": [
+ "A list of all dataviews that are used for the filters"
+ ],
+ "signature": [
+ {
+ "pluginId": "dataViews",
+ "scope": "common",
+ "docId": "kibDataViewsPluginApi",
+ "section": "def-common.DataView",
+ "text": "DataView"
+ },
+ "[]"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.intl",
+ "type": "Object",
+ "tags": [],
+ "label": "intl",
+ "description": [
+ "This is injected by the lazer loader"
+ ],
+ "signature": [
+ "ReactIntl.InjectedIntl"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.timeRangeForSuggestionsOverride",
+ "type": "CompoundType",
+ "tags": [],
+ "label": "timeRangeForSuggestionsOverride",
+ "description": [
+ "Controls whether or not filter suggestions are influenced by the global time"
+ ],
+ "signature": [
+ "boolean | undefined"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ },
+ {
+ "parentPluginId": "unifiedSearch",
+ "id": "def-public.FilterItemsProps.hiddenPanelOptions",
+ "type": "Array",
+ "tags": [],
+ "label": "hiddenPanelOptions",
+ "description": [
+ "Array of panel options that controls the styling of each filter pill"
+ ],
+ "signature": [
+ "FilterPanelOption",
+ "[] | undefined"
+ ],
+ "path": "src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx",
+ "deprecated": false
+ }
+ ],
+ "initialIsOpen": false
+ },
{
"parentPluginId": "unifiedSearch",
"id": "def-public.QueryStringInputProps",
diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx
index 97b843cc9dde3..a5328347a3625 100644
--- a/api_docs/unified_search.mdx
+++ b/api_docs/unified_search.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUnifiedSearchPluginApi
slug: /kibana-dev-docs/api/unifiedSearch
title: "unifiedSearch"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the unifiedSearch plugin
-date: 2022-08-10
+description: API docs for the unifiedSearch plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import unifiedSearchObj from './unified_search.devdocs.json';
@@ -18,7 +21,7 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 97 | 2 | 84 | 16 |
+| 108 | 2 | 84 | 16 |
## Client
diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx
index e412a8083cf9a..d6b1410085d75 100644
--- a/api_docs/unified_search_autocomplete.mdx
+++ b/api_docs/unified_search_autocomplete.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUnifiedSearchAutocompletePluginApi
slug: /kibana-dev-docs/api/unifiedSearch-autocomplete
title: "unifiedSearch.autocomplete"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the unifiedSearch.autocomplete plugin
-date: 2022-08-10
+description: API docs for the unifiedSearch.autocomplete plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json';
@@ -18,7 +21,7 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 97 | 2 | 84 | 16 |
+| 108 | 2 | 84 | 16 |
## Client
diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx
index cc52631ac135a..f1422e2da619e 100644
--- a/api_docs/url_forwarding.mdx
+++ b/api_docs/url_forwarding.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUrlForwardingPluginApi
slug: /kibana-dev-docs/api/urlForwarding
title: "urlForwarding"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the urlForwarding plugin
-date: 2022-08-10
+description: API docs for the urlForwarding plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import urlForwardingObj from './url_forwarding.devdocs.json';
diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx
index e128db53581e2..8c0738785659a 100644
--- a/api_docs/usage_collection.mdx
+++ b/api_docs/usage_collection.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUsageCollectionPluginApi
slug: /kibana-dev-docs/api/usageCollection
title: "usageCollection"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the usageCollection plugin
-date: 2022-08-10
+description: API docs for the usageCollection plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import usageCollectionObj from './usage_collection.devdocs.json';
diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx
index b6ffdcec694e3..7b4f36876f174 100644
--- a/api_docs/ux.mdx
+++ b/api_docs/ux.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibUxPluginApi
slug: /kibana-dev-docs/api/ux
title: "ux"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the ux plugin
-date: 2022-08-10
+description: API docs for the ux plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import uxObj from './ux.devdocs.json';
diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx
index 7c22d241bd58e..d1ca9c1799349 100644
--- a/api_docs/vis_default_editor.mdx
+++ b/api_docs/vis_default_editor.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisDefaultEditorPluginApi
slug: /kibana-dev-docs/api/visDefaultEditor
title: "visDefaultEditor"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visDefaultEditor plugin
-date: 2022-08-10
+description: API docs for the visDefaultEditor plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visDefaultEditorObj from './vis_default_editor.devdocs.json';
diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx
index 9b11dd3d5a4c7..28f78831cc229 100644
--- a/api_docs/vis_type_gauge.mdx
+++ b/api_docs/vis_type_gauge.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeGaugePluginApi
slug: /kibana-dev-docs/api/visTypeGauge
title: "visTypeGauge"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeGauge plugin
-date: 2022-08-10
+description: API docs for the visTypeGauge plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeGaugeObj from './vis_type_gauge.devdocs.json';
diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx
index 74c7d1b717ada..50e7e19e26736 100644
--- a/api_docs/vis_type_heatmap.mdx
+++ b/api_docs/vis_type_heatmap.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeHeatmapPluginApi
slug: /kibana-dev-docs/api/visTypeHeatmap
title: "visTypeHeatmap"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeHeatmap plugin
-date: 2022-08-10
+description: API docs for the visTypeHeatmap plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json';
diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx
index f71e3f5648562..dc67a737d1e99 100644
--- a/api_docs/vis_type_pie.mdx
+++ b/api_docs/vis_type_pie.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypePiePluginApi
slug: /kibana-dev-docs/api/visTypePie
title: "visTypePie"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypePie plugin
-date: 2022-08-10
+description: API docs for the visTypePie plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypePieObj from './vis_type_pie.devdocs.json';
diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx
index 41a117811917b..f5d1e470e712b 100644
--- a/api_docs/vis_type_table.mdx
+++ b/api_docs/vis_type_table.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeTablePluginApi
slug: /kibana-dev-docs/api/visTypeTable
title: "visTypeTable"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeTable plugin
-date: 2022-08-10
+description: API docs for the visTypeTable plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeTableObj from './vis_type_table.devdocs.json';
diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx
index 36444e9743320..078ba6536f657 100644
--- a/api_docs/vis_type_timelion.mdx
+++ b/api_docs/vis_type_timelion.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeTimelionPluginApi
slug: /kibana-dev-docs/api/visTypeTimelion
title: "visTypeTimelion"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeTimelion plugin
-date: 2022-08-10
+description: API docs for the visTypeTimelion plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeTimelionObj from './vis_type_timelion.devdocs.json';
diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx
index e9a30d0942595..9d18d6a2cb129 100644
--- a/api_docs/vis_type_timeseries.mdx
+++ b/api_docs/vis_type_timeseries.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeTimeseriesPluginApi
slug: /kibana-dev-docs/api/visTypeTimeseries
title: "visTypeTimeseries"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeTimeseries plugin
-date: 2022-08-10
+description: API docs for the visTypeTimeseries plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json';
diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx
index f30de804741fc..3b572d668e70e 100644
--- a/api_docs/vis_type_vega.mdx
+++ b/api_docs/vis_type_vega.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeVegaPluginApi
slug: /kibana-dev-docs/api/visTypeVega
title: "visTypeVega"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeVega plugin
-date: 2022-08-10
+description: API docs for the visTypeVega plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeVegaObj from './vis_type_vega.devdocs.json';
diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx
index 28ed93c1531bf..f7cd6b727ef71 100644
--- a/api_docs/vis_type_vislib.mdx
+++ b/api_docs/vis_type_vislib.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeVislibPluginApi
slug: /kibana-dev-docs/api/visTypeVislib
title: "visTypeVislib"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeVislib plugin
-date: 2022-08-10
+description: API docs for the visTypeVislib plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeVislibObj from './vis_type_vislib.devdocs.json';
diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx
index 8f0bc09bcb539..45160066493f5 100644
--- a/api_docs/vis_type_xy.mdx
+++ b/api_docs/vis_type_xy.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisTypeXyPluginApi
slug: /kibana-dev-docs/api/visTypeXy
title: "visTypeXy"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visTypeXy plugin
-date: 2022-08-10
+description: API docs for the visTypeXy plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visTypeXyObj from './vis_type_xy.devdocs.json';
diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json
index 62b7651579dc5..4752d972ce270 100644
--- a/api_docs/visualizations.devdocs.json
+++ b/api_docs/visualizations.devdocs.json
@@ -5157,7 +5157,11 @@
"section": "def-public.ContainerOutput",
"text": "ContainerOutput"
},
- "> | undefined; updateInput: (changes: Partial<",
+ "> | undefined; getQuery: () => Promise<",
+ "Query",
+ " | ",
+ "AggregateQuery",
+ " | undefined>; updateInput: (changes: Partial<",
{
"pluginId": "visualizations",
"scope": "public",
@@ -5165,7 +5169,9 @@
"section": "def-public.VisualizeInput",
"text": "VisualizeInput"
},
- ">) => void; reportsEmbeddableLoad: () => boolean; getInspectorAdapters: () => ",
+ ">) => void; reportsEmbeddableLoad: () => boolean; getFilters: () => Promise<",
+ "Filter",
+ "[]>; getInspectorAdapters: () => ",
{
"pluginId": "inspector",
"scope": "common",
diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx
index 12a8c58e18e10..77bc2d77102e1 100644
--- a/api_docs/visualizations.mdx
+++ b/api_docs/visualizations.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibVisualizationsPluginApi
slug: /kibana-dev-docs/api/visualizations
title: "visualizations"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the visualizations plugin
-date: 2022-08-10
+description: API docs for the visualizations plugin
+date: 2022-08-11
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import visualizationsObj from './visualizations.devdocs.json';
diff --git a/dev_docs/contributing/best_practices.mdx b/dev_docs/contributing/best_practices.mdx
index 3e7fca5539d77..16c66417b89c1 100644
--- a/dev_docs/contributing/best_practices.mdx
+++ b/dev_docs/contributing/best_practices.mdx
@@ -2,7 +2,7 @@
id: kibBestPractices
slug: /kibana-dev-docs/contributing/best-practices
title: Best practices
-summary: Best practices to follow when building a Kibana plugin.
+description: Best practices to follow when building a Kibana plugin.
date: 2021-03-17
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/contributing/code_walkthrough.mdx b/dev_docs/contributing/code_walkthrough.mdx
index 74995c246503c..bae394887c20e 100644
--- a/dev_docs/contributing/code_walkthrough.mdx
+++ b/dev_docs/contributing/code_walkthrough.mdx
@@ -2,7 +2,7 @@
id: kibRepoStructure
slug: /kibana-dev-docs/contributing/repo-structure
title: Repository structure
-summary: High level walk-through of our repository structure.
+description: High level walk-through of our repository structure.
date: 2021-10-07
tags: ['contributor', 'dev', 'github', 'getting started', 'onboarding', 'kibana']
---
diff --git a/dev_docs/contributing/dev_principles.mdx b/dev_docs/contributing/dev_principles.mdx
index 0b8f68d232367..cbea79e658684 100644
--- a/dev_docs/contributing/dev_principles.mdx
+++ b/dev_docs/contributing/dev_principles.mdx
@@ -2,7 +2,7 @@
id: kibDevPrinciples
slug: /kibana-dev-docs/contributing/dev-principles
title: Developer principles
-summary: Follow our development principles to help keep our code base stable, maintainable and scalable.
+description: Follow our development principles to help keep our code base stable, maintainable and scalable.
date: 2021-03-04
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/contributing/documentation.mdx b/dev_docs/contributing/documentation.mdx
index caf2f439548bc..50cc0c8761400 100644
--- a/dev_docs/contributing/documentation.mdx
+++ b/dev_docs/contributing/documentation.mdx
@@ -2,7 +2,7 @@
id: kibDocumentation
slug: /kibana-dev-docs/contributing/documentation
title: Documentation
-summary: Writing documentation during development
+description: Writing documentation during development
date: 2022-03-01
tags: ['kibana', 'onboarding', 'dev']
---
diff --git a/dev_docs/contributing/how_we_use_github.mdx b/dev_docs/contributing/how_we_use_github.mdx
index 339eebc89197b..d427ba7d44f2e 100644
--- a/dev_docs/contributing/how_we_use_github.mdx
+++ b/dev_docs/contributing/how_we_use_github.mdx
@@ -2,7 +2,7 @@
id: kibGitHub
slug: /kibana-dev-docs/contributing/github
title: How we use Github
-summary: Forking, branching, committing and using labels in the Kibana GitHub repo
+description: Forking, branching, committing and using labels in the Kibana GitHub repo
date: 2021-09-16
tags: ['contributor', 'dev', 'github', 'getting started', 'onboarding', 'kibana']
---
diff --git a/dev_docs/contributing/standards.mdx b/dev_docs/contributing/standards.mdx
index cef9199aee924..1bb54ada1509c 100644
--- a/dev_docs/contributing/standards.mdx
+++ b/dev_docs/contributing/standards.mdx
@@ -2,7 +2,7 @@
id: kibStandards
slug: /kibana-dev-docs/standards
title: Standards and guidelines
-summary: Standards and guidelines we expect every Kibana developer to abide by
+description: Standards and guidelines we expect every Kibana developer to abide by
date: 2021-09-28
tags: ['contributor', 'dev', 'github', 'getting started', 'onboarding', 'kibana']
---
diff --git a/dev_docs/getting_started/dev_welcome.mdx b/dev_docs/getting_started/dev_welcome.mdx
index 4080e0850b946..4f5115af6b731 100644
--- a/dev_docs/getting_started/dev_welcome.mdx
+++ b/dev_docs/getting_started/dev_welcome.mdx
@@ -2,7 +2,7 @@
id: kibDevDocsWelcome
slug: /kibana-dev-docs/getting-started/welcome
title: Welcome
-summary: Build custom solutions and applications on top of Kibana.
+description: Build custom solutions and applications on top of Kibana.
date: 2021-01-02
tags: ['kibana', 'dev', 'contributor']
---
diff --git a/dev_docs/getting_started/hello_world_plugin.mdx b/dev_docs/getting_started/hello_world_plugin.mdx
index 8fa4ea4316129..08fd7e4a721c2 100644
--- a/dev_docs/getting_started/hello_world_plugin.mdx
+++ b/dev_docs/getting_started/hello_world_plugin.mdx
@@ -2,7 +2,7 @@
id: kibHelloWorldApp
slug: /kibana-dev-docs/getting-started/hello-world-app
title: Hello World
-summary: Build a very basic plugin that registers an application that says "Hello World!".
+description: Build a very basic plugin that registers an application that says "Hello World!".
date: 2021-08-03
tags: ['kibana', 'dev', 'contributor', 'tutorials']
---
diff --git a/dev_docs/getting_started/setting_up_a_development_env.mdx b/dev_docs/getting_started/setting_up_a_development_env.mdx
index bbbb356d9ea08..8599adf0e53b3 100644
--- a/dev_docs/getting_started/setting_up_a_development_env.mdx
+++ b/dev_docs/getting_started/setting_up_a_development_env.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialSetupDevEnv
slug: /kibana-dev-docs/getting-started/setup-dev-env
title: Set up a Development Environment
-summary: Learn how to setup a development environment for contributing to the Kibana repository
+description: Learn how to setup a development environment for contributing to the Kibana repository
date: 2022-07-07
tags: ['kibana', 'onboarding', 'dev', 'architecture', 'setup']
---
diff --git a/dev_docs/getting_started/troubleshooting.mdx b/dev_docs/getting_started/troubleshooting.mdx
index b224a3200eefb..cb0e1bad1bef5 100644
--- a/dev_docs/getting_started/troubleshooting.mdx
+++ b/dev_docs/getting_started/troubleshooting.mdx
@@ -2,7 +2,7 @@
id: kibTroubleshooting
slug: /kibana-dev-docs/getting-started/troubleshooting
title: Troubleshooting
-summary: A collection of tips for working around strange issues.
+description: A collection of tips for working around strange issues.
date: 2021-09-08
tags: ['kibana', 'onboarding', 'dev', 'troubleshooting']
---
diff --git a/dev_docs/key_concepts/anatomy_of_a_plugin.mdx b/dev_docs/key_concepts/anatomy_of_a_plugin.mdx
index f99c41ff18d07..a126477ea4c2f 100644
--- a/dev_docs/key_concepts/anatomy_of_a_plugin.mdx
+++ b/dev_docs/key_concepts/anatomy_of_a_plugin.mdx
@@ -2,7 +2,7 @@
id: kibDevAnatomyOfAPlugin
slug: /kibana-dev-docs/key-concepts/anatomy-of-a-plugin
title: Anatomy of a plugin
-summary: Anatomy of a Kibana plugin.
+description: Anatomy of a Kibana plugin.
date: 2021-08-03
tags: ['kibana', 'onboarding', 'dev']
---
diff --git a/dev_docs/key_concepts/audit_logging.mdx b/dev_docs/key_concepts/audit_logging.mdx
index 6ec4de320d582..5546e52bf5dd8 100644
--- a/dev_docs/key_concepts/audit_logging.mdx
+++ b/dev_docs/key_concepts/audit_logging.mdx
@@ -2,7 +2,7 @@
id: kibAuditLogging
slug: /kibana-dev-docs/key-concepts/audit-logging
title: Audit Logging
-summary: Audit Logging
+description: Audit Logging
date: 2022-06-15
tags: ['kibana', 'onboarding', 'dev', 'logging', 'audit']
---
diff --git a/dev_docs/key_concepts/building_blocks.mdx b/dev_docs/key_concepts/building_blocks.mdx
index aeb2d2be7d6c9..5a7b79b93debf 100644
--- a/dev_docs/key_concepts/building_blocks.mdx
+++ b/dev_docs/key_concepts/building_blocks.mdx
@@ -2,7 +2,7 @@
id: kibBuildingBlocks
slug: /kibana-dev-docs/key-concepts/building-blocks
title: Building blocks
-summary: Consider these building blocks when developing your plugin.
+description: Consider these building blocks when developing your plugin.
date: 2021-02-24
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/key_concepts/data_views.mdx b/dev_docs/key_concepts/data_views.mdx
index 6a0c2a701fae2..59853f8e0c67e 100644
--- a/dev_docs/key_concepts/data_views.mdx
+++ b/dev_docs/key_concepts/data_views.mdx
@@ -2,7 +2,7 @@
id: kibDataViewsKeyConcepts
slug: /kibana-dev-docs/key-concepts/data-view-intro
title: Data Views
-summary: Data views are the central method of defining queryable data sets in Kibana
+description: Data views are the central method of defining queryable data sets in Kibana
date: 2021-08-11
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/dev_docs/key_concepts/embeddables.mdx b/dev_docs/key_concepts/embeddables.mdx
index 2d5e14b7d4669..f1a2bea5b9b12 100644
--- a/dev_docs/key_concepts/embeddables.mdx
+++ b/dev_docs/key_concepts/embeddables.mdx
@@ -2,7 +2,7 @@
id: kibDevDocsEmbeddables
slug: /kibana-dev-docs/key-concepts/embeddables
title: Embeddables
-summary: Embeddables provide a way to expose a reusable widget.
+description: Embeddables provide a way to expose a reusable widget.
date: 2022-07-27
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx b/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx
index 417d6e4983d4f..98de7d082bc55 100644
--- a/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx
+++ b/dev_docs/key_concepts/kibana_platform_plugin_intro.mdx
@@ -2,7 +2,7 @@
id: kibPlatformIntro
slug: /kibana-dev-docs/key-concepts/platform-intro
title: Plugins, packages, and the platform
-summary: An introduction to the Kibana platform and how to use it to build a plugin.
+description: An introduction to the Kibana platform and how to use it to build a plugin.
date: 2021-01-06
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/key_concepts/navigation.mdx b/dev_docs/key_concepts/navigation.mdx
index 6f3a5e737f91f..e383f21187d41 100644
--- a/dev_docs/key_concepts/navigation.mdx
+++ b/dev_docs/key_concepts/navigation.mdx
@@ -2,7 +2,7 @@
id: kibDevKeyConceptsNavigation
slug: /kibana-dev-docs/routing-and-navigation
title: Routing, Navigation and URL
-summary: Learn best practices about navigation inside Kibana
+description: Learn best practices about navigation inside Kibana
date: 2021-10-05
tags: ['kibana', 'dev', 'architecture', 'contributor']
---
diff --git a/dev_docs/key_concepts/performance.mdx b/dev_docs/key_concepts/performance.mdx
index c57630f508dcd..4d808ed402d32 100644
--- a/dev_docs/key_concepts/performance.mdx
+++ b/dev_docs/key_concepts/performance.mdx
@@ -2,7 +2,7 @@
id: kibDevPerformance
slug: /kibana-dev-docs/key-concepts/performance
title: Performance
-summary: Performance tips for Kibana development.
+description: Performance tips for Kibana development.
date: 2021-12-03
tags: ['kibana', 'onboarding', 'dev', 'performance']
---
diff --git a/dev_docs/key_concepts/persistable_state.mdx b/dev_docs/key_concepts/persistable_state.mdx
index 25d3f37a86be4..75dae5447ffa0 100644
--- a/dev_docs/key_concepts/persistable_state.mdx
+++ b/dev_docs/key_concepts/persistable_state.mdx
@@ -2,7 +2,7 @@
id: kibDevDocsPersistableStateIntro
slug: /kibana-dev-docs/key-concepts/persistable-state-intro
title: Persistable State
-summary: Persitable state is a key concept to understand when building a Kibana plugin.
+description: Persitable state is a key concept to understand when building a Kibana plugin.
date: 2021-02-02
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/dev_docs/key_concepts/saved_objects.mdx b/dev_docs/key_concepts/saved_objects.mdx
index 159e6e90a4037..ee974267c0bb9 100644
--- a/dev_docs/key_concepts/saved_objects.mdx
+++ b/dev_docs/key_concepts/saved_objects.mdx
@@ -2,7 +2,7 @@
id: kibDevDocsSavedObjectsIntro
slug: /kibana-dev-docs/key-concepts/saved-objects-intro
title: Saved Objects
-summary: Saved Objects are a key concept to understand when building a Kibana plugin.
+description: Saved Objects are a key concept to understand when building a Kibana plugin.
date: 2021-02-02
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/dev_docs/tutorials/advanced_settings.mdx b/dev_docs/tutorials/advanced_settings.mdx
index b0c12ad5e5edd..d14da92edc93c 100644
--- a/dev_docs/tutorials/advanced_settings.mdx
+++ b/dev_docs/tutorials/advanced_settings.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialAdvancedSettings
slug: /kibana-dev-docs/tutorials/advanced-settings
title: How to register a new advanced setting
-summary: Learn how to add and use a new advanced setting
+description: Learn how to add and use a new advanced setting
date: 2022-02-07
tags: ['kibana','onboarding', 'dev', 'architecture', 'tutorials']
---
diff --git a/dev_docs/tutorials/building_a_kibana_distributable.mdx b/dev_docs/tutorials/building_a_kibana_distributable.mdx
index e73481058ab35..d95f6246434b9 100644
--- a/dev_docs/tutorials/building_a_kibana_distributable.mdx
+++ b/dev_docs/tutorials/building_a_kibana_distributable.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialBuildingDistributable
slug: /kibana-dev-docs/tutorials/building-distributable
title: Building a Kibana distributable
-summary: Learn how to build a Kibana distributable
+description: Learn how to build a Kibana distributable
date: 2021-05-10
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'build', 'distributable']
---
diff --git a/dev_docs/tutorials/ci.mdx b/dev_docs/tutorials/ci.mdx
index 32e5a8503a22c..6598ed9855dc0 100644
--- a/dev_docs/tutorials/ci.mdx
+++ b/dev_docs/tutorials/ci.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialCI
slug: /kibana-dev-docs/tutorials/ci
title: CI
-summary: CI
+description: CI
date: 2022-02-03
tags: ['kibana', 'onboarding', 'dev', 'ci']
---
diff --git a/dev_docs/tutorials/data/search.mdx b/dev_docs/tutorials/data/search.mdx
index d422eb811b60b..4c64dc0b02164 100644
--- a/dev_docs/tutorials/data/search.mdx
+++ b/dev_docs/tutorials/data/search.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialDataSearchAndSessions
slug: /kibana-dev-docs/tutorials/data/search-and-sessions
title: Kibana data.search Services
-summary: Kibana Search Services
+description: Kibana Search Services
date: 2021-02-10
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'search', 'sessions', 'search-sessions']
---
diff --git a/dev_docs/tutorials/data_views.mdx b/dev_docs/tutorials/data_views.mdx
index eda4b34ac2fd4..51aac0e321692 100644
--- a/dev_docs/tutorials/data_views.mdx
+++ b/dev_docs/tutorials/data_views.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialDataViews
slug: /kibana-dev-docs/tutorials/data-views
title: Data views API
-summary: Data views API
+description: Data views API
date: 2021-08-11
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/tutorials/debugging.mdx b/dev_docs/tutorials/debugging.mdx
index d5d86a9025303..fabd475f88d77 100644
--- a/dev_docs/tutorials/debugging.mdx
+++ b/dev_docs/tutorials/debugging.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialDebugging
slug: /kibana-dev-docs/tutorials/debugging
title: Debugging in development
-summary: Learn how to debug Kibana while running from source
+description: Learn how to debug Kibana while running from source
date: 2021-04-26
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'debugging']
---
diff --git a/dev_docs/tutorials/development_windows.mdx b/dev_docs/tutorials/development_windows.mdx
index 0a39714dfd8ec..ea872072057a3 100644
--- a/dev_docs/tutorials/development_windows.mdx
+++ b/dev_docs/tutorials/development_windows.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialSetupWindowsDevWSL
slug: /kibana-dev-docs/tutorial/setup-windows-development-wsl
title: WSL on Windows Development
-summary: Learn how to setup a Windows development environment using WSL
+description: Learn how to setup a Windows development environment using WSL
date: 2022-07-07
tags: ['kibana', 'onboarding', 'setup', 'windows', 'development', 'wsl']
---
diff --git a/dev_docs/tutorials/endpoints.mdx b/dev_docs/tutorials/endpoints.mdx
index ab7aeda0e5693..851c3046fead6 100644
--- a/dev_docs/tutorials/endpoints.mdx
+++ b/dev_docs/tutorials/endpoints.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialServerEndpoint
slug: /kibana-dev-docs/tutorials/registering-endpoints
title: Registering and accessing an endpoint
-summary: Learn how to register a new endpoint and access it
+description: Learn how to register a new endpoint and access it
date: 2021-11-24
tags: ['kibana', 'dev', 'architecture', 'tutorials']
---
diff --git a/dev_docs/tutorials/expressions.mdx b/dev_docs/tutorials/expressions.mdx
index d9abf3dd57eb8..36df396306cac 100644
--- a/dev_docs/tutorials/expressions.mdx
+++ b/dev_docs/tutorials/expressions.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialExpressions
slug: /kibana-dev-docs/tutorials/expressions
title: Kibana Expressions Service
-summary: Kibana Expressions Service
+description: Kibana Expressions Service
date: 2021-06-01
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/tutorials/kibana_page_template.mdx b/dev_docs/tutorials/kibana_page_template.mdx
index f7169ea33cea7..5c037f4f3d062 100644
--- a/dev_docs/tutorials/kibana_page_template.mdx
+++ b/dev_docs/tutorials/kibana_page_template.mdx
@@ -2,7 +2,7 @@
id: kibDevDocsKPTTutorial
slug: /kibana-dev-docs/tutorials/kibana-page-template
title: Kibana Page Template
-summary: Learn how to create pages in Kibana
+description: Learn how to create pages in Kibana
date: 2021-03-20
tags: ['kibana', 'dev', 'ui', 'tutorials']
---
diff --git a/dev_docs/tutorials/saved_objects.mdx b/dev_docs/tutorials/saved_objects.mdx
index a9d8cd7c6ec1c..f922077cb5e54 100644
--- a/dev_docs/tutorials/saved_objects.mdx
+++ b/dev_docs/tutorials/saved_objects.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialSavedObject
slug: /kibana-dev-docs/tutorials/saved-objects
title: Register a new saved object type
-summary: Learn how to register a new saved object type.
+description: Learn how to register a new saved object type.
date: 2021-02-05
tags: ['kibana','onboarding', 'dev', 'architecture', 'tutorials']
---
diff --git a/dev_docs/tutorials/screenshotting.mdx b/dev_docs/tutorials/screenshotting.mdx
index 76f2859928491..5d506e2cb13b4 100644
--- a/dev_docs/tutorials/screenshotting.mdx
+++ b/dev_docs/tutorials/screenshotting.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialScreenshotting
slug: /kibana-dev-docs/tutorials/screenshotting
title: Kibana Screenshotting Service
-summary: Kibana Screenshotting Service
+description: Kibana Screenshotting Service
date: 2022-04-12
tags: ['kibana', 'onboarding', 'dev', 'architecture']
---
diff --git a/dev_docs/tutorials/submit_a_pull_request.mdx b/dev_docs/tutorials/submit_a_pull_request.mdx
index f7d530f6cec66..0402a533b2498 100644
--- a/dev_docs/tutorials/submit_a_pull_request.mdx
+++ b/dev_docs/tutorials/submit_a_pull_request.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialSubmitPullRequest
slug: /kibana-dev-docs/tutorials/submit-pull-request
title: Submitting a Kibana pull request
-summary: Learn how to submit a Kibana pull request
+description: Learn how to submit a Kibana pull request
date: 2021-06-24
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'github', 'pr', 'pull request', 'ci']
---
diff --git a/dev_docs/tutorials/testing_plugins.mdx b/dev_docs/tutorials/testing_plugins.mdx
index b43fa19927cc4..4fbfd1b257443 100644
--- a/dev_docs/tutorials/testing_plugins.mdx
+++ b/dev_docs/tutorials/testing_plugins.mdx
@@ -2,7 +2,7 @@
id: kibDevTutorialTestingPlugins
slug: /kibana-dev-docs/tutorials/testing-plugins
title: Testing Kibana Plugins
-summary: Learn how to test different aspects of Kibana plugins
+description: Learn how to test different aspects of Kibana plugins
date: 2021-07-05
tags: ['kibana', 'onboarding', 'dev', 'architecture', 'testing']
---
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index 67626e0580390..10bd6fbba96ce 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -455,6 +455,10 @@ activities.
|The features plugin enhance Kibana with a per-feature privilege system.
+|{kib-repo}blob/{branch}/x-pack/plugins/files/README.md[files]
+|File upload, download, sharing, and serving over HTTP implementation in Kibana.
+
+
|{kib-repo}blob/{branch}/x-pack/plugins/file_upload[fileUpload]
|WARNING: Missing README.
diff --git a/docs/user/ml/images/ml-data-visualizer-sample.jpg b/docs/user/ml/images/ml-data-visualizer-sample.jpg
deleted file mode 100644
index 4d77ef3010c3f..0000000000000
Binary files a/docs/user/ml/images/ml-data-visualizer-sample.jpg and /dev/null differ
diff --git a/docs/user/ml/images/ml-data-visualizer-sample.png b/docs/user/ml/images/ml-data-visualizer-sample.png
new file mode 100644
index 0000000000000..9ce55dfe9d182
Binary files /dev/null and b/docs/user/ml/images/ml-data-visualizer-sample.png differ
diff --git a/docs/user/ml/images/ml-explain-log-rate-before.png b/docs/user/ml/images/ml-explain-log-rate-before.png
new file mode 100644
index 0000000000000..e154ddbeebebf
Binary files /dev/null and b/docs/user/ml/images/ml-explain-log-rate-before.png differ
diff --git a/docs/user/ml/images/ml-explain-log-rate.png b/docs/user/ml/images/ml-explain-log-rate.png
new file mode 100644
index 0000000000000..c814ec50d6774
Binary files /dev/null and b/docs/user/ml/images/ml-explain-log-rate.png differ
diff --git a/docs/user/ml/index.asciidoc b/docs/user/ml/index.asciidoc
index e66ca4ee19780..fd86906f4b989 100644
--- a/docs/user/ml/index.asciidoc
+++ b/docs/user/ml/index.asciidoc
@@ -15,7 +15,7 @@ if your data is stored in {es} and contains a time field, you can use the
*{data-viz}* to identify possible fields for {anomaly-detect}:
[role="screenshot"]
-image::user/ml/images/ml-data-visualizer-sample.jpg[{data-viz} for sample flight data]
+image::user/ml/images/ml-data-visualizer-sample.png[{data-viz} for sample flight data]
You can also upload a CSV, NDJSON, or log file. The *{data-viz}*
identifies the file format and field mappings. You can then optionally import
@@ -98,3 +98,48 @@ image::user/ml/images/outliers.png[{oldetection-cap} results in {kib}]
For more information about the {dfanalytics} feature, see
{ml-docs}/ml-dfanalytics.html[{ml-cap} {dfanalytics}].
+
+[[xpack-ml-aiops]]
+== AIOps
+
+AIOps is a part of {ml-app} in {kib} which provides features that use advanced
+statistical methods to help you interpret your data and its behavior.
+
+[discrete]
+[[explain-log-rate-spikes]]
+=== Explain log rate spikes
+
+preview::[]
+
+Explain log rate spikes is a feature that uses advanced statistical methods to
+identify reasons for increases in log rates. It makes it easy to find and
+investigate causes of unusual spikes by using the analysis workflow view.
+Examine the histogram chart of the log rates for a given {data-source}, and find
+the reason behind a particular change possibly in millions of log events across
+multiple fields and values.
+
+You can find explain log rate spikes under **{ml-app}** > **AIOps** where you
+can select the {data-source} or saved search that you want to analyze.
+
+[role="screenshot"]
+image::user/ml/images/ml-explain-log-rate-before.png[Log event histogram chart]
+
+Select a spike in the log event histogram chart to start the analysis. It
+identifies statistically significant field-value combinations that contribute to
+the spike and displays them in a table. The table also shows an indicator of the
+level of impact and a sparkline showing the shape of the impact in the chart.
+Hovering over a row displays the impact on the histogram chart in more detail.
+You can also pin a table row by clicking on it then move the cursor to the
+histogram chart. It displays a tooltip with exact count values for the pinned
+field which enables closer investigation.
+
+Brushes in the chart show the baseline time range and the deviation in the
+analyzed data. You can move the brushes to redefine both the baseline and the
+deviation and rerun the analysis with the modified values.
+
+[role="screenshot"]
+image::user/ml/images/ml-explain-log-rate.png[Log rate spike explained]
+
+
+
+
diff --git a/package.json b/package.json
index 90bd299ba581a..e67bcca74beb7 100644
--- a/package.json
+++ b/package.json
@@ -371,6 +371,7 @@
"bitmap-sdf": "^1.0.3",
"brace": "0.11.1",
"canvg": "^3.0.9",
+ "cbor-x": "^1.3.3",
"chalk": "^4.1.0",
"cheerio": "^1.0.0-rc.10",
"chroma-js": "^1.4.1",
@@ -383,6 +384,7 @@
"copy-to-clipboard": "^3.0.8",
"core-js": "^3.23.5",
"cronstrue": "^1.51.0",
+ "cuid": "^2.1.8",
"cytoscape": "^3.10.0",
"cytoscape-dagre": "^2.2.2",
"d3": "3.5.17",
diff --git a/packages/home/sample_data_card/README.mdx b/packages/home/sample_data_card/README.mdx
index 5e2fa83830573..a4cf6faddfac2 100644
--- a/packages/home/sample_data_card/README.mdx
+++ b/packages/home/sample_data_card/README.mdx
@@ -2,7 +2,7 @@
id: home/SampleData/Cards
slug: /home/sample-data/cards
title: Sample Data Cards
-summary: A component that displays Sample Data Sets as cards and grid of cards.
+description: A component that displays Sample Data Sets as cards and grid of cards.
tags: ['home', 'component', 'sample-data']
date: 2022-06-30
---
diff --git a/packages/home/sample_data_tab/README.mdx b/packages/home/sample_data_tab/README.mdx
index 7ad4ad5dab3e0..8e9b6a373129b 100644
--- a/packages/home/sample_data_tab/README.mdx
+++ b/packages/home/sample_data_tab/README.mdx
@@ -2,7 +2,7 @@
id: home/SampleData/Tab
slug: /home/sample-data/tab
title: Sample Data Tab
-summary: A component that displays the content of the Sample Data tab in the `home` plugin.
+description: A component that displays the content of the Sample Data tab in the `home` plugin.
tags: ['home', 'component', 'sample-data']
date: 2022-06-30
---
diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts
index 380c706696b9d..fe2206033a2b8 100644
--- a/packages/kbn-doc-links/src/get_doc_links.ts
+++ b/packages/kbn-doc-links/src/get_doc_links.ts
@@ -359,6 +359,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
macos_system_ext: `${SECURITY_SOLUTION_DOCS}deploy-elastic-endpoint.html#system-extension-endpoint`,
linux_deadlock: `${SECURITY_SOLUTION_DOCS}ts-management.html`,
},
+ responseActions: `${SECURITY_SOLUTION_DOCS}response-actions.html`,
},
query: {
eql: `${ELASTICSEARCH_DOCS}eql.html`,
diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts
index 4153f9579321a..99396183fc64f 100644
--- a/packages/kbn-doc-links/src/types.ts
+++ b/packages/kbn-doc-links/src/types.ts
@@ -264,6 +264,7 @@ export interface DocLinks {
linux_deadlock: string;
};
readonly threatIntelInt: string;
+ readonly responseActions: string;
};
readonly query: {
readonly eql: string;
diff --git a/packages/kbn-docs-utils/src/api_docs/auto_generated_warning.ts b/packages/kbn-docs-utils/src/api_docs/auto_generated_warning.ts
new file mode 100644
index 0000000000000..055648f7b5669
--- /dev/null
+++ b/packages/kbn-docs-utils/src/api_docs/auto_generated_warning.ts
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export const AUTO_GENERATED_WARNING = `####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####`;
diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_api.ts b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_api.ts
index 156e09b2fce1b..06532dc8a027f 100644
--- a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_api.ts
+++ b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_api.ts
@@ -17,6 +17,7 @@ import {
ReferencedDeprecationsByPlugin,
UnreferencedDeprecationsByPlugin,
} from '../types';
+import { AUTO_GENERATED_WARNING } from '../auto_generated_warning';
import { getPluginApiDocId } from '../utils';
export function writeDeprecationDocByApi(
@@ -76,18 +77,18 @@ export function writeDeprecationDocByApi(
const mdx = dedent(`
---
+${AUTO_GENERATED_WARNING}
id: kibDevDocsDeprecationsByApi
slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api
title: Deprecated API usage by API
-summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
+description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
date: ${moment().format('YYYY-MM-DD')}
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
## Referenced deprecated APIs
-${tableMdx}
+${tableMdx}
## Unreferenced deprecated APIs
diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_plugin.ts b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_plugin.ts
index e79c109311c0b..d25a42d7de50e 100644
--- a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_plugin.ts
+++ b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_doc_by_plugin.ts
@@ -12,6 +12,7 @@ import dedent from 'dedent';
import fs from 'fs';
import Path from 'path';
import { ApiDeclaration, ApiReference, ReferencedDeprecationsByPlugin } from '../types';
+import { AUTO_GENERATED_WARNING } from '../auto_generated_warning';
import { getPluginApiDocId } from '../utils';
export function writeDeprecationDocByPlugin(
@@ -34,7 +35,7 @@ export function writeDeprecationDocByPlugin(
return `
## ${key}
-
+
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
${Object.keys(groupedDeprecationReferences)
@@ -70,16 +71,16 @@ export function writeDeprecationDocByPlugin(
const mdx = dedent(`
---
+${AUTO_GENERATED_WARNING}
id: kibDevDocsDeprecationsByPlugin
slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin
title: Deprecated API usage by plugin
-summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
+description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by.
date: ${moment().format('YYYY-MM-DD')}
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
-${tableMdx}
+${tableMdx}
`);
diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_due_by_team.ts b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_due_by_team.ts
index 712dd9c8e637f..2defdb49aeaa0 100644
--- a/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_due_by_team.ts
+++ b/packages/kbn-docs-utils/src/api_docs/mdx/write_deprecations_due_by_team.ts
@@ -16,6 +16,7 @@ import {
PluginOrPackage,
ReferencedDeprecationsByPlugin,
} from '../types';
+import { AUTO_GENERATED_WARNING } from '../auto_generated_warning';
import { getPluginApiDocId } from '../utils';
export function writeDeprecationDueByTeam(
@@ -58,7 +59,7 @@ export function writeDeprecationDueByTeam(
return `
## ${key}
-
+
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
${Object.keys(groupedDeprecationReferences)
@@ -97,16 +98,16 @@ export function writeDeprecationDueByTeam(
const mdx = dedent(`
---
+${AUTO_GENERATED_WARNING}
id: kibDevDocsDeprecationsDueByTeam
slug: /kibana-dev-docs/api-meta/deprecations-due-by-team
title: Deprecated APIs due to be removed, by team
-summary: Lists the teams that are referencing deprecated APIs with a remove by date.
+description: Lists the teams that are referencing deprecated APIs with a remove by date.
date: ${moment().format('YYYY-MM-DD')}
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
-${tableMdx}
+${tableMdx}
`);
diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_directory_doc.ts b/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_directory_doc.ts
index c98621356439c..129e1212625e3 100644
--- a/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_directory_doc.ts
+++ b/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_directory_doc.ts
@@ -11,6 +11,7 @@ import Path from 'path';
import dedent from 'dedent';
import { ToolingLog } from '@kbn/tooling-log';
import { PluginApi, PluginMetaInfo } from '../types';
+import { AUTO_GENERATED_WARNING } from '../auto_generated_warning';
import { getPluginApiDocId } from '../utils';
function hasPublicApi(doc: PluginApi): boolean {
@@ -74,24 +75,24 @@ export function writePluginDirectoryDoc(
const mdx =
dedent(`
---
+${AUTO_GENERATED_WARNING}
id: kibDevDocsPluginDirectory
slug: /kibana-dev-docs/api-meta/plugin-api-directory
title: Directory
-summary: Directory of public APIs available through plugins or packages.
+description: Directory of public APIs available through plugins or packages.
date: ${moment().format('YYYY-MM-DD')}
tags: ['contributor', 'dev', 'apidocs', 'kibana']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
### Overall stats
-| Count | Plugins or Packages with a
public API | Number of teams |
+| Count | Plugins or Packages with a
public API | Number of teams |
|--------------|----------|------------------------|
| ${totalStats.pluginCnt} | ${totalStats.pluginCntWithPublicApi} | ${totalStats.teamCnt} |
### Public API health stats
-| API Count | Any Count | Missing comments | Missing exports |
+| API Count | Any Count | Missing comments | Missing exports |
|--------------|----------|-----------------|--------|
| ${totalStats.totalApiCnt} | ${totalStats.anyCnt} | ${totalStats.missingCommentCnt} | ${
totalStats.missingExportCnt
@@ -99,13 +100,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
## Plugin Directory
-| Plugin name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
+| Plugin name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
${getDirectoryTable(pluginApiMap, pluginStatsMap, true)}
## Package Directory
-| Package name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
+| Package name | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
${getDirectoryTable(pluginApiMap, pluginStatsMap, false)}
diff --git a/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_mdx_docs.ts b/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_mdx_docs.ts
index 562d2a8981764..da65c9f6b3357 100644
--- a/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_mdx_docs.ts
+++ b/packages/kbn-docs-utils/src/api_docs/mdx/write_plugin_mdx_docs.ts
@@ -19,6 +19,7 @@ import {
getSlug,
} from '../utils';
import { writePluginDocSplitByFolder } from './write_plugin_split_by_folder';
+import { AUTO_GENERATED_WARNING } from '../auto_generated_warning';
import { WritePluginDocsOpts } from './types';
/**
@@ -75,14 +76,14 @@ export function writePluginDoc(
let mdx =
dedent(`
---
+${AUTO_GENERATED_WARNING}
id: ${getPluginApiDocId(doc.id)}
slug: /kibana-dev-docs/api/${slug}
title: "${doc.id}"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the ${doc.id} plugin
+description: API docs for the ${doc.id} plugin
date: ${moment().format('YYYY-MM-DD')}
tags: ['contributor', 'dev', 'apidocs', 'kibana', '${doc.id}']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import ${json} from './${fileName}.devdocs.json';
diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx
index 6a66fa74f7c01..b72bb38869f78 100644
--- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx
+++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibPluginAPluginApi
slug: /kibana-dev-docs/api/pluginA
title: "pluginA"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the pluginA plugin
-date: 2022-04-30
+description: API docs for the pluginA plugin
+date: 2022-08-08
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginA']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import pluginAObj from './plugin_a.devdocs.json';
diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx
index 4082de6306895..f1b79e0d69ce5 100644
--- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx
+++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_a_foo.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibPluginAFooPluginApi
slug: /kibana-dev-docs/api/pluginA-foo
title: "pluginA.foo"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the pluginA.foo plugin
-date: 2022-04-30
+description: API docs for the pluginA.foo plugin
+date: 2022-08-08
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginA.foo']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import pluginAFooObj from './plugin_a_foo.devdocs.json';
diff --git a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx
index d69da971f7e3e..2d0c28885f8d3 100644
--- a/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx
+++ b/packages/kbn-docs-utils/src/api_docs/tests/snapshots/plugin_b.mdx
@@ -1,12 +1,15 @@
---
+####
+#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
+#### Reach out in #docs-engineering for more info.
+####
id: kibPluginBPluginApi
slug: /kibana-dev-docs/api/pluginB
title: "pluginB"
image: https://source.unsplash.com/400x175/?github
-summary: API docs for the pluginB plugin
-date: 2022-04-30
+description: API docs for the pluginB plugin
+date: 2022-08-08
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'pluginB']
-warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info.
---
import pluginBObj from './plugin_b.devdocs.json';
diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml
index 955ec123c1626..c12c3081a737e 100644
--- a/packages/kbn-optimizer/limits.yml
+++ b/packages/kbn-optimizer/limits.yml
@@ -133,3 +133,4 @@ pageLoadAssetSize:
kibanaUsageCollection: 16463
kubernetesSecurity: 77234
threatIntelligence: 29195
+ files: 22673
diff --git a/packages/kbn-performance-testing-dataset-extractor/jest.config.js b/packages/kbn-performance-testing-dataset-extractor/jest.config.js
index e31a2d7996893..4800a9edea7c5 100644
--- a/packages/kbn-performance-testing-dataset-extractor/jest.config.js
+++ b/packages/kbn-performance-testing-dataset-extractor/jest.config.js
@@ -7,7 +7,7 @@
*/
module.exports = {
- preset: '@kbn/test/jest_node',
+ preset: '@kbn/test',
rootDir: '../..',
roots: ['/packages/kbn-performance-testing-dataset-extractor'],
};
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/cli.ts b/packages/kbn-performance-testing-dataset-extractor/src/cli.ts
index 914a7d587efdf..37be456d66aa1 100644
--- a/packages/kbn-performance-testing-dataset-extractor/src/cli.ts
+++ b/packages/kbn-performance-testing-dataset-extractor/src/cli.ts
@@ -16,7 +16,8 @@ import { run } from '@kbn/dev-cli-runner';
import { createFlagError } from '@kbn/dev-cli-errors';
import { EsVersion, readConfigFile } from '@kbn/test';
import path from 'path';
-import { extractor, ScalabilitySetup } from './extractor';
+import { extractor } from './extractor';
+import { ScalabilitySetup } from './types';
interface Vars {
[key: string]: string;
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/constants.ts b/packages/kbn-performance-testing-dataset-extractor/src/constants.ts
new file mode 100644
index 0000000000000..a9dc0b9d2ffbe
--- /dev/null
+++ b/packages/kbn-performance-testing-dataset-extractor/src/constants.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export const DATE_FORMAT = `YYYY-MM-DD'T'HH:mm:ss.SSS'Z'`;
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts
index 948d410c8669e..c878f148e4e67 100644
--- a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts
+++ b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts
@@ -8,7 +8,7 @@
import { Client } from '@elastic/elasticsearch';
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
-import { SearchRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+import { SearchRequest, MsearchRequestItem } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { ToolingLog } from '@kbn/tooling-log';
interface ClientOptions {
@@ -36,6 +36,7 @@ interface Transaction {
name: string;
type: string;
duration: { us: number };
+ span_count: { started: number };
}
export interface Document {
@@ -98,6 +99,7 @@ const addRangeFilter = (range: { startTime: string; endTime: string }): QueryDsl
export class ESClient {
client: Client;
log: ToolingLog;
+ tracesIndex: string = '.ds-traces-apm-default*';
constructor(options: ClientOptions, log: ToolingLog) {
this.client = new Client({
@@ -112,6 +114,7 @@ export class ESClient {
async getTransactions(queryFilters: QueryDslQueryContainer[]) {
const searchRequest: SearchRequest = {
+ index: this.tracesIndex,
body: {
sort: [
{
@@ -172,9 +175,44 @@ export class ESClient {
return await this.getTransactions(queryFilters);
}
- async getSpans(transactionId: string) {
- const filters = [{ field: 'parent.id', value: transactionId }];
- const queryFilters = filters.map((filter) => addBooleanFilter(filter));
- return await this.getTransactions(queryFilters);
+ getMsearchRequestItem = (queryFilters: QueryDslQueryContainer[]): MsearchRequestItem => {
+ return {
+ query: {
+ bool: {
+ filter: [
+ {
+ bool: {
+ filter: queryFilters,
+ },
+ },
+ ],
+ },
+ },
+ };
+ };
+
+ async getSpans(transactionIds: string[]) {
+ const searches = new Array();
+
+ for (const transactionId of transactionIds) {
+ const filters = [{ field: 'parent.id', value: transactionId }];
+ const queryFilters = filters.map((filter) => addBooleanFilter(filter));
+ const requestItem = this.getMsearchRequestItem(queryFilters);
+ searches.push({ index: this.tracesIndex }, requestItem);
+ }
+ this.log.debug(`Msearch request: ${JSON.stringify(searches)}`);
+ const result = await this.client.msearch({
+ searches,
+ });
+ this.log.debug(`Msearch result: ${JSON.stringify(result)}`);
+ return result.responses.flatMap((response) => {
+ if ('error' in response) {
+ throw new Error(`Msearch failure: ${JSON.stringify(response.error)}`);
+ } else if (response.hits.hits.length > 0) {
+ return response.hits.hits;
+ } else {
+ return [];
+ }
+ });
}
}
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/es_request.ts b/packages/kbn-performance-testing-dataset-extractor/src/es_request.ts
deleted file mode 100644
index 5160d1cf1b0cc..0000000000000
--- a/packages/kbn-performance-testing-dataset-extractor/src/es_request.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { ESClient, SpanDocument } from './es_client';
-import { KibanaRequest } from './server_request';
-
-const httpMethodRegExp = /(GET|POST|DELETE|HEAD|PUT|OPTIONS)/;
-const httpPathRegExp = /(?<=GET|POST|DELETE|HEAD|PUT|OPTIONS).*/;
-
-interface Request {
- id: string;
- transactionId: string;
- name: string;
- action: string;
- request: {
- method?: string;
- path?: string;
- params?: string;
- body?: JSON;
- };
- date: string;
- duration: number;
-}
-
-interface Stream {
- startTime: number;
- endTime: number;
- requests: Request[];
-}
-
-const strToJSON = (str: string): JSON | undefined => {
- try {
- return JSON.parse(str);
- } catch (e) {
- return;
- }
-};
-
-const findFirstMatch = (regExp: RegExp, testString: string) => {
- const found = regExp.exec(testString);
- return found ? found[0] : undefined;
-};
-
-const parseQueryStatement = (statement: string): { params?: string; body?: JSON } => {
- // github.com/elastic/apm-agent-nodejs/blob/5ba1b2609d18b12a64e1e559236717dd38d64a51/lib/instrumentation/elasticsearch-shared.js#L27-L29
- // Some ES endpoints support both query params and a body, statement string might contain both of it
- const split = statement.split('\n\n');
- if (split.length === 2) {
- return { params: split[0], body: strToJSON(split[1]) };
- } else {
- const body = strToJSON(split[0]);
- return body ? { body } : { params: split[0] };
- }
-};
-
-export const fetchRequests = async (esClient: ESClient, requests: KibanaRequest[]) => {
- const esRequests = new Array();
- for (const request of requests) {
- const transactionId = request.transaction.id;
- const hits = await esClient.getSpans(transactionId);
- const spans = hits
- .map((hit) => hit!._source as SpanDocument)
- .map((hit) => {
- const query = hit?.span.db?.statement ? parseQueryStatement(hit?.span.db?.statement) : {};
- return {
- id: hit.span.id,
- transactionId: hit.transaction.id,
- name: hit.span.name,
- action: hit.span?.action,
- request: {
- method: findFirstMatch(httpMethodRegExp, hit.span.name),
- path: findFirstMatch(httpPathRegExp, hit.span.name.replace(/\s+/g, '')),
- params: query?.params,
- body: query?.body,
- },
- date: hit['@timestamp'],
- duration: hit.span?.duration?.us,
- };
- })
- // filter out requests without method, path and POST/PUT/DELETE without body
- .filter(
- (hit) =>
- hit &&
- hit.request?.method &&
- hit.request?.path &&
- (hit.request?.method === 'GET' || hit.request?.body)
- );
- esRequests.push(...spans);
- }
-
- return esRequests;
-};
-
-export const requestsToStreams = (requests: Request[]) => {
- const sorted = requests.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
- const streams = new Map();
-
- for (const request of sorted) {
- const startTime = new Date(request.date).getTime();
- const endTime = new Date(request.date).getTime() + request.duration / 1000;
- // searching if query starts before any existing stream ended
- const match = Array.from(streams.keys()).filter((key) => {
- const streamEndTime = streams.get(key)?.endTime;
- return streamEndTime ? startTime < streamEndTime : false;
- });
- const stream = streams.get(match[0]);
- if (stream) {
- // adding query to the existing stream
- stream.requests.push(request);
- // updating the stream endTime if needed
- if (endTime > stream.endTime) {
- stream.endTime = endTime;
- }
- // saving updated stream
- streams.set(match[0], stream);
- } else {
- // add a new stream
- streams.set(request.date, {
- startTime,
- endTime,
- requests: [request],
- });
- }
- }
-
- const values = Array.from(streams.values());
- return values.map((stream) => {
- return {
- startTime: new Date(stream.startTime).toISOString(),
- endTime: new Date(stream.endTime).toISOString(),
- requests: stream.requests,
- };
- });
-};
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/extractor.ts b/packages/kbn-performance-testing-dataset-extractor/src/extractor.ts
index e0587af1637d8..992c93b16922d 100644
--- a/packages/kbn-performance-testing-dataset-extractor/src/extractor.ts
+++ b/packages/kbn-performance-testing-dataset-extractor/src/extractor.ts
@@ -13,38 +13,10 @@ import path from 'path';
import { ToolingLog } from '@kbn/tooling-log';
import { SearchHit } from '@elastic/elasticsearch/lib/api/types';
import { ESClient, Document, TransactionDocument } from './es_client';
-import { getRequests } from './server_request';
-import { fetchRequests, requestsToStreams } from './es_request';
-
-const DATE_FORMAT = `YYYY-MM-DD'T'HH:mm:ss.SSS'Z'`;
-
-interface CLIParams {
- param: {
- journeyName: string;
- scalabilitySetup: ScalabilitySetup;
- buildId: string;
- withoutStaticResources: boolean;
- };
- client: {
- baseURL: string;
- username: string;
- password: string;
- };
- log: ToolingLog;
-}
-
-interface InjectionStep {
- action: string;
- minUsersCount?: number;
- maxUsersCount: number;
- duration: string;
-}
-
-export interface ScalabilitySetup {
- warmup: InjectionStep[];
- test: InjectionStep[];
- maxDuration: string;
-}
+import { getESRequests, getKibanaRequests } from './request';
+import { requestsToStreams } from './stream';
+import { CLIParams, Request } from './types';
+import { DATE_FORMAT } from './constants';
const calculateTransactionTimeRage = (hit: SearchHit) => {
const trSource = hit._source as Document;
@@ -100,12 +72,13 @@ export const extractor = async ({ param, client, log }: CLIParams) => {
const source = hits[0]!._source as TransactionDocument;
const kibanaVersion = source.service.version;
- const kibanaRequests = getRequests(hits, withoutStaticResources, log);
- const esRequests = await fetchRequests(esClient, kibanaRequests);
+ const kibanaRequests = getKibanaRequests(hits, withoutStaticResources);
+ const esRequests = await getESRequests(esClient, kibanaRequests);
log.info(
`Found ${kibanaRequests.length} Kibana server and ${esRequests.length} Elasticsearch requests`
);
- const streams = requestsToStreams(esRequests);
+ const esStreams = requestsToStreams(esRequests);
+ const kibanaStreams = requestsToStreams(kibanaRequests);
const outputDir = path.resolve('target/scalability_traces');
const fileName = `${journeyName.replace(/ /g, '')}-${buildId}.json`;
@@ -116,7 +89,7 @@ export const extractor = async ({ param, client, log }: CLIParams) => {
journeyName,
kibanaVersion,
scalabilitySetup,
- requests: kibanaRequests,
+ streams: kibanaStreams,
},
path.resolve(outputDir, 'server'),
fileName,
@@ -128,7 +101,7 @@ export const extractor = async ({ param, client, log }: CLIParams) => {
{
journeyName,
kibanaVersion,
- streams: Array.from(streams.values()),
+ streams: esStreams,
},
path.resolve(outputDir, 'es'),
fileName,
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/request.ts b/packages/kbn-performance-testing-dataset-extractor/src/request.ts
new file mode 100644
index 0000000000000..7c9efaf935742
--- /dev/null
+++ b/packages/kbn-performance-testing-dataset-extractor/src/request.ts
@@ -0,0 +1,106 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { SearchHit } from '@elastic/elasticsearch/lib/api/types';
+import { ESClient, TransactionDocument, Headers, SpanDocument } from './es_client';
+import { Request } from './types';
+
+const httpMethodRegExp = /(GET|POST|DELETE|HEAD|PUT|OPTIONS)/;
+const httpPathRegExp = /(?<=GET|POST|DELETE|HEAD|PUT|OPTIONS).*/;
+const staticResourcesRegExp = /\.(css|ico|js|json|jpeg|jpg|gif|png|svg|otf|ttf|woff|woff2)$/;
+
+const strToJSON = (str: string): JSON | undefined => {
+ try {
+ return JSON.parse(str);
+ } catch (e) {
+ return;
+ }
+};
+
+const findFirstMatch = (regExp: RegExp, testString: string) => {
+ const found = regExp.exec(testString);
+ return found ? found[0] : undefined;
+};
+
+const parseQueryStatement = (statement: string): { params?: string; body?: JSON } => {
+ // github.com/elastic/apm-agent-nodejs/blob/5ba1b2609d18b12a64e1e559236717dd38d64a51/lib/instrumentation/elasticsearch-shared.js#L27-L29
+ // Some ES endpoints support both query params and a body, statement string might contain both of it
+ const split = statement.split('\n\n');
+ if (split.length === 2) {
+ return { params: split[0], body: strToJSON(split[1]) };
+ } else {
+ const body = strToJSON(split[0]);
+ return body ? { body } : { params: split[0] };
+ }
+};
+
+const combineHeaderFieldValues = (headers: Headers): { [key: string]: string } => {
+ return Object.assign(
+ {},
+ ...Object.keys(headers).map((key) => ({ [key]: headers[key].join(', ') }))
+ );
+};
+
+export const getKibanaRequests = (
+ hits: Array>,
+ withoutStaticResources: boolean
+): Request[] => {
+ const data = hits
+ .map((hit) => hit!._source as TransactionDocument)
+ .map((hit) => {
+ const payload = hit.http.request?.body?.original;
+ return {
+ transactionId: hit.transaction.id,
+ name: hit.transaction.name,
+ date: hit['@timestamp'],
+ duration: hit.transaction.duration.us,
+ http: {
+ method: hit.http.request.method,
+ path: hit.url.path,
+ headers: combineHeaderFieldValues(hit.http.request.headers),
+ body: payload ? JSON.stringify(strToJSON(payload)) : undefined,
+ statusCode: hit.http.response.status_code,
+ },
+ spanCount: hit.transaction.span_count.started,
+ };
+ });
+
+ return withoutStaticResources
+ ? data.filter((item) => !staticResourcesRegExp.test(item.http.path))
+ : data;
+};
+
+export const getESRequests = async (esClient: ESClient, requests: Request[]) => {
+ const esRequests = new Array();
+ const transactionIds = requests
+ .filter((r) => r.spanCount && r?.spanCount > 0)
+ .map((r) => r.transactionId);
+ const hits = await esClient.getSpans(transactionIds);
+ for (const hit of hits.map((i) => i!._source as SpanDocument)) {
+ const query = hit?.span?.db?.statement ? parseQueryStatement(hit?.span?.db?.statement) : {};
+ const method = findFirstMatch(httpMethodRegExp, hit.span.name);
+ const path = findFirstMatch(httpPathRegExp, hit.span.name.replace(/\s+/g, ''));
+ // filter out requests without method, path and POST/PUT/DELETE without body
+ if (method && path && (method === 'GET' || query?.body)) {
+ esRequests.push({
+ transactionId: hit.transaction.id,
+ spanId: hit.span.id,
+ name: hit.span.name,
+ date: hit['@timestamp'],
+ duration: hit.span?.duration?.us,
+ http: {
+ method,
+ path,
+ params: query?.params,
+ body: query?.body,
+ },
+ });
+ }
+ }
+ return esRequests;
+};
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/server_request.ts b/packages/kbn-performance-testing-dataset-extractor/src/server_request.ts
deleted file mode 100644
index dd553b83848c8..0000000000000
--- a/packages/kbn-performance-testing-dataset-extractor/src/server_request.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import { SearchHit } from '@elastic/elasticsearch/lib/api/types';
-import { ToolingLog } from '@kbn/tooling-log';
-import { TransactionDocument, Headers } from './es_client';
-
-const staticResourcesRegExp = /\.(css|ico|js|json|jpeg|jpg|gif|png|otf|ttf|woff|woff2)$/;
-
-export interface KibanaRequest {
- traceId: string;
- parentId?: string;
- processor: string;
- environment: string;
- request: {
- timestamp: string;
- method: string;
- path: string;
- headers: { [key: string]: string };
- body?: string;
- statusCode: number;
- };
- transaction: {
- id: string;
- name: string;
- type: string;
- };
-}
-
-const parsePayload = (payload: string, traceId: string, log: ToolingLog): string | undefined => {
- let body;
- try {
- body = JSON.parse(payload);
- } catch (error) {
- log.error(`Failed to parse payload - trace_id: '${traceId}'`);
- }
- return body;
-};
-
-const combineHeaderFieldValues = (headers: Headers): { [key: string]: string } => {
- return Object.assign(
- {},
- ...Object.keys(headers).map((key) => ({ [key]: headers[key].join(', ') }))
- );
-};
-
-export const getRequests = (
- hits: Array>,
- withoutStaticResources: boolean,
- log: ToolingLog
-): KibanaRequest[] => {
- const data = hits
- .map((hit) => hit!._source as TransactionDocument)
- .map((hit) => {
- const payload = hit.http.request?.body?.original;
- return {
- traceId: hit.trace.id,
- parentId: hit?.parent?.id,
- processor: hit.processor,
- environment: hit.service.environment,
- request: {
- timestamp: hit['@timestamp'],
- method: hit.http.request.method,
- path: hit.url.path,
- headers: combineHeaderFieldValues(hit.http.request.headers),
- body: payload ? JSON.stringify(parsePayload(payload, hit.trace.id, log)) : undefined,
- statusCode: hit.http.response.status_code,
- },
- transaction: {
- id: hit.transaction.id,
- name: hit.transaction.name,
- type: hit.transaction.type,
- },
- };
- });
-
- return withoutStaticResources
- ? data.filter((item) => !staticResourcesRegExp.test(item.request.path))
- : data;
-};
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/stream.test.ts b/packages/kbn-performance-testing-dataset-extractor/src/stream.test.ts
new file mode 100644
index 0000000000000..51fdde19358a3
--- /dev/null
+++ b/packages/kbn-performance-testing-dataset-extractor/src/stream.test.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { requestsToStreams, getTime } from './stream';
+
+test('requests to stream', () => {
+ const requests = new Array(
+ {
+ transactionId: 'a8ba23df51ebb853',
+ spanId: '85c8de731132bea2',
+ name: 'Elasticsearch: GET /.kibana_8.5.0/_doc/config%3A8.5.0',
+ date: '2022-08-08T17:43:58.647Z',
+ duration: 398,
+ http: {
+ method: 'GET',
+ path: '/.kibana_8.5.0/_doc/config%3A8.5.0',
+ },
+ },
+ {
+ transactionId: '15ba53df5t9bb165',
+ spanId: '15v8de5341v2neat',
+ name: 'Elasticsearch: GET /.kibana_8.5.0/_doc/config%3A8.5.0',
+ date: '2022-08-08T17:43:58.641Z',
+ duration: 1988,
+ http: {
+ method: 'GET',
+ path: '/.kibana_8.5.0/_doc/config%3A8.5.0',
+ },
+ },
+ {
+ transactionId: '90d8037a799382ac',
+ spanId: 'b819755f297188d9',
+ name: 'Elasticsearch: GET /_security/_authenticate',
+ date: '2022-08-08T17:43:58.649Z',
+ duration: 1002,
+ http: {
+ method: 'GET',
+ path: '/_security/_authenticate',
+ },
+ },
+ {
+ transactionId: '1381d9ed5af967f9',
+ spanId: '690d11ebfefd06ad',
+ name: 'Elasticsearch: GET /.kibana_8.5.0/_doc/config%3A8.5.0',
+ date: '2022-08-08T17:43:58.648Z',
+ duration: 2400,
+ http: {
+ method: 'GET',
+ path: '/.kibana_8.5.0/_doc/config%3A8.5.0',
+ },
+ },
+ {
+ transactionId: '96174ca1fbd14763',
+ spanId: '4c81025cb74c9cd6',
+ name: 'Elasticsearch: GET /_security/_authenticate',
+ date: '2022-08-08T17:43:58.640Z',
+ duration: 4166,
+ http: {
+ method: 'GET',
+ path: '/_security/_authenticate',
+ },
+ }
+ );
+
+ const streams = requestsToStreams(requests);
+ const sorted = requests.sort((a, b) => getTime(a.date) - getTime(b.date));
+
+ expect(streams.length).toBe(3);
+ expect(streams[0].requests.length).toBe(2);
+ expect(streams[0].startTime).toBe(streams[0].requests[0].date);
+ expect(streams[0].startTime).toBe(sorted[0].date);
+ expect(streams[1].requests.length).toBe(1);
+ expect(getTime(streams[1].startTime)).toBeGreaterThan(getTime(streams[0].endTime));
+ expect(streams[2].requests.length).toBe(2);
+});
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/stream.ts b/packages/kbn-performance-testing-dataset-extractor/src/stream.ts
new file mode 100644
index 0000000000000..48f7dfe2d08c3
--- /dev/null
+++ b/packages/kbn-performance-testing-dataset-extractor/src/stream.ts
@@ -0,0 +1,57 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { Request, Stream } from './types';
+
+export const getTime = (date: string) => new Date(date).getTime();
+
+/**
+ * Combines concurrent requests into the streams and returns it as Array
+ * @param requests requests array
+ */
+export const requestsToStreams = (requests: T[]) => {
+ const sorted = requests.sort((a, b) => getTime(a.date) - getTime(b.date));
+ const streams = new Map>();
+
+ for (const request of sorted) {
+ const startTime = getTime(request.date) * 1000;
+ const endTime = getTime(request.date) * 1000 + request.duration;
+ // Checking if request starts before any existing stream ended
+ const match = Array.from(streams.keys()).filter((key) => {
+ const streamEndTimestamp = streams.get(key)?.endTime;
+ return streamEndTimestamp ? startTime < streamEndTimestamp : false;
+ });
+ const stream = streams.get(match[0]);
+ if (stream) {
+ // Adding request to the existing stream
+ stream.requests.push(request);
+ // Updating the stream end time if needed
+ if (endTime > stream.endTime) {
+ stream.endTime = endTime;
+ }
+ // Saving the updated stream
+ streams.set(match[0], stream);
+ } else {
+ // Otherwise adding a new stream
+ streams.set(request.date, {
+ startTime,
+ endTime,
+ requests: [request],
+ });
+ }
+ }
+
+ const values = Array.from(streams.values());
+ return values.map((stream) => {
+ return {
+ startTime: new Date(stream.startTime / 1000).toISOString(),
+ endTime: new Date(stream.endTime / 1000).toISOString(),
+ requests: stream.requests,
+ };
+ });
+};
diff --git a/packages/kbn-performance-testing-dataset-extractor/src/types.ts b/packages/kbn-performance-testing-dataset-extractor/src/types.ts
new file mode 100644
index 0000000000000..1cd51f3388a7c
--- /dev/null
+++ b/packages/kbn-performance-testing-dataset-extractor/src/types.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { ToolingLog } from '@kbn/tooling-log';
+
+export interface Request {
+ transactionId: string;
+ spanId?: string;
+ name: string;
+ date: string;
+ duration: number;
+ http: {
+ method: string;
+ path: string;
+ headers?: { [key: string]: string };
+ params?: string;
+ body?: JSON | string;
+ };
+ spanCount?: number;
+}
+
+export interface Stream {
+ startTime: number;
+ endTime: number;
+ requests: T[];
+}
+
+export interface InjectionStep {
+ action: string;
+ minUsersCount?: number;
+ maxUsersCount: number;
+ duration: string;
+}
+
+export interface ScalabilitySetup {
+ warmup: InjectionStep[];
+ test: InjectionStep[];
+ maxDuration: string;
+}
+
+export interface CLIParams {
+ param: {
+ journeyName: string;
+ scalabilitySetup: ScalabilitySetup;
+ buildId: string;
+ withoutStaticResources: boolean;
+ };
+ client: {
+ baseURL: string;
+ username: string;
+ password: string;
+ };
+ log: ToolingLog;
+}
diff --git a/packages/kbn-shared-ux-components/README.mdx b/packages/kbn-shared-ux-components/README.mdx
index 8fee1571e5220..f4673a0804f31 100644
--- a/packages/kbn-shared-ux-components/README.mdx
+++ b/packages/kbn-shared-ux-components/README.mdx
@@ -2,7 +2,7 @@
id: kibSharedUXComponents
slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-components
title: Shared UX Components
-summary:
+description:
date: 2022-03-11
tags: ['kibana', 'dev', 'sharedUX']
---
diff --git a/packages/kbn-shared-ux-components/src/page_template/page_template.mdx b/packages/kbn-shared-ux-components/src/page_template/page_template.mdx
index 59acf8910cf29..fbaada158e277 100644
--- a/packages/kbn-shared-ux-components/src/page_template/page_template.mdx
+++ b/packages/kbn-shared-ux-components/src/page_template/page_template.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/PageTemplate
slug: /shared-ux-components/page_template/page_template
title: Page Template
-summary: A Kibana-specific wrapper around `EuiTemplate`
+description: A Kibana-specific wrapper around `EuiTemplate`
tags: ['shared-ux', 'component']
date: 2022-04-04
---
diff --git a/packages/kbn-shared-ux-services/README.mdx b/packages/kbn-shared-ux-services/README.mdx
index 2ef3040128c87..589aae4cc7ed2 100755
--- a/packages/kbn-shared-ux-services/README.mdx
+++ b/packages/kbn-shared-ux-services/README.mdx
@@ -2,7 +2,7 @@
id: kibSharedUXServices
slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-services
title: Shared UX Services
-summary: The `@kbn/shared-ux-services` package provides a thin service abstraction for components and solutions created by the Shared UX team.
+description: The `@kbn/shared-ux-services` package provides a thin service abstraction for components and solutions created by the Shared UX team.
date: 2022-03-11
tags: ['kibana', 'dev', 'sharedUX']
---
diff --git a/packages/kbn-shared-ux-storybook/README.mdx b/packages/kbn-shared-ux-storybook/README.mdx
index cfebeedcd1ac3..11992e336e627 100644
--- a/packages/kbn-shared-ux-storybook/README.mdx
+++ b/packages/kbn-shared-ux-storybook/README.mdx
@@ -2,7 +2,7 @@
id: kibSharedUXStorybook
slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-storybook
title: Shared UX Storybook
-summary: The `@kbn/shared-ux-storybook` package provides Storybook assets for Shared UX and other teams.
+description: The `@kbn/shared-ux-storybook` package provides Storybook assets for Shared UX and other teams.
date: 2022-03-11
tags: ['kibana', 'dev', 'sharedUX']
---
diff --git a/packages/kbn-shared-ux-utility/README.mdx b/packages/kbn-shared-ux-utility/README.mdx
index a3a3ee965f699..ec91bc4b16ab8 100644
--- a/packages/kbn-shared-ux-utility/README.mdx
+++ b/packages/kbn-shared-ux-utility/README.mdx
@@ -2,7 +2,7 @@
id: kibSharedUXUtility
slug: /kibana-dev-docs/shared-ux/packages/kbn-shared-ux-utility
title: Shared UX Utilities
-summary: The `@kbn/shared-ux-utility` package contains a set of React, DOM and other utilities.
+description: The `@kbn/shared-ux-utility` package contains a set of React, DOM and other utilities.
date: 2022-03-11
tags: ['kibana', 'dev', 'sharedUX']
---
diff --git a/packages/shared-ux/avatar/solution/README.mdx b/packages/shared-ux/avatar/solution/README.mdx
index 841274441f6ed..86f5bed3cc8c2 100644
--- a/packages/shared-ux/avatar/solution/README.mdx
+++ b/packages/shared-ux/avatar/solution/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/KibanaSolutionAvatar
slug: /shared-ux/components/avatar-solution
title: Solution Avatar
-summary: A wrapper around `EuiAvatar` tailored for use in Kibana solutions.
+description: A wrapper around `EuiAvatar` tailored for use in Kibana solutions.
tags: ['shared-ux', 'component']
date: 2022-05-04
---
diff --git a/packages/shared-ux/button/exit_full_screen/impl/README.mdx b/packages/shared-ux/button/exit_full_screen/impl/README.mdx
index 03a885ba6151c..790cff6a72f23 100644
--- a/packages/shared-ux/button/exit_full_screen/impl/README.mdx
+++ b/packages/shared-ux/button/exit_full_screen/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/ExitFullScreenButton
slug: /shared-ux/components/exit-full-screen-button
title: Exit Full Screen Button
-summary: A button that floats over the plugin workspace and allows someone to exit "full screen" mode.
+description: A button that floats over the plugin workspace and allows someone to exit "full screen" mode.
tags: ['shared-ux', 'component']
date: 2021-12-28
---
diff --git a/packages/shared-ux/button_toolbar/README.mdx b/packages/shared-ux/button_toolbar/README.mdx
index fb693dab44498..c073ef003cda4 100644
--- a/packages/shared-ux/button_toolbar/README.mdx
+++ b/packages/shared-ux/button_toolbar/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/ButtonToolbar
slug: /shared-ux/button-toolbar
title: Button Toolbar
-summary:
+description:
tags: ['shared-ux', 'component']
date: 2022-06-14
---
diff --git a/packages/shared-ux/button_toolbar/src/popover/popover.mdx b/packages/shared-ux/button_toolbar/src/popover/popover.mdx
index d1ade51485ae4..dcdeb01de3f04 100644
--- a/packages/shared-ux/button_toolbar/src/popover/popover.mdx
+++ b/packages/shared-ux/button_toolbar/src/popover/popover.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/Popover
slug: /shared-ux/components/toolbar/popovers/popover
title: Toolbar Popover
-summary: A popover component that can be placed within a toolbar button.
+description: A popover component that can be placed within a toolbar button.
tags: ['shared-ux', 'component']
date: 2022-03-28
---
diff --git a/packages/shared-ux/card/no_data/impl/README.mdx b/packages/shared-ux/card/no_data/impl/README.mdx
index e2b044c27ac44..02b626fcc700b 100644
--- a/packages/shared-ux/card/no_data/impl/README.mdx
+++ b/packages/shared-ux/card/no_data/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/NoDataCard
slug: /shared-ux/components/no-data-card
title: No Data Card
-summary: A card displayed when no data is available is available in Kibana.
+description: A card displayed when no data is available is available in Kibana.
tags: ['shared-ux', 'component']
date: 2022-06-15
---
diff --git a/packages/shared-ux/link/redirect_app/impl/README.mdx b/packages/shared-ux/link/redirect_app/impl/README.mdx
index 07d4f75ab764d..337ea5e0d8450 100644
--- a/packages/shared-ux/link/redirect_app/impl/README.mdx
+++ b/packages/shared-ux/link/redirect_app/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Components/AppLink
slug: /shared-ux/components/redirect-app-links
title: Redirect App Links
-summary: A component for redirecting links contained within it to the appropriate Kibana solution without a page refresh.
+description: A component for redirecting links contained within it to the appropriate Kibana solution without a page refresh.
tags: ['shared-ux', 'component']
date: 2022-05-04
---
diff --git a/packages/shared-ux/page/analytics_no_data/impl/README.mdx b/packages/shared-ux/page/analytics_no_data/impl/README.mdx
index 6ba0e9298c264..0d5a5bae445ef 100644
--- a/packages/shared-ux/page/analytics_no_data/impl/README.mdx
+++ b/packages/shared-ux/page/analytics_no_data/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Page/AnalyticsNoDataPage
slug: /shared-ux/page/analytics-no-data-page
title: Analytics "No Data" Page
-summary: An entire page that can be displayed when Kibana "has no data", specifically for Analytics.
+description: An entire page that can be displayed when Kibana "has no data", specifically for Analytics.
tags: ['shared-ux', 'component']
date: 2021-12-28
---
diff --git a/packages/shared-ux/page/kibana_no_data/impl/README.mdx b/packages/shared-ux/page/kibana_no_data/impl/README.mdx
index afa1bd95c19bd..bc5dc37ac679a 100644
--- a/packages/shared-ux/page/kibana_no_data/impl/README.mdx
+++ b/packages/shared-ux/page/kibana_no_data/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Page/KibanaNoDataPage
slug: /shared-ux/page/kibana-no-data
title: Kibana No Data Page
-summary: A page to be displayed when there is no data in Elasticsearch, or no data views.
+description: A page to be displayed when there is no data in Elasticsearch, or no data views.
tags: ['shared-ux', 'component']
date: 2022-04-20
---
diff --git a/packages/shared-ux/page/solution_nav/README.mdx b/packages/shared-ux/page/solution_nav/README.mdx
index abad92c1e4108..6ddd8462237ba 100644
--- a/packages/shared-ux/page/solution_nav/README.mdx
+++ b/packages/shared-ux/page/solution_nav/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Page/SolutionNav
slug: /shared-ux/page/solution-nav
title: Solution Page Navigation
-summary: A customized `EuiSideNav` for pages within Solutions in Kibana.
+description: A customized `EuiSideNav` for pages within Solutions in Kibana.
tags: ['shared-ux', 'component']
date: 2022-06-30
---
diff --git a/packages/shared-ux/prompt/no_data_views/impl/README.mdx b/packages/shared-ux/prompt/no_data_views/impl/README.mdx
index a2bc63fed0765..26facfce8d86e 100644
--- a/packages/shared-ux/prompt/no_data_views/impl/README.mdx
+++ b/packages/shared-ux/prompt/no_data_views/impl/README.mdx
@@ -2,7 +2,7 @@
id: sharedUX/Prompt/NoDataViews
slug: /shared-ux/prompt/no-data-views
title: No Data Views Prompt
-summary: A prompt to be displayed when there is data in Elasticsearch, but no data views
+description: A prompt to be displayed when there is data in Elasticsearch, but no data views
tags: ['shared-ux', 'component', 'prompt', 'no-data']
date: 2022-02-09
---
diff --git a/src/core/server/deprecations/README.mdx b/src/core/server/deprecations/README.mdx
index ed542610e753f..2594bd2f0dd6b 100644
--- a/src/core/server/deprecations/README.mdx
+++ b/src/core/server/deprecations/README.mdx
@@ -2,7 +2,7 @@
id: kibCoreDeprecationsService
slug: /kibana-dev-docs/services/deprecations-service
title: Core Deprecations service
-summary: The Deprecations service helps surface deprecated configs and features for plugins to our users
+description: The Deprecations service helps surface deprecated configs and features for plugins to our users
date: 2021-06-27
tags: ['kibana','dev', 'contributor', 'api docs']
---
diff --git a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts
index f25868cc8dd3f..b71529d2ff1a9 100644
--- a/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts
+++ b/src/core/server/integration_tests/saved_objects/migrations/type_registrations.test.ts
@@ -49,6 +49,8 @@ const previouslyRegisteredTypes = [
'event_loop_delays_daily',
'exception-list',
'exception-list-agnostic',
+ 'file',
+ 'fileShare',
'file-upload-telemetry',
'file-upload-usage-collection-telemetry',
'fleet-agent-actions',
diff --git a/src/core/server/logging/README.mdx b/src/core/server/logging/README.mdx
index 11437d1e8df20..9b3cf8f77e24e 100644
--- a/src/core/server/logging/README.mdx
+++ b/src/core/server/logging/README.mdx
@@ -3,7 +3,7 @@ id: kibCoreLogging
slug: /kibana-dev-docs/services/logging
title: Logging system
image: https://source.unsplash.com/400x175/?Logging
-summary: Core logging contains the system and service for Kibana logs.
+description: Core logging contains the system and service for Kibana logs.
date: 2020-12-02
tags: ['kibana','dev', 'contributor', 'api docs']
---
diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts
index 022d60acbed9b..faa45c52d84b8 100644
--- a/src/core/test_helpers/kbn_server.ts
+++ b/src/core/test_helpers/kbn_server.ts
@@ -24,7 +24,7 @@ import { CliArgs, Env } from '@kbn/config';
import { InternalCoreSetup, InternalCoreStart } from '../server/internal_types';
import { Root } from '../server/root';
-export type HttpMethod = 'delete' | 'get' | 'head' | 'post' | 'put';
+export type HttpMethod = 'delete' | 'get' | 'head' | 'post' | 'put' | 'patch';
const DEFAULTS_SETTINGS = {
server: {
@@ -157,6 +157,7 @@ export const request: Record<
head: (root, path) => getSupertest(root, 'head', path),
post: (root, path) => getSupertest(root, 'post', path),
put: (root, path) => getSupertest(root, 'put', path),
+ patch: (root, path) => getSupertest(root, 'patch', path),
};
export interface TestElasticsearchUtils {
diff --git a/src/dev/build/tasks/build_kibana_platform_plugins.ts b/src/dev/build/tasks/build_kibana_platform_plugins.ts
index ffb73666e4468..9beb296b7c38c 100644
--- a/src/dev/build/tasks/build_kibana_platform_plugins.ts
+++ b/src/dev/build/tasks/build_kibana_platform_plugins.ts
@@ -31,6 +31,7 @@ export const BuildKibanaPlatformPlugins: Task = {
watch: false,
dist: true,
includeCoreBundle: true,
+ inspectWorkers: false,
limitsPath: Path.resolve(REPO_ROOT, 'packages/kbn-optimizer/limits.yml'),
});
diff --git a/src/plugins/controls/README.mdx b/src/plugins/controls/README.mdx
index 46ba1ed3ba9e7..d6805e814e7ff 100644
--- a/src/plugins/controls/README.mdx
+++ b/src/plugins/controls/README.mdx
@@ -2,7 +2,7 @@
id: controls
slug: /kibana-dev-docs/controls
title: Controls Plugin
-summary: Introduction to the Controls Plugin.
+description: Introduction to the Controls Plugin.
date: 2020-01-12
tags: ['kibana', 'controls', 'dashboard']
related: []
diff --git a/src/plugins/dashboard/kibana.json b/src/plugins/dashboard/kibana.json
index eced5b967f89a..2df14c7afb35c 100644
--- a/src/plugins/dashboard/kibana.json
+++ b/src/plugins/dashboard/kibana.json
@@ -20,7 +20,8 @@
"uiActions",
"urlForwarding",
"presentationUtil",
- "visualizations"
+ "visualizations",
+ "unifiedSearch"
],
"optionalPlugins": [
"home",
diff --git a/src/plugins/dashboard/public/application/actions/filters_notification_badge.test.tsx b/src/plugins/dashboard/public/application/actions/filters_notification_badge.test.tsx
new file mode 100644
index 0000000000000..5b990fe3ae62e
--- /dev/null
+++ b/src/plugins/dashboard/public/application/actions/filters_notification_badge.test.tsx
@@ -0,0 +1,135 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { getSampleDashboardInput } from '../test_helpers';
+import { DashboardContainer } from '../embeddable/dashboard_container';
+
+import { coreMock, uiSettingsServiceMock } from '@kbn/core/public/mocks';
+import { CoreStart } from '@kbn/core/public';
+import { FiltersNotificationBadge } from '.';
+import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
+import { type Query, type AggregateQuery, Filter } from '@kbn/es-query';
+
+import {
+ ErrorEmbeddable,
+ FilterableEmbeddable,
+ IContainer,
+ isErrorEmbeddable,
+} from '../../services/embeddable';
+import {
+ ContactCardEmbeddable,
+ ContactCardEmbeddableFactory,
+ ContactCardEmbeddableInput,
+ ContactCardEmbeddableOutput,
+ CONTACT_CARD_EMBEDDABLE,
+} from '../../services/embeddable_test_samples';
+import { getStubPluginServices } from '@kbn/presentation-util-plugin/public';
+import { screenshotModePluginMock } from '@kbn/screenshot-mode-plugin/public/mocks';
+
+const { setup, doStart } = embeddablePluginMock.createInstance();
+setup.registerEmbeddableFactory(
+ CONTACT_CARD_EMBEDDABLE,
+ new ContactCardEmbeddableFactory((() => null) as any, {} as any)
+);
+const start = doStart();
+
+let action: FiltersNotificationBadge;
+let container: DashboardContainer;
+let embeddable: ContactCardEmbeddable & FilterableEmbeddable;
+const mockGetFilters = jest.fn(async () => [] as Filter[]);
+const mockGetQuery = jest.fn(async () => undefined as Query | AggregateQuery | undefined);
+let coreStart: CoreStart;
+
+const getMockPhraseFilter = (key: string, value: string) => {
+ return {
+ meta: {
+ type: 'phrase',
+ key,
+ params: {
+ query: value,
+ },
+ },
+ query: {
+ match_phrase: {
+ [key]: value,
+ },
+ },
+ $state: {
+ store: 'appState',
+ },
+ };
+};
+
+beforeEach(async () => {
+ coreStart = coreMock.createStart();
+
+ const containerOptions = {
+ ExitFullScreenButton: () => null,
+ SavedObjectFinder: () => null,
+ application: {} as any,
+ embeddable: start,
+ inspector: {} as any,
+ notifications: {} as any,
+ overlays: coreStart.overlays,
+ savedObjectMetaData: {} as any,
+ uiActions: {} as any,
+ uiSettings: uiSettingsServiceMock.createStartContract(),
+ http: coreStart.http,
+ theme: coreStart.theme,
+ presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
+ };
+
+ container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
+
+ const contactCardEmbeddable = await container.addNewEmbeddable<
+ ContactCardEmbeddableInput,
+ ContactCardEmbeddableOutput,
+ ContactCardEmbeddable
+ >(CONTACT_CARD_EMBEDDABLE, {
+ firstName: 'Kibanana',
+ });
+ if (isErrorEmbeddable(contactCardEmbeddable)) {
+ throw new Error('Failed to create embeddable');
+ }
+
+ action = new FiltersNotificationBadge(
+ coreStart.application,
+ embeddablePluginMock.createStartContract(),
+ coreStart.overlays,
+ coreStart.theme,
+ coreStart.uiSettings
+ );
+ embeddable = embeddablePluginMock.mockFilterableEmbeddable(contactCardEmbeddable, {
+ getFilters: () => mockGetFilters(),
+ getQuery: () => mockGetQuery(),
+ });
+});
+
+test('Badge is incompatible with Error Embeddables', async () => {
+ const errorEmbeddable = new ErrorEmbeddable(
+ 'Wow what an awful error',
+ { id: ' 404' },
+ embeddable.getRoot() as IContainer
+ );
+ expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false);
+});
+
+test('Badge is not shown when panel has no app-level filters or queries', async () => {
+ expect(await action.isCompatible({ embeddable })).toBe(false);
+});
+
+test('Badge is shown when panel has at least one app-level filter', async () => {
+ mockGetFilters.mockResolvedValue([getMockPhraseFilter('fieldName', 'someValue')] as Filter[]);
+ expect(await action.isCompatible({ embeddable })).toBe(true);
+});
+
+test('Badge is shown when panel has at least one app-level query', async () => {
+ mockGetQuery.mockResolvedValue({ sql: 'SELECT * FROM test_dataview' } as AggregateQuery);
+ expect(await action.isCompatible({ embeddable })).toBe(true);
+});
diff --git a/src/plugins/dashboard/public/application/actions/filters_notification_badge.tsx b/src/plugins/dashboard/public/application/actions/filters_notification_badge.tsx
new file mode 100644
index 0000000000000..e5a1d1af32eea
--- /dev/null
+++ b/src/plugins/dashboard/public/application/actions/filters_notification_badge.tsx
@@ -0,0 +1,119 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React from 'react';
+
+import { CoreStart, OverlayStart } from '@kbn/core/public';
+import {
+ EditPanelAction,
+ EmbeddableStart,
+ isFilterableEmbeddable,
+} from '@kbn/embeddable-plugin/public';
+import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
+
+import { type AggregateQuery } from '@kbn/es-query';
+import { Action, IncompatibleActionError } from '../../services/ui_actions';
+import { toMountPoint } from '../../services/kibana_react';
+import { IEmbeddable, isErrorEmbeddable } from '../../services/embeddable';
+import { dashboardFilterNotificationBadge } from '../../dashboard_strings';
+
+export const BADGE_FILTERS_NOTIFICATION = 'ACTION_FILTERS_NOTIFICATION';
+
+export interface FiltersNotificationActionContext {
+ embeddable: IEmbeddable;
+}
+
+export class FiltersNotificationBadge implements Action {
+ public readonly id = BADGE_FILTERS_NOTIFICATION;
+ public readonly type = BADGE_FILTERS_NOTIFICATION;
+ public readonly order = 2;
+
+ private displayName = dashboardFilterNotificationBadge.getDisplayName();
+ private icon = 'filter';
+
+ constructor(
+ private application: CoreStart['application'],
+ private embeddableService: EmbeddableStart,
+ private overlays: OverlayStart,
+ private theme: CoreStart['theme'],
+ private uiSettings: CoreStart['uiSettings']
+ ) {}
+
+ public getDisplayName({ embeddable }: FiltersNotificationActionContext) {
+ if (!embeddable.getRoot() || !embeddable.getRoot().isContainer) {
+ throw new IncompatibleActionError();
+ }
+ return this.displayName;
+ }
+
+ public getIconType({ embeddable }: FiltersNotificationActionContext) {
+ if (!embeddable.getRoot() || !embeddable.getRoot().isContainer) {
+ throw new IncompatibleActionError();
+ }
+ return this.icon;
+ }
+
+ public isCompatible = async ({ embeddable }: FiltersNotificationActionContext) => {
+ // add all possible early returns to avoid the async import unless absolutely necessary
+ if (
+ isErrorEmbeddable(embeddable) ||
+ !embeddable.getRoot().isContainer ||
+ !isFilterableEmbeddable(embeddable)
+ ) {
+ return false;
+ }
+ if ((await embeddable.getFilters()).length > 0) return true;
+
+ // all early returns failed, so go ahead and check the query now
+ const { isOfQueryType, isOfAggregateQueryType } = await import('@kbn/es-query');
+ const query = await embeddable.getQuery();
+ return (
+ (isOfQueryType(query) && query.query !== '') ||
+ isOfAggregateQueryType(query as AggregateQuery)
+ );
+ };
+
+ public execute = async (context: FiltersNotificationActionContext) => {
+ const { embeddable } = context;
+
+ const isCompatible = await this.isCompatible({ embeddable });
+ if (!isCompatible || !isFilterableEmbeddable(embeddable)) {
+ throw new IncompatibleActionError();
+ }
+
+ const { Provider: KibanaReactContextProvider } = createKibanaReactContext({
+ uiSettings: this.uiSettings,
+ });
+ const editPanelAction = new EditPanelAction(
+ this.embeddableService.getEmbeddableFactory,
+ this.application,
+ this.embeddableService.getStateTransfer()
+ );
+ const FiltersNotificationModal = await import('./filters_notification_modal').then(
+ (m) => m.FiltersNotificationModal
+ );
+
+ const session = this.overlays.openModal(
+ toMountPoint(
+
+ session.close()}
+ />
+ ,
+ { theme$: this.theme.theme$ }
+ ),
+ {
+ 'data-test-subj': 'filtersNotificationModal',
+ }
+ );
+ };
+}
diff --git a/src/plugins/dashboard/public/application/actions/filters_notification_modal.test.tsx b/src/plugins/dashboard/public/application/actions/filters_notification_modal.test.tsx
new file mode 100644
index 0000000000000..2729395b7eec5
--- /dev/null
+++ b/src/plugins/dashboard/public/application/actions/filters_notification_modal.test.tsx
@@ -0,0 +1,132 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React from 'react';
+import { findTestSubject, mountWithIntl } from '@kbn/test-jest-helpers';
+
+import { DashboardContainer } from '../embeddable/dashboard_container';
+import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
+import { getSampleDashboardInput } from '../test_helpers';
+import { CoreStart } from '@kbn/core/public';
+import { coreMock, uiSettingsServiceMock } from '@kbn/core/public/mocks';
+import { EuiModalFooter } from '@elastic/eui';
+import { getStubPluginServices } from '@kbn/presentation-util-plugin/public';
+import { screenshotModePluginMock } from '@kbn/screenshot-mode-plugin/public/mocks';
+import { FiltersNotificationModal, FiltersNotificationProps } from './filters_notification_modal';
+import { FilterableEmbeddable, isErrorEmbeddable, ViewMode } from '../../services/embeddable';
+import {
+ CONTACT_CARD_EMBEDDABLE,
+ ContactCardEmbeddableFactory,
+ ContactCardEmbeddableInput,
+ ContactCardEmbeddableOutput,
+ ContactCardEmbeddable,
+} from '../../services/embeddable_test_samples';
+import { act } from 'react-dom/test-utils';
+
+describe('LibraryNotificationPopover', () => {
+ const { setup, doStart } = embeddablePluginMock.createInstance();
+ setup.registerEmbeddableFactory(
+ CONTACT_CARD_EMBEDDABLE,
+ new ContactCardEmbeddableFactory((() => null) as any, {} as any)
+ );
+ const start = doStart();
+
+ let container: DashboardContainer;
+ let embeddable: ContactCardEmbeddable & FilterableEmbeddable;
+ let defaultProps: FiltersNotificationProps;
+ let coreStart: CoreStart;
+
+ beforeEach(async () => {
+ coreStart = coreMock.createStart();
+
+ const containerOptions = {
+ ExitFullScreenButton: () => null,
+ SavedObjectFinder: () => null,
+ application: {} as any,
+ embeddable: start,
+ inspector: {} as any,
+ notifications: {} as any,
+ overlays: coreStart.overlays,
+ savedObjectMetaData: {} as any,
+ uiActions: {} as any,
+ uiSettings: uiSettingsServiceMock.createStartContract(),
+ http: coreStart.http,
+ theme: coreStart.theme,
+ presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
+ };
+
+ container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
+ const contactCardEmbeddable = await container.addNewEmbeddable<
+ ContactCardEmbeddableInput,
+ ContactCardEmbeddableOutput,
+ ContactCardEmbeddable
+ >(CONTACT_CARD_EMBEDDABLE, {
+ firstName: 'Kibanana',
+ });
+ if (isErrorEmbeddable(contactCardEmbeddable)) {
+ throw new Error('Failed to create embeddable');
+ }
+ embeddable = embeddablePluginMock.mockFilterableEmbeddable(contactCardEmbeddable, {
+ getFilters: jest.fn(),
+ getQuery: jest.fn(),
+ });
+
+ defaultProps = {
+ context: { embeddable: contactCardEmbeddable },
+ displayName: 'test display',
+ id: 'testId',
+ editPanelAction: {
+ execute: jest.fn(),
+ } as unknown as FiltersNotificationProps['editPanelAction'],
+ onClose: jest.fn(),
+ };
+ });
+
+ function mountComponent(props?: Partial) {
+ return mountWithIntl();
+ }
+
+ test('show modal footer in edit mode', async () => {
+ embeddable.updateInput({ viewMode: ViewMode.EDIT });
+ await act(async () => {
+ const component = mountComponent();
+ const footer = component.find(EuiModalFooter);
+ expect(footer.exists()).toBe(true);
+ });
+ });
+
+ test('hide modal footer in view mode', async () => {
+ embeddable.updateInput({ viewMode: ViewMode.VIEW });
+ await act(async () => {
+ const component = mountComponent();
+ const footer = component.find(EuiModalFooter);
+ expect(footer.exists()).toBe(false);
+ });
+ });
+
+ test('clicking edit button executes edit panel action', async () => {
+ embeddable.updateInput({ viewMode: ViewMode.EDIT });
+ await act(async () => {
+ const component = mountComponent();
+ const editButton = findTestSubject(component, 'filtersNotificationModal__editButton');
+ editButton.simulate('click');
+ expect(defaultProps.editPanelAction.execute).toHaveBeenCalled();
+ });
+ });
+
+ test('clicking close button calls onClose', async () => {
+ embeddable.updateInput({ viewMode: ViewMode.EDIT });
+ await act(async () => {
+ const component = mountComponent();
+ const editButton = findTestSubject(component, 'filtersNotificationModal__closeButton');
+ editButton.simulate('click');
+ expect(defaultProps.onClose).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/plugins/dashboard/public/application/actions/filters_notification_modal.tsx b/src/plugins/dashboard/public/application/actions/filters_notification_modal.tsx
new file mode 100644
index 0000000000000..b188674a85b69
--- /dev/null
+++ b/src/plugins/dashboard/public/application/actions/filters_notification_modal.tsx
@@ -0,0 +1,162 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { useState } from 'react';
+import useMount from 'react-use/lib/useMount';
+
+import {
+ EuiButton,
+ EuiButtonEmpty,
+ EuiCodeBlock,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiForm,
+ EuiFormRow,
+ EuiLoadingContent,
+ EuiModalBody,
+ EuiModalFooter,
+ EuiModalHeader,
+ EuiModalHeaderTitle,
+} from '@elastic/eui';
+import { css } from '@emotion/react';
+import { DataView } from '@kbn/data-views-plugin/public';
+import {
+ EditPanelAction,
+ FilterableEmbeddable,
+ IEmbeddable,
+ ViewMode,
+} from '@kbn/embeddable-plugin/public';
+import {
+ type AggregateQuery,
+ type Filter,
+ getAggregateQueryMode,
+ isOfQueryType,
+} from '@kbn/es-query';
+import { FilterItems } from '@kbn/unified-search-plugin/public';
+
+import { FiltersNotificationActionContext } from './filters_notification_badge';
+import { DashboardContainer } from '../embeddable';
+import { dashboardFilterNotificationBadge } from '../../dashboard_strings';
+
+export interface FiltersNotificationProps {
+ context: FiltersNotificationActionContext;
+ displayName: string;
+ id: string;
+ editPanelAction: EditPanelAction;
+ onClose: () => void;
+}
+
+export function FiltersNotificationModal({
+ context,
+ displayName,
+ id,
+ editPanelAction,
+ onClose,
+}: FiltersNotificationProps) {
+ const { embeddable } = context;
+ const [isLoading, setIsLoading] = useState(true);
+ const [filters, setFilters] = useState([]);
+ const [queryString, setQueryString] = useState('');
+ const [queryLanguage, setQueryLanguage] = useState<'sql' | 'esql' | undefined>();
+
+ useMount(() => {
+ Promise.all([
+ (embeddable as IEmbeddable & FilterableEmbeddable).getFilters(),
+ (embeddable as IEmbeddable & FilterableEmbeddable).getQuery(),
+ ]).then(([embeddableFilters, embeddableQuery]) => {
+ setFilters(embeddableFilters);
+ if (embeddableQuery) {
+ if (isOfQueryType(embeddableQuery)) {
+ setQueryString(embeddableQuery.query as string);
+ } else {
+ const language = getAggregateQueryMode(embeddableQuery);
+ setQueryLanguage(language);
+ setQueryString(embeddableQuery[language as keyof AggregateQuery]);
+ }
+ }
+ setIsLoading(false);
+ });
+ });
+
+ const dataViewList: DataView[] = (embeddable.getRoot() as DashboardContainer)?.getAllDataViews();
+ const viewMode = embeddable.getInput().viewMode;
+
+ return (
+ <>
+
+
+
+ {isLoading ? (
+
+ ) : (
+
+ {queryString !== '' && (
+
+
+ {queryString}
+
+
+ )}
+ {filters && filters.length > 0 && (
+
+
+
+
+
+ )}
+
+ )}
+
+
+ {viewMode !== ViewMode.VIEW && (
+
+ )}
+ >
+ );
+}
diff --git a/src/plugins/dashboard/public/application/actions/index.ts b/src/plugins/dashboard/public/application/actions/index.ts
index 2c6263314cb25..5c95e3c42cccd 100644
--- a/src/plugins/dashboard/public/application/actions/index.ts
+++ b/src/plugins/dashboard/public/application/actions/index.ts
@@ -23,5 +23,6 @@ export {
LibraryNotificationAction,
ACTION_LIBRARY_NOTIFICATION,
} from './library_notification_action';
+export { FiltersNotificationBadge, BADGE_FILTERS_NOTIFICATION } from './filters_notification_badge';
export type { ExportContext } from './export_csv_action';
export { ExportCSVAction, ACTION_EXPORT_CSV } from './export_csv_action';
diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
index 9f59e8637ba1c..2bb7bbb51b376 100644
--- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
@@ -16,6 +16,8 @@ import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
import { ControlGroupContainer } from '@kbn/controls-plugin/public';
import { Filter, TimeRange } from '@kbn/es-query';
+import { DataView } from '@kbn/data-views-plugin/public';
+
import { UiActionsStart } from '../../services/ui_actions';
import { RefreshInterval, Query } from '../../services/data';
import {
@@ -114,6 +116,24 @@ export class DashboardContainer extends Container {
+ return this.allDataViews;
+ };
+
+ /**
+ * Use this to set the dataviews that are used in the dashboard when they change/update
+ * @param newDataViews The new array of dataviews that will overwrite the old dataviews array
+ */
+ public setAllDataViews = (newDataViews: DataView[]) => {
+ this.allDataViews = newDataViews;
+ };
+
public getPanelCount = () => {
return Object.keys(this.getInput().panels).length;
};
diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
index 5497ae15a8714..30bb15c6ecd49 100644
--- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
+++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
@@ -258,9 +258,9 @@ export const useDashboardAppState = ({
if (newDataViewIds?.[0]) {
dashboardContainer.controlGroup?.setRelevantDataViewId(newDataViewIds[0]);
}
-
// fetch all data views. These should be cached locally at this time so we will not need to query ES.
const allDataViews = await Promise.all(newDataViewIds.map((id) => dataViews.get(id)));
+ dashboardContainer.setAllDataViews(allDataViews);
setDashboardAppState((s) => ({ ...s, dataViews: allDataViews }));
},
});
diff --git a/src/plugins/dashboard/public/dashboard_strings.ts b/src/plugins/dashboard/public/dashboard_strings.ts
index d826f16b381e9..a158df1013558 100644
--- a/src/plugins/dashboard/public/dashboard_strings.ts
+++ b/src/plugins/dashboard/public/dashboard_strings.ts
@@ -191,6 +191,29 @@ export const dashboardReplacePanelAction = {
}),
};
+export const dashboardFilterNotificationBadge = {
+ getDisplayName: () =>
+ i18n.translate('dashboard.panel.filters', {
+ defaultMessage: 'Panel filters',
+ }),
+ getEditButtonTitle: () =>
+ i18n.translate('dashboard.panel.filters.modal.editButton', {
+ defaultMessage: 'Edit filters',
+ }),
+ getCloseButtonTitle: () =>
+ i18n.translate('dashboard.panel.filters.modal.closeButton', {
+ defaultMessage: 'Close',
+ }),
+ getQueryTitle: () =>
+ i18n.translate('dashboard.panel.filters.modal.queryTitle', {
+ defaultMessage: 'Query',
+ }),
+ getFiltersTitle: () =>
+ i18n.translate('dashboard.panel.filters.modal.filtersTitle', {
+ defaultMessage: 'Filters',
+ }),
+};
+
/*
Dashboard Editor
*/
diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx
index ba06709d69f7b..c86ee5829eb44 100644
--- a/src/plugins/dashboard/public/plugin.tsx
+++ b/src/plugins/dashboard/public/plugin.tsx
@@ -26,9 +26,10 @@ import {
SavedObjectsClientContract,
} from '@kbn/core/public';
import { VisualizationsStart } from '@kbn/visualizations-plugin/public';
-
-import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/public';
import { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public';
+import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
+import { replaceUrlHashQuery } from '@kbn/kibana-utils-plugin/public';
+
import { createKbnUrlTracker } from './services/kibana_utils';
import { UsageCollectionSetup } from './services/usage_collection';
import { UiActionsSetup, UiActionsStart } from './services/ui_actions';
@@ -51,6 +52,7 @@ import {
CONTEXT_MENU_TRIGGER,
EmbeddableSetup,
EmbeddableStart,
+ PANEL_BADGE_TRIGGER,
PANEL_NOTIFICATION_TRIGGER,
} from './services/embeddable';
import {
@@ -79,6 +81,7 @@ import { PlaceholderEmbeddableFactory } from './application/embeddable/placehold
import { ExportCSVAction } from './application/actions/export_csv_action';
import { dashboardFeatureCatalog } from './dashboard_strings';
import { SpacesPluginStart } from './services/spaces';
+import { FiltersNotificationBadge } from './application/actions/filters_notification_badge';
export interface DashboardFeatureFlagConfig {
allowByValueEmbeddables: boolean;
@@ -93,6 +96,7 @@ export interface DashboardSetupDependencies {
uiActions: UiActionsSetup;
usageCollection?: UsageCollectionSetup;
screenshotMode: ScreenshotModePluginSetup;
+ unifiedSearch: UnifiedSearchPublicPluginStart;
}
export interface DashboardStartDependencies {
@@ -111,6 +115,7 @@ export interface DashboardStartDependencies {
visualizations: VisualizationsStart;
screenshotMode: ScreenshotModePluginStart;
dataViewEditor: DataViewEditorStart;
+ unifiedSearch: UnifiedSearchPublicPluginStart;
}
export interface DashboardSetup {
@@ -336,13 +341,13 @@ export class DashboardPlugin
}
public start(core: CoreStart, plugins: DashboardStartDependencies): DashboardStart {
- const { notifications, overlays, application, theme } = core;
+ const { notifications, overlays, application, theme, uiSettings } = core;
const { uiActions, data, share, presentationUtil, embeddable } = plugins;
const dashboardCapabilities: Readonly = application.capabilities
.dashboard as DashboardCapabilities;
- const SavedObjectFinder = getSavedObjectFinder(core.savedObjects, core.uiSettings);
+ const SavedObjectFinder = getSavedObjectFinder(core.savedObjects, uiSettings);
const expandPanelAction = new ExpandPanelAction();
uiActions.registerAction(expandPanelAction);
@@ -361,6 +366,16 @@ export class DashboardPlugin
uiActions.registerAction(clonePanelAction);
uiActions.attachAction(CONTEXT_MENU_TRIGGER, clonePanelAction.id);
+ const panelLevelFiltersNotification = new FiltersNotificationBadge(
+ application,
+ embeddable,
+ overlays,
+ theme,
+ uiSettings
+ );
+ uiActions.registerAction(panelLevelFiltersNotification);
+ uiActions.attachAction(PANEL_BADGE_TRIGGER, panelLevelFiltersNotification.id);
+
if (share) {
const ExportCSVPlugin = new ExportCSVAction({ core, data });
uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, ExportCSVPlugin);
diff --git a/src/plugins/data/README.mdx b/src/plugins/data/README.mdx
index a8cb06ff9e60b..ca1bd6fd98954 100644
--- a/src/plugins/data/README.mdx
+++ b/src/plugins/data/README.mdx
@@ -3,7 +3,7 @@ id: kibDataPlugin
slug: /kibana-dev-docs/key-concepts/data-plugin
title: Data services
image: https://source.unsplash.com/400x175/?Search
-summary: The data plugin contains services for searching, querying and filtering.
+description: The data plugin contains services for searching, querying and filtering.
date: 2020-12-02
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/src/plugins/data_views/README.mdx b/src/plugins/data_views/README.mdx
index 7fdd435db746e..6d2ef4c97bb33 100644
--- a/src/plugins/data_views/README.mdx
+++ b/src/plugins/data_views/README.mdx
@@ -3,7 +3,7 @@ id: kibDataPlugin
slug: /kibana-dev-docs/services/data-plugin
title: Data services
image: https://source.unsplash.com/400x175/?Search
-summary: The data plugin contains services for searching, querying and filtering.
+description: The data plugin contains services for searching, querying and filtering.
date: 2020-12-02
tags: ['kibana', 'dev', 'contributor', 'api docs']
---
diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts
index a823e54665709..fcf60947db758 100644
--- a/src/plugins/data_views/common/data_views/data_views.test.ts
+++ b/src/plugins/data_views/common/data_views/data_views.test.ts
@@ -21,7 +21,7 @@ import { stubbedSavedObjectIndexPattern } from '../data_view.stub';
const createFieldsFetcher = () =>
({
- getFieldsForWildcard: () => [],
+ getFieldsForWildcard: jest.fn(async () => []),
} as any as IDataViewsApiClient);
const fieldFormats = fieldFormatsMock;
@@ -56,6 +56,7 @@ describe('IndexPatterns', () => {
let indexPatternsNoAccess: DataViewsService;
let savedObjectsClient: SavedObjectsClientCommon;
let SOClientGetDelay = 0;
+ let apiClient: IDataViewsApiClient;
const uiSettings = {
get: () => Promise.resolve(false),
getAll: () => {},
@@ -97,10 +98,12 @@ describe('IndexPatterns', () => {
};
});
+ apiClient = createFieldsFetcher();
+
indexPatterns = new DataViewsService({
uiSettings,
savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientCommon,
- apiClient: createFieldsFetcher(),
+ apiClient,
fieldFormats,
onNotification: () => {},
onError: () => {},
@@ -112,7 +115,7 @@ describe('IndexPatterns', () => {
indexPatternsNoAccess = new DataViewsService({
uiSettings,
savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientCommon,
- apiClient: createFieldsFetcher(),
+ apiClient,
fieldFormats,
onNotification: () => {},
onError: () => {},
@@ -441,6 +444,13 @@ describe('IndexPatterns', () => {
expect(defaultDataViewResult?.id).toBe('id1');
expect(uiSettings.set).toBeCalledTimes(0);
});
+ });
+
+ describe('refreshFields', () => {
+ beforeEach(() => {
+ // preserve mocked functionality
+ jest.clearAllMocks();
+ });
test('refreshFields includes runtimeFields', async () => {
const indexPatternSpec: DataViewSpec = {
@@ -455,10 +465,22 @@ describe('IndexPatterns', () => {
title: 'test',
};
+ const indexPattern = await indexPatterns.create(indexPatternSpec);
+ await indexPatterns.refreshFields(indexPattern);
+ expect(indexPattern.fields.length).toBe(1);
+ });
+
+ test('refreshFields properly includes allowNoIndex', async () => {
+ const indexPatternSpec: DataViewSpec = {
+ allowNoIndex: true,
+ title: 'test',
+ };
+
const indexPattern = await indexPatterns.create(indexPatternSpec);
indexPatterns.refreshFields(indexPattern);
- expect(indexPattern.fields.length).toBe(1);
+ // @ts-expect-error
+ expect(apiClient.getFieldsForWildcard.mock.calls[0][0].allowNoIndex).toBe(true);
});
});
});
diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts
index c6782e82abc34..aca409ea08624 100644
--- a/src/plugins/data_views/common/data_views/data_views.ts
+++ b/src/plugins/data_views/common/data_views/data_views.ts
@@ -500,6 +500,7 @@ export class DataViewsService {
this.getFieldsForWildcard({
type: indexPattern.type,
rollupIndex: indexPattern?.typeMeta?.params?.rollup_index,
+ allowNoIndex: indexPattern.allowNoIndex,
...options,
pattern: indexPattern.title as string,
});
diff --git a/src/plugins/data_views/common/utils.ts b/src/plugins/data_views/common/utils.ts
index c12e6c71c92ba..9b86dfefc2631 100644
--- a/src/plugins/data_views/common/utils.ts
+++ b/src/plugins/data_views/common/utils.ts
@@ -20,11 +20,11 @@ import { DATA_VIEW_SAVED_OBJECT_TYPE } from './constants';
*/
export async function findByName(client: SavedObjectsClientCommon, name: string) {
if (name) {
- const savedObjects = await client.find({
+ const savedObjects = await client.find<{ name: DataViewSavedObjectAttrs['name'] }>({
type: DATA_VIEW_SAVED_OBJECT_TYPE,
perPage: 10,
search: `"${name}"`,
- searchFields: ['name'],
+ searchFields: ['name.keyword'],
fields: ['name'],
});
diff --git a/src/plugins/data_views/server/saved_objects/data_views.ts b/src/plugins/data_views/server/saved_objects/data_views.ts
index 3036efd5559d3..4b8318b3d065f 100644
--- a/src/plugins/data_views/server/saved_objects/data_views.ts
+++ b/src/plugins/data_views/server/saved_objects/data_views.ts
@@ -38,7 +38,14 @@ export const dataViewSavedObjectType: SavedObjectsType = {
properties: {
title: { type: 'text' },
type: { type: 'keyword' },
- name: { type: 'text' },
+ name: {
+ type: 'text',
+ fields: {
+ keyword: {
+ type: 'keyword',
+ },
+ },
+ },
},
},
migrations: indexPatternSavedObjectTypeMigrations,
diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx
index c2e76e517f64d..1fb7acc18b7db 100644
--- a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx
+++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx
@@ -20,9 +20,14 @@ import { i18n } from '@kbn/i18n';
import { isEqual } from 'lodash';
import { I18nProvider } from '@kbn/i18n-react';
import type { KibanaExecutionContext } from '@kbn/core/public';
-import { Container, Embeddable } from '@kbn/embeddable-plugin/public';
+import { Container, Embeddable, FilterableEmbeddable } from '@kbn/embeddable-plugin/public';
import { Adapters, RequestAdapter } from '@kbn/inspector-plugin/common';
-import { APPLY_FILTER_TRIGGER, FilterManager, generateFilters } from '@kbn/data-plugin/public';
+import {
+ APPLY_FILTER_TRIGGER,
+ FilterManager,
+ generateFilters,
+ mapAndFlattenFilters,
+} from '@kbn/data-plugin/public';
import { ISearchSource } from '@kbn/data-plugin/public';
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
@@ -83,7 +88,7 @@ interface SearchEmbeddableConfig {
export class SavedSearchEmbeddable
extends Embeddable
- implements ISearchEmbeddable
+ implements ISearchEmbeddable, FilterableEmbeddable
{
private readonly savedSearch: SavedSearch;
private inspectorAdapters: Adapters;
@@ -548,6 +553,22 @@ export class SavedSearchEmbeddable
return this.savedSearch.description;
}
+ /**
+ * @returns Local/panel-level array of filters for Saved Search embeddable
+ */
+ public async getFilters() {
+ return mapAndFlattenFilters(
+ (this.savedSearch.searchSource.getFields().filter as Filter[]) ?? []
+ );
+ }
+
+ /**
+ * @returns Local/panel-level query for Saved Search embeddable
+ */
+ public async getQuery() {
+ return this.savedSearch.searchSource.getFields().query;
+ }
+
public destroy() {
super.destroy();
if (this.searchProps) {
diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts
index 29409f63548af..4b4d63f4596a4 100644
--- a/src/plugins/embeddable/public/index.ts
+++ b/src/plugins/embeddable/public/index.ts
@@ -15,6 +15,7 @@ export type {
Adapters,
ReferenceOrValueEmbeddable,
SelfStyledEmbeddable,
+ FilterableEmbeddable,
ChartActionContext,
ContainerInput,
ContainerOutput,
@@ -79,6 +80,7 @@ export {
EmbeddableStateTransfer,
EmbeddableRenderer,
useEmbeddableFactory,
+ isFilterableEmbeddable,
} from './lib';
export { AttributeService, ATTRIBUTE_SERVICE_KEY } from './lib/attribute_service';
diff --git a/src/plugins/embeddable/public/lib/filterable_embeddable/index.ts b/src/plugins/embeddable/public/lib/filterable_embeddable/index.ts
new file mode 100644
index 0000000000000..ffa9470a34af4
--- /dev/null
+++ b/src/plugins/embeddable/public/lib/filterable_embeddable/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export type { FilterableEmbeddable } from './types';
+export { isFilterableEmbeddable } from './types';
diff --git a/src/plugins/embeddable/public/lib/filterable_embeddable/types.ts b/src/plugins/embeddable/public/lib/filterable_embeddable/types.ts
new file mode 100644
index 0000000000000..8fe2b85e02ada
--- /dev/null
+++ b/src/plugins/embeddable/public/lib/filterable_embeddable/types.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { type AggregateQuery, type Filter, type Query } from '@kbn/es-query';
+
+/**
+ * All embeddables that implement this interface should support being filtered
+ * and/or queried via the top navigation bar
+ * @public
+ */
+export interface FilterableEmbeddable {
+ /**
+ * Gets the embeddable's local filters
+ **/
+ getFilters: () => Promise;
+ /**
+ * Gets the embeddable's local query
+ **/
+ getQuery: () => Promise;
+}
+
+/**
+ * Ensure that embeddable supports filtering/querying
+ * @param incoming Embeddable that is being tested to check if it is a FilterableEmbeddable
+ * @returns true if the incoming embeddable is a FilterableEmbeddable, false if it is not
+ */
+export function isFilterableEmbeddable(incoming: unknown): incoming is FilterableEmbeddable {
+ return (
+ !!(incoming as FilterableEmbeddable).getFilters && !!(incoming as FilterableEmbeddable).getQuery
+ );
+}
diff --git a/src/plugins/embeddable/public/lib/index.ts b/src/plugins/embeddable/public/lib/index.ts
index 6f57003403aca..f8c30b12c5c74 100644
--- a/src/plugins/embeddable/public/lib/index.ts
+++ b/src/plugins/embeddable/public/lib/index.ts
@@ -16,3 +16,4 @@ export * from './panel';
export * from './state_transfer';
export * from './reference_or_value_embeddable';
export * from './self_styled_embeddable';
+export * from './filterable_embeddable';
diff --git a/src/plugins/embeddable/public/mocks.tsx b/src/plugins/embeddable/public/mocks.tsx
index 9f05b3eeaa001..25ccb141cd356 100644
--- a/src/plugins/embeddable/public/mocks.tsx
+++ b/src/plugins/embeddable/public/mocks.tsx
@@ -10,6 +10,7 @@ import React from 'react';
import { coreMock, themeServiceMock } from '@kbn/core/public/mocks';
import { CoreStart } from '@kbn/core/public';
import { Start as InspectorStart } from '@kbn/inspector-plugin/public';
+import { type AggregateQuery, type Filter, type Query } from '@kbn/es-query';
import { inspectorPluginMock } from '@kbn/inspector-plugin/public/mocks';
import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks';
@@ -27,6 +28,7 @@ import {
SavedObjectEmbeddableInput,
ReferenceOrValueEmbeddable,
SelfStyledEmbeddable,
+ FilterableEmbeddable,
} from '.';
import { SelfStyledOptions } from './lib/self_styled_embeddable/types';
@@ -112,6 +114,19 @@ export function mockSelfStyledEmbeddable(
return newEmbeddable as OriginalEmbeddableType & SelfStyledEmbeddable;
}
+export function mockFilterableEmbeddable(
+ embeddable: OriginalEmbeddableType,
+ options: {
+ getFilters: () => Promise;
+ getQuery: () => Promise;
+ }
+): OriginalEmbeddableType & FilterableEmbeddable {
+ const newEmbeddable: FilterableEmbeddable = embeddable as unknown as FilterableEmbeddable;
+ newEmbeddable.getFilters = () => options.getFilters();
+ newEmbeddable.getQuery = () => options.getQuery();
+ return newEmbeddable as OriginalEmbeddableType & FilterableEmbeddable;
+}
+
const createSetupContract = (): Setup => {
const setupContract: Setup = {
registerEmbeddableFactory: jest.fn(),
@@ -159,4 +174,5 @@ export const embeddablePluginMock = {
createInstance,
mockRefOrValEmbeddable,
mockSelfStyledEmbeddable,
+ mockFilterableEmbeddable,
};
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/default_value.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/default_value.mdx
index 5e03d6ad16528..be5dc8034d039 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/default_value.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/default_value.mdx
@@ -2,7 +2,7 @@
id: formLibCoreDefaultValue
slug: /form-lib/core/default-value
title: Default value
-summary: Initiate a field with the correct value
+description: Initiate a field with the correct value
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/field_hook.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/field_hook.mdx
index c7be88c4336a6..8532a1857871c 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/field_hook.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/field_hook.mdx
@@ -2,7 +2,7 @@
id: formLibCoreFieldHook
slug: /form-lib/core/field-hook
title: Field hook
-summary: You don't manually create them but you'll get all the love from them
+description: You don't manually create them but you'll get all the love from them
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/form_component.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/form_component.mdx
index df479b5c72f37..db642ef846fca 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/form_component.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/form_component.mdx
@@ -2,7 +2,7 @@
id: formLibCoreFormComponent
slug: /form-lib/core/form-component
title:
-summary: The boundary of your form
+description: The boundary of your form
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/form_hook.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/form_hook.mdx
index 46fac236123fd..824f9f6671384 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/form_hook.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/form_hook.mdx
@@ -2,7 +2,7 @@
id: formLibCoreFormHook
slug: /form-lib/core/form-hook
title: Form hook
-summary: The heart of the lib; It manages your fields so you don't have to
+description: The heart of the lib; It manages your fields so you don't have to
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/fundamentals.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/fundamentals.mdx
index c168cb4115bc2..4276519c54e87 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/fundamentals.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/fundamentals.mdx
@@ -2,7 +2,7 @@
id: formLibCoreFundamentals
slug: /form-lib/core/fundamentals
title: Fundamentals
-summary: Let's understand the basics
+description: Let's understand the basics
tags: ['forms', 'kibana', 'dev']
date: 2022-03-18
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_array.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_array.mdx
index b92880fdf806d..ca849fd067ccb 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_array.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_array.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseArray
slug: /form-lib/core/use-array
title:
-summary: The perfect companion to generate dynamic fields
+description: The perfect companion to generate dynamic fields
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_behavior_subject.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_behavior_subject.mdx
index f7eca9c360ac4..40190343f5bfe 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_behavior_subject.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_behavior_subject.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseBehaviorSubject
slug: /form-lib/utils/use-behavior-subject
title: useBehaviorSubject()
-summary: Util to create a rxjs BehaviorSubject with a handler to change its value
+description: Util to create a rxjs BehaviorSubject with a handler to change its value
tags: ['forms', 'kibana', 'dev']
date: 2021-08-20
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_field.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_field.mdx
index dd073e0b38d1f..d5729dc778816 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_field.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_field.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseField
slug: /form-lib/core/use-field
title:
-summary: Drop it anywhere in your and see the magic happen
+description: Drop it anywhere in your and see the magic happen
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_data.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_data.mdx
index 0deb449591871..2e5f628a86370 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_data.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_data.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseFormData
slug: /form-lib/core/use-form-data
title: useFormData()
-summary: Get fields value updates from anywhere
+description: Get fields value updates from anywhere
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_hook.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_hook.mdx
index 21c77afd6dbce..82cd0c88834a3 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_hook.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_hook.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseForm
slug: /form-lib/core/use-form
title: useForm()
-summary: The only hook you'll need to declare a new form
+description: The only hook you'll need to declare a new form
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_is_modified.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_is_modified.mdx
index d90b9100a04af..d7c0603cc07c5 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_form_is_modified.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_form_is_modified.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseFormIsModified
slug: /form-lib/core/use-form-is-modified
title: useFormIsModified()
-summary: Know when your form has been modified by the user
+description: Know when your form has been modified by the user
tags: ['forms', 'kibana', 'dev']
date: 2022-03-18
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/core/use_multi_fields.mdx b/src/plugins/es_ui_shared/static/forms/docs/core/use_multi_fields.mdx
index 2a16b8e878be8..281db05d5f1a6 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/core/use_multi_fields.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/core/use_multi_fields.mdx
@@ -2,7 +2,7 @@
id: formLibCoreUseMultiFields
slug: /form-lib/core/use-multi-fields
title:
-summary: Because sometimes you need more than one field
+description: Because sometimes you need more than one field
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx
index f2525d5a16fba..82516423424f6 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/dynamic_fields.mdx
@@ -2,7 +2,7 @@
id: formLibExampleDynamicFields
slug: /form-lib/examples/dynamic-fields
title: Dynamic fields
-summary: Let the user add any number of fields on the fly
+description: Let the user add any number of fields on the fly
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx
index 260908f94a790..7e7cce5e81332 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/fields_composition.mdx
@@ -2,7 +2,7 @@
id: formLibExampleFieldsComposition
slug: /form-lib/examples/fields-composition
title: Fields composition
-summary: Be DRY and compose your form
+description: Be DRY and compose your form
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/listening_to_changes.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/listening_to_changes.mdx
index c99184f5a5c0e..6574a7ca4e2d1 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/listening_to_changes.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/listening_to_changes.mdx
@@ -2,7 +2,7 @@
id: formLibExampleListeningToChanges
slug: /form-lib/examples/listening-to-changes
title: Listening to changes
-summary: React to changes deep down the tree
+description: React to changes deep down the tree
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx
index 393711b393e0f..dd3b402e85e3f 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/serializers_deserializers.mdx
@@ -2,7 +2,7 @@
id: formLibExampleSerializersDeserializers
slug: /form-lib/examples/serializers-deserializers
title: Serializers & Deserializers
-summary: No need for a 1:1 map of your API with your form fields, be creative!
+description: No need for a 1:1 map of your API with your form fields, be creative!
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/style_fields.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/style_fields.mdx
index db7c98772eddb..81ed07ffd5daf 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/style_fields.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/style_fields.mdx
@@ -2,7 +2,7 @@
id: formLibExampleStyleFields
slug: /form-lib/examples/styles-fields
title: Style fields
-summary: Customize your fields however you want
+description: Customize your fields however you want
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/examples/validation.mdx b/src/plugins/es_ui_shared/static/forms/docs/examples/validation.mdx
index 0f4e9617d9af3..c45cae8602f19 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/examples/validation.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/examples/validation.mdx
@@ -2,7 +2,7 @@
id: formLibExampleValidation
slug: /form-lib/examples/validation
title: Validation
-summary: Don't let invalid data leak out of your form!
+description: Don't let invalid data leak out of your form!
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/helpers/components.mdx b/src/plugins/es_ui_shared/static/forms/docs/helpers/components.mdx
index 1b35e41a98739..97ea955aaecb1 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/helpers/components.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/helpers/components.mdx
@@ -2,7 +2,7 @@
id: formLibHelpersComponents
slug: /form-lib/helpers/components
title: Components
-summary: Build complex forms the easy way
+description: Build complex forms the easy way
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/helpers/validators.mdx b/src/plugins/es_ui_shared/static/forms/docs/helpers/validators.mdx
index aba2d6dffb1ba..7fbe4c4e38dc3 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/helpers/validators.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/helpers/validators.mdx
@@ -2,7 +2,7 @@
id: formLibHelpersValidators
slug: /form-lib/helpers/validators
title: Validators
-summary: Build complex forms the easy way
+description: Build complex forms the easy way
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/es_ui_shared/static/forms/docs/welcome.mdx b/src/plugins/es_ui_shared/static/forms/docs/welcome.mdx
index 2d1156f403bff..8a356868e49c2 100644
--- a/src/plugins/es_ui_shared/static/forms/docs/welcome.mdx
+++ b/src/plugins/es_ui_shared/static/forms/docs/welcome.mdx
@@ -2,7 +2,7 @@
id: formLibWelcome
slug: /form-lib/welcome
title: Welcome
-summary: Build complex forms the easy way
+description: Build complex forms the easy way
tags: ['forms', 'kibana', 'dev']
date: 2021-04-14
---
diff --git a/src/plugins/presentation_util/README.mdx b/src/plugins/presentation_util/README.mdx
index 2cbb03232b9dd..2fc73204db4e1 100755
--- a/src/plugins/presentation_util/README.mdx
+++ b/src/plugins/presentation_util/README.mdx
@@ -2,7 +2,7 @@
id: presentationUtilPlugin
slug: /kibana-dev-docs/presentationPlugin
title: Presentation Utility Plugin
-summary: Introduction to the Presentation Utility Plugin.
+description: Introduction to the Presentation Utility Plugin.
date: 2020-01-12
tags: ['kibana', 'presentation', 'services']
related: []
diff --git a/src/plugins/share/README.mdx b/src/plugins/share/README.mdx
index 1a1fef0587812..bb4433b54b480 100644
--- a/src/plugins/share/README.mdx
+++ b/src/plugins/share/README.mdx
@@ -2,7 +2,7 @@
id: kibDevSharePluginReadme
slug: /kibana-dev-docs/tutorials/share
title: Kibana share Plugin
-summary: Introduction to Kibana "share" plugin services (sharing popup menu, URL locators, and short URLs).
+description: Introduction to Kibana "share" plugin services (sharing popup menu, URL locators, and short URLs).
date: 2022-02-21
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'share', 'url', 'short-url', 'locator']
---
diff --git a/src/plugins/shared_ux/docs/about.mdx b/src/plugins/shared_ux/docs/about.mdx
index a31a9b99195f2..213ce774be217 100644
--- a/src/plugins/shared_ux/docs/about.mdx
+++ b/src/plugins/shared_ux/docs/about.mdx
@@ -2,7 +2,7 @@
id: sharedUX/About
slug: /shared-ux/about
title: About Shared UX
-summary: .
+description: .
date: 2021-01-05
tags: ['shared-ux']
---
diff --git a/src/plugins/unified_search/public/filter_bar/filter_bar.tsx b/src/plugins/unified_search/public/filter_bar/filter_bar.tsx
index 3eda5ded37078..3cf8c41b3c498 100644
--- a/src/plugins/unified_search/public/filter_bar/filter_bar.tsx
+++ b/src/plugins/unified_search/public/filter_bar/filter_bar.tsx
@@ -11,7 +11,7 @@ import { InjectedIntl, injectI18n } from '@kbn/i18n-react';
import type { Filter } from '@kbn/es-query';
import React, { useRef } from 'react';
import { DataView } from '@kbn/data-views-plugin/public';
-import FilterItems, { Props as FilterItemsProps } from './filter_item/filter_items';
+import FilterItems, { type FilterItemsProps } from './filter_item/filter_items';
import { filterBarStyles } from './filter_bar.styles';
diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx
index f869aeeb07a32..abacffe4a46a9 100644
--- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx
+++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_item.tsx
@@ -20,6 +20,7 @@ import {
import classNames from 'classnames';
import React, { MouseEvent, useState, useEffect, HTMLAttributes } from 'react';
import { IUiSettingsClient } from '@kbn/core/public';
+
import { DataView } from '@kbn/data-views-plugin/public';
import {
getIndexPatternFromFilter,
@@ -42,6 +43,7 @@ export interface FilterItemProps {
uiSettings: IUiSettingsClient;
hiddenPanelOptions?: FilterPanelOption[];
timeRangeForSuggestionsOverride?: boolean;
+ readOnly?: boolean;
}
type FilterPopoverProps = HTMLAttributes & EuiPopoverProps;
@@ -67,7 +69,7 @@ export function FilterItem(props: FilterItemProps) {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const [indexPatternExists, setIndexPatternExists] = useState(undefined);
const [renderedComponent, setRenderedComponent] = useState('menu');
- const { id, filter, indexPatterns, hiddenPanelOptions } = props;
+ const { id, filter, indexPatterns, hiddenPanelOptions, readOnly = false } = props;
useEffect(() => {
if (isPopoverOpen) {
@@ -355,6 +357,7 @@ export function FilterItem(props: FilterItemProps) {
const filterViewProps = {
filter,
+ readOnly,
valueLabel: valueLabelConfig.title,
fieldLabel: getFieldDisplayValueFromFilter(filter, indexPatterns),
filterLabelStatus: valueLabelConfig.status,
@@ -377,7 +380,9 @@ export function FilterItem(props: FilterItemProps) {
panelPaddingSize: 'none',
};
- return (
+ return readOnly ? (
+
+ ) : (
{renderedComponent === 'menu' ? (
diff --git a/src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx b/src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx
index 0119bf10cfa27..4c29c4284860d 100644
--- a/src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx
+++ b/src/plugins/unified_search/public/filter_bar/filter_item/filter_items.tsx
@@ -17,19 +17,34 @@ import { DataView } from '@kbn/data-views-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { FilterItem, FilterItemProps } from './filter_item';
-export interface Props {
+/**
+ * Properties for the filter items component, which will render a single filter pill for every filter that is sent in
+ * as part of the `Filter[]` property.
+ */
+export interface FilterItemsProps {
+ /** Array of filters that will be rendered as filter pills */
filters: Filter[];
+ /** Optional property that controls whether or not clicking the filter pill opens a popover *and* whether
+ * or not the `x` button to remove the filter is rendered.*/
+ readOnly?: boolean;
+ /** If not read only, this is called whenever a filter is removed and/or updated */
onFiltersUpdated?: (filters: Filter[]) => void;
+ /** A list of all dataviews that are used for the filters */
indexPatterns: DataView[];
+ /** This is injected by the lazer loader */
intl: InjectedIntl;
+ /** Controls whether or not filter suggestions are influenced by the global time */
timeRangeForSuggestionsOverride?: boolean;
+ /** Array of panel options that controls the styling of each filter pill */
hiddenPanelOptions?: FilterItemProps['hiddenPanelOptions'];
}
-const FilterItemsUI = React.memo(function FilterItemsUI(props: Props) {
+const FilterItemsUI = React.memo(function FilterItemsUI(props: FilterItemsProps) {
const groupRef = useRef(null);
const kibana = useKibana();
const { appName, usageCollection, uiSettings } = kibana.services;
+ const { readOnly = false } = props;
+
if (!uiSettings) return null;
const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName);
@@ -59,6 +74,7 @@ const FilterItemsUI = React.memo(function FilterItemsUI(props: Props) {
uiSettings={uiSettings!}
hiddenPanelOptions={props.hiddenPanelOptions}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
+ readOnly={readOnly}
/>
));
diff --git a/src/plugins/unified_search/public/filter_bar/filter_view/index.tsx b/src/plugins/unified_search/public/filter_bar/filter_view/index.tsx
index 0e10766139820..ffffee70534bd 100644
--- a/src/plugins/unified_search/public/filter_bar/filter_view/index.tsx
+++ b/src/plugins/unified_search/public/filter_bar/filter_view/index.tsx
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { EuiBadge, EuiBadgeProps, useInnerText } from '@elastic/eui';
+import { EuiBadge, EuiBadgeProps, EuiToolTip, useInnerText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { FC } from 'react';
import { Filter, isFilterPinned } from '@kbn/es-query';
@@ -15,6 +15,7 @@ import type { FilterLabelStatus } from '../filter_item/filter_item';
interface Props {
filter: Filter;
+ readOnly: boolean;
valueLabel: string;
fieldLabel?: string;
filterLabelStatus: FilterLabelStatus;
@@ -25,6 +26,7 @@ interface Props {
export const FilterView: FC = ({
filter,
+ readOnly,
iconOnClick,
onClick,
valueLabel,
@@ -36,13 +38,17 @@ export const FilterView: FC = ({
}: Props) => {
const [ref, innerText] = useInnerText();
- let title =
- errorMessage ||
- i18n.translate('unifiedSearch.filter.filterBar.moreFilterActionsMessage', {
- defaultMessage: 'Filter: {innerText}. Select for more filter actions.',
- values: { innerText },
- });
+ const filterString = readOnly
+ ? i18n.translate('unifiedSearch.filter.filterBar.filterString', {
+ defaultMessage: 'Filter: {innerText}.',
+ values: { innerText },
+ })
+ : i18n.translate('unifiedSearch.filter.filterBar.filterActionsMessage', {
+ defaultMessage: 'Filter: {innerText}. Select for more filter actions.',
+ values: { innerText },
+ });
+ let title: string = errorMessage || filterString;
if (isFilterPinned(filter)) {
title = `${i18n.translate('unifiedSearch.filter.filterBar.pinnedFilterPrefix', {
defaultMessage: 'Pinned',
@@ -54,41 +60,58 @@ export const FilterView: FC = ({
})} ${title}`;
}
- const badgeProps: EuiBadgeProps = {
- title,
- color: 'hollow',
- iconType: 'cross',
- iconSide: 'right',
- closeButtonProps: {
- // Removing tab focus on close button because the same option can be obtained through the context menu
- // Also, we may want to add a `DEL` keyboard press functionality
- tabIndex: -1,
- },
- iconOnClick,
- iconOnClickAriaLabel: i18n.translate(
- 'unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel',
- {
- defaultMessage: 'Delete {filter}',
- values: { filter: innerText },
- }
- ),
- onClick,
- onClickAriaLabel: i18n.translate('unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel', {
- defaultMessage: 'Filter actions',
- }),
- };
+ const sharedProps = { color: 'hollow', tabIndex: 0 };
+ const badgeProps: EuiBadgeProps = readOnly
+ ? // prevent native tooltip for read-only filter pulls by setting title to undefined
+ { ...sharedProps, title: undefined }
+ : {
+ ...sharedProps,
+ title, // use native tooltip for non-read-only filter pills
+ iconType: 'cross',
+ iconSide: 'right',
+ closeButtonProps: {
+ // Removing tab focus on close button because the same option can be obtained through the context menu
+ // Also, we may want to add a `DEL` keyboard press functionality
+ tabIndex: -1,
+ },
+ iconOnClick,
+ iconOnClickAriaLabel: i18n.translate(
+ 'unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel',
+ {
+ defaultMessage: 'Delete {filter}',
+ values: { filter: innerText },
+ }
+ ),
+ onClick,
+ onClickAriaLabel: i18n.translate(
+ 'unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel',
+ {
+ defaultMessage: 'Filter actions',
+ }
+ ),
+ };
- return (
+ const FilterPill = () => (
+
+
+ );
+
+ return readOnly ? (
+
-
+
-
+
+ ) : (
+
+
+
);
};
diff --git a/src/plugins/unified_search/public/filter_bar/index.tsx b/src/plugins/unified_search/public/filter_bar/index.tsx
index 30f94c3972ee1..a70b6b93de5dd 100644
--- a/src/plugins/unified_search/public/filter_bar/index.tsx
+++ b/src/plugins/unified_search/public/filter_bar/index.tsx
@@ -8,6 +8,8 @@
import React from 'react';
+export type { FilterItemsProps } from './filter_item/filter_items';
+
const Fallback = () => ;
const LazyFilterBar = React.lazy(() => import('./filter_bar'));
@@ -18,6 +20,9 @@ export const FilterBar = (props: React.ComponentProps) =>
);
const LazyFilterItems = React.lazy(() => import('./filter_item/filter_items'));
+/**
+ * Renders a group of filter pills
+ */
export const FilterItems = (props: React.ComponentProps) => (
}>
@@ -25,6 +30,9 @@ export const FilterItems = (props: React.ComponentProps)
);
const LazyFilterLabel = React.lazy(() => import('./filter_editor/lib/filter_label'));
+/**
+ * Renders the label for a single filter pill
+ */
export const FilterLabel = (props: React.ComponentProps) => (
}>
@@ -32,6 +40,9 @@ export const FilterLabel = (props: React.ComponentProps)
);
const LazyFilterItem = React.lazy(() => import('./filter_item/filter_item'));
+/**
+ * Renders a single filter pill
+ */
export const FilterItem = (props: React.ComponentProps) => (
}>
diff --git a/src/plugins/unified_search/public/index.ts b/src/plugins/unified_search/public/index.ts
index 69b7ae95bf2fb..131b445017353 100755
--- a/src/plugins/unified_search/public/index.ts
+++ b/src/plugins/unified_search/public/index.ts
@@ -14,7 +14,8 @@ export { QueryStringInput } from './query_string_input';
export type { StatefulSearchBarProps, SearchBarProps } from './search_bar';
export type { UnifiedSearchPublicPluginStart, UnifiedSearchPluginSetup } from './types';
export { SearchBar } from './search_bar';
-export { FilterLabel, FilterItem } from './filter_bar';
+export type { FilterItemsProps } from './filter_bar';
+export { FilterLabel, FilterItem, FilterItems } from './filter_bar';
export { DataViewsList } from './dataview_picker/dataview_list';
export { DataViewPicker } from './dataview_picker';
diff --git a/src/plugins/usage_collection/README.mdx b/src/plugins/usage_collection/README.mdx
index 03d8f7badb8c2..a703a3de00820 100644
--- a/src/plugins/usage_collection/README.mdx
+++ b/src/plugins/usage_collection/README.mdx
@@ -2,7 +2,7 @@
id: kibUsageCollectionPlugin
slug: /kibana-dev-docs/key-concepts/usage-collection-plugin
title: Usage collection service
-summary: The Usage Collection Service defines a set of APIs for other plugins to report the usage of their features.
+description: The Usage Collection Service defines a set of APIs for other plugins to report the usage of their features.
date: 2021-02-24
tags: ['kibana','dev', 'contributor', 'api docs']
---
diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
index 4bc5aec2396f2..f0aab3b880ae3 100644
--- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
+++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
@@ -24,6 +24,7 @@ import {
Embeddable,
EmbeddableInput,
EmbeddableOutput,
+ FilterableEmbeddable,
IContainer,
ReferenceOrValueEmbeddable,
SavedObjectEmbeddableInput,
@@ -37,6 +38,7 @@ import {
} from '@kbn/expressions-plugin/public';
import type { RenderMode } from '@kbn/expressions-plugin/common';
import { DATA_VIEW_SAVED_OBJECT_TYPE } from '@kbn/data-views-plugin/public';
+import { mapAndFlattenFilters } from '@kbn/data-plugin/public';
import { isFallbackDataView } from '../visualize_app/utils';
import { VisualizationMissedSavedObjectError } from '../components/visualization_missed_saved_object_error';
import VisualizationError from '../components/visualization_error';
@@ -94,7 +96,9 @@ export type VisualizeByReferenceInput = SavedObjectEmbeddableInput & VisualizeIn
export class VisualizeEmbeddable
extends Embeddable
- implements ReferenceOrValueEmbeddable
+ implements
+ ReferenceOrValueEmbeddable,
+ FilterableEmbeddable
{
private handler?: ExpressionLoader;
private timefilter: TimefilterContract;
@@ -188,6 +192,32 @@ export class VisualizeEmbeddable
return this.vis.description;
}
+ /**
+ * Gets the Visualize embeddable's local filters
+ * @returns Local/panel-level array of filters for Visualize embeddable
+ */
+ public async getFilters() {
+ let input = this.getInput();
+ if (this.inputIsRefType(input)) {
+ input = await this.getInputAsValueType();
+ }
+ const filters = input.savedVis?.data.searchSource?.filter ?? [];
+ // must clone the filters so that it's not read only, because mapAndFlattenFilters modifies the array
+ return mapAndFlattenFilters(_.cloneDeep(filters));
+ }
+
+ /**
+ * Gets the Visualize embeddable's local query
+ * @returns Local/panel-level query for Visualize embeddable
+ */
+ public async getQuery() {
+ let input = this.getInput();
+ if (this.inputIsRefType(input)) {
+ input = await this.getInputAsValueType();
+ }
+ return input.savedVis?.data.searchSource?.query;
+ }
+
public getInspectorAdapters = () => {
if (!this.handler || (this.inspectorAdapters && !Object.keys(this.inspectorAdapters).length)) {
return undefined;
diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts
index 6734690c4b3bd..d36ba21513b0a 100644
--- a/test/functional/page_objects/dashboard_page.ts
+++ b/test/functional/page_objects/dashboard_page.ts
@@ -562,7 +562,7 @@ export class DashboardPageObject extends FtrService {
public async getPanelTitles() {
this.log.debug('in getPanelTitles');
- const titleObjects = await this.testSubjects.findAll('dashboardPanelTitle');
+ const titleObjects = await this.find.allByCssSelector('span.embPanel__titleInner');
return await Promise.all(titleObjects.map(async (title) => await title.getVisibleText()));
}
diff --git a/tsconfig.base.json b/tsconfig.base.json
index c3a37ced8434e..04afc7e8bb049 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -329,6 +329,8 @@
"@kbn/features-plugin/*": ["x-pack/plugins/features/*"],
"@kbn/file-upload-plugin": ["x-pack/plugins/file_upload"],
"@kbn/file-upload-plugin/*": ["x-pack/plugins/file_upload/*"],
+ "@kbn/files-plugin": ["x-pack/plugins/files"],
+ "@kbn/files-plugin/*": ["x-pack/plugins/files/*"],
"@kbn/fleet-plugin": ["x-pack/plugins/fleet"],
"@kbn/fleet-plugin/*": ["x-pack/plugins/fleet/*"],
"@kbn/global-search-bar-plugin": ["x-pack/plugins/global_search_bar"],
diff --git a/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx b/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx
index b4eb2e0809f4e..c593da55ffded 100644
--- a/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx
+++ b/x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { isEqual } from 'lodash';
import React, { useEffect, useRef } from 'react';
import * as d3Brush from 'd3-brush';
@@ -74,7 +75,14 @@ export function DualBrush({
}: DualBrushProps) {
const d3BrushContainer = useRef(null);
const brushes = useRef([]);
+
+ // We need to pass props to refs here because the d3-brush code doesn't consider
+ // native React prop changes. The brush code does its own check whether these props changed then.
+ // The initialized brushes might otherwise act on stale data.
const widthRef = useRef(width);
+ const minRef = useRef(min);
+ const maxRef = useRef(max);
+ const snapTimestampsRef = useRef(snapTimestamps);
const { baselineMin, baselineMax, deviationMin, deviationMax } = windowParameters;
@@ -93,11 +101,14 @@ export function DualBrush({
function brushend(this: d3Selection.BaseType) {
const currentWidth = widthRef.current;
- const x = d3.scaleLinear().domain([min, max]).rangeRound([0, currentWidth]);
+ const x = d3
+ .scaleLinear()
+ .domain([minRef.current, maxRef.current])
+ .rangeRound([0, currentWidth]);
const px2ts = (px: number) => Math.round(x.invert(px));
- const xMin = x(min) ?? 0;
- const xMax = x(max) ?? 0;
+ const xMin = x(minRef.current) ?? 0;
+ const xMax = x(maxRef.current) ?? 0;
const minExtentPx = Math.round((xMax - xMin) / 100);
const baselineBrush = d3.select('#aiops-brush-baseline');
@@ -157,8 +168,8 @@ export function DualBrush({
newWindowParameters.baselineMax = px2ts(newBaselineMax);
}
- const snappedWindowParameters = snapTimestamps
- ? getSnappedWindowParameters(newWindowParameters, snapTimestamps)
+ const snappedWindowParameters = snapTimestampsRef.current
+ ? getSnappedWindowParameters(newWindowParameters, snapTimestampsRef.current)
: newWindowParameters;
const newBrushPx = {
@@ -235,7 +246,7 @@ export function DualBrush({
mlBrushSelection
.attr('class', 'brush')
.selectAll('.overlay')
- .attr('width', width)
+ .attr('width', widthRef.current)
.style('pointer-events', 'none');
mlBrushSelection
@@ -252,10 +263,13 @@ export function DualBrush({
.data(brushes.current, (d) => (d as DualBrush).id);
mlBrushSelection.each(function (brushObject, i, n) {
- const x = d3.scaleLinear().domain([min, max]).rangeRound([0, widthRef.current]);
+ const x = d3
+ .scaleLinear()
+ .domain([minRef.current, maxRef.current])
+ .rangeRound([0, widthRef.current]);
brushObject.brush.extent([
[0, BRUSH_MARGIN],
- [width, BRUSH_HEIGHT - BRUSH_MARGIN],
+ [widthRef.current, BRUSH_HEIGHT - BRUSH_MARGIN],
]);
brushObject.brush(d3.select(n[i] as SVGGElement));
const xStart = x(brushObject.start) ?? 0;
@@ -268,11 +282,17 @@ export function DualBrush({
widthRef.current = width;
newBrush('baseline', baselineMin, baselineMax);
newBrush('deviation', deviationMin, deviationMax);
- } else {
- if (widthRef.current !== width) {
- widthRef.current = width;
- updateBrushes();
- }
+ } else if (
+ widthRef.current !== width ||
+ minRef.current !== min ||
+ maxRef.current !== max ||
+ !isEqual(snapTimestampsRef.current, snapTimestamps)
+ ) {
+ widthRef.current = width;
+ minRef.current = min;
+ maxRef.current = max;
+ snapTimestampsRef.current = snapTimestamps;
+ updateBrushes();
}
drawBrushes();
diff --git a/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.test.ts b/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.test.ts
index 50ddd0a429649..3524d4ae37867 100644
--- a/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.test.ts
+++ b/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.test.ts
@@ -240,7 +240,13 @@ describe('transform connector for export', () => {
it('should not change connectors without secrets', () => {
expect(transformConnectorsForExport(connectorsWithNoSecrets, actionTypeRegistry)).toEqual(
- connectorsWithNoSecrets
+ connectorsWithNoSecrets.map((connector) => ({
+ ...connector,
+ attributes: {
+ ...connector.attributes,
+ secrets: {},
+ },
+ }))
);
});
@@ -250,6 +256,7 @@ describe('transform connector for export', () => {
...connector,
attributes: {
...connector.attributes,
+ secrets: {},
isMissingSecrets: true,
},
}))
diff --git a/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.ts b/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.ts
index 250346f33d4af..9c690885bfe3c 100644
--- a/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.ts
+++ b/x-pack/plugins/actions/server/saved_objects/transform_connectors_for_export.ts
@@ -28,6 +28,7 @@ function transformConnectorForExport(
actionType: ActionType
): SavedObject {
let isMissingSecrets = false;
+
try {
// If connector requires secrets, this will throw an error
validateSecrets(actionType, {});
@@ -39,11 +40,11 @@ function transformConnectorForExport(
isMissingSecrets = true;
}
- // Skip connectors
return {
...connector,
attributes: {
...connector.attributes,
+ secrets: {},
isMissingSecrets,
},
};
diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts
index 532cefec75f20..b5606543b04e5 100644
--- a/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts
+++ b/x-pack/plugins/actions/server/usage/actions_telemetry.test.ts
@@ -112,6 +112,7 @@ Object {
"some.type": 1,
},
"countTotal": 4,
+ "hasErrors": false,
}
`);
});
@@ -130,6 +131,8 @@ Object {
Object {
"countByType": Object {},
"countTotal": 0,
+ "errorMessage": "oh no",
+ "hasErrors": true,
}
`);
});
@@ -194,6 +197,7 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 1,
"countTotal": 2,
+ "hasErrors": false,
}
`);
});
@@ -295,6 +299,7 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 1,
"countTotal": 4,
+ "hasErrors": false,
}
`);
});
@@ -316,6 +321,8 @@ Object {
"countEmailByService": Object {},
"countNamespaces": 0,
"countTotal": 0,
+ "errorMessage": "oh no",
+ "hasErrors": true,
}
`);
});
@@ -438,6 +445,7 @@ Object {
"some.type": 1,
},
"countTotal": 6,
+ "hasErrors": false,
}
`);
});
@@ -546,6 +554,7 @@ Object {
},
"countNamespaces": 1,
"countTotal": 6,
+ "hasErrors": false,
}
`);
});
@@ -645,6 +654,7 @@ Object {
},
"countNamespaces": 3,
"countTotal": 6,
+ "hasErrors": false,
}
`);
});
@@ -744,6 +754,7 @@ Object {
__slack: 7,
},
countTotal: 120,
+ hasErrors: false,
});
});
@@ -765,6 +776,8 @@ Object {
"countFailed": 0,
"countFailedByType": Object {},
"countTotal": 0,
+ "errorMessage": "oh no",
+ "hasErrors": true,
}
`);
});
diff --git a/x-pack/plugins/actions/server/usage/actions_telemetry.ts b/x-pack/plugins/actions/server/usage/actions_telemetry.ts
index 82f65ddf0cf8a..1e2320e2b1a5d 100644
--- a/x-pack/plugins/actions/server/usage/actions_telemetry.ts
+++ b/x-pack/plugins/actions/server/usage/actions_telemetry.ts
@@ -43,7 +43,6 @@ export async function getTotalCount(
`,
},
};
-
try {
const searchResult = await esClient.search({
index: kibanaIndex,
@@ -78,6 +77,7 @@ export async function getTotalCount(
}
}
return {
+ hasErrors: false,
countTotal:
Object.keys(aggs).reduce(
(total: number, key: string) => parseInt(aggs[key], 10) + total,
@@ -86,8 +86,13 @@ export async function getTotalCount(
countByType,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
+
logger.warn(`Error executing actions telemetry task: getTotalCount - ${JSON.stringify(err)}`);
+
return {
+ hasErrors: true,
+ errorMessage,
countTotal: 0,
countByType: {},
};
@@ -101,6 +106,8 @@ export async function getInUseTotalCount(
referenceType?: string,
preconfiguredActions?: PreConfiguredAction[]
): Promise<{
+ hasErrors: boolean;
+ errorMessage?: string;
countTotal: number;
countByType: Record;
countByAlertHistoryConnectorType: number;
@@ -363,6 +370,7 @@ export async function getInUseTotalCount(
}
return {
+ hasErrors: false,
countTotal: aggs.total + (preconfiguredActionsAggs?.total ?? 0),
countByType: countByActionTypeId,
countByAlertHistoryConnectorType: preconfiguredAlertHistoryConnectors,
@@ -370,10 +378,14 @@ export async function getInUseTotalCount(
countNamespaces: namespacesList.size,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
+
logger.warn(
`Error executing actions telemetry task: getInUseTotalCount - ${JSON.stringify(err)}`
);
return {
+ hasErrors: true,
+ errorMessage,
countTotal: 0,
countByType: {},
countByAlertHistoryConnectorType: 0,
@@ -383,21 +395,6 @@ export async function getInUseTotalCount(
}
}
-export async function getInUseByAlertingTotalCounts(
- esClient: ElasticsearchClient,
- kibanaIndex: string,
- logger: Logger,
- preconfiguredActions?: PreConfiguredAction[]
-): Promise<{
- countTotal: number;
- countByType: Record;
- countByAlertHistoryConnectorType: number;
- countEmailByService: Record;
- countNamespaces: number;
-}> {
- return await getInUseTotalCount(esClient, kibanaIndex, logger, 'alert', preconfiguredActions);
-}
-
function replaceFirstAndLastDotSymbols(strToReplace: string) {
const hasFirstSymbolDot = strToReplace.startsWith('.');
const appliedString = hasFirstSymbolDot ? strToReplace.replace('.', '__') : strToReplace;
@@ -410,6 +407,8 @@ export async function getExecutionsPerDayCount(
eventLogIndex: string,
logger: Logger
): Promise<{
+ hasErrors: boolean;
+ errorMessage?: string;
countTotal: number;
countByType: Record;
countFailed: number;
@@ -566,6 +565,7 @@ export async function getExecutionsPerDayCount(
);
return {
+ hasErrors: false,
countTotal: aggsExecutions.total,
countByType: Object.entries(aggsExecutions.connectorTypes).reduce(
(res: Record, [key, value]) => {
@@ -588,10 +588,13 @@ export async function getExecutionsPerDayCount(
avgExecutionTimeByType,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing actions telemetry task: getExecutionsPerDayCount - ${JSON.stringify(err)}`
);
return {
+ hasErrors: true,
+ errorMessage,
countTotal: 0,
countByType: {},
countFailed: 0,
diff --git a/x-pack/plugins/actions/server/usage/actions_usage_collector.test.ts b/x-pack/plugins/actions/server/usage/actions_usage_collector.test.ts
index 7efc54a5f99d3..58bd3798536f9 100644
--- a/x-pack/plugins/actions/server/usage/actions_usage_collector.test.ts
+++ b/x-pack/plugins/actions/server/usage/actions_usage_collector.test.ts
@@ -6,9 +6,11 @@
*/
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
+
import { registerActionsUsageCollector } from './actions_usage_collector';
import { configSchema, ActionsConfig } from '../config';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
+import { ConcreteTaskInstance, TaskManagerStartContract } from '@kbn/task-manager-plugin/server';
const mockTaskManagerStart = taskManagerMock.createStart();
@@ -43,4 +45,50 @@ describe('registerActionsUsageCollector', () => {
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('actions');
});
+
+ it('should return an error message if fetching data fails', async () => {
+ mockTaskManagerStart.get.mockRejectedValueOnce(new Error('error message'));
+ const taskManagerPromise = new Promise((resolve) => {
+ resolve(mockTaskManagerStart);
+ });
+ registerActionsUsageCollector(
+ usageCollectionMock as UsageCollectionSetup,
+ config,
+ taskManagerPromise
+ );
+ // @ts-ignore
+ expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
+ expect.objectContaining({
+ has_errors: true,
+ error_messages: ['error message'],
+ })
+ );
+ });
+
+ it('should return the task state including error messages', async () => {
+ const mockStats = {
+ has_errors: true,
+ error_messages: ['an error message'],
+ count_active_total: 1,
+ count_disabled_total: 10,
+ };
+ mockTaskManagerStart.get.mockResolvedValue({
+ id: '1',
+ state: mockStats,
+ } as unknown as ConcreteTaskInstance);
+
+ const taskManagerPromise = new Promise((resolve) => {
+ resolve(mockTaskManagerStart);
+ });
+ registerActionsUsageCollector(
+ usageCollectionMock as UsageCollectionSetup,
+ config,
+ taskManagerPromise
+ );
+ // @ts-ignore
+ expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual({
+ alert_history_connector_enabled: false,
+ ...mockStats,
+ });
+ });
});
diff --git a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts
index 1a6b22b0b0ce6..f6e02b2e0fec9 100644
--- a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts
+++ b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts
@@ -23,6 +23,8 @@ export function createActionsUsageCollector(
return true;
},
schema: {
+ has_errors: { type: 'boolean' },
+ error_messages: { type: 'array', items: { type: 'text' } },
alert_history_connector_enabled: {
type: 'boolean',
_meta: { description: 'Indicates if preconfigured alert history connector is enabled.' },
@@ -51,13 +53,16 @@ export function createActionsUsageCollector(
const doc = await getLatestTaskState(await taskManager);
// get the accumulated state from the recurring task
const { runs, ...state } = get(doc, 'state') as ActionsUsage & { runs: number };
-
return {
...state,
alert_history_connector_enabled: config.preconfiguredAlertHistoryEsIndex,
};
} catch (err) {
+ const errMessage = err && err.message ? err.message : err.toString();
+
return {
+ has_errors: true,
+ error_messages: [errMessage],
alert_history_connector_enabled: false,
count_total: 0,
count_by_type: {},
diff --git a/x-pack/plugins/actions/server/usage/task.ts b/x-pack/plugins/actions/server/usage/task.ts
index 68b109ec8b0fa..15f70529d3852 100644
--- a/x-pack/plugins/actions/server/usage/task.ts
+++ b/x-pack/plugins/actions/server/usage/task.ts
@@ -101,36 +101,39 @@ export function telemetryTaskRunner(
getTotalCount(esClient, kibanaIndex, logger, preconfiguredActions),
getInUseTotalCount(esClient, kibanaIndex, logger, undefined, preconfiguredActions),
getExecutionsPerDayCount(esClient, eventLogIndex, logger),
- ])
- .then(([totalAggegations, totalInUse, totalExecutionsPerDay]) => {
- return {
- state: {
- runs: (state.runs || 0) + 1,
- count_total: totalAggegations.countTotal,
- count_by_type: totalAggegations.countByType,
- count_active_total: totalInUse.countTotal,
- count_active_by_type: totalInUse.countByType,
- count_active_alert_history_connectors: totalInUse.countByAlertHistoryConnectorType,
- count_active_email_connectors_by_service_type: totalInUse.countEmailByService,
- count_actions_namespaces: totalInUse.countNamespaces,
- count_actions_executions_per_day: totalExecutionsPerDay.countTotal,
- count_actions_executions_by_type_per_day: totalExecutionsPerDay.countByType,
- count_actions_executions_failed_per_day: totalExecutionsPerDay.countFailed,
- count_actions_executions_failed_by_type_per_day:
- totalExecutionsPerDay.countFailedByType,
- avg_execution_time_per_day: totalExecutionsPerDay.avgExecutionTime,
- avg_execution_time_by_type_per_day: totalExecutionsPerDay.avgExecutionTimeByType,
- },
- runAt: getNextMidnight(),
- };
- })
- .catch((errMsg) => {
- logger.warn(`Error executing actions telemetry task: ${errMsg}`);
- return {
- state: {},
- runAt: getNextMidnight(),
- };
- });
+ ]).then(([totalAggegations, totalInUse, totalExecutionsPerDay]) => {
+ const hasErrors =
+ totalAggegations.hasErrors || totalInUse.hasErrors || totalExecutionsPerDay.hasErrors;
+
+ const errorMessages = [
+ totalAggegations.errorMessage,
+ totalInUse.errorMessage,
+ totalExecutionsPerDay.errorMessage,
+ ].filter((message) => message !== undefined);
+
+ return {
+ state: {
+ has_errors: hasErrors,
+ ...(errorMessages.length > 0 && { error_messages: errorMessages }),
+ runs: (state.runs || 0) + 1,
+ count_total: totalAggegations.countTotal,
+ count_by_type: totalAggegations.countByType,
+ count_active_total: totalInUse.countTotal,
+ count_active_by_type: totalInUse.countByType,
+ count_active_alert_history_connectors: totalInUse.countByAlertHistoryConnectorType,
+ count_active_email_connectors_by_service_type: totalInUse.countEmailByService,
+ count_actions_namespaces: totalInUse.countNamespaces,
+ count_actions_executions_per_day: totalExecutionsPerDay.countTotal,
+ count_actions_executions_by_type_per_day: totalExecutionsPerDay.countByType,
+ count_actions_executions_failed_per_day: totalExecutionsPerDay.countFailed,
+ count_actions_executions_failed_by_type_per_day:
+ totalExecutionsPerDay.countFailedByType,
+ avg_execution_time_per_day: totalExecutionsPerDay.avgExecutionTime,
+ avg_execution_time_by_type_per_day: totalExecutionsPerDay.avgExecutionTimeByType,
+ },
+ runAt: getNextMidnight(),
+ };
+ });
},
};
};
diff --git a/x-pack/plugins/actions/server/usage/types.ts b/x-pack/plugins/actions/server/usage/types.ts
index 4d9f9c6ef17ff..b58ac9c096f63 100644
--- a/x-pack/plugins/actions/server/usage/types.ts
+++ b/x-pack/plugins/actions/server/usage/types.ts
@@ -8,6 +8,8 @@
import { MakeSchemaFrom } from '@kbn/usage-collection-plugin/server';
export interface ActionsUsage {
+ has_errors: boolean;
+ error_messages?: string[];
alert_history_connector_enabled: boolean;
count_total: number;
count_by_type: Record;
diff --git a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx
index a6a2a6808dbaf..3b0ad9ddfc2e6 100644
--- a/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx
+++ b/x-pack/plugins/aiops/public/components/explain_log_rate_spikes/explain_log_rate_spikes_page.tsx
@@ -171,7 +171,7 @@ export const ExplainLogRateSpikesPage: FC = ({
}
return (
-
+
@@ -268,6 +268,7 @@ export const ExplainLogRateSpikesPage: FC = ({
/>
}
+ data-test-subj="aiopsNoWindowParametersEmptyPrompt"
/>
)}
diff --git a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.test.ts b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.test.ts
index fd8960adf4d8c..b13e678ce4402 100644
--- a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.test.ts
+++ b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.test.ts
@@ -8,6 +8,7 @@
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { registerAlertingUsageCollector } from './alerting_usage_collector';
import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks';
+import { ConcreteTaskInstance, TaskManagerStartContract } from '@kbn/task-manager-plugin/server';
const taskManagerStart = taskManagerMock.createStart();
beforeEach(() => jest.resetAllMocks());
@@ -38,4 +39,41 @@ describe('registerAlertingUsageCollector', () => {
expect(usageCollectionMock.makeUsageCollector).toHaveBeenCalledTimes(1);
expect(usageCollectionMock.makeUsageCollector.mock.calls[0][0].type).toBe('alerts');
});
+
+ it('should return an error message if fetching data fails', async () => {
+ taskManagerStart.get.mockRejectedValueOnce(new Error('error message'));
+ const taskManagerPromise = new Promise((resolve) => {
+ resolve(taskManagerStart);
+ });
+ registerAlertingUsageCollector(usageCollectionMock as UsageCollectionSetup, taskManagerPromise);
+ // @ts-ignore
+ expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
+ expect.objectContaining({
+ has_errors: true,
+ error_messages: ['error message'],
+ })
+ );
+ });
+
+ it('should return the task state including error messages', async () => {
+ const mockStats = {
+ has_errors: true,
+ error_messages: ['an error message'],
+ count_active_total: 1,
+ count_disabled_total: 10,
+ };
+ taskManagerStart.get.mockResolvedValue({
+ id: '1',
+ state: mockStats,
+ } as unknown as ConcreteTaskInstance);
+
+ const taskManagerPromise = new Promise((resolve) => {
+ resolve(taskManagerStart);
+ });
+ registerAlertingUsageCollector(usageCollectionMock as UsageCollectionSetup, taskManagerPromise);
+ // @ts-ignore
+ expect(await usageCollectionMock.makeUsageCollector.mock.calls[0][0].fetch()).toEqual(
+ mockStats
+ );
+ });
});
diff --git a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts
index 2c7f4db1d9fa9..d03faa3aaf65f 100644
--- a/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts
+++ b/x-pack/plugins/alerting/server/usage/alerting_usage_collector.ts
@@ -126,11 +126,12 @@ export function createAlertingUsageCollector(
// get the accumulated state from the recurring task
const { runs, ...state } = get(doc, 'state') as AlertingUsage & { runs: number };
- return {
- ...state,
- };
+ return state;
} catch (err) {
+ const errMessage = err && err.message ? err.message : err.toString();
return {
+ has_errors: true,
+ error_messages: [errMessage],
count_total: 0,
count_active_total: 0,
count_disabled_total: 0,
@@ -202,6 +203,11 @@ export function createAlertingUsageCollector(
}
},
schema: {
+ has_errors: { type: 'boolean' },
+ error_messages: {
+ type: 'array',
+ items: { type: 'text' },
+ },
count_total: { type: 'long' },
count_active_total: { type: 'long' },
count_disabled_total: { type: 'long' },
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts
index 754cab335f8e9..f3e21f6a161fa 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.test.ts
@@ -1398,6 +1398,7 @@ describe('event log telemetry', () => {
logs__alert__document__count: 0,
},
},
+ hasErrors: false,
});
});
@@ -1419,6 +1420,8 @@ describe('event log telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toStrictEqual({
+ hasErrors: true,
+ errorMessage: 'oh no',
countTotalRuleExecutions: 0,
countRuleExecutionsByType: {},
countTotalFailedExecutions: 0,
@@ -1495,6 +1498,7 @@ describe('event log telemetry', () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
logs__alert__document__count: 1,
},
+ hasErrors: false,
});
});
@@ -1518,6 +1522,8 @@ describe('event log telemetry', () => {
expect(telemetry).toStrictEqual({
countExecutionTimeouts: 0,
countExecutionTimeoutsByType: {},
+ errorMessage: 'oh no',
+ hasErrors: true,
});
});
});
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts
index a6c3e90cfc1c7..703d579e66c25 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_event_log.ts
@@ -37,6 +37,8 @@ interface Opts {
}
interface GetExecutionsPerDayCountResults {
+ hasErrors: boolean;
+ errorMessage?: string;
countTotalRuleExecutions: number;
countRuleExecutionsByType: Record;
countTotalFailedExecutions: number;
@@ -55,6 +57,8 @@ interface GetExecutionsPerDayCountResults {
}
interface GetExecutionTimeoutsPerDayCountResults {
+ hasErrors: boolean;
+ errorMessage?: string;
countExecutionTimeouts: number;
countExecutionTimeoutsByType: Record;
}
@@ -167,12 +171,14 @@ export async function getExecutionsPerDayCount({
aggregations.by_rule_type_id.buckets as GetExecutionCountsAggregationBucket[];
return {
+ hasErrors: false,
...parseRuleTypeBucket(aggregationsByRuleTypeId),
...parseExecutionFailureByRuleType(aggregationsByRuleTypeId),
...parseExecutionCountAggregationResults(aggregations),
countTotalRuleExecutions: totalRuleExecutions ?? 0,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getExecutionsPerDayCount - ${JSON.stringify(err)}`,
{
@@ -181,6 +187,8 @@ export async function getExecutionsPerDayCount({
}
);
return {
+ hasErrors: true,
+ errorMessage,
countTotalRuleExecutions: 0,
countRuleExecutionsByType: {},
countTotalFailedExecutions: 0,
@@ -235,10 +243,13 @@ export async function getExecutionTimeoutsPerDayCount({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
+ hasErrors: false,
countExecutionTimeouts: totalTimedoutExecutionsCount ?? 0,
countExecutionTimeoutsByType: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
+
logger.warn(
`Error executing alerting telemetry task: getExecutionsTimeoutsPerDayCount - ${JSON.stringify(
err
@@ -249,6 +260,8 @@ export async function getExecutionTimeoutsPerDayCount({
}
);
return {
+ hasErrors: true,
+ errorMessage,
countExecutionTimeouts: 0,
countExecutionTimeoutsByType: {},
};
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.test.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.test.ts
index 4b17875bc8b60..79b5d473ebe05 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.test.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.test.ts
@@ -88,6 +88,7 @@ describe('kibana index telemetry', () => {
logs__alert__document__count: 1,
},
count_total: 4,
+ hasErrors: false,
schedule_time: {
avg: '4.5s',
max: '10s',
@@ -129,6 +130,8 @@ describe('kibana index telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toEqual({
+ errorMessage: 'oh no',
+ hasErrors: true,
connectors_per_alert: {
avg: 0,
max: 0,
@@ -219,6 +222,7 @@ describe('kibana index telemetry', () => {
},
countNamespaces: 1,
countTotal: 4,
+ hasErrors: false,
});
});
@@ -243,6 +247,8 @@ describe('kibana index telemetry', () => {
countByType: {},
countNamespaces: 0,
countTotal: 0,
+ errorMessage: 'oh no',
+ hasErrors: true,
});
});
});
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.ts
index f2ef27374263c..5443fb91e2e1f 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_kibana.ts
@@ -31,12 +31,14 @@ type GetTotalCountsResults = Pick<
| 'throttle_time_number_s'
| 'schedule_time_number_s'
| 'connectors_per_alert'
->;
+> & { errorMessage?: string; hasErrors: boolean };
interface GetTotalCountInUseResults {
countTotal: number;
countByType: Record;
countNamespaces: number;
+ errorMessage?: string;
+ hasErrors: boolean;
}
export async function getTotalCountAggregations({
@@ -79,17 +81,17 @@ export async function getTotalCountAggregations({
int parsed = 0;
if (doc['alert.schedule.interval'].size() > 0) {
def interval = doc['alert.schedule.interval'].value;
-
+
if (interval.length() > 1) {
// get last char
String timeChar = interval.substring(interval.length() - 1);
// remove last char
interval = interval.substring(0, interval.length() - 1);
-
+
if (interval.chars().allMatch(Character::isDigit)) {
// using of regex is not allowed in painless language
parsed = Integer.parseInt(interval);
-
+
if (timeChar.equals("s")) {
parsed = parsed;
} else if (timeChar.equals("m")) {
@@ -115,17 +117,17 @@ export async function getTotalCountAggregations({
int parsed = 0;
if (doc['alert.throttle'].size() > 0) {
def throttle = doc['alert.throttle'].value;
-
+
if (throttle.length() > 1) {
// get last char
String timeChar = throttle.substring(throttle.length() - 1);
// remove last char
throttle = throttle.substring(0, throttle.length() - 1);
-
+
if (throttle.chars().allMatch(Character::isDigit)) {
// using of regex is not allowed in painless language
parsed = Integer.parseInt(throttle);
-
+
if (timeChar.equals("s")) {
parsed = parsed;
} else if (timeChar.equals("m")) {
@@ -186,6 +188,7 @@ export async function getTotalCountAggregations({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
+ hasErrors: false,
count_total: totalRulesCount ?? 0,
count_by_type: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
throttle_time: {
@@ -215,6 +218,8 @@ export async function getTotalCountAggregations({
},
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
+
logger.warn(
`Error executing alerting telemetry task: getTotalCountAggregations - ${JSON.stringify(err)}`,
{
@@ -223,6 +228,8 @@ export async function getTotalCountAggregations({
}
);
return {
+ hasErrors: true,
+ errorMessage,
count_total: 0,
count_by_type: {},
throttle_time: {
@@ -296,11 +303,13 @@ export async function getTotalCountInUse({
typeof results.hits.total === 'number' ? results.hits.total : results.hits.total?.value;
return {
+ hasErrors: false,
countTotal: totalEnabledRulesCount ?? 0,
countByType: parseSimpleRuleTypeBucket(aggregations.by_rule_type_id.buckets),
countNamespaces: aggregations.namespaces_count.value ?? 0,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getTotalCountInUse - ${JSON.stringify(err)}`,
{
@@ -309,6 +318,8 @@ export async function getTotalCountInUse({
}
);
return {
+ hasErrors: true,
+ errorMessage,
countTotal: 0,
countByType: {},
countNamespaces: 0,
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.test.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.test.ts
index 6d58da12ca278..3061571ab7ed9 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.test.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.test.ts
@@ -225,6 +225,7 @@ describe('task manager telemetry', () => {
logs__alert__document__count: 4,
},
},
+ hasErrors: false,
});
});
@@ -247,6 +248,8 @@ describe('task manager telemetry', () => {
expect(loggerMeta?.tags).toEqual(['alerting', 'telemetry-failed']);
expect(loggerMeta?.error?.stack_trace).toBeDefined();
expect(telemetry).toStrictEqual({
+ errorMessage: 'oh no',
+ hasErrors: true,
countFailedAndUnrecognizedTasks: 0,
countFailedAndUnrecognizedTasksByStatus: {},
countFailedAndUnrecognizedTasksByStatusByType: {},
diff --git a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.ts b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.ts
index b13f300bcd4a0..41f41f6ab7ada 100644
--- a/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.ts
+++ b/x-pack/plugins/alerting/server/usage/lib/get_telemetry_from_task_manager.ts
@@ -26,6 +26,8 @@ interface GetFailedAndUnrecognizedTasksAggregationBucket extends AggregationsStr
}
interface GetFailedAndUnrecognizedTasksResults {
+ hasErrors: boolean;
+ errorMessage?: string;
countFailedAndUnrecognizedTasks: number;
countFailedAndUnrecognizedTasksByStatus: Record;
countFailedAndUnrecognizedTasksByStatusByType: Record>;
@@ -115,10 +117,12 @@ export async function getFailedAndUnrecognizedTasksPerDay({
aggregations.by_status.buckets as GetFailedAndUnrecognizedTasksAggregationBucket[];
return {
+ hasErrors: false,
...parseBucket(aggregationsByStatus),
countFailedAndUnrecognizedTasks: totalFailedAndUnrecognizedTasks ?? 0,
};
} catch (err) {
+ const errorMessage = err && err.message ? err.message : err.toString();
logger.warn(
`Error executing alerting telemetry task: getFailedAndUnrecognizedTasksPerDay - ${JSON.stringify(
err
@@ -129,6 +133,8 @@ export async function getFailedAndUnrecognizedTasksPerDay({
}
);
return {
+ hasErrors: true,
+ errorMessage,
countFailedAndUnrecognizedTasks: 0,
countFailedAndUnrecognizedTasksByStatus: {},
countFailedAndUnrecognizedTasksByStatusByType: {},
diff --git a/x-pack/plugins/alerting/server/usage/task.ts b/x-pack/plugins/alerting/server/usage/task.ts
index 9d01ac21e845b..0bbfab30f0796 100644
--- a/x-pack/plugins/alerting/server/usage/task.ts
+++ b/x-pack/plugins/alerting/server/usage/task.ts
@@ -111,10 +111,33 @@ export function telemetryTaskRunner(
dailyExecutionTimeoutCounts,
dailyFailedAndUnrecognizedTasks,
]) => {
+ const hasErrors =
+ totalCountAggregations.hasErrors ||
+ totalInUse.hasErrors ||
+ dailyExecutionCounts.hasErrors ||
+ dailyExecutionTimeoutCounts.hasErrors ||
+ dailyFailedAndUnrecognizedTasks.hasErrors;
+
+ const errorMessages = [
+ totalCountAggregations.errorMessage,
+ totalInUse.errorMessage,
+ dailyExecutionCounts.errorMessage,
+ dailyExecutionTimeoutCounts.errorMessage,
+ dailyFailedAndUnrecognizedTasks.errorMessage,
+ ].filter((message) => message !== undefined);
+
return {
state: {
+ has_errors: hasErrors,
+ ...(errorMessages.length > 0 && { error_messages: errorMessages }),
runs: (state.runs || 0) + 1,
- ...totalCountAggregations,
+ count_total: totalCountAggregations.count_total,
+ count_by_type: totalCountAggregations.count_by_type,
+ throttle_time: totalCountAggregations.throttle_time,
+ schedule_time: totalCountAggregations.schedule_time,
+ throttle_time_number_s: totalCountAggregations.throttle_time_number_s,
+ schedule_time_number_s: totalCountAggregations.schedule_time_number_s,
+ connectors_per_alert: totalCountAggregations.connectors_per_alert,
count_active_by_type: totalInUse.countByType,
count_active_total: totalInUse.countTotal,
count_disabled_total: totalCountAggregations.count_total - totalInUse.countTotal,
diff --git a/x-pack/plugins/alerting/server/usage/types.ts b/x-pack/plugins/alerting/server/usage/types.ts
index b045fd5009c70..a0f45d1932309 100644
--- a/x-pack/plugins/alerting/server/usage/types.ts
+++ b/x-pack/plugins/alerting/server/usage/types.ts
@@ -6,6 +6,8 @@
*/
export interface AlertingUsage {
+ has_errors: boolean;
+ error_messages?: string[];
count_total: number;
count_active_total: number;
count_disabled_total: number;
diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
index 4fc2b9836b88c..1835eee137f41 100644
--- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
+++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
@@ -222,7 +222,7 @@ export const serviceDetail = {
...page({
tab: 'nodes',
title: i18n.translate('xpack.apm.views.nodes.title', {
- defaultMessage: 'JVMs',
+ defaultMessage: 'Metrics',
}),
element: ,
}),
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx
index 7ac3b14e7faa9..763d4cf0717a1 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.test.tsx
@@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import { isMetricsTabHidden, isJVMsTabHidden } from '.';
+import { isMetricsTabHidden, isMetricsJVMsTabHidden } from '.';
describe('APM service template', () => {
describe('isMetricsTabHidden', () => {
@@ -41,8 +41,8 @@ describe('APM service template', () => {
});
});
});
- describe('isJVMsTabHidden', () => {
- describe('hides JVMs tab', () => {
+ describe('isMetricsJVMsTabHidden', () => {
+ describe('hides metrics JVMs tab', () => {
[
{ agentName: undefined },
{ agentName: 'ruby', runtimeName: 'ruby' },
@@ -55,18 +55,18 @@ describe('APM service template', () => {
{ runtimeName: 'aws_lambda' },
].map((input) => {
it(`when input ${JSON.stringify(input)}`, () => {
- expect(isJVMsTabHidden(input)).toBeTruthy();
+ expect(isMetricsJVMsTabHidden(input)).toBeTruthy();
});
});
});
- describe('shows JVMs tab', () => {
+ describe('shows metrics JVMs tab', () => {
[
{ agentName: 'java' },
{ agentName: 'opentelemetry/java' },
{ agentName: 'ruby', runtimeName: 'jruby' },
].map((input) => {
it(`when input ${JSON.stringify(input)}`, () => {
- expect(isJVMsTabHidden(input)).toBeFalsy();
+ expect(isMetricsJVMsTabHidden(input)).toBeFalsy();
});
});
});
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
index 80957e990f250..7acf14fc0bf01 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
@@ -155,7 +155,7 @@ export function isMetricsTabHidden({
);
}
-export function isJVMsTabHidden({
+export function isMetricsJVMsTabHidden({
agentName,
runtimeName,
}: {
@@ -255,9 +255,9 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) {
query,
}),
label: i18n.translate('xpack.apm.serviceDetails.nodesTabLabel', {
- defaultMessage: 'JVMs',
+ defaultMessage: 'Metrics',
}),
- hidden: isJVMsTabHidden({ agentName, runtimeName }),
+ hidden: isMetricsJVMsTabHidden({ agentName, runtimeName }),
},
{
key: 'infrastructure',
diff --git a/x-pack/plugins/canvas/PLUGINS.mdx b/x-pack/plugins/canvas/PLUGINS.mdx
index 77fe65f864607..c0e0bc9c92f5a 100644
--- a/x-pack/plugins/canvas/PLUGINS.mdx
+++ b/x-pack/plugins/canvas/PLUGINS.mdx
@@ -2,7 +2,7 @@
id: canvasPlugins
slug: /playground/kibana/canvas-plugins
title: Develop Canvas plugins
-summary: Introduction to
+description: Introduction to
date: 2021-02-18
tags: ['kibana', 'canvas', 'plugins']
related: []
diff --git a/x-pack/plugins/canvas/shareable_runtime/README.mdx b/x-pack/plugins/canvas/shareable_runtime/README.mdx
index a9d58bb3833d9..07fbe7af27825 100644
--- a/x-pack/plugins/canvas/shareable_runtime/README.mdx
+++ b/x-pack/plugins/canvas/shareable_runtime/README.mdx
@@ -2,7 +2,7 @@
id: canvasShareableWorkpads
slug: /playground/kibana/canvas-shareable-workpads
title: Share a Canvas Workpad on a Website
-summary: How to share a static snapshot of a workpad on an external website.
+description: How to share a static snapshot of a workpad on an external website.
date: 2021-02-18
tags: ['kibana', 'canvas', 'share']
related: []
diff --git a/x-pack/plugins/cases/public/containers/user_profiles/api.mock.ts b/x-pack/plugins/cases/public/containers/user_profiles/api.mock.ts
index 57578086ceddf..e9382f7092ae0 100644
--- a/x-pack/plugins/cases/public/containers/user_profiles/api.mock.ts
+++ b/x-pack/plugins/cases/public/containers/user_profiles/api.mock.ts
@@ -10,6 +10,7 @@ import { UserProfile } from '@kbn/security-plugin/common';
export const userProfiles: UserProfile[] = [
{
uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
+ enabled: true,
data: {},
user: {
username: 'damaged_raccoon',
@@ -19,6 +20,7 @@ export const userProfiles: UserProfile[] = [
},
{
uid: 'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0',
+ enabled: true,
data: {},
user: {
username: 'physical_dinosaur',
@@ -28,6 +30,7 @@ export const userProfiles: UserProfile[] = [
},
{
uid: 'u_9xDEQqUqoYCnFnPPLq5mIRHKL8gBTo_NiKgOnd5gGk0_0',
+ enabled: true,
data: {},
user: {
username: 'wet_dingo',
diff --git a/x-pack/plugins/enterprise_search/common/types/error_codes.ts b/x-pack/plugins/enterprise_search/common/types/error_codes.ts
index a982289fbdb67..327d000003f9b 100644
--- a/x-pack/plugins/enterprise_search/common/types/error_codes.ts
+++ b/x-pack/plugins/enterprise_search/common/types/error_codes.ts
@@ -12,4 +12,5 @@ export enum ErrorCode {
INDEX_NOT_FOUND = 'index_not_found',
RESOURCE_NOT_FOUND = 'resource_not_found',
UNAUTHORIZED = 'unauthorized',
+ UNCAUGHT_EXCEPTION = 'uncaught_exception',
}
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/api_key/api_key.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/api_key/api_key.tsx
index 1fc67699c9a6d..f24fc6234d0c8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/api_key/api_key.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/api_key/api_key.tsx
@@ -7,36 +7,23 @@
import React from 'react';
-import { EuiCodeBlock, EuiFormLabel, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { EuiCodeBlock, EuiFormLabel, EuiSpacer } from '@elastic/eui';
interface ApiKeyProps {
- actions?: React.ReactNode;
apiKey: string;
label?: string;
}
-export const ApiKey: React.FC = ({ apiKey, label, actions }) => {
- const codeBlock = (
+export const ApiKey: React.FC = ({ apiKey, label }) => (
+ <>
+ {label && (
+ <>
+ {label}
+
+ >
+ )}
{apiKey}
- );
- return (
- <>
- {label && (
- <>
- {label}
-
- >
- )}
- {actions ? (
-
- {codeBlock}
- {actions}
-
- ) : (
- codeBlock
- )}
- >
- );
-};
+ >
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/method_connector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/method_connector.tsx
index a3d3456e21f40..59d43d8635e1b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/method_connector.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector/method_connector.tsx
@@ -69,49 +69,6 @@ export const MethodConnector: React.FC = () => {
const { setIsModalVisible } = useActions(AddConnectorPackageLogic);
const { fullIndexName, language } = useValues(NewSearchIndexLogic);
- const confirmModal = isModalVisible && (
- {
- event?.preventDefault();
- setIsModalVisible(false);
- }}
- onConfirm={(event) => {
- event.preventDefault();
- makeRequest({ deleteExistingConnector: true, indexName: fullIndexName, language });
- }}
- cancelButtonText={i18n.translate(
- 'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.cancelButton.label',
- {
- defaultMessage: 'Cancel',
- }
- )}
- confirmButtonText={i18n.translate(
- 'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.confirmButton.label',
- {
- defaultMessage: 'Replace configuration',
- }
- )}
- defaultFocusedButton="confirm"
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content..newIndex.steps.buildConnector.confirmModal.description',
- {
- defaultMessage:
- 'A deleted index named {indexName} was originally tied to an existing connector configuration. Would you like to replace the existing connector configuration with a new one?',
- values: {
- indexName: fullIndexName,
- },
- }
- )}
-
- );
-
return (
{
BUILD_SEARCH_EXPERIENCE_STEP,
]}
/>
- {confirmModal}
+ {isModalVisible && (
+ {
+ event?.preventDefault();
+ setIsModalVisible(false);
+ }}
+ onConfirm={(event) => {
+ event.preventDefault();
+ makeRequest({ deleteExistingConnector: true, indexName: fullIndexName, language });
+ }}
+ cancelButtonText={i18n.translate(
+ 'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.cancelButton.label',
+ {
+ defaultMessage: 'Cancel',
+ }
+ )}
+ confirmButtonText={i18n.translate(
+ 'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.confirmButton.label',
+ {
+ defaultMessage: 'Replace configuration',
+ }
+ )}
+ defaultFocusedButton="confirm"
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content..newIndex.steps.buildConnector.confirmModal.description',
+ {
+ defaultMessage:
+ 'A deleted index named {indexName} was originally tied to an existing connector configuration. Would you like to replace the existing connector configuration with a new one?',
+ values: {
+ indexName: fullIndexName,
+ },
+ }
+ )}
+
+ )}
);
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/document_list/document_list.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/document_list/document_list.tsx
index 779c636968435..43ed12f040d0c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/document_list/document_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/document_list/document_list.tsx
@@ -57,72 +57,10 @@ export const DocumentList: React.FC = () => {
return [];
};
- const docsPerPageButton = (
- {
- setIsPopoverOpen(true);
- }}
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage',
- {
- defaultMessage: 'Documents per page: {docPerPage}',
- values: { docPerPage: docsPerPage },
- }
- )}
-
- );
-
const getIconType = (size: number) => {
return size === docsPerPage ? 'check' : 'empty';
};
- const docsPerPageOptions = [
- {
- setIsPopoverOpen(false);
- setDocsPerPage(10);
- }}
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
- { defaultMessage: '{docCount} documents', values: { docCount: 10 } }
- )}
- ,
-
- {
- setIsPopoverOpen(false);
- setDocsPerPage(25);
- }}
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
- { defaultMessage: '{docCount} documents', values: { docCount: 25 } }
- )}
- ,
- {
- setIsPopoverOpen(false);
- setDocsPerPage(50);
- }}
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
- { defaultMessage: '{docCount} documents', values: { docCount: 50 } }
- )}
- ,
- ];
-
return (
<>
{
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.docsPerPage',
{ defaultMessage: 'Document count per page dropdown' }
)}
- button={docsPerPageButton}
+ button={
+ {
+ setIsPopoverOpen(true);
+ }}
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage',
+ {
+ defaultMessage: 'Documents per page: {docPerPage}',
+ values: { docPerPage: docsPerPage },
+ }
+ )}
+
+ }
isOpen={isPopoverOpen}
closePopover={() => {
setIsPopoverOpen(false);
@@ -183,7 +138,51 @@ export const DocumentList: React.FC = () => {
panelPaddingSize="none"
anchorPosition="downLeft"
>
-
+ {
+ setIsPopoverOpen(false);
+ setDocsPerPage(10);
+ }}
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
+ { defaultMessage: '{docCount} documents', values: { docCount: 10 } }
+ )}
+ ,
+
+ {
+ setIsPopoverOpen(false);
+ setDocsPerPage(25);
+ }}
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
+ { defaultMessage: '{docCount} documents', values: { docCount: 25 } }
+ )}
+ ,
+ {
+ setIsPopoverOpen(false);
+ setDocsPerPage(50);
+ }}
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
+ { defaultMessage: '{docCount} documents', values: { docCount: 50 } }
+ )}
+ ,
+ ]}
+ />
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.test.tsx
index 325d52ab2d2fd..b579df9da5c8b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.test.tsx
@@ -11,14 +11,12 @@ import React from 'react';
import { shallow } from 'enzyme';
-import { EuiModal, EuiFieldText } from '@elastic/eui';
+import { EuiModal, EuiFieldText, EuiCodeBlock } from '@elastic/eui';
const mockActions = { makeRequest: jest.fn(), setKeyName: jest.fn() };
const mockValues = { apiKey: '', isLoading: false, isSuccess: false, keyName: '' };
-import { ApiKey } from '../../../api_key/api_key';
-
import { GenerateApiKeyModal } from './modal';
const onCloseMock = jest.fn();
@@ -84,8 +82,8 @@ describe('GenerateApiKeyModal', () => {
);
expect(wrapper.find(EuiFieldText)).toHaveLength(0);
expect(wrapper.find('[data-test-subj="generateApiKeyButton"]')).toHaveLength(0);
- expect(wrapper.find(ApiKey)).toHaveLength(1);
- expect(wrapper.find(ApiKey).prop('apiKey')).toEqual('apiKeyFromBackend123123==');
+ expect(wrapper.find(EuiCodeBlock)).toHaveLength(1);
+ expect(wrapper.find(EuiCodeBlock).children().text()).toEqual('apiKeyFromBackend123123==');
});
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx
index fcb95fd4ade32..2690deea0c6de 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx
@@ -26,14 +26,14 @@ import {
EuiText,
EuiSpacer,
EuiLink,
+ EuiFormLabel,
+ EuiCodeBlock,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { docLinks } from '../../../../../shared/doc_links';
-import { ApiKey } from '../../../api_key/api_key';
-
import { GenerateApiKeyModalLogic } from './generate_api_key_modal.logic';
interface GenerateApiKeyModalProps {
@@ -114,10 +114,21 @@ export const GenerateApiKeyModal: React.FC = ({ indexN
>
) : (
- {keyName}
+
+
+
+
+ {apiKey}
+
+
+
= ({ indexN
href={encodeURI(`data:text/csv;charset=utf-8,${apiKey}`)}
download={`${keyName}.csv`}
/>
- }
- />
+
+
)}
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx
index c435bac2a5811..19974d4b281b3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/api_key_configuration.tsx
@@ -23,6 +23,43 @@ import { Status } from '../../../../../../common/types/api';
import { GenerateConnectorApiKeyApiLogic } from '../../../api/connector_package/generate_connector_api_key_api_logic';
import { ApiKey } from '../../api_key/api_key';
+const ConfirmModal: React.FC<{
+ onCancel: () => void;
+ onConfirm: () => void;
+}> = ({ onCancel, onConfirm }) => (
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.description',
+ {
+ defaultMessage:
+ 'Generating a new API key will invalidate the previous key. Are you sure you want to generate a new API key? This can not be undone.',
+ }
+ )}
+
+);
+
export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = ({
hasApiKey,
indexName,
@@ -44,50 +81,18 @@ export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> =
const [isModalVisible, setIsModalVisible] = useState(false);
- const confirmModal = (
- {
- event?.preventDefault();
- setIsModalVisible(false);
- }}
- onConfirm={(event) => {
- event.preventDefault();
- makeRequest({ indexName });
- setIsModalVisible(false);
- }}
- cancelButtonText={i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.cancelButton.label',
- {
- defaultMessage: 'Cancel',
- }
- )}
- confirmButtonText={i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.confirmButton.label',
- {
- defaultMessage: 'Generate API key',
- }
- )}
- defaultFocusedButton="confirm"
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.description',
- {
- defaultMessage:
- 'Generating a new API key will invalidate the previous key. Are you sure you want to generate a new API key? This can not be undone.',
- }
- )}
-
- );
+ const onCancel = () => {
+ setIsModalVisible(false);
+ };
+
+ const onConfirm = () => {
+ makeRequest({ indexName });
+ setIsModalVisible(false);
+ };
return (
- {isModalVisible && confirmModal}
+ {isModalVisible && }
{i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx
index 596b1837323da..acd8c856c3893 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx
@@ -55,172 +55,6 @@ export const ConnectorConfiguration: React.FC = () => {
const hasApiKey = !!(indexData.connector.api_key_id ?? apiKeyData);
- const ScheduleStep: React.FC = () => (
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.scheduleSync.description',
- {
- defaultMessage:
- 'Once your connectors are configured to your liking, don’t forget to set a recurring sync schedule to make sure your documents are indexed and relevant. You can also trigger a one-time sync without enabling a sync schedule.',
- }
- )}
-
-
-
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.button.label',
- {
- defaultMessage: 'Set schedule and sync',
- }
- )}
-
-
-
-
-
- );
-
- const ConnectorPackage: React.FC = () => (
- <>
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.firstParagraph',
- {
- defaultMessage:
- 'The connectors repository contains several connector client examples to help you utilize our framework for accelerated development against custom data sources.',
- }
- )}
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.button.label',
- {
- defaultMessage: 'Explore the connectors repository',
- }
- )}
-
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.clientExamplesLink',
- { defaultMessage: 'connector client examples' }
- )}
-
- ),
- }}
- />
-
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.configurationFileLink',
- { defaultMessage: 'configuration file' }
- )}
-
- ),
- }}
- />
-
-
-
- {`${
- apiKeyData?.encoded
- ? `elasticsearch:
- api_key: "${apiKeyData?.encoded}"
-`
- : ''
- }connector_id: "${indexData.connector.id}"
-`}
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorDeployedText',
- {
- defaultMessage:
- 'Once you’ve configured the connector, deploy the connector to your self managed infrastructure.',
- }
- )}
-
-
- {!indexData.connector.status || indexData.connector.status === ConnectorStatus.CREATED ? (
-
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorText',
- {
- defaultMessage:
- 'Your connector has not connected to Enterprise Search. Troubleshoot your configuration and refresh the page.',
- }
- )}
-
- recheckIndex()}
- isLoading={recheckIndexLoading}
- >
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnector.button.label',
- {
- defaultMessage: 'Recheck now',
- }
- )}
-
-
- ) : (
-
- )}
- >
- );
-
return (
<>
@@ -246,7 +80,137 @@ export const ConnectorConfiguration: React.FC = () => {
titleSize: 'xs',
},
{
- children: ,
+ children: (
+ <>
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.firstParagraph',
+ {
+ defaultMessage:
+ 'The connectors repository contains several connector client examples to help you utilize our framework for accelerated development against custom data sources.',
+ }
+ )}
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.button.label',
+ {
+ defaultMessage: 'Explore the connectors repository',
+ }
+ )}
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.clientExamplesLink',
+ { defaultMessage: 'connector client examples' }
+ )}
+
+ ),
+ }}
+ />
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.configurationFileLink',
+ { defaultMessage: 'configuration file' }
+ )}
+
+ ),
+ }}
+ />
+
+
+
+ {`${
+ apiKeyData?.encoded
+ ? `elasticsearch:
+ api_key: "${apiKeyData?.encoded}"
+ `
+ : ''
+ }connector_id: "${indexData.connector.id}"
+ `}
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorDeployedText',
+ {
+ defaultMessage:
+ 'Once you’ve configured the connector, deploy the connector to your self managed infrastructure.',
+ }
+ )}
+
+
+ {!indexData.connector.status ||
+ indexData.connector.status === ConnectorStatus.CREATED ? (
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorText',
+ {
+ defaultMessage:
+ 'Your connector has not connected to Enterprise Search. Troubleshoot your configuration and refresh the page.',
+ }
+ )}
+
+ recheckIndex()}
+ isLoading={recheckIndexLoading}
+ >
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnector.button.label',
+ {
+ defaultMessage: 'Recheck now',
+ }
+ )}
+
+
+ ) : (
+
+ )}
+ >
+ ),
status:
!indexData.connector.status ||
indexData.connector.status === ConnectorStatus.CREATED
@@ -275,7 +239,40 @@ export const ConnectorConfiguration: React.FC = () => {
titleSize: 'xs',
},
{
- children: ,
+ children: (
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.scheduleSync.description',
+ {
+ defaultMessage:
+ 'Once your connectors are configured to your liking, don’t forget to set a recurring sync schedule to make sure your documents are indexed and relevant. You can also trigger a one-time sync without enabling a sync schedule.',
+ }
+ )}
+
+
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.button.label',
+ {
+ defaultMessage: 'Set schedule and sync',
+ }
+ )}
+
+
+
+
+
+ ),
status: indexData.connector.scheduling.enabled ? 'complete' : 'incomplete',
title: i18n.translate(
'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.title',
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_config.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_config.tsx
index 472fb9570209e..5588a9c16fd5d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration_config.tsx
@@ -35,28 +35,6 @@ export const ConnectorConfigurationConfig: React.FC = () => {
title: label,
}));
- const display = (
-
-
-
-
-
-
-
- setIsEditing(!isEditing)}>
- {i18n.translate(
- 'xpack.enterpriseSearch.content.indices.configurationConnector.config.editButton.title',
- {
- defaultMessage: 'Edit configuration',
- }
- )}
-
-
-
-
-
- );
-
return (
@@ -130,7 +108,31 @@ export const ConnectorConfigurationConfig: React.FC = () => {
- {isEditing ? : displayList.length > 0 && display}
+ {isEditing ? (
+
+ ) : (
+ displayList.length > 0 && (
+
+
+
+
+
+
+
+ setIsEditing(!isEditing)}>
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.indices.configurationConnector.config.editButton.title',
+ {
+ defaultMessage: 'Edit configuration',
+ }
+ )}
+
+
+
+
+
+ )
+ )}
);
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx
index d972d7a1f3efa..b1fa1aaa378af 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_overview_panels.tsx
@@ -28,20 +28,20 @@ import {
import { IndexViewLogic } from '../index_view_logic';
import { SearchIndexTabId } from '../search_index';
+const StatusPanel: React.FC<{ ingestionStatus: IngestionStatus }> = ({ ingestionStatus }) => (
+
+
+
+);
+
export const ConnectorOverviewPanels: React.FC = () => {
const { ingestionStatus, index } = useValues(IndexViewLogic);
- const statusPanel = (
-
-
-
- );
-
return isConnectorIndex(index) ? (
@@ -83,10 +83,10 @@ export const ConnectorOverviewPanels: React.FC = () => {
tabId: SearchIndexTabId.CONFIGURATION,
})}
>
- {statusPanel}
+
) : (
- statusPanel
+
)}
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts
index 1be7c2e9cf58d..319209c67fda7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts
@@ -148,7 +148,7 @@ export const IndexViewLogic = kea {
fetchIndices({ meta, returnHiddenIndices: showHiddenIndices, searchQuery });
}, [searchQuery, meta.page.current, showHiddenIndices]);
- const createNewIndexButton = (
-
-
- {i18n.translate('xpack.enterpriseSearch.content.searchIndices.create.buttonTitle', {
- defaultMessage: 'Create new index',
- })}
-
-
- );
-
- const engineSteps = (
- <>
-
-
- {i18n.translate('xpack.enterpriseSearch.content.searchIndices.searchIndices.stepsTitle', {
- defaultMessage: 'Build beautiful search experiences with Enterprise Search',
- })}
-
-
-
-
-
-
-
-
-
-
-
- >
- );
-
- const hiddenIndicesSwitch = (
- setShowHiddenIndices(event.target.checked)}
- />
- );
-
const pageTitle = isLoading
? ''
: indices.length !== 0
@@ -122,7 +80,20 @@ export const SearchIndices: React.FC = () => {
isLoading={isLoading}
pageHeader={{
pageTitle,
- rightSideItems: isLoading ? [] : [createNewIndexButton],
+ rightSideItems: isLoading
+ ? []
+ : [
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndices.create.buttonTitle',
+ {
+ defaultMessage: 'Create new index',
+ }
+ )}
+
+ ,
+ ],
}}
>
{!hasNoIndices ? (
@@ -143,14 +114,18 @@ export const SearchIndices: React.FC = () => {
defaultMessage="Your Elasticsearch indices are now front and center in Enterprise Search. You can create new indices and build search experiences with them directly. To learn more about how to use Elasticsearch indices in Enterprise Search {docLink}"
values={{
docLink: (
-
+
{i18n.translate(
'xpack.enterpriseSearch.content.indices.callout.docLink',
{
defaultMessage: 'read the documentation',
}
)}
-
+
),
}}
/>
@@ -179,7 +154,18 @@ export const SearchIndices: React.FC = () => {
- {hiddenIndicesSwitch}
+
+ setShowHiddenIndices(event.target.checked)}
+ />
+
{
<>
- {engineSteps}
+ <>
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.content.searchIndices.searchIndices.stepsTitle',
+ {
+ defaultMessage: 'Build beautiful search experiences with Enterprise Search',
+ }
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ >
>
)}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
index 5be5bf8cc0373..e65941cb7f20e 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
@@ -5,8 +5,18 @@
* 2.0.
*/
+import { i18n } from '@kbn/i18n';
+
import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api';
import { RouteDependencies } from '../../plugin';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
+
+const errorMessage = i18n.translate(
+ 'xpack.enterpriseSearch.server.routes.configData.errorMessage',
+ {
+ defaultMessage: 'Error fetching data from Enterprise Search',
+ }
+);
export function registerConfigDataRoute({ router, config, log }: RouteDependencies) {
router.get(
@@ -14,18 +24,18 @@ export function registerConfigDataRoute({ router, config, log }: RouteDependenci
path: '/internal/enterprise_search/config_data',
validate: false,
},
- async (context, request, response) => {
- const data = await callEnterpriseSearchConfigAPI({ request, config, log });
+ elasticsearchErrorHandler(log, async (context, request, response) => {
+ const data = await callEnterpriseSearchConfigAPI({ config, log, request });
if ('responseStatus' in data) {
return response.customError({
+ body: errorMessage,
statusCode: data.responseStatus,
- body: 'Error fetching data from Enterprise Search',
});
} else if (!Object.keys(data).length) {
return response.customError({
+ body: errorMessage,
statusCode: 502,
- body: 'Error fetching data from Enterprise Search',
});
} else {
return response.ok({
@@ -33,6 +43,6 @@ export function registerConfigDataRoute({ router, config, log }: RouteDependenci
headers: { 'content-type': 'application/json' },
});
}
- }
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts
index 5c2f191eb1395..015567712d648 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts
@@ -16,8 +16,9 @@ import { updateConnectorScheduling } from '../../lib/connectors/update_connector
import { RouteDependencies } from '../../plugin';
import { createError } from '../../utils/create_error';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
-export function registerConnectorRoutes({ router }: RouteDependencies) {
+export function registerConnectorRoutes({ router, log }: RouteDependencies) {
router.post(
{
path: '/internal/enterprise_search/connectors',
@@ -29,25 +30,12 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
try {
const body = await addConnector(client, request.body);
return response.ok({ body });
} catch (error) {
- if (error.statusCode === 403) {
- return createError({
- errorCode: ErrorCode.UNAUTHORIZED,
- message: i18n.translate(
- 'xpack.enterpriseSearch.server.routes.addConnector.unauthorizedError',
- {
- defaultMessage: 'You do not have the correct access rights to create this resource',
- }
- ),
- response,
- statusCode: 403,
- });
- }
if (
(error as Error).message === ErrorCode.CONNECTOR_DOCUMENT_ALREADY_EXISTS ||
(error as Error).message === ErrorCode.INDEX_ALREADY_EXISTS
@@ -64,15 +52,12 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
statusCode: 409,
});
}
- return response.customError({
- body: i18n.translate('xpack.enterpriseSearch.server.routes.addConnector.error', {
- defaultMessage: 'Error fetching data from Enterprise Search',
- }),
- statusCode: 502,
- });
+
+ throw error;
}
- }
+ })
);
+
router.post(
{
path: '/internal/enterprise_search/connectors/{connectorId}/configuration',
@@ -86,7 +71,7 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
try {
await updateConnectorConfiguration(client, request.params.connectorId, request.body);
@@ -99,8 +84,9 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
statusCode: 502,
});
}
- }
+ })
);
+
router.post(
{
path: '/internal/enterprise_search/connectors/{connectorId}/scheduling',
@@ -111,7 +97,7 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
try {
await updateConnectorScheduling(client, request.params.connectorId, request.body);
@@ -124,8 +110,9 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
statusCode: 502,
});
}
- }
+ })
);
+
router.post(
{
path: '/internal/enterprise_search/connectors/{connectorId}/start_sync',
@@ -135,7 +122,7 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
try {
await startConnectorSync(client, request.params.connectorId);
@@ -148,6 +135,6 @@ export function registerConnectorRoutes({ router }: RouteDependencies) {
statusCode: 502,
});
}
- }
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/crawler/crawler.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/crawler/crawler.ts
index eec442fcaef7a..41a00607cfc25 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/crawler/crawler.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/crawler/crawler.ts
@@ -6,7 +6,6 @@
*/
import { schema } from '@kbn/config-schema';
-
import { i18n } from '@kbn/i18n';
import { ErrorCode } from '../../../../common/types/error_codes';
@@ -15,13 +14,14 @@ import { fetchCrawlerByIndexName } from '../../../lib/crawler/fetch_crawlers';
import { RouteDependencies } from '../../../plugin';
import { createError } from '../../../utils/create_error';
+import { elasticsearchErrorHandler } from '../../../utils/elasticsearch_error_handler';
import { registerCrawlerCrawlRulesRoutes } from './crawler_crawl_rules';
import { registerCrawlerEntryPointRoutes } from './crawler_entry_points';
import { registerCrawlerSitemapRoutes } from './crawler_sitemaps';
export function registerCrawlerRoutes(routeDependencies: RouteDependencies) {
- const { router, enterpriseSearchRequestHandler } = routeDependencies;
+ const { router, enterpriseSearchRequestHandler, log } = routeDependencies;
router.post(
{
@@ -33,11 +33,13 @@ export function registerCrawlerRoutes(routeDependencies: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
+
const indexExists = await client.asCurrentUser.indices.exists({
index: request.body.index_name,
});
+
if (indexExists) {
return createError({
errorCode: ErrorCode.INDEX_ALREADY_EXISTS,
@@ -51,7 +53,9 @@ export function registerCrawlerRoutes(routeDependencies: RouteDependencies) {
statusCode: 409,
});
}
+
const crawler = await fetchCrawlerByIndexName(client, request.body.index_name);
+
if (crawler) {
return createError({
errorCode: ErrorCode.CRAWLER_ALREADY_EXISTS,
@@ -81,10 +85,11 @@ export function registerCrawlerRoutes(routeDependencies: RouteDependencies) {
statusCode: 409,
});
}
+
return enterpriseSearchRequestHandler.createRequest({
path: '/api/ent/v1/internal/indices',
})(context, request, response);
- }
+ })
);
router.post(
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/create_api_key.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/create_api_key.ts
index 2a0f745f2e4c8..da3b8c736146e 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/create_api_key.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/create_api_key.ts
@@ -11,9 +11,10 @@ import { SecurityPluginStart } from '@kbn/security-plugin/server';
import { createApiKey } from '../../lib/indices/create_api_key';
import { RouteDependencies } from '../../plugin';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
export function registerCreateAPIKeyRoute(
- { router }: RouteDependencies,
+ { log, router }: RouteDependencies,
security: SecurityPluginStart
) {
router.post(
@@ -28,24 +29,20 @@ export function registerCreateAPIKeyRoute(
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { indexName } = request.params;
const { keyName } = request.body;
- try {
- const createResponse = await createApiKey(request, security, indexName, keyName);
- if (!createResponse) {
- throw new Error('Unable to create API Key');
- }
- return response.ok({
- body: { apiKey: createResponse },
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error creating API Key',
- statusCode: 502,
- });
+
+ const createResponse = await createApiKey(request, security, indexName, keyName);
+
+ if (!createResponse) {
+ throw new Error('Unable to create API Key');
}
- }
+
+ return response.ok({
+ body: { apiKey: createResponse },
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts
index c254d0300e94d..bf44bab16fc2a 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/indices.ts
@@ -19,27 +19,23 @@ import { fetchIndices } from '../../lib/indices/fetch_indices';
import { generateApiKey } from '../../lib/indices/generate_api_key';
import { RouteDependencies } from '../../plugin';
import { createError } from '../../utils/create_error';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
import { isIndexNotFoundException } from '../../utils/identify_exceptions';
-export function registerIndexRoutes({ router }: RouteDependencies) {
+export function registerIndexRoutes({ router, log }: RouteDependencies) {
router.get(
{ path: '/internal/enterprise_search/search_indices', validate: false },
- async (context, _, response) => {
+ elasticsearchErrorHandler(log, async (context, _, response) => {
const { client } = (await context.core).elasticsearch;
- try {
- const indices = await fetchIndices(client, '*', false, true);
- return response.ok({
- body: indices,
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
- }
- }
+ const indices = await fetchIndices(client, '*', false, true);
+
+ return response.ok({
+ body: indices,
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
+
router.get(
{
path: '/internal/enterprise_search/indices',
@@ -52,7 +48,7 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const {
page,
size,
@@ -60,44 +56,40 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
search_query: searchQuery,
} = request.query;
const { client } = (await context.core).elasticsearch;
- try {
- const indexPattern = searchQuery ? `*${searchQuery}*` : '*';
- const totalIndices = await fetchIndices(client, indexPattern, !!returnHiddenIndices, false);
- const totalResults = totalIndices.length;
- const totalPages = Math.ceil(totalResults / size) || 1;
- const startIndex = (page - 1) * size;
- const endIndex = page * size;
- const selectedIndices = totalIndices.slice(startIndex, endIndex);
- const indexNames = selectedIndices.map(({ name }) => name);
- const connectors = await fetchConnectors(client, indexNames);
- const crawlers = await fetchCrawlers(client, indexNames);
- const indices = selectedIndices.map((index) => ({
- ...index,
- connector: connectors.find((connector) => connector.index_name === index.name),
- crawler: crawlers.find((crawler) => crawler.index_name === index.name),
- }));
- return response.ok({
- body: {
- indices,
- meta: {
- page: {
- current: page,
- size: indices.length,
- total_pages: totalPages,
- total_results: totalResults,
- },
+
+ const indexPattern = searchQuery ? `*${searchQuery}*` : '*';
+ const totalIndices = await fetchIndices(client, indexPattern, !!returnHiddenIndices, false);
+ const totalResults = totalIndices.length;
+ const totalPages = Math.ceil(totalResults / size) || 1;
+ const startIndex = (page - 1) * size;
+ const endIndex = page * size;
+ const selectedIndices = totalIndices.slice(startIndex, endIndex);
+ const indexNames = selectedIndices.map(({ name }) => name);
+ const connectors = await fetchConnectors(client, indexNames);
+ const crawlers = await fetchCrawlers(client, indexNames);
+ const indices = selectedIndices.map((index) => ({
+ ...index,
+ connector: connectors.find((connector) => connector.index_name === index.name),
+ crawler: crawlers.find((crawler) => crawler.index_name === index.name),
+ }));
+
+ return response.ok({
+ body: {
+ indices,
+ meta: {
+ page: {
+ current: page,
+ size: indices.length,
+ total_pages: totalPages,
+ total_results: totalResults,
},
},
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching index data from Elasticsearch',
- statusCode: 502,
- });
- }
- }
+ },
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
+
router.get(
{
path: '/internal/enterprise_search/indices/{indexName}',
@@ -107,9 +99,10 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { indexName } = request.params;
const { client } = (await context.core).elasticsearch;
+
try {
const index = await fetchIndex(client, indexName);
return response.ok({
@@ -125,13 +118,12 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
statusCode: 404,
});
}
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
+
+ throw error;
}
- }
+ })
);
+
router.get(
{
path: '/internal/enterprise_search/indices/{indexName}/exists',
@@ -141,25 +133,35 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { indexName } = request.params;
const { client } = (await context.core).elasticsearch;
+ let indexExists: boolean;
+
try {
- const indexExists = await client.asCurrentUser.indices.exists({ index: indexName });
- return response.ok({
- body: {
- exists: indexExists,
- },
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
+ indexExists = await client.asCurrentUser.indices.exists({ index: indexName });
+ } catch (e) {
+ log.warn(
+ i18n.translate('xpack.enterpriseSearch.server.routes.indices.existsErrorLogMessage', {
+ defaultMessage: 'An error occured while resolving request to {requestUrl}',
+ values: {
+ requestUrl: request.url.toString(),
+ },
+ })
+ );
+ log.warn(e);
+ indexExists = false;
}
- }
+
+ return response.ok({
+ body: {
+ exists: indexExists,
+ },
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
+
router.post(
{
path: '/internal/enterprise_search/indices/{indexName}/api_key',
@@ -169,23 +171,19 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { indexName } = request.params;
const { client } = (await context.core).elasticsearch;
- try {
- const apiKey = await generateApiKey(client, indexName);
- return response.ok({
- body: apiKey,
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
- }
- }
+
+ const apiKey = await generateApiKey(client, indexName);
+
+ return response.ok({
+ body: apiKey,
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
+
router.post(
{
path: '/internal/enterprise_search/indices',
@@ -196,67 +194,66 @@ export function registerIndexRoutes({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { ['index_name']: indexName, language } = request.body;
const { client } = (await context.core).elasticsearch;
- try {
- const indexExists = await client.asCurrentUser.indices.exists({
- index: request.body.index_name,
+
+ const indexExists = await client.asCurrentUser.indices.exists({
+ index: request.body.index_name,
+ });
+
+ if (indexExists) {
+ return createError({
+ errorCode: ErrorCode.INDEX_ALREADY_EXISTS,
+ message: i18n.translate(
+ 'xpack.enterpriseSearch.server.routes.createApiIndex.indexExistsError',
+ {
+ defaultMessage: 'This index already exists',
+ }
+ ),
+ response,
+ statusCode: 409,
});
- if (indexExists) {
- return createError({
- errorCode: ErrorCode.INDEX_ALREADY_EXISTS,
- message: i18n.translate(
- 'xpack.enterpriseSearch.server.routes.createApiIndex.indexExistsError',
- {
- defaultMessage: 'This index already exists',
- }
- ),
- response,
- statusCode: 409,
- });
- }
- const crawler = await fetchCrawlerByIndexName(client, request.body.index_name);
- if (crawler) {
- return createError({
- errorCode: ErrorCode.CRAWLER_ALREADY_EXISTS,
- message: i18n.translate(
- 'xpack.enterpriseSearch.server.routes.createApiIndex.crawlerExistsError',
- {
- defaultMessage: 'A crawler for this index already exists',
- }
- ),
- response,
- statusCode: 409,
- });
- }
+ }
- const connector = await fetchConnectorByIndexName(client, request.body.index_name);
+ const crawler = await fetchCrawlerByIndexName(client, request.body.index_name);
- if (connector) {
- return createError({
- errorCode: ErrorCode.CONNECTOR_DOCUMENT_ALREADY_EXISTS,
- message: i18n.translate(
- 'xpack.enterpriseSearch.server.routes.createApiIndex.connectorExistsError',
- {
- defaultMessage: 'A connector for this index already exists',
- }
- ),
- response,
- statusCode: 409,
- });
- }
- const createIndexResponse = await createApiIndex(client, indexName, language);
- return response.ok({
- body: createIndexResponse,
- headers: { 'content-type': 'application/json' },
+ if (crawler) {
+ return createError({
+ errorCode: ErrorCode.CRAWLER_ALREADY_EXISTS,
+ message: i18n.translate(
+ 'xpack.enterpriseSearch.server.routes.createApiIndex.crawlerExistsError',
+ {
+ defaultMessage: 'A crawler for this index already exists',
+ }
+ ),
+ response,
+ statusCode: 409,
});
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
+ }
+
+ const connector = await fetchConnectorByIndexName(client, request.body.index_name);
+
+ if (connector) {
+ return createError({
+ errorCode: ErrorCode.CONNECTOR_DOCUMENT_ALREADY_EXISTS,
+ message: i18n.translate(
+ 'xpack.enterpriseSearch.server.routes.createApiIndex.connectorExistsError',
+ {
+ defaultMessage: 'A connector for this index already exists',
+ }
+ ),
+ response,
+ statusCode: 409,
});
}
- }
+
+ const createIndexResponse = await createApiIndex(client, indexName, language);
+
+ return response.ok({
+ body: createIndexResponse,
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts
index 506fcaf73bd1f..b963157694acf 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/mapping.ts
@@ -9,8 +9,9 @@ import { schema } from '@kbn/config-schema';
import { fetchMapping } from '../../lib/fetch_mapping';
import { RouteDependencies } from '../../plugin';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
-export function registerMappingRoute({ router }: RouteDependencies) {
+export function registerMappingRoute({ router, log }: RouteDependencies) {
router.get(
{
path: '/internal/enterprise_search/mappings/{index_name}',
@@ -20,20 +21,15 @@ export function registerMappingRoute({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
- try {
- const mapping = await fetchMapping(client, request.params.index_name);
- return response.ok({
- body: mapping,
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
- }
- }
+
+ const mapping = await fetchMapping(client, request.params.index_name);
+
+ return response.ok({
+ body: mapping,
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts
index 68391bf8b4f4b..ee57f4a59c568 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/search.ts
@@ -13,6 +13,7 @@ import { ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } from '../../../common/c
import { fetchSearchResults } from '../../lib/fetch_search_results';
import { RouteDependencies } from '../../plugin';
+import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
const calculateMeta = (searchResults: SearchResponseBody, page: number, size: number) => {
let totalResults = 0;
@@ -35,7 +36,7 @@ const calculateMeta = (searchResults: SearchResponseBody, page: number, size: nu
};
};
-export function registerSearchRoute({ router }: RouteDependencies) {
+export function registerSearchRoute({ router, log }: RouteDependencies) {
router.get(
{
path: '/internal/enterprise_search/indices/{index_name}/search',
@@ -52,34 +53,29 @@ export function registerSearchRoute({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query;
const from = page * size;
- try {
- const searchResults: SearchResponseBody = await fetchSearchResults(
- client,
- request.params.index_name,
- '',
- from,
- size
- );
- return response.ok({
- body: {
- meta: calculateMeta(searchResults, page, size),
- results: searchResults,
- },
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
- }
- }
+ const searchResults: SearchResponseBody = await fetchSearchResults(
+ client,
+ request.params.index_name,
+ '',
+ from,
+ size
+ );
+
+ return response.ok({
+ body: {
+ meta: calculateMeta(searchResults, page, size),
+ results: searchResults,
+ },
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
+
router.get(
{
path: '/internal/enterprise_search/indices/{index_name}/search/{query}',
@@ -97,32 +93,26 @@ export function registerSearchRoute({ router }: RouteDependencies) {
}),
},
},
- async (context, request, response) => {
+ elasticsearchErrorHandler(log, async (context, request, response) => {
const { client } = (await context.core).elasticsearch;
const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query;
const from = page * size;
- try {
- const searchResults = await fetchSearchResults(
- client,
- request.params.index_name,
- request.params.query,
- from,
- size
- );
- return response.ok({
- body: {
- meta: calculateMeta(searchResults, page, size),
- results: searchResults,
- },
- headers: { 'content-type': 'application/json' },
- });
- } catch (error) {
- return response.customError({
- body: 'Error fetching data from Enterprise Search',
- statusCode: 502,
- });
- }
- }
+ const searchResults = await fetchSearchResults(
+ client,
+ request.params.index_name,
+ request.params.query,
+ from,
+ size
+ );
+
+ return response.ok({
+ body: {
+ meta: calculateMeta(searchResults, page, size),
+ results: searchResults,
+ },
+ headers: { 'content-type': 'application/json' },
+ });
+ })
);
}
diff --git a/x-pack/plugins/enterprise_search/server/utils/create_error.ts b/x-pack/plugins/enterprise_search/server/utils/create_error.ts
index 388c540148f6c..ca9fac814f4c9 100644
--- a/x-pack/plugins/enterprise_search/server/utils/create_error.ts
+++ b/x-pack/plugins/enterprise_search/server/utils/create_error.ts
@@ -9,16 +9,19 @@ import { KibanaResponseFactory } from '@kbn/core-http-server';
import { ErrorCode } from '../../common/types/error_codes';
+export interface EnterpriseSearchError {
+ errorCode: ErrorCode;
+ message: string;
+ statusCode: number;
+}
+
export function createError({
errorCode,
message,
response,
statusCode,
-}: {
- errorCode: ErrorCode;
- message: string;
+}: EnterpriseSearchError & {
response: KibanaResponseFactory;
- statusCode: number;
}) {
return response.customError({
body: {
diff --git a/x-pack/plugins/enterprise_search/server/utils/elasticsearch_error_handler.ts b/x-pack/plugins/enterprise_search/server/utils/elasticsearch_error_handler.ts
new file mode 100644
index 0000000000000..3f938149e5a16
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/server/utils/elasticsearch_error_handler.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { RequestHandler } from '@kbn/core/server';
+import { Logger } from '@kbn/core/server';
+
+import { i18n } from '@kbn/i18n';
+
+import { ErrorCode } from '../../common/types/error_codes';
+
+import { createError, EnterpriseSearchError } from './create_error';
+import { isUnauthorizedException } from './identify_exceptions';
+
+export function elasticsearchErrorHandler(
+ log: Logger,
+ requestHandler: RequestHandler
+): RequestHandler {
+ return async (context, request, response) => {
+ try {
+ return await requestHandler(context, request, response);
+ } catch (error) {
+ let enterpriseSearchError: EnterpriseSearchError | undefined;
+
+ if (isUnauthorizedException(error)) {
+ enterpriseSearchError = {
+ errorCode: ErrorCode.UNAUTHORIZED,
+ message: i18n.translate('xpack.enterpriseSearch.server.routes.unauthorizedError', {
+ defaultMessage: 'You do not have sufficient permissions.',
+ }),
+ statusCode: 403,
+ };
+ } else {
+ enterpriseSearchError = {
+ errorCode: ErrorCode.UNCAUGHT_EXCEPTION,
+ message: i18n.translate('xpack.enterpriseSearch.server.routes.uncaughtExceptionError', {
+ defaultMessage: 'Enterprise Search encountered an error.',
+ }),
+ statusCode: 502,
+ };
+ }
+
+ if (enterpriseSearchError !== undefined) {
+ log.error(
+ i18n.translate('xpack.enterpriseSearch.server.routes.errorLogMessage', {
+ defaultMessage:
+ 'An error occured while resolving request to {requestUrl}: {errorMessage}',
+ values: {
+ errorMessage: enterpriseSearchError.message,
+ requestUrl: request.url.toString(),
+ },
+ })
+ );
+ log.error(error);
+ return createError({
+ ...enterpriseSearchError,
+ message: i18n.translate('xpack.enterpriseSearch.server.routes.checkKibanaLogsMessage', {
+ defaultMessage: '{errorMessage} Check Kibana Server logs for details.',
+ values: {
+ errorMessage: enterpriseSearchError.message,
+ },
+ }),
+ response,
+ });
+ }
+
+ throw error;
+ }
+ };
+}
diff --git a/x-pack/plugins/enterprise_search/server/utils/identify_exceptions.ts b/x-pack/plugins/enterprise_search/server/utils/identify_exceptions.ts
index ce0349b95c207..7bc13135343dc 100644
--- a/x-pack/plugins/enterprise_search/server/utils/identify_exceptions.ts
+++ b/x-pack/plugins/enterprise_search/server/utils/identify_exceptions.ts
@@ -5,20 +5,23 @@
* 2.0.
*/
-interface ErrorResponse {
+interface ElasticsearchResponseError {
meta?: {
body?: {
error?: {
type: string;
};
};
+ statusCode?: number;
};
name: 'ResponseError';
- statusCode: string;
}
-export const isIndexNotFoundException = (error: ErrorResponse) =>
+export const isIndexNotFoundException = (error: ElasticsearchResponseError) =>
error?.meta?.body?.error?.type === 'index_not_found_exception';
-export const isResourceAlreadyExistsException = (error: ErrorResponse) =>
+export const isResourceAlreadyExistsException = (error: ElasticsearchResponseError) =>
error?.meta?.body?.error?.type === 'resource_already_exists_exception';
+
+export const isUnauthorizedException = (error: ElasticsearchResponseError) =>
+ error.meta?.statusCode === 403;
diff --git a/x-pack/plugins/files/.i18nrc.json b/x-pack/plugins/files/.i18nrc.json
new file mode 100755
index 0000000000000..863f776e2a64e
--- /dev/null
+++ b/x-pack/plugins/files/.i18nrc.json
@@ -0,0 +1,7 @@
+{
+ "prefix": "files",
+ "paths": {
+ "files": "."
+ },
+ "translations": ["translations/ja-JP.json"]
+}
diff --git a/x-pack/plugins/files/README.md b/x-pack/plugins/files/README.md
new file mode 100755
index 0000000000000..baaea2ecb44cd
--- /dev/null
+++ b/x-pack/plugins/files/README.md
@@ -0,0 +1,13 @@
+# files
+
+File upload, download, sharing, and serving over HTTP implementation in Kibana.
+
+## Status
+
+The files plugin is currently still under development. If you want to use files please reach out to the (App Services team)[https://github.com/orgs/elastic/teams/kibana-app-services] and let's talk about your use case and share our current roadmap.
+
+---
+
+## Development
+
+See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
diff --git a/x-pack/plugins/files/common/api_routes.ts b/x-pack/plugins/files/common/api_routes.ts
new file mode 100644
index 0000000000000..f3647edaf83f0
--- /dev/null
+++ b/x-pack/plugins/files/common/api_routes.ts
@@ -0,0 +1,209 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { PLUGIN_ID } from './constants';
+import type {
+ FileJSON,
+ Pagination,
+ FilesMetrics,
+ FileShareJSON,
+ FileShareJSONWithToken,
+} from './types';
+
+export const API_BASE_PATH = `/api/${PLUGIN_ID}`;
+
+export const FILES_API_BASE_PATH = `${API_BASE_PATH}/files`;
+
+export const FILES_SHARE_API_BASE_PATH = `${API_BASE_PATH}/shares`;
+
+export const FILES_PUBLIC_API_BASE_PATH = `${API_BASE_PATH}/public`;
+
+/**
+ * Abstract type definition for API route inputs and outputs.
+ *
+ * These definitions should be shared between the public and server
+ * as the single source of truth.
+ */
+export interface HttpApiInterfaceEntryDefinition<
+ P = unknown,
+ Q = unknown,
+ B = unknown,
+ R = unknown
+> {
+ inputs: {
+ params: P;
+ query: Q;
+ body: B;
+ };
+ output: R;
+}
+
+export type CreateFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ unknown,
+ unknown,
+ {
+ name: string;
+ alt?: string;
+ meta?: Record;
+ mimeType?: string;
+ },
+ { file: FileJSON }
+>;
+
+export type DeleteFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ id: string;
+ },
+ unknown,
+ unknown,
+ { ok: true }
+>;
+
+export type DownloadFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ id: string;
+ fileName?: string;
+ },
+ unknown,
+ unknown,
+ any
+>;
+
+export type GetByIdFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ id: string;
+ },
+ unknown,
+ unknown,
+ { file: FileJSON }
+>;
+
+export type ListFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ unknown,
+ Pagination,
+ unknown,
+ { files: FileJSON[] }
+>;
+
+export type UpdateFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ { id: string },
+ unknown,
+ { name?: string; alt?: string; meta?: Record },
+ { file: FileJSON }
+>;
+
+export type UploadFileKindHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ { id: string },
+ unknown,
+ any,
+ {
+ ok: true;
+ size: number;
+ }
+>;
+
+export type FindFilesHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ unknown,
+ Pagination,
+ {
+ /**
+ * Filter for set of file-kinds
+ */
+ kind?: string[];
+
+ /**
+ * Filter for match on names
+ */
+ name?: string[];
+
+ /**
+ * Filter for set of meta attributes matching this object
+ */
+ meta?: {};
+
+ /**
+ * Filter for match on extensions
+ */
+ extension?: string[];
+
+ /**
+ * Filter for match on extensions
+ */
+ status?: string[];
+ },
+ { files: FileJSON[] }
+>;
+
+export type FilesMetricsHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ unknown,
+ unknown,
+ unknown,
+ FilesMetrics
+>;
+
+export type FileShareHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ fileId: string;
+ },
+ unknown,
+ {
+ /**
+ * Unix timestamp of when the share will expire.
+ */
+ validUntil?: number;
+ /**
+ * Optional name to uniquely identify this share instance.
+ */
+ name?: string;
+ },
+ FileShareJSONWithToken
+>;
+
+export type FileUnshareHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ /**
+ * Share token id
+ */
+ id: string;
+ },
+ unknown,
+ unknown,
+ {
+ ok: true;
+ }
+>;
+
+export type FileGetShareHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ {
+ /**
+ * ID of the share object
+ */
+ id: string;
+ },
+ unknown,
+ unknown,
+ {
+ share: FileShareJSON;
+ }
+>;
+
+export type FileListSharesHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ unknown,
+ Pagination & { forFileId?: string },
+ unknown,
+ {
+ shares: FileShareJSON[];
+ }
+>;
+
+export type FilePublicDownloadHttpEndpoint = HttpApiInterfaceEntryDefinition<
+ { fileName?: string },
+ { token: string },
+ unknown,
+ // Should be a readable stream
+ any
+>;
diff --git a/x-pack/plugins/files/common/constants.ts b/x-pack/plugins/files/common/constants.ts
new file mode 100644
index 0000000000000..be0bfa3ca80c4
--- /dev/null
+++ b/x-pack/plugins/files/common/constants.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/**
+ * The files plugin ID
+ */
+export const PLUGIN_ID = 'files' as const;
+/**
+ * The files plugin name
+ */
+export const PLUGIN_NAME = 'files' as const;
+
+/**
+ * Unique type name of the file saved object
+ */
+export const FILE_SO_TYPE = 'file';
+/**
+ * Unique type name of the public file saved object
+ */
+export const FILE_SHARE_SO_TYPE = 'fileShare';
+
+/**
+ * The name of the fixed size ES-backed blob store
+ */
+export const ES_FIXED_SIZE_INDEX_BLOB_STORE = 'esFixedSizeIndex' as const;
diff --git a/x-pack/plugins/files/common/index.ts b/x-pack/plugins/files/common/index.ts
new file mode 100755
index 0000000000000..8a97030efff6f
--- /dev/null
+++ b/x-pack/plugins/files/common/index.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { FILE_SO_TYPE, PLUGIN_ID, PLUGIN_NAME, ES_FIXED_SIZE_INDEX_BLOB_STORE } from './constants';
+
+export type {
+ File,
+ FileKind,
+ FileJSON,
+ FileShare,
+ FileStatus,
+ Pagination,
+ FileMetadata,
+ FilesMetrics,
+ FileShareJSON,
+ FileCompression,
+ FileSavedObject,
+ BaseFileMetadata,
+ FileShareOptions,
+ FileUnshareOptions,
+ BlobStorageSettings,
+ UpdatableFileMetadata,
+ FileShareJSONWithToken,
+ UpdatableFileShareMetadata,
+} from './types';
diff --git a/x-pack/plugins/files/common/types.ts b/x-pack/plugins/files/common/types.ts
new file mode 100644
index 0000000000000..2fef7ab3f17c4
--- /dev/null
+++ b/x-pack/plugins/files/common/types.ts
@@ -0,0 +1,519 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { SavedObject } from '@kbn/core/server';
+import type { Readable } from 'stream';
+import type { ES_FIXED_SIZE_INDEX_BLOB_STORE } from './constants';
+
+/**
+ * Values for paginating through results.
+ */
+export interface Pagination {
+ /**
+ * Page of results.
+ */
+ page?: number;
+ /**
+ * Number of results per page.
+ */
+ perPage?: number;
+}
+
+/**
+ * Status of a file.
+ *
+ * AWAITING_UPLOAD - A file object has been created but does not have any contents.
+ * UPLOADING - File contents are being uploaded.
+ * READY - File contents have been uploaded and are ready for to be downloaded.
+ * UPLOAD_ERROR - An attempt was made to upload file contents but failed.
+ * DELETED - The file contents have been or are being deleted.
+ */
+export type FileStatus = 'AWAITING_UPLOAD' | 'UPLOADING' | 'READY' | 'UPLOAD_ERROR' | 'DELETED';
+
+/**
+ * Supported file compression algorithms
+ */
+export type FileCompression = 'br' | 'gzip' | 'deflate' | 'none';
+
+/**
+ * File metadata fields are defined per the ECS specification:
+ *
+ * https://www.elastic.co/guide/en/ecs/current/ecs-file.html
+ *
+ * Custom fields are named according to the custom field convention: "CustomFieldName".
+ */
+// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
+export type BaseFileMetadata = {
+ /**
+ * Name of the file
+ *
+ * @note This field is recommended since it will provide a better UX
+ */
+ name?: string;
+
+ /**
+ * MIME type of the file contents
+ */
+ mime_type?: string;
+
+ /**
+ * ISO string representing the file creation date
+ */
+ created?: string;
+
+ /**
+ * Size of the file
+ */
+ size?: number;
+
+ /**
+ * Hash of the file's contents
+ */
+ hash?: {
+ /**
+ * UTF-8 string representing MD5 hash
+ */
+ md5?: string;
+ /**
+ * UTF-8 string representing sha1 hash
+ */
+ sha1?: string;
+ /**
+ * UTF-8 string representing sha256 hash
+ */
+ sha256?: string;
+ /**
+ * UTF-8 string representing sha384 hash
+ */
+ sha384?: string;
+ /**
+ * UTF-8 string representing sha512 hash
+ */
+ sha512?: string;
+ /**
+ * UTF-8 string representing shadeep hash
+ */
+ ssdeep?: string;
+ /**
+ * UTF-8 string representing tlsh hash
+ */
+ tlsh?: string;
+ [hashName: string]: string | undefined;
+ };
+
+ /**
+ * The file extension, for example "jpg", "png", "svg" and so forth
+ */
+ extension?: string;
+
+ /**
+ * Alternate text that can be used used to describe the contents of the file
+ * in human-friendly language
+ */
+ Alt?: string;
+
+ /**
+ * ISO string representing when the file was last updated
+ */
+ Updated?: string;
+
+ /**
+ * The file's current status
+ */
+ Status?: FileStatus;
+
+ /**
+ * The maximum number of bytes per file chunk
+ */
+ ChunkSize?: number;
+
+ /**
+ * Compression algorithm used to transform chunks before they were stored.
+ */
+ Compression?: FileCompression;
+};
+
+/**
+ * Extra metadata on a file object specific to Kibana implementation.
+ */
+export type FileMetadata = Required<
+ Pick
+> &
+ BaseFileMetadata & {
+ /**
+ * Unique identifier of the kind of file. Kibana applications can register
+ * these at runtime.
+ */
+ FileKind: string;
+
+ /**
+ * User-defined metadata
+ */
+ Meta?: Meta;
+ };
+
+/**
+ * Attributes of a file that represent a serialised version of the file.
+ */
+export interface FileJSON {
+ /**
+ * Unique file ID.
+ */
+ id: string;
+ /**
+ * ISO string of when this file was created
+ */
+ created: FileMetadata['created'];
+ /**
+ * ISO string of when the file was updated
+ */
+ updated: FileMetadata['Updated'];
+ /**
+ * File name.
+ *
+ * @note Does not have to be unique.
+ */
+ name: FileMetadata['name'];
+ /**
+ * MIME type of the file's contents.
+ */
+ mimeType: FileMetadata['mime_type'];
+ /**
+ * The size, in bytes, of the file content.
+ */
+ size: FileMetadata['size'];
+ /**
+ * The file extension (dot suffix).
+ *
+ * @note this value can be derived from MIME type but is stored for search
+ * convenience.
+ */
+ extension: FileMetadata['extension'];
+
+ /**
+ * A consumer defined set of attributes.
+ *
+ * Consumers of the file service can add their own tags and identifiers to
+ * a file using the "meta" object.
+ */
+ meta: FileMetadata['Meta'];
+ /**
+ * Use this text to describe the file contents for display and accessibility.
+ */
+ alt: FileMetadata['Alt'];
+ /**
+ * A unique kind that governs various aspects of the file. A consumer of the
+ * files service must register a file kind and link their files to a specific
+ * kind.
+ *
+ * @note This enables stricter access controls to CRUD and other functionality
+ * exposed by the files service.
+ */
+ fileKind: FileMetadata['FileKind'];
+ /**
+ * The current status of the file.
+ *
+ * See {@link FileStatus} for more details.
+ */
+ status: FileMetadata['Status'];
+}
+
+/**
+ * An {@link SavedObject} containing a file object (i.e., metadata only).
+ */
+export type FileSavedObject = SavedObject>;
+
+/**
+ * The set of file metadata that can be updated.
+ */
+export type UpdatableFileMetadata = Pick, 'meta' | 'alt' | 'name'>;
+
+/**
+ * Data stored with a file share object
+ */
+// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
+export type FileShare = {
+ /**
+ * ISO timestamp of when the file share was created.
+ */
+ created: string;
+
+ /**
+ * Secret token used to access the associated file.
+ */
+ token: string;
+
+ /**
+ * Human friendly name for this share token.
+ */
+ name?: string;
+
+ /**
+ * The unix timestamp (in milliseconds) this file share will expire.
+ *
+ * TODO: in future we could add a special value like "forever", but this should
+ * not be the default.
+ */
+ valid_until: number;
+};
+
+/**
+ * Attributes of a file that represent a serialised version of the file.
+ */
+export interface FileShareJSON {
+ /**
+ * Unique ID share instance
+ */
+ id: string;
+ /**
+ * ISO timestamp the share was created
+ */
+ created: FileShare['created'];
+ /**
+ * Unix timestamp (in milliseconds) of when this share expires
+ */
+ validUntil: FileShare['valid_until'];
+ /**
+ * A user-friendly name for the file share
+ */
+ name?: FileShare['name'];
+ /**
+ * The ID of the file this share is linked to
+ */
+ fileId: string;
+}
+
+/**
+ * A version of the file share with a token included.
+ *
+ * @note This should only be shown when the file share is first created
+ */
+export type FileShareJSONWithToken = FileShareJSON & {
+ /**
+ * Secret token that can be used to access files
+ */
+ token: string;
+};
+
+/**
+ * Set of attributes that can be updated in a file share.
+ */
+export type UpdatableFileShareMetadata = Pick;
+
+/**
+ * Arguments to pass to share a file
+ */
+export interface FileShareOptions {
+ /**
+ * Optional name for the file share, should be human-friendly.
+ */
+ name?: string;
+ /**
+ * Unix timestamp (in milliseconds) when the file share will expire.
+ *
+ * @note default is 30 days
+ */
+ validUntil?: number;
+}
+/**
+ * Arguments for unsharing a file
+ */
+export interface FileUnshareOptions {
+ /**
+ * Specify the share instance to remove
+ */
+ shareId: string;
+}
+
+/**
+ * A class with set of properties and behaviors of the "smart" file object and adds
+ * behaviours for interacting with files on top of the pure data.
+ */
+export interface File extends FileJSON {
+ /**
+ * Update a file object's metadatathat can be updated.
+ *
+ * @param attr - The of attributes to update.
+ */
+ update(attr: Partial>): Promise>;
+
+ /**
+ * Stream file content to storage.
+ *
+ * @param content - The content to stream to storage.
+ */
+ uploadContent(content: Readable): Promise;
+
+ /**
+ * Stream file content from storage.
+ */
+ downloadContent(): Promise;
+
+ /**
+ * Delete a file.
+ *
+ * @note This will delete the file metadata, contents and any other objects
+ * related to the file owned by files.
+ */
+ delete(): Promise;
+
+ /**
+ * Generate a secure token that can be used to access a file's content.
+ *
+ * @note This makes a file available for public download. Any agent with the
+ * token will bypass normal authz and authn checks.
+ *
+ * @param opts - Share file options.
+ */
+ share(opts?: FileShareOptions): Promise;
+
+ /**
+ * List all current {@link FileShareJSON} objects that have been created for
+ * a file.
+ */
+ listShares(): Promise;
+
+ /**
+ * Remove a {@link FileShareJSON} object therefore ceasing to share a file's
+ * content.
+ *
+ * @param opts - Unshare file options
+ */
+ unshare(opts: FileUnshareOptions): Promise;
+
+ /**
+ * Get a JSON representation of the file. Convenient for serialisation.
+ */
+ toJSON(): FileJSON;
+}
+
+/**
+ * Defines all the settings for supported blob stores.
+ *
+ * Key names map to unique blob store implementations and so must not be changed
+ * without a migration
+ */
+export interface BlobStorageSettings {
+ /**
+ * Single index that supports up to 50GB of blobs
+ */
+ [ES_FIXED_SIZE_INDEX_BLOB_STORE]?: {
+ index: string;
+ };
+ // Other blob store settings will go here once available
+}
+
+interface HttpEndpointDefinition {
+ /**
+ * Specify the tags for this endpoint.
+ *
+ * @example
+ * // This will enable access control to this endpoint for users that can access "myApp" only.
+ * { tags: ['access:myApp'] }
+ *
+ */
+ tags: string[];
+}
+
+/**
+ * A descriptor of meta values associated with a set or "kind" of files.
+ *
+ * @note In order to use the file service consumers must register a {@link FileKind}
+ * in the {@link FileKindsRegistry}.
+ */
+export interface FileKind {
+ /**
+ * Unique file kind ID
+ */
+ id: string;
+ /**
+ * Maximum size, in bytes, a file of this kind can be.
+ */
+ maxSizeBytes?: number;
+
+ /**
+ * The MIME type of the file content.
+ *
+ * @default accept all mime types
+ */
+ allowedMimeTypes?: string[];
+
+ /**
+ * Blob store specific settings that enable configuration of storage
+ * details.
+ */
+ blobStoreSettings?: BlobStorageSettings;
+
+ /**
+ * Optionally specify which HTTP routes to create for the file kind
+ */
+ http: {
+ /**
+ * Enable creating this file type
+ */
+ create?: HttpEndpointDefinition;
+ /**
+ * Enable the file metadata to updated
+ */
+ update?: HttpEndpointDefinition;
+ /**
+ * Enable the file to be deleted (metadata and contents)
+ */
+ delete?: HttpEndpointDefinition;
+ /**
+ * Enable file to be retrieved by ID.
+ */
+ getById?: HttpEndpointDefinition;
+ /**
+ * Enable file to be listed
+ */
+ list?: HttpEndpointDefinition;
+ /**
+ * Enable the file to be downloaded
+ */
+ download?: HttpEndpointDefinition;
+ /**
+ * Enable the file to be shared publicly
+ */
+ share?: HttpEndpointDefinition;
+ };
+}
+
+/**
+ * A collection of generally useful metrics about files.
+ */
+export interface FilesMetrics {
+ /**
+ * Metrics about all storage media.
+ */
+ storage: {
+ /**
+ * The ES fixed size blob store.
+ */
+ [ES_FIXED_SIZE_INDEX_BLOB_STORE]: {
+ /**
+ * The total size in bytes that can be used in this storage medium
+ */
+ capacity: number;
+ /**
+ * Bytes currently used
+ */
+ used: number;
+ /**
+ * Bytes currently available
+ */
+ available: number;
+ };
+ };
+ /**
+ * A count of all files grouped by status
+ */
+ countByStatus: Record;
+ /**
+ * A count of all files grouped by extension
+ */
+ countByExtension: Record;
+}
diff --git a/x-pack/plugins/files/jest.config.js b/x-pack/plugins/files/jest.config.js
new file mode 100644
index 0000000000000..ade30bacab1fa
--- /dev/null
+++ b/x-pack/plugins/files/jest.config.js
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+module.exports = {
+ preset: '@kbn/test',
+ rootDir: '../../..',
+ roots: ['/x-pack/plugins/files'],
+ coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/files',
+ coverageReporters: ['text', 'html'],
+ collectCoverageFrom: ['/x-pack/plugins/files/{common,public,server}/**/*.{js,ts,tsx}'],
+};
diff --git a/x-pack/plugins/files/jest.integration.config.js b/x-pack/plugins/files/jest.integration.config.js
new file mode 100644
index 0000000000000..fbcfd8ed04b67
--- /dev/null
+++ b/x-pack/plugins/files/jest.integration.config.js
@@ -0,0 +1,12 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+module.exports = {
+ preset: '@kbn/test/jest_integration',
+ rootDir: '../../..',
+ roots: ['/x-pack/plugins/files'],
+};
diff --git a/x-pack/plugins/files/kibana.json b/x-pack/plugins/files/kibana.json
new file mode 100755
index 0000000000000..73571304b194a
--- /dev/null
+++ b/x-pack/plugins/files/kibana.json
@@ -0,0 +1,14 @@
+{
+ "id": "files",
+ "version": "1.0.0",
+ "kibanaVersion": "kibana",
+ "owner": {
+ "name": "@elastic/kibana-app-services",
+ "githubTeam": "team:AppServicesUx"
+ },
+ "description": "File upload, download, sharing, and serving over HTTP implementation in Kibana.",
+ "server": true,
+ "ui": true,
+ "requiredPlugins": [],
+ "optionalPlugins": ["security"]
+}
diff --git a/x-pack/plugins/files/public/files_client/files_client.ts b/x-pack/plugins/files/public/files_client/files_client.ts
new file mode 100644
index 0000000000000..ffa8e815368f0
--- /dev/null
+++ b/x-pack/plugins/files/public/files_client/files_client.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import * as qs from 'query-string';
+import type { HttpStart } from '@kbn/core/public';
+import type { FilesClient } from '../types';
+import { FILES_API_BASE_PATH } from '../../common/api_routes';
+
+const apiRoutes = {
+ getCreateFileRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}`,
+ getUploadRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}/blob`,
+ getDownloadRoute: (fileKind: string, id: string, fileName?: string) =>
+ `${FILES_API_BASE_PATH}/${fileKind}/${id}/blob/${fileName ? fileName : ''}`,
+ getUpdateRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
+ getDeleteRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
+ getListRoute: (fileKind: string, page?: number, perPage?: number) => {
+ const qParams = qs.stringify({ page, perPage });
+ return `${FILES_API_BASE_PATH}/${fileKind}/list${qParams ? `?${qParams}` : ''}`;
+ },
+ getByIdRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
+};
+
+interface Args {
+ fileKind: string;
+ http: HttpStart;
+}
+
+export const createFilesClient = ({ http, fileKind }: Args): FilesClient => {
+ return {
+ create(args) {
+ return http.post(apiRoutes.getCreateFileRoute(fileKind), {
+ headers: {
+ 'content-type': 'application/json',
+ },
+ body: JSON.stringify(args),
+ });
+ },
+ delete(args) {
+ return http.delete(apiRoutes.getDeleteRoute(fileKind, args.id));
+ },
+ download(args) {
+ return http.get(apiRoutes.getDownloadRoute(fileKind, args.id, args.fileName));
+ },
+ getById(args) {
+ return http.get(apiRoutes.getByIdRoute(fileKind, args.id));
+ },
+ list(args) {
+ return http.get(apiRoutes.getListRoute(fileKind, args.page, args.perPage));
+ },
+ update({ id, ...body }) {
+ return http.patch(apiRoutes.getUpdateRoute(fileKind, id), {
+ headers: {
+ 'content-type': 'application/json',
+ },
+ body: JSON.stringify(body),
+ });
+ },
+ upload(args) {
+ return http.put(apiRoutes.getUploadRoute(fileKind, args.id), {
+ body: args.body,
+ });
+ },
+ };
+};
diff --git a/x-pack/plugins/watcher/server/models/watch_status_model/index.js b/x-pack/plugins/files/public/files_client/index.ts
similarity index 81%
rename from x-pack/plugins/watcher/server/models/watch_status_model/index.js
rename to x-pack/plugins/files/public/files_client/index.ts
index 8c5b9e305794b..60f3022e825df 100644
--- a/x-pack/plugins/watcher/server/models/watch_status_model/index.js
+++ b/x-pack/plugins/files/public/files_client/index.ts
@@ -5,4 +5,4 @@
* 2.0.
*/
-export { WatchStatusModel } from './watch_status_model';
+export { createFilesClient } from './files_client';
diff --git a/x-pack/plugins/files/public/index.ts b/x-pack/plugins/files/public/index.ts
new file mode 100644
index 0000000000000..4b707aaa3b6a2
--- /dev/null
+++ b/x-pack/plugins/files/public/index.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FilesPlugin } from './plugin';
+
+export type { FilesClient, FilesClientFactory } from './types';
+
+export function plugin() {
+ return new FilesPlugin();
+}
diff --git a/x-pack/plugins/files/public/plugin.ts b/x-pack/plugins/files/public/plugin.ts
new file mode 100644
index 0000000000000..92358d067d36a
--- /dev/null
+++ b/x-pack/plugins/files/public/plugin.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
+import type { FilesClientFactory } from './types';
+import { createFilesClient } from './files_client';
+
+/**
+ * Public setup-phase contract
+ */
+export interface FilesSetup {
+ /**
+ * A factory for creating an {@link FilesClient} instance. This requires a
+ * registered {@link FileKind}.
+ */
+ filesClientFactory: FilesClientFactory;
+}
+
+export type FilesStart = FilesSetup;
+
+/**
+ * Bringing files to Kibana
+ */
+export class FilesPlugin implements Plugin {
+ private api: undefined | FilesSetup;
+
+ setup(core: CoreSetup): FilesSetup {
+ this.api = {
+ filesClientFactory: {
+ asScoped(fileKind: string) {
+ return createFilesClient({ fileKind, http: core.http });
+ },
+ },
+ };
+ return this.api;
+ }
+
+ start(core: CoreStart): FilesStart {
+ return this.api!;
+ }
+}
diff --git a/x-pack/plugins/files/public/types.ts b/x-pack/plugins/files/public/types.ts
new file mode 100644
index 0000000000000..a260e1e08a067
--- /dev/null
+++ b/x-pack/plugins/files/public/types.ts
@@ -0,0 +1,84 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type {
+ HttpApiInterfaceEntryDefinition,
+ CreateFileKindHttpEndpoint,
+ DeleteFileKindHttpEndpoint,
+ DownloadFileKindHttpEndpoint,
+ GetByIdFileKindHttpEndpoint,
+ ListFileKindHttpEndpoint,
+ UpdateFileKindHttpEndpoint,
+ UploadFileKindHttpEndpoint,
+} from '../common/api_routes';
+
+/**
+ * @param args - Input to the endpoint which includes body, params and query of the RESTful endpoint.
+ */
+type ClientMethodFrom = (
+ args: E['inputs']['body'] & E['inputs']['params'] & E['inputs']['query']
+) => Promise;
+
+/**
+ * A client that can be used to manage a specific {@link FileKind}.
+ */
+export interface FilesClient {
+ /**
+ * Create a new file object with the provided metadata.
+ *
+ * @param args - create file args
+ */
+ create: ClientMethodFrom;
+ /**
+ * Delete a file object and all associated share and content objects.
+ *
+ * @param args - delete file args
+ */
+ delete: ClientMethodFrom;
+ /**
+ * Get a file object by ID.
+ *
+ * @param args - get file by ID args
+ */
+ getById: ClientMethodFrom;
+ /**
+ * List all file objects, of a given {@link FileKind}.
+ *
+ * @param args - list files args
+ */
+ list: ClientMethodFrom;
+ /**
+ * Update a set of of metadata values of the file object.
+ *
+ * @param args - update file args
+ */
+ update: ClientMethodFrom;
+ /**
+ * Stream the contents of the file to Kibana server for storage.
+ *
+ * @param args - upload file args
+ */
+ upload: ClientMethodFrom;
+ /**
+ * Stream a download of the file object's content.
+ *
+ * @param args - download file args
+ */
+ download: ClientMethodFrom;
+}
+
+/**
+ * A factory for creating a {@link FilesClient}
+ */
+export interface FilesClientFactory {
+ /**
+ * Create a {@link FileClient} for a given {@link FileKind}.
+ *
+ * @param fileKind - The {@link FileKind} to create a client for.
+ */
+ asScoped(fileKind: string): FilesClient;
+}
diff --git a/x-pack/plugins/files/server/audit_events.ts b/x-pack/plugins/files/server/audit_events.ts
new file mode 100644
index 0000000000000..ab5d33a65b764
--- /dev/null
+++ b/x-pack/plugins/files/server/audit_events.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { EcsEventOutcome } from '@kbn/logging';
+import { AuditEvent } from '@kbn/security-plugin/server';
+
+export type AuditAction = 'create' | 'delete';
+
+interface CreateAuditEventArgs {
+ message: string;
+ action: AuditAction;
+ error?: Error;
+ outcome?: EcsEventOutcome;
+}
+
+export function createAuditEvent({
+ message,
+ action,
+ error,
+ outcome,
+}: CreateAuditEventArgs): AuditEvent {
+ return {
+ message,
+ event: {
+ action,
+ outcome: outcome ?? error ? 'failure' : 'success',
+ },
+ error: error && {
+ message: error?.message,
+ },
+ };
+}
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/README.md b/x-pack/plugins/files/server/blob_storage_service/adapters/README.md
new file mode 100644
index 0000000000000..48f9cfc5635c2
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/README.md
@@ -0,0 +1,6 @@
+The intention is that we implement any additional blob stores in this folder.
+
+For ex. Google, AWS and Azure all offer blob storage solutions that we can allow
+our users to take advantage of. By default we store everything in Elasticsearch.
+
+It is not the intention that other plugins interact directly with these adapters.
\ No newline at end of file
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.test.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.test.ts
new file mode 100644
index 0000000000000..56f61e83e47f9
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.test.ts
@@ -0,0 +1,334 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Logger } from '@kbn/core/server';
+import { set } from 'lodash';
+import { Readable } from 'stream';
+import { encode } from 'cbor-x';
+import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mocks';
+import { ContentStream, ContentStreamEncoding, ContentStreamParameters } from './content_stream';
+import type { GetResponse } from '@elastic/elasticsearch/lib/api/types';
+
+describe('ContentStream', () => {
+ let client: ReturnType;
+ let logger: Logger;
+ let stream: ContentStream;
+
+ function toReadable(...args: unknown[]) {
+ return Readable.from([...args.map(encode)]) as unknown as GetResponse;
+ }
+
+ const getContentStream = ({
+ id = 'something',
+ index = 'somewhere',
+ params = {
+ encoding: 'base64' as ContentStreamEncoding,
+ size: 1,
+ } as ContentStreamParameters,
+ } = {}) => {
+ return new ContentStream(client, id, index, logger, params);
+ };
+
+ beforeEach(() => {
+ client = elasticsearchServiceMock.createClusterClient().asInternalUser;
+ logger = loggingSystemMock.createLogger();
+ client.get.mockResponse(toReadable(set({}, '_source.data', Buffer.from('some content'))));
+ });
+
+ describe('read', () => {
+ beforeEach(() => {
+ stream = getContentStream({ params: { size: 1 } });
+ });
+
+ it('should perform a search using index and the document id', async () => {
+ await new Promise((resolve) => stream.once('data', resolve));
+
+ expect(client.get).toHaveBeenCalledTimes(1);
+
+ const [[request]] = client.get.mock.calls;
+ expect(request).toHaveProperty('index', 'somewhere');
+ expect(request).toHaveProperty('id', 'something.0');
+ });
+
+ it('should read the document contents', async () => {
+ const data = await new Promise((resolve) => stream.once('data', resolve));
+ expect(data).toEqual(Buffer.from('some content'));
+ });
+
+ it('should be an empty stream on empty response', async () => {
+ client.get.mockResponseOnce(toReadable());
+ const onData = jest.fn();
+
+ stream.on('data', onData);
+ await new Promise((resolve) => stream.once('end', resolve));
+
+ expect(onData).not.toHaveBeenCalled();
+ });
+
+ it('should emit an error event', async () => {
+ client.get.mockRejectedValueOnce('some error');
+
+ stream.read();
+ const error = await new Promise((resolve) => stream.once('error', resolve));
+
+ expect(error).toBe('some error');
+ });
+
+ it('should decode base64 encoded content', async () => {
+ client.get.mockResponseOnce(
+ toReadable(set({}, '_source.data', Buffer.from('encoded content')))
+ );
+ const data = await new Promise((resolve) => stream.once('data', resolve));
+
+ expect(data).toEqual(Buffer.from('encoded content'));
+ });
+
+ it('should compound content from multiple chunks', async () => {
+ const [one, two, three] = ['12', '34', '56'].map(Buffer.from);
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', one)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', two)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', three)));
+
+ stream = getContentStream({
+ params: { size: 6 },
+ });
+
+ let data = '';
+ for await (const chunk of stream) {
+ data += chunk;
+ }
+
+ expect(data).toEqual('123456');
+ expect(client.get).toHaveBeenCalledTimes(3);
+
+ const [[request1], [request2], [request3]] = client.get.mock.calls;
+
+ expect(request1).toHaveProperty('index', 'somewhere');
+ expect(request1).toHaveProperty('id', 'something.0');
+ expect(request2).toHaveProperty('index', 'somewhere');
+ expect(request2).toHaveProperty('id', 'something.1');
+ expect(request3).toHaveProperty('index', 'somewhere');
+ expect(request3).toHaveProperty('id', 'something.2');
+ });
+
+ it('should stop reading on empty chunk', async () => {
+ const [one, two, three] = ['12', '34', ''].map(Buffer.from);
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', one)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', two)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', three)));
+ stream = getContentStream({ params: { size: 12 } });
+ let data = '';
+ for await (const chunk of stream) {
+ data += chunk;
+ }
+
+ expect(data).toEqual('1234');
+ expect(client.get).toHaveBeenCalledTimes(3);
+ });
+
+ it('should read while chunks are present when there is no size', async () => {
+ const [one, two] = ['12', '34'].map(Buffer.from);
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', one)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', two)));
+ client.get.mockResponseOnce(toReadable({}));
+ stream = getContentStream({ params: { size: undefined } });
+ let data = '';
+ for await (const chunk of stream) {
+ data += chunk;
+ }
+
+ expect(data).toEqual('1234');
+ expect(client.get).toHaveBeenCalledTimes(3);
+ });
+
+ it('should decode every chunk separately', async () => {
+ const [one, two, three, four] = ['12', '34', '56', ''].map(Buffer.from);
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', one)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', two)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', three)));
+ client.get.mockResponseOnce(toReadable(set({}, '_source.data', four)));
+ stream = getContentStream({ params: { size: 12 } });
+ let data = '';
+ for await (const chunk of stream) {
+ data += chunk;
+ }
+
+ expect(data).toEqual('123456');
+ });
+ });
+
+ describe('write', () => {
+ beforeEach(() => {
+ stream = getContentStream({ params: { size: 1 } });
+ });
+ it('should not send a request until stream is closed', () => {
+ stream.write('something');
+
+ expect(client.update).not.toHaveBeenCalled();
+ });
+
+ it('should provide a document ID after writing to a destination', async () => {
+ stream = new ContentStream(client, undefined, 'somewhere', logger);
+ expect(stream.getContentReferenceId()).toBe(undefined);
+ stream.end('some data');
+ await new Promise((resolve) => stream.once('finish', resolve));
+ expect(stream.getContentReferenceId()).toEqual(expect.any(String));
+ });
+
+ it('should send the contents when stream ends', async () => {
+ stream.write('123');
+ stream.write('456');
+ stream.end();
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(client.index).toHaveBeenCalledTimes(1);
+
+ const [[request]] = client.index.mock.calls;
+
+ expect(request).toHaveProperty('id', 'something.0');
+ expect(request).toHaveProperty('index', 'somewhere');
+ expect(request).toHaveProperty(
+ 'document',
+ encode({ data: Buffer.from('123456'), bid: 'something', last: true })
+ );
+ });
+
+ it('should update a number of written bytes', async () => {
+ stream.write('123');
+ stream.write('456');
+ stream.end();
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(stream.bytesWritten).toBe(6);
+ });
+
+ it('should emit an error event', async () => {
+ client.index.mockRejectedValueOnce('some error');
+
+ stream.end('data');
+ const error = await new Promise((resolve) => stream.once('error', resolve));
+
+ expect(error).toBe('some error');
+ });
+
+ it('should remove all previous chunks before writing', async () => {
+ stream.end('12345');
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(client.deleteByQuery).toHaveBeenCalledTimes(1);
+
+ const [[request]] = client.deleteByQuery.mock.calls;
+
+ expect(request).toHaveProperty('index', 'somewhere');
+ expect(request).toHaveProperty('query.bool.must.match.bid', 'something');
+ });
+
+ it('should split data into chunks', async () => {
+ stream = getContentStream({ params: { maxChunkSize: '3B' } });
+ stream.end('123456789');
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(client.index).toHaveBeenCalledTimes(3);
+ expect(client.index).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({
+ document: encode({ data: Buffer.from('123'), bid: 'something' }),
+ id: 'something.0',
+ index: 'somewhere',
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ expect(client.index).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining({
+ id: 'something.1',
+ index: 'somewhere',
+ document: encode({ data: Buffer.from('456'), bid: 'something' }),
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ expect(client.index).toHaveBeenNthCalledWith(
+ 3,
+ expect.objectContaining({
+ id: 'something.2',
+ index: 'somewhere',
+ document: encode({ data: Buffer.from('789'), bid: 'something', last: true }),
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ });
+
+ it('should encode every chunk separately', async () => {
+ stream = getContentStream({ params: { maxChunkSize: '3B' } });
+ stream.end('12345678');
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(client.index).toHaveBeenCalledTimes(3);
+ expect(client.index).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({
+ id: 'something.0',
+ index: 'somewhere',
+ document: encode({
+ data: Buffer.from('123'),
+ bid: 'something',
+ }),
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ expect(client.index).toHaveBeenNthCalledWith(
+ 2,
+ expect.objectContaining({
+ id: 'something.1',
+ index: 'somewhere',
+ document: encode({
+ data: Buffer.from('456'),
+ bid: 'something',
+ }),
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ expect(client.index).toHaveBeenNthCalledWith(
+ 3,
+ expect.objectContaining({
+ id: 'something.2',
+ index: 'somewhere',
+ document: encode({
+ data: Buffer.from('78'),
+ bid: 'something',
+ last: true,
+ }),
+ }),
+ expect.objectContaining({
+ headers: { accept: 'application/json', 'content-type': 'application/cbor' },
+ })
+ );
+ });
+
+ it('should clear the job contents on writing empty data', async () => {
+ stream.end();
+ await new Promise((resolve) => stream.once('finish', resolve));
+
+ expect(client.deleteByQuery).toHaveBeenCalledTimes(1);
+ expect(client.index).toHaveBeenCalledTimes(0);
+
+ const [[deleteRequest]] = client.deleteByQuery.mock.calls;
+
+ expect(deleteRequest).toHaveProperty('query.bool.must.match.bid', 'something');
+ });
+ });
+});
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.ts
new file mode 100644
index 0000000000000..746c66798b5e8
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/content_stream.ts
@@ -0,0 +1,382 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import cuid from 'cuid';
+import * as cborx from 'cbor-x';
+import { errors as esErrors } from '@elastic/elasticsearch';
+import type { ElasticsearchClient, Logger } from '@kbn/core/server';
+import { ByteSizeValue } from '@kbn/config-schema';
+import { defaults } from 'lodash';
+import { Duplex, Writable, Readable } from 'stream';
+
+import type { FileChunkDocument } from '../mappings';
+
+type Callback = (error?: Error) => void;
+
+export type ContentStreamEncoding = 'base64' | 'raw';
+
+interface IndexRequestParams {
+ data: Buffer;
+ id: string;
+ index: string;
+ bid: string;
+}
+
+export interface ContentStreamParameters {
+ /**
+ * The maximum size allowed per chunk.
+ *
+ * @default 4mb
+ */
+ maxChunkSize?: string;
+ /**
+ * The file size in bytes. This can be used to optimize downloading.
+ */
+ size?: number;
+}
+
+export class ContentStream extends Duplex {
+ private buffers: Buffer[] = [];
+ private bytesBuffered = 0;
+
+ private bytesRead = 0;
+ private chunksRead = 0;
+ private chunksWritten = 0;
+ private maxChunkSize?: number;
+ private parameters: Required;
+
+ /**
+ * The number of bytes written so far.
+ * Does not include data that is still queued for writing.
+ */
+ bytesWritten = 0;
+
+ constructor(
+ private readonly client: ElasticsearchClient,
+ private id: undefined | string,
+ private readonly index: string,
+ private readonly logger: Logger,
+ parameters: ContentStreamParameters = {}
+ ) {
+ super();
+ this.parameters = defaults(parameters, {
+ encoding: 'base64',
+ size: -1,
+ maxChunkSize: '4mb',
+ });
+ }
+
+ private getMaxContentSize(): number {
+ return ByteSizeValue.parse(this.parameters.maxChunkSize).getValueInBytes();
+ }
+
+ private getMaxChunkSize() {
+ if (!this.maxChunkSize) {
+ this.maxChunkSize = this.getMaxContentSize();
+ this.logger.debug(`Chunk size is ${this.maxChunkSize} bytes.`);
+ }
+
+ return this.maxChunkSize;
+ }
+
+ private async readChunk(): Promise<[data: null | Buffer, last?: boolean]> {
+ if (!this.id) {
+ throw new Error('No document ID provided. Cannot read chunk.');
+ }
+ const id = this.getChunkId(this.chunksRead);
+
+ this.logger.debug(`Reading chunk #${this.chunksRead}.`);
+
+ try {
+ const stream = await this.client.get(
+ {
+ id,
+ index: this.index,
+ _source_includes: ['data', 'last'],
+ },
+ {
+ asStream: true, // This tells the ES client to not process the response body in any way.
+ headers: { accept: 'application/cbor' },
+ }
+ );
+
+ const chunks: Buffer[] = [];
+ for await (const chunk of stream as unknown as Readable) {
+ chunks.push(chunk);
+ }
+ const buffer = Buffer.concat(chunks);
+ const source: undefined | FileChunkDocument = buffer.byteLength
+ ? cborx.decode(Buffer.concat(chunks))?._source
+ : undefined;
+
+ const dataBuffer = source?.data as unknown as Buffer;
+ return [dataBuffer?.byteLength ? dataBuffer : null, source?.last];
+ } catch (e) {
+ if (e instanceof esErrors.ResponseError && e.statusCode === 404) {
+ const readingHeadChunk = this.chunksRead <= 0;
+ if (this.isSizeUnknown() && !readingHeadChunk) {
+ // Assume there is no more content to read.
+ return [null];
+ }
+ if (readingHeadChunk) {
+ this.logger.error(`File not found (id: ${this.getHeadChunkId()}).`);
+ }
+ }
+ throw e;
+ }
+ }
+
+ private isSizeUnknown(): boolean {
+ return this.parameters.size < 0;
+ }
+
+ private isRead() {
+ const { size } = this.parameters;
+ if (size > 0) {
+ return this.bytesRead >= size;
+ }
+ return false;
+ }
+
+ _read() {
+ this.readChunk()
+ .then(([buffer, last]) => {
+ if (!buffer) {
+ this.logger.debug(`Chunk is empty.`);
+ this.push(null);
+ return;
+ }
+
+ this.push(buffer);
+ this.chunksRead++;
+ this.bytesRead += buffer.byteLength;
+
+ if (this.isRead() || last) {
+ this.logger.debug(`Read ${this.bytesRead} of ${this.parameters.size} bytes.`);
+ this.push(null);
+ }
+ })
+ .catch((err) => this.destroy(err));
+ }
+
+ private async removeChunks() {
+ const bid = this.getId();
+ this.logger.debug(`Clearing existing chunks for ${bid}`);
+ await this.client.deleteByQuery({
+ index: this.index,
+ ignore_unavailable: true,
+ query: {
+ bool: {
+ must: { match: { bid } },
+ },
+ },
+ });
+ }
+
+ private getId(): string {
+ if (!this.id) {
+ this.id = cuid();
+ }
+ return this.id;
+ }
+
+ private getHeadChunkId() {
+ return `${this.getId()}.0`;
+ }
+
+ private getChunkId(chunkNumber = 0) {
+ return chunkNumber === 0 ? this.getHeadChunkId() : `${this.getId()}.${chunkNumber}`;
+ }
+
+ private async indexChunk({ bid, data, id, index }: IndexRequestParams, last?: true) {
+ await this.client.index(
+ {
+ id,
+ index,
+ document: cborx.encode(
+ last
+ ? {
+ data,
+ bid,
+ last,
+ }
+ : { data, bid }
+ ),
+ },
+ {
+ headers: {
+ 'content-type': 'application/cbor',
+ accept: 'application/json',
+ },
+ }
+ );
+ }
+
+ /**
+ * Holds a reference to the last written chunk without actually writing it to ES.
+ *
+ * This enables us to reliably determine what the real last chunk is at the cost
+ * of holding, at most, 2 full chunks in memory.
+ */
+ private indexRequestBuffer: undefined | IndexRequestParams;
+ private async writeChunk(data: Buffer) {
+ const chunkId = this.getChunkId(this.chunksWritten);
+
+ if (!this.indexRequestBuffer) {
+ this.indexRequestBuffer = {
+ id: chunkId,
+ index: this.index,
+ data,
+ bid: this.getId(),
+ };
+ return;
+ }
+
+ this.logger.debug(`Writing chunk with ID "${this.indexRequestBuffer.id}".`);
+ await this.indexChunk(this.indexRequestBuffer);
+ // Hold a reference to the next buffer now that we indexed the previous one.
+ this.indexRequestBuffer = {
+ id: chunkId,
+ index: this.index,
+ data,
+ bid: this.getId(),
+ };
+ }
+
+ private async finalizeLastChunk() {
+ if (!this.indexRequestBuffer) {
+ return;
+ }
+ this.logger.debug(`Writing last chunk with id "${this.indexRequestBuffer.id}".`);
+ await this.indexChunk(this.indexRequestBuffer, true);
+ this.indexRequestBuffer = undefined;
+ }
+
+ private async flush(size = this.bytesBuffered) {
+ const buffersToFlush: Buffer[] = [];
+ let bytesToFlush = 0;
+
+ /*
+ Loop over each buffer, keeping track of how many bytes we have added
+ to the array of buffers to be flushed. The array of buffers to be flushed
+ contains buffers by reference, not copies. This avoids putting pressure on
+ the CPU for copying buffers or for gc activity. Please profile performance
+ with a large byte configuration and a large number of records (900k+)
+ before changing this code.
+ */
+ while (this.buffers.length) {
+ const remainder = size - bytesToFlush;
+ if (remainder <= 0) {
+ break;
+ }
+ const buffer = this.buffers.shift()!;
+ const chunkedBuffer = buffer.slice(0, remainder);
+ buffersToFlush.push(chunkedBuffer);
+ bytesToFlush += chunkedBuffer.byteLength;
+
+ if (buffer.byteLength > remainder) {
+ this.buffers.unshift(buffer.slice(remainder));
+ }
+ }
+
+ // We call Buffer.concat with the fewest number of buffers possible
+ const chunk = Buffer.concat(buffersToFlush);
+
+ if (!this.chunksWritten) {
+ await this.removeChunks();
+ }
+ if (chunk.byteLength) {
+ await this.writeChunk(chunk);
+ this.chunksWritten++;
+ }
+
+ this.bytesWritten += chunk.byteLength;
+ this.bytesBuffered -= bytesToFlush;
+ }
+
+ private async flushAllFullChunks() {
+ const maxChunkSize = this.getMaxChunkSize();
+
+ while (this.bytesBuffered >= maxChunkSize && this.buffers.length) {
+ await this.flush(maxChunkSize);
+ }
+ }
+
+ _write(chunk: Buffer | string, encoding: BufferEncoding, callback: Callback) {
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);
+ this.bytesBuffered += buffer.byteLength;
+ this.buffers.push(buffer);
+
+ this.flushAllFullChunks()
+ .then(() => callback())
+ .catch(callback);
+ }
+
+ _final(callback: Callback) {
+ this.flush()
+ .then(() => this.finalizeLastChunk())
+ .then(() => callback())
+ .catch(callback);
+ }
+
+ /**
+ * This ID can be used to retrieve or delete all of the file chunks but does
+ * not necessarily correspond to an existing document.
+ *
+ * @note do not use this ID with anything other than a {@link ContentStream}
+ * compatible implementation for reading blob-like structures from ES.
+ *
+ * @note When creating a new blob, this value may be undefined until the first
+ * chunk is written.
+ */
+ public getContentReferenceId(): undefined | string {
+ return this.id;
+ }
+
+ public getBytesWritten(): number {
+ return this.bytesWritten;
+ }
+}
+
+export interface ContentStreamArgs {
+ client: ElasticsearchClient;
+ /**
+ * Provide base ID from which all chunks derive their IDs.
+ */
+ id?: string;
+
+ /**
+ * The Elasticsearch index name to read from or write to.
+ */
+ index: string;
+
+ /**
+ * Known size of the file we are reading. This value can be used to optimize
+ * reading of the file.
+ */
+ logger: Logger;
+ parameters?: ContentStreamParameters;
+}
+
+function getContentStream({ client, id, index, logger, parameters }: ContentStreamArgs) {
+ return new ContentStream(client, id, index, logger, parameters);
+}
+
+export type WritableContentStream = Writable &
+ Pick;
+
+export function getWritableContentStream(args: ContentStreamArgs): WritableContentStream {
+ return getContentStream(args);
+}
+
+export type ReadableContentStream = Readable;
+
+export function getReadableContentStream(
+ args: Omit & { id: string }
+): ReadableContentStream {
+ return getContentStream(args);
+}
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/index.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/index.ts
new file mode 100644
index 0000000000000..a31e0c8b672dc
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/content_stream/index.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export {
+ ContentStream,
+ getReadableContentStream,
+ getWritableContentStream,
+} from './content_stream';
+
+export type {
+ ContentStreamArgs,
+ ContentStreamEncoding,
+ ContentStreamParameters,
+ ReadableContentStream,
+ WritableContentStream,
+} from './content_stream';
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/es.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/es.ts
new file mode 100644
index 0000000000000..5074ab12bdfc7
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/es.ts
@@ -0,0 +1,139 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import assert from 'assert';
+import { once } from 'lodash';
+import { errors } from '@elastic/elasticsearch';
+import type { ElasticsearchClient, Logger } from '@kbn/core/server';
+import { Readable, Transform } from 'stream';
+import { pipeline } from 'stream/promises';
+import { promisify } from 'util';
+import type { BlobStorageClient } from '../../types';
+import type { ReadableContentStream } from './content_stream';
+import { getReadableContentStream, getWritableContentStream } from './content_stream';
+import { mappings } from './mappings';
+
+/**
+ * Export this value for convenience to be used in tests. Do not use outside of
+ * this adapter.
+ * @internal
+ */
+export const BLOB_STORAGE_SYSTEM_INDEX_NAME = '.kibana_blob_storage';
+
+export const MAX_BLOB_STORE_SIZE_BYTES = 50 * 1024 * 1024 * 1024; // 50 GiB
+
+export class ElasticsearchBlobStorageClient implements BlobStorageClient {
+ constructor(
+ private readonly esClient: ElasticsearchClient,
+ private readonly index: string = BLOB_STORAGE_SYSTEM_INDEX_NAME,
+ private readonly chunkSize: undefined | string,
+ private readonly logger: Logger
+ ) {
+ assert(
+ this.index.startsWith('.kibana'),
+ `Elasticsearch blob store index name must start with ".kibana", got ${this.index}.`
+ );
+ }
+
+ /**
+ * @note
+ * There is a known issue where calling this function simultaneously can result
+ * in a race condition where one of the calls will fail because the index is already
+ * being created.
+ *
+ * This is only an issue for the very first time the index is being created.
+ */
+ private createIndexIfNotExists = once(async (): Promise => {
+ try {
+ const index = this.index;
+ if (await this.esClient.indices.exists({ index })) {
+ this.logger.debug(`${index} already exists.`);
+ return;
+ }
+
+ this.logger.info(`Creating ${index} for Elasticsearch blob store.`);
+
+ await this.esClient.indices.create({
+ index,
+ body: {
+ settings: {
+ number_of_shards: 1,
+ auto_expand_replicas: '0-1',
+ },
+ mappings,
+ },
+ });
+ } catch (e) {
+ if (e instanceof errors.ResponseError && e.statusCode === 400) {
+ this.logger.warn('Unable to create blob storage index, it may have been created already.');
+ }
+ // best effort
+ }
+ });
+
+ public async upload(
+ src: Readable,
+ { transforms, id }: { transforms?: Transform[]; id?: string } = {}
+ ): Promise<{ id: string; size: number }> {
+ await this.createIndexIfNotExists();
+
+ try {
+ const dest = getWritableContentStream({
+ id,
+ client: this.esClient,
+ index: this.index,
+ logger: this.logger.get('content-stream-upload'),
+ parameters: {
+ maxChunkSize: this.chunkSize,
+ },
+ });
+ await pipeline.apply(null, [src, ...(transforms ?? []), dest] as unknown as Parameters<
+ typeof pipeline
+ >);
+
+ return {
+ id: dest.getContentReferenceId()!,
+ size: dest.getBytesWritten(),
+ };
+ } catch (e) {
+ this.logger.error(`Could not write chunks to Elasticsearch: ${e}`);
+ throw e;
+ }
+ }
+
+ private getReadableContentStream(id: string, size?: number): ReadableContentStream {
+ return getReadableContentStream({
+ id,
+ client: this.esClient,
+ index: this.index,
+ logger: this.logger.get('content-stream-download'),
+ parameters: {
+ size,
+ },
+ });
+ }
+
+ public async download({ id, size }: { id: string; size?: number }): Promise {
+ return this.getReadableContentStream(id, size);
+ }
+
+ public async delete(id: string): Promise {
+ try {
+ const dest = getWritableContentStream({
+ id,
+ client: this.esClient,
+ index: this.index,
+ logger: this.logger.get('content-stream-delete'),
+ });
+ /** @note Overwriting existing content with an empty buffer to remove all the chunks. */
+ await promisify(dest.end.bind(dest, '', 'utf8'))();
+ } catch (e) {
+ this.logger.error(`Could not delete file: ${e}`);
+ throw e;
+ }
+ }
+}
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/index.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/index.ts
new file mode 100644
index 0000000000000..75ac82acb66df
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { ElasticsearchBlobStorageClient, MAX_BLOB_STORE_SIZE_BYTES } from './es';
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts
new file mode 100644
index 0000000000000..b947c980164fc
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/integration_tests/es.test.ts
@@ -0,0 +1,162 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import sinon from 'sinon';
+import { ElasticsearchClient } from '@kbn/core/server';
+import { Readable } from 'stream';
+import {
+ createTestServers,
+ TestElasticsearchUtils,
+ TestKibanaUtils,
+} from '@kbn/core/test_helpers/kbn_server';
+
+import { ElasticsearchBlobStorageClient, BLOB_STORAGE_SYSTEM_INDEX_NAME } from '../es';
+
+describe('Elasticsearch blob storage', () => {
+ let manageES: TestElasticsearchUtils;
+ let manageKbn: TestKibanaUtils;
+ let esBlobStorage: ElasticsearchBlobStorageClient;
+ let esClient: ElasticsearchClient;
+ const sandbox = sinon.createSandbox();
+
+ beforeAll(async () => {
+ const { startES, startKibana } = createTestServers({ adjustTimeout: jest.setTimeout });
+ manageES = await startES();
+ manageKbn = await startKibana();
+ esClient = manageKbn.coreStart.elasticsearch.client.asInternalUser;
+ });
+
+ afterAll(async () => {
+ await manageKbn.root.shutdown();
+ await manageKbn.stop();
+ await manageES.stop();
+ });
+
+ const createEsBlobStorage = ({ chunkSize }: { chunkSize?: string } = {}) =>
+ new ElasticsearchBlobStorageClient(
+ esClient,
+ undefined,
+ chunkSize,
+ manageKbn.root.logger.get('es-blob-test')
+ );
+
+ beforeEach(() => {
+ esBlobStorage = createEsBlobStorage();
+ sandbox.spy(esClient, 'get');
+ });
+
+ afterEach(async () => {
+ await esClient.indices.delete({ index: BLOB_STORAGE_SYSTEM_INDEX_NAME });
+ sandbox.restore();
+ });
+
+ it('sets up a new blob storage index after first write', async () => {
+ expect(await esClient.indices.exists({ index: BLOB_STORAGE_SYSTEM_INDEX_NAME })).toBe(false);
+ await esBlobStorage.upload(Readable.from(['upload this']));
+ expect(await esClient.indices.exists({ index: BLOB_STORAGE_SYSTEM_INDEX_NAME })).toBe(true);
+ });
+
+ it('uploads and retrieves file content of known size', async () => {
+ const { id, size } = await esBlobStorage.upload(Readable.from(['upload this']));
+ const rs = await esBlobStorage.download({ id, size });
+ const chunks: string[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(chunks.join('')).toBe('upload this');
+ expect((esClient.get as sinon.SinonSpy).calledOnce).toBe(true);
+ });
+
+ /**
+ * Test a case where, if, for whatever reason, the file size is unknown we should
+ * still be able to download the file.
+ */
+ it('uploads and retrieves file content of unknown size', async () => {
+ const { id } = await esBlobStorage.upload(Readable.from(['upload this']));
+ const rs = await esBlobStorage.download({ id });
+ const chunks: string[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(chunks.join('')).toBe('upload this');
+ // Called once because we should have found 'last: true'
+ expect((esClient.get as sinon.SinonSpy).calledOnce).toBe(true);
+ expect((esClient.get as sinon.SinonSpy).args[0]).toEqual([
+ {
+ id: id + '.0',
+ index: BLOB_STORAGE_SYSTEM_INDEX_NAME,
+ _source_includes: ['data', 'last'],
+ },
+ {
+ headers: { accept: 'application/cbor' },
+ asStream: true,
+ },
+ ]);
+ });
+
+ it('uploads and downloads a file of many chunks', async () => {
+ const fileString = Buffer.alloc(36 * 1028, 'a');
+ esBlobStorage = createEsBlobStorage({ chunkSize: '1024B' });
+ const { id } = await esBlobStorage.upload(Readable.from([fileString]));
+ expect(await getAllDocCount()).toMatchObject({ count: 37 });
+ const rs = await esBlobStorage.download({ id });
+ const chunks: string[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(chunks.join('')).toBe(fileString.toString('utf-8'));
+ });
+
+ const getAllDocCount = async () => {
+ await esClient.indices.refresh({ index: BLOB_STORAGE_SYSTEM_INDEX_NAME });
+ return esClient.count({
+ index: BLOB_STORAGE_SYSTEM_INDEX_NAME,
+ query: { match_all: {} },
+ });
+ };
+
+ it('uploads and removes file content', async () => {
+ const { id } = await esBlobStorage.upload(Readable.from(['upload this']));
+ expect(await getAllDocCount()).toMatchObject({ count: 1 });
+ await esBlobStorage.delete(id);
+ expect(await getAllDocCount()).toMatchObject({ count: 0 });
+ });
+
+ it('chunks files and then deletes all chunks when cleaning up', async () => {
+ const oneMiB = 1024 * 1024;
+ const fileString = Buffer.alloc(31 * oneMiB, 'a');
+ const fileString2 = Buffer.alloc(8 * oneMiB, 'b');
+
+ esBlobStorage = createEsBlobStorage();
+ const { id } = await esBlobStorage.upload(Readable.from([fileString]));
+ const { id: id2 } = await esBlobStorage.upload(Readable.from([fileString2]));
+ expect(await getAllDocCount()).toMatchObject({ count: 10 });
+ await esBlobStorage.delete(id);
+ expect(await getAllDocCount()).toMatchObject({ count: 2 });
+ // Now we check that the other file is still intact
+ const rs = await esBlobStorage.download({ id: id2 });
+ const chunks: Buffer[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ const resultString = chunks.join('');
+ expect(resultString).toBe(fileString2.toString('utf-8'));
+ });
+
+ it('stores chunks at exactly max chunk size', async () => {
+ esBlobStorage = createEsBlobStorage({ chunkSize: '1024B' });
+ const fileBuffer = Buffer.alloc(2048, 'a');
+ const { id } = await esBlobStorage.upload(Readable.from([fileBuffer]));
+ expect(await getAllDocCount()).toMatchObject({ count: 2 });
+ const rs = await esBlobStorage.download({ id });
+ const chunks: Buffer[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(chunks.join('')).toEqual(fileBuffer.toString('utf-8'));
+ });
+});
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/es/mappings.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/es/mappings.ts
new file mode 100644
index 0000000000000..dbcd57a06ba18
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/es/mappings.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type {
+ MappingTypeMapping,
+ MappingProperty,
+} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+
+/**
+ * These are the fields we expect to find a given document acting as a file chunk.
+ *
+ * @note not all fields are used by this adapter but this represents the standard
+ * shape for any consumers of BlobStorage in ES.
+ */
+export interface FileChunkDocument {
+ /**
+ * Data contents. Could be part of a file (chunk) or the entire file.
+ */
+ data: string;
+
+ /**
+ * Blob ID field that tags a set of blobs as belonging to the same file.
+ */
+ bid: string;
+
+ /**
+ * Whether this is the last chunk in a sequence.
+ */
+ last?: boolean;
+}
+
+export const mappings: MappingTypeMapping = {
+ dynamic: false,
+ properties: {
+ data: { type: 'binary' }, // Binary fields are automatically marked as not searchable by ES
+ bid: { type: 'keyword', index: false },
+ last: { type: 'boolean', index: false },
+ } as Record, // Ensure that our ES types and TS types stay somewhat in sync
+} as const;
diff --git a/x-pack/plugins/files/server/blob_storage_service/adapters/index.ts b/x-pack/plugins/files/server/blob_storage_service/adapters/index.ts
new file mode 100644
index 0000000000000..75ac82acb66df
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/adapters/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { ElasticsearchBlobStorageClient, MAX_BLOB_STORE_SIZE_BYTES } from './es';
diff --git a/x-pack/plugins/files/server/blob_storage_service/blob_storage_service.ts b/x-pack/plugins/files/server/blob_storage_service/blob_storage_service.ts
new file mode 100644
index 0000000000000..0bc1c632e2c32
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/blob_storage_service.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { ElasticsearchClient, Logger } from '@kbn/core/server';
+import { BlobStorageSettings, ES_FIXED_SIZE_INDEX_BLOB_STORE } from '../../common';
+import { BlobStorageClient } from './types';
+import { ElasticsearchBlobStorageClient, MAX_BLOB_STORE_SIZE_BYTES } from './adapters';
+
+interface ElasticsearchBlobStorageSettings {
+ index?: string;
+ chunkSize?: string;
+}
+
+export class BlobStorageService {
+ constructor(private readonly esClient: ElasticsearchClient, private readonly logger: Logger) {}
+
+ private createESBlobStorage({
+ index,
+ chunkSize,
+ }: ElasticsearchBlobStorageSettings): BlobStorageClient {
+ return new ElasticsearchBlobStorageClient(
+ this.esClient,
+ index,
+ chunkSize,
+ this.logger.get('elasticsearch-blob-storage')
+ );
+ }
+
+ public createBlobStorageClient(args?: BlobStorageSettings): BlobStorageClient {
+ return this.createESBlobStorage({ ...args?.esFixedSizeIndex });
+ }
+
+ public getStaticBlobStorageSettings() {
+ return {
+ [ES_FIXED_SIZE_INDEX_BLOB_STORE]: {
+ capacity: MAX_BLOB_STORE_SIZE_BYTES,
+ },
+ };
+ }
+}
diff --git a/x-pack/plugins/files/server/blob_storage_service/index.ts b/x-pack/plugins/files/server/blob_storage_service/index.ts
new file mode 100644
index 0000000000000..fd8d4e190c092
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/index.ts
@@ -0,0 +1,10 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { BlobStorageService } from './blob_storage_service';
+export { ElasticsearchBlobStorageClient } from './adapters';
+export type { BlobStorageClient, UploadOptions } from './types';
diff --git a/x-pack/plugins/files/server/blob_storage_service/types.ts b/x-pack/plugins/files/server/blob_storage_service/types.ts
new file mode 100644
index 0000000000000..6a5c40708a973
--- /dev/null
+++ b/x-pack/plugins/files/server/blob_storage_service/types.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { JsonValue } from '@kbn/utility-types';
+import type { Readable, Transform } from 'stream';
+
+export type BlobAttribute = [key: string, value: JsonValue];
+
+export interface UploadOptions {
+ /**
+ * Optionally provide any transforms to run on the readable source stream
+ * as it is being uploaded.
+ */
+ transforms?: Transform[];
+
+ /**
+ * The ID to use to derive blob IDs.
+ *
+ * If "mycoolid" is provided. The blob IDs will look like:
+ * "mycoolid.0"
+ * "mycoolid.1"
+ * "mycoolid.2"
+ *
+ * And so on.
+ */
+ id?: string;
+}
+
+/**
+ * An interface that must be implemented by any blob storage adapter.
+ *
+ * @note
+ * The blob storage target must be fully managed by Kibana through this interface
+ * to avoid corrupting stored data.
+ *
+ * @note
+ * File IDs are stored in Kibana Saved Objects as references to a file.
+ *
+ * @internal
+ */
+export interface BlobStorageClient {
+ /**
+ * Upload a new file.
+ *
+ * Generates a random file ID and returns it upon successfully uploading a
+ * file. The file size can be used when downloading the file later.
+ *
+ * @param content - The readable stream to upload.
+ * @param opts - Optional options to use when uploading the file.
+ */
+ upload(content: Readable, opts?: UploadOptions): Promise<{ id: string; size: number }>;
+
+ /**
+ * Download a file.
+ *
+ * Given an ID, and optional file size, retrieve the file contents as a readable
+ * stream.
+ *
+ * @param args - Arguments to download a file
+ */
+ download(args: { id: string; size?: number }): Promise;
+
+ /**
+ * Delete a file given a unique ID.
+ *
+ * @param id - The ID of the file to delete.
+ */
+ delete(id: string): Promise;
+}
diff --git a/x-pack/plugins/files/server/file/errors.ts b/x-pack/plugins/files/server/file/errors.ts
new file mode 100644
index 0000000000000..d0d0eef84c052
--- /dev/null
+++ b/x-pack/plugins/files/server/file/errors.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/* eslint-disable max-classes-per-file */
+
+class FileError extends Error {
+ constructor(message?: string) {
+ super(message);
+ Error.captureStackTrace(this);
+ }
+}
+
+export class ContentAlreadyUploadedError extends FileError {}
+export class NoDownloadAvailableError extends FileError {}
+export class UploadInProgressError extends FileError {}
+export class AlreadyDeletedError extends FileError {}
diff --git a/x-pack/plugins/files/server/file/file.test.ts b/x-pack/plugins/files/server/file/file.test.ts
new file mode 100644
index 0000000000000..ebb1efe32422c
--- /dev/null
+++ b/x-pack/plugins/files/server/file/file.test.ts
@@ -0,0 +1,85 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { ElasticsearchClient, ISavedObjectsRepository } from '@kbn/core/server';
+import { createSandbox } from 'sinon';
+import {
+ elasticsearchServiceMock,
+ loggingSystemMock,
+ savedObjectsServiceMock,
+ httpServiceMock,
+} from '@kbn/core/server/mocks';
+import { Readable } from 'stream';
+import { promisify } from 'util';
+
+const setImmediate = promisify(global.setImmediate);
+
+import { BlobStorageService } from '../blob_storage_service';
+import { InternalFileService } from '../file_service/internal_file_service';
+import {
+ FileKindsRegistryImpl,
+ getFileKindsRegistry,
+ setFileKindsRegistry,
+} from '../file_kinds_registry';
+import { InternalFileShareService } from '../file_share_service';
+import { FileMetadataClient } from '../file_client';
+import { SavedObjectsFileMetadataClient } from '../file_client/file_metadata_client/adapters/saved_objects';
+
+describe('File', () => {
+ let esClient: ElasticsearchClient;
+ let fileService: InternalFileService;
+ let blobStorageService: BlobStorageService;
+ let fileShareService: InternalFileShareService;
+ let soClient: ISavedObjectsRepository;
+ let fileMetadaClient: FileMetadataClient;
+
+ const sandbox = createSandbox();
+ const fileKind = 'fileKind';
+
+ beforeAll(() => {
+ setFileKindsRegistry(new FileKindsRegistryImpl(httpServiceMock.createRouter()));
+ getFileKindsRegistry().register({ http: {}, id: fileKind });
+ });
+
+ beforeEach(() => {
+ const logger = loggingSystemMock.createLogger();
+ esClient = elasticsearchServiceMock.createInternalClient();
+ soClient = savedObjectsServiceMock.createStartContract().createInternalRepository();
+ fileMetadaClient = new SavedObjectsFileMetadataClient('test', soClient, logger);
+ blobStorageService = new BlobStorageService(esClient, logger);
+ fileShareService = new InternalFileShareService(soClient);
+ fileService = new InternalFileService(
+ fileMetadaClient,
+ blobStorageService,
+ fileShareService,
+ undefined,
+ getFileKindsRegistry(),
+ logger
+ );
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ sandbox.restore();
+ });
+
+ it('deletes file content when an upload fails', async () => {
+ const createBlobSpy = sandbox.spy(blobStorageService, 'createBlobStorageClient');
+
+ (esClient.index as jest.Mock).mockRejectedValue(new Error('test'));
+ const fileSO = { attributes: { Status: 'AWAITING_UPLOAD' } };
+ (soClient.create as jest.Mock).mockResolvedValue(fileSO);
+ (soClient.update as jest.Mock).mockResolvedValue(fileSO);
+
+ const file = await fileService.createFile({ name: 'test', fileKind });
+ const [{ returnValue: blobStore }] = createBlobSpy.getCalls();
+ const blobStoreSpy = sandbox.spy(blobStore, 'delete');
+ expect(blobStoreSpy.calledOnce).toBe(false);
+ await expect(file.uploadContent(Readable.from(['test']))).rejects.toThrow(new Error('test'));
+ await setImmediate();
+ expect(blobStoreSpy.calledOnce).toBe(true);
+ });
+});
diff --git a/x-pack/plugins/files/server/file/file.ts b/x-pack/plugins/files/server/file/file.ts
new file mode 100644
index 0000000000000..00544a7e14f08
--- /dev/null
+++ b/x-pack/plugins/files/server/file/file.ts
@@ -0,0 +1,267 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { Logger } from '@kbn/core/server';
+import mimeType from 'mime';
+import { Readable } from 'stream';
+import type { FileCompression, FileShareJSON, FileShareJSONWithToken } from '../../common/types';
+import type {
+ File as IFile,
+ FileKind,
+ FileMetadata,
+ FileStatus,
+ UpdatableFileMetadata,
+ FileJSON,
+} from '../../common';
+import {
+ fileAttributesReducer,
+ Action,
+ createDefaultFileAttributes,
+} from './file_attributes_reducer';
+import { createAuditEvent } from '../audit_events';
+import { InternalFileService } from '../file_service/internal_file_service';
+import { InternalFileShareService } from '../file_share_service';
+import type { FileClientImpl } from '../file_client/file_client';
+import { toJSON } from './to_json';
+import {
+ AlreadyDeletedError,
+ ContentAlreadyUploadedError,
+ NoDownloadAvailableError,
+ UploadInProgressError,
+} from './errors';
+
+/**
+ * Public class that provides all data and functionality consumers will need at the
+ * individual file level
+ *
+ * @note Instantiation should not happen outside of this plugin
+ */
+export class File implements IFile {
+ private readonly logAuditEvent: InternalFileService['writeAuditLog'];
+
+ constructor(
+ public readonly id: string,
+ private fileMetadata: FileMetadata,
+ private readonly fileClient: FileClientImpl,
+ private readonly internalFileService: InternalFileService,
+ private readonly fileShareService: InternalFileShareService,
+ private readonly logger: Logger
+ ) {
+ this.logAuditEvent = this.internalFileService.writeAuditLog.bind(this.internalFileService);
+ }
+
+ private async updateFileState(action: Action) {
+ const { metadata } = await this.fileClient.update({
+ id: this.id,
+ metadata: fileAttributesReducer(this.metadata, action),
+ });
+ this.fileMetadata = metadata;
+ }
+
+ private isReady(): boolean {
+ return this.status === 'READY';
+ }
+
+ private isDeleted(): boolean {
+ return this.status === 'DELETED';
+ }
+
+ private uploadInProgress(): boolean {
+ return this.status === 'UPLOADING';
+ }
+
+ public async update(attrs: Partial): Promise {
+ await this.updateFileState({
+ action: 'updateFile',
+ payload: attrs,
+ });
+ return this;
+ }
+
+ public async uploadContent(content: Readable): Promise {
+ if (this.uploadInProgress()) {
+ throw new UploadInProgressError('Upload already in progress.');
+ }
+ if (this.isReady()) {
+ throw new ContentAlreadyUploadedError('Already uploaded file content.');
+ }
+ this.logger.debug(`Uploading file [id = ${this.id}][name = ${this.name}].`);
+ await this.updateFileState({
+ action: 'uploading',
+ });
+
+ try {
+ const { size } = await this.fileClient.upload(this.id, content);
+ await this.updateFileState({
+ action: 'uploaded',
+ payload: { size },
+ });
+ } catch (e) {
+ await this.updateFileState({ action: 'uploadError' });
+ this.fileClient.deleteContent(this.id).catch(() => {}); // Best effort to remove any uploaded content
+ throw e;
+ }
+ }
+
+ public downloadContent(): Promise {
+ const { size } = this.metadata;
+ if (!this.isReady()) {
+ throw new NoDownloadAvailableError('This file content is not available for download.');
+ }
+ // We pass through this file ID to retrieve blob content.
+ return this.fileClient.download({ id: this.id, size });
+ }
+
+ public async delete(): Promise {
+ if (this.uploadInProgress()) {
+ throw new UploadInProgressError('Cannot delete file while upload in progress');
+ }
+ if (this.isDeleted()) {
+ throw new AlreadyDeletedError('File has already been deleted');
+ }
+ await this.updateFileState({
+ action: 'delete',
+ });
+ // Stop sharing this file
+ await this.fileShareService.deleteForFile({ file: this });
+ await this.fileClient.delete({ id: this.id, hasContent: this.isReady() });
+ this.logAuditEvent(
+ createAuditEvent({
+ action: 'delete',
+ outcome: 'success',
+ message: `Deleted file "${this.name}" of kind "${this.fileKind}" with id "${this.id}"`,
+ })
+ );
+ }
+
+ public async share({
+ name,
+ validUntil,
+ }: {
+ name?: string;
+ validUntil?: number;
+ }): Promise {
+ const shareObject = await this.fileShareService.share({ file: this, name, validUntil });
+ this.internalFileService.writeAuditLog(
+ createAuditEvent({
+ action: 'create',
+ message: `Shared file "${this.name}" with id "${this.id}"`,
+ })
+ );
+ return shareObject;
+ }
+
+ async listShares(): Promise {
+ const { shares } = await this.fileShareService.list({ fileId: this.id });
+ return shares;
+ }
+
+ async unshare(opts: { shareId: string }): Promise {
+ await this.fileShareService.delete({ id: opts.shareId });
+ this.internalFileService.writeAuditLog(
+ createAuditEvent({
+ action: 'delete',
+ message: `Removed share for "${this.name}" with id "${this.id}"`,
+ })
+ );
+ }
+
+ public toJSON(): FileJSON {
+ return toJSON(this.id, this.metadata);
+ }
+
+ private get metadata(): FileMetadata {
+ return this.fileMetadata;
+ }
+
+ public get created(): string {
+ return this.metadata.created;
+ }
+
+ public get updated(): string {
+ return this.metadata.Updated;
+ }
+
+ public get chunkSize(): number | undefined {
+ return this.metadata.ChunkSize;
+ }
+
+ public get fileKind(): string {
+ return this.fileClient.fileKind;
+ }
+
+ public get name(): string {
+ return this.metadata.name;
+ }
+
+ public get status(): FileStatus {
+ return this.metadata.Status;
+ }
+
+ public get compression(): undefined | FileCompression {
+ return this.metadata.Compression;
+ }
+
+ public get size(): undefined | number {
+ return this.metadata.size;
+ }
+
+ public get meta(): M {
+ return this.metadata.Meta as M;
+ }
+
+ public get alt(): undefined | string {
+ return this.metadata.Alt;
+ }
+
+ public get mimeType(): undefined | string {
+ return this.metadata.mime_type;
+ }
+
+ public get extension(): undefined | string {
+ return this.metadata.extension;
+ }
+
+ /**
+ * Static method for creating files so that we can keep all of the audit logging for files
+ * in the same place.
+ */
+ public static async create(
+ {
+ name,
+ fileKind,
+ alt,
+ meta,
+ mime,
+ }: { name: string; fileKind: FileKind; alt?: string; meta?: unknown; mime?: string },
+ internalFileService: InternalFileService,
+ fileClient: FileClientImpl
+ ) {
+ const fileMeta = await fileClient.create({
+ metadata: {
+ ...createDefaultFileAttributes(),
+ name,
+ mime_type: mime,
+ Alt: alt,
+ Meta: meta,
+ FileKind: fileKind.id,
+ extension: (mime && mimeType.getExtension(mime)) ?? undefined,
+ },
+ });
+
+ const file = internalFileService.toFile(fileMeta.id, fileMeta.metadata, fileKind, fileClient);
+
+ internalFileService.writeAuditLog(
+ createAuditEvent({
+ action: 'create',
+ message: `Created file "${file.name}" of kind "${file.fileKind}" and id "${file.id}"`,
+ })
+ );
+
+ return file;
+ }
+}
diff --git a/x-pack/plugins/files/server/file/file_attributes_reducer.ts b/x-pack/plugins/files/server/file/file_attributes_reducer.ts
new file mode 100644
index 0000000000000..93bf2f74545d9
--- /dev/null
+++ b/x-pack/plugins/files/server/file/file_attributes_reducer.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import moment from 'moment';
+import { FileMetadata, UpdatableFileMetadata } from '../../common';
+
+export type Action =
+ | {
+ action: 'delete';
+ payload?: undefined;
+ }
+ | {
+ action: 'uploading';
+ payload?: undefined;
+ }
+ | { action: 'uploaded'; payload: { size: number } }
+ | { action: 'uploadError'; payload?: undefined }
+ | { action: 'updateFile'; payload: Partial };
+
+export function createDefaultFileAttributes(): Pick<
+ FileMetadata,
+ 'created' | 'Updated' | 'Status'
+> {
+ const dateString = new Date().toISOString();
+ return {
+ created: dateString,
+ Status: 'AWAITING_UPLOAD',
+ Updated: dateString,
+ };
+}
+
+export function fileAttributesReducer(
+ state: FileMetadata,
+ { action, payload }: Action
+): FileMetadata {
+ switch (action) {
+ case 'delete':
+ return { ...state, Status: 'DELETED' };
+ case 'uploading':
+ return {
+ ...state,
+ Status: 'UPLOADING',
+ Updated: moment().toISOString(),
+ };
+ case 'uploaded':
+ return {
+ ...state,
+ ...payload,
+ Status: 'READY',
+ Updated: moment().toISOString(),
+ };
+ case 'uploadError':
+ return {
+ ...state,
+ Status: 'UPLOAD_ERROR',
+ Updated: moment().toISOString(),
+ };
+ case 'updateFile':
+ return {
+ ...state,
+ name: payload.name ?? state.name,
+ Alt: payload.alt ?? state.Alt,
+ Meta: payload.meta ?? state.Meta,
+ Updated: moment().toISOString(),
+ };
+ default:
+ return state;
+ }
+}
diff --git a/x-pack/plugins/files/server/file/index.ts b/x-pack/plugins/files/server/file/index.ts
new file mode 100644
index 0000000000000..02740d7eaab6d
--- /dev/null
+++ b/x-pack/plugins/files/server/file/index.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import * as fileErrors from './errors';
+
+export { File } from './file';
+export { toJSON } from './to_json';
+export { createDefaultFileAttributes, fileAttributesReducer } from './file_attributes_reducer';
+export type { Action } from './file_attributes_reducer';
+export { fileErrors };
diff --git a/x-pack/plugins/files/server/file/to_json.ts b/x-pack/plugins/files/server/file/to_json.ts
new file mode 100644
index 0000000000000..390aa1672e06e
--- /dev/null
+++ b/x-pack/plugins/files/server/file/to_json.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { FileMetadata, FileJSON } from '../../common/types';
+
+export function toJSON(id: string, attrs: FileMetadata): FileJSON {
+ const {
+ name,
+ mime_type: mimeType,
+ size,
+ created,
+ Updated,
+ FileKind,
+ Status,
+ Alt,
+ extension,
+ Meta,
+ } = attrs;
+ return {
+ id,
+ name,
+ mimeType,
+ size,
+ created,
+ extension,
+ alt: Alt,
+ status: Status,
+ meta: Meta as M,
+ updated: Updated,
+ fileKind: FileKind,
+ };
+}
diff --git a/x-pack/plugins/files/server/file_client/create_es_file_client.ts b/x-pack/plugins/files/server/file_client/create_es_file_client.ts
new file mode 100644
index 0000000000000..2ffb9bd458c6d
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/create_es_file_client.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Logger, ElasticsearchClient } from '@kbn/core/server';
+import { ElasticsearchBlobStorageClient } from '../blob_storage_service';
+import { FileClientImpl, FileClient } from './file_client';
+import { EsIndexFilesMetadataClient } from './file_metadata_client';
+
+const NO_FILE_KIND = 'none';
+
+/**
+ * Arguments to create an ES file client.
+ */
+export interface CreateEsFileClientArgs {
+ /**
+ * The name of the ES index that will store file metadata.
+ */
+ metadataIndex: string;
+ /**
+ * The name of the ES index that will store file contents.
+ */
+ blobStorageIndex: string;
+ /**
+ * An elasticsearch client that will be used to interact with the cluster
+ */
+ elasticsearchClient: ElasticsearchClient;
+ /**
+ * The maximum file size to be write
+ */
+ maxSizeBytes?: number;
+ /**
+ * A logger for debuggin purposes
+ */
+ logger: Logger;
+}
+
+/**
+ * A utility function for creating an instance of {@link FileClient}
+ * that will speak with ES indices only for file functionality.
+ *
+ * @note This client is not intended to be aware of {@link FileKind}s.
+ *
+ * @param arg - See {@link CreateEsFileClientArgs}
+ */
+export function createEsFileClient(arg: CreateEsFileClientArgs): FileClient {
+ const { blobStorageIndex, elasticsearchClient, logger, metadataIndex, maxSizeBytes } = arg;
+ return new FileClientImpl(
+ {
+ id: NO_FILE_KIND,
+ http: {},
+ maxSizeBytes,
+ },
+ new EsIndexFilesMetadataClient(metadataIndex, elasticsearchClient, logger),
+ new ElasticsearchBlobStorageClient(elasticsearchClient, blobStorageIndex, undefined, logger)
+ );
+}
diff --git a/x-pack/plugins/files/server/file_client/file_client.ts b/x-pack/plugins/files/server/file_client/file_client.ts
new file mode 100644
index 0000000000000..cc9a4a6de2994
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_client.ts
@@ -0,0 +1,191 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { Readable } from 'stream';
+import cuid from 'cuid';
+import { FileKind, FileMetadata } from '../../common/types';
+import type { FileMetadataClient } from './file_metadata_client';
+import type {
+ BlobStorageClient,
+ UploadOptions as BlobUploadOptions,
+} from '../blob_storage_service';
+import { enforceMaxByteSizeTransform } from './stream_transforms';
+
+export interface DeleteArgs {
+ /** ID of the file to delete */
+ id: string;
+ /**
+ * If `true`, the file will be deleted from the blob storage.
+ *
+ * @default true
+ */
+ hasContent?: boolean;
+}
+
+/**
+ * Args to create a file
+ */
+export interface CreateArgs {
+ /**
+ * Unique file ID
+ */
+ id?: string;
+ /**
+ * The file's metadata
+ */
+ metadata: Omit & { FileKind?: string };
+}
+
+export type UploadOptions = Omit;
+
+/**
+ * Wraps the {@link FileMetadataClient} and {@link BlobStorageClient} client
+ * to provide basic file CRUD functionality.
+ *
+ * For now this is just a shallow type of the implementation for export purposes.
+ */
+export interface FileClient {
+ /** See {@link FileMetadata.FileKind}. */
+ fileKind: string;
+
+ /**
+ * See {@link FileMetadataClient.create}.
+ *
+ * @param arg - Arg to create a file.
+ * */
+ create(arg: CreateArgs): ReturnType;
+
+ /**
+ * See {@link FileMetadataClient.get}
+ *
+ * @param arg - Argument to get a file
+ */
+ get: FileMetadataClient['get'];
+
+ /**
+ * {@link FileMetadataClient.update}
+ *
+ * @param arg - Argument to get a file
+ */
+ update: FileMetadataClient['update'];
+
+ /**
+ * Delete a file.
+ * @param arg - Argument to delete a file
+ */
+ delete(arg: DeleteArgs): Promise;
+
+ /**
+ * See {@link BlobStorageClient.delete}
+ *
+ * @param id - Argument to delete a file
+ */
+ deleteContent: BlobStorageClient['delete'];
+
+ /**
+ * See {@link FileMetadataClient.list}
+ *
+ * @param arg - Argument to list files
+ */
+ list: FileMetadataClient['list'];
+
+ /**
+ * See {@link FileMetadataClient.find}.
+ *
+ * @param arg - Argument to find files
+ */
+ find: FileMetadataClient['find'];
+
+ /**
+ * See {@link BlobStorageClient.upload}
+ *
+ * @param id - Readable stream to upload
+ * @param rs - Readable stream to upload
+ * @param opts - Argument for uploads
+ */
+ upload(id: string, rs: Readable, opts?: UploadOptions): ReturnType;
+
+ /**
+ * See {@link BlobStorageClient.download}
+ *
+ * @param args - to download a file
+ */
+ download: BlobStorageClient['download'];
+}
+export class FileClientImpl implements FileClient {
+ constructor(
+ private fileKindDescriptor: FileKind,
+ private readonly metadataClient: FileMetadataClient,
+ private readonly blobStorageClient: BlobStorageClient
+ ) {}
+
+ public get fileKind(): string {
+ return this.fileKindDescriptor.id;
+ }
+
+ public create = async ({
+ id,
+ metadata,
+ }: CreateArgs): ReturnType => {
+ return this.metadataClient.create({
+ id: id || cuid(),
+ metadata: {
+ FileKind: this.fileKind,
+ ...metadata,
+ },
+ });
+ };
+
+ public get: FileMetadataClient['get'] = async (arg) => {
+ return this.metadataClient.get(arg);
+ };
+
+ public update: FileMetadataClient['update'] = (arg) => {
+ return this.metadataClient.update(arg);
+ };
+
+ public find: FileMetadataClient['find'] = (arg) => {
+ return this.metadataClient.find(arg);
+ };
+
+ public async delete({ id, hasContent = true }: DeleteArgs) {
+ if (hasContent) await this.blobStorageClient.delete(id);
+ return this.metadataClient.delete({ id });
+ }
+
+ public deleteContent: BlobStorageClient['delete'] = (arg) => {
+ return this.blobStorageClient.delete(arg);
+ };
+
+ public list: FileMetadataClient['list'] = (arg) => {
+ return this.metadataClient.list(arg);
+ };
+
+ /**
+ * Upload a blob
+ * @param id - The ID of the file content is associated with
+ * @param rs - The readable stream of the file content
+ * @param options - Options for the upload
+ */
+ public upload = async (
+ id: string,
+ rs: Readable,
+ options?: UploadOptions
+ ): ReturnType => {
+ return this.blobStorageClient.upload(rs, {
+ ...options,
+ transforms: [
+ ...(options?.transforms || []),
+ enforceMaxByteSizeTransform(this.fileKindDescriptor.maxSizeBytes ?? Infinity),
+ ],
+ id,
+ });
+ };
+
+ public download: BlobStorageClient['download'] = (args) => {
+ return this.blobStorageClient.download(args);
+ };
+}
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/es_index.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/es_index.ts
new file mode 100644
index 0000000000000..5b41dca5e158e
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/es_index.ts
@@ -0,0 +1,149 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { once } from 'lodash';
+import { pipe } from 'lodash/fp';
+import { Logger } from '@kbn/core/server';
+import { toElasticsearchQuery } from '@kbn/es-query';
+import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import { MappingProperty } from '@elastic/elasticsearch/lib/api/types';
+import type { FilesMetrics, FileMetadata, Pagination } from '../../../../common';
+import type { FindFileArgs } from '../../../file_service';
+import type {
+ DeleteArg,
+ FileDescriptor,
+ FileMetadataClient,
+ GetArg,
+ GetUsageMetricsArgs,
+ ListArg,
+ UpdateArgs,
+} from '../file_metadata_client';
+import { filterArgsToKuery, filterDeletedFiles } from './query_filters';
+import { fileObjectType } from '../../../saved_objects/file';
+
+const filterArgsToESQuery = pipe(filterArgsToKuery, toElasticsearchQuery);
+
+const fileMappings: MappingProperty = {
+ dynamic: false,
+ type: 'object',
+ properties: {
+ ...fileObjectType.mappings.properties,
+ },
+};
+
+interface FileDocument {
+ file: FileMetadata;
+}
+
+export class EsIndexFilesMetadataClient implements FileMetadataClient {
+ constructor(
+ private readonly index: string,
+ private readonly esClient: ElasticsearchClient,
+ private readonly logger: Logger
+ ) {}
+
+ private createIfNotExists = once(async () => {
+ try {
+ if (await this.esClient.indices.exists({ index: this.index })) {
+ return;
+ }
+ await this.esClient.indices.create({
+ index: this.index,
+ mappings: {
+ dynamic: false,
+ properties: {
+ file: fileMappings,
+ },
+ },
+ });
+ } catch (e) {
+ // best effort
+ }
+ });
+
+ async create({ id, metadata }: FileDescriptor): Promise> {
+ await this.createIfNotExists();
+ const result = await this.esClient.index({
+ index: this.index,
+ id,
+ document: { file: metadata },
+ refresh: true,
+ });
+ return {
+ id: result._id,
+ metadata,
+ };
+ }
+
+ async get({ id }: GetArg): Promise> {
+ const { _source: doc } = await this.esClient.get>({
+ index: this.index,
+ id,
+ });
+
+ if (!doc) {
+ this.logger.error(`File with id "${id}" not found`);
+ throw new Error('File not found');
+ }
+
+ return {
+ id,
+ metadata: doc.file,
+ };
+ }
+
+ async delete({ id }: DeleteArg): Promise {
+ await this.esClient.delete({ index: this.index, id });
+ }
+
+ async update({ id, metadata }: UpdateArgs): Promise> {
+ await this.esClient.update({ index: this.index, id, doc: { file: metadata }, refresh: true });
+ return this.get({ id });
+ }
+
+ private paginationToES({ page = 1, perPage = 50 }: Pagination) {
+ return {
+ size: perPage,
+ from: (page - 1) * perPage,
+ };
+ }
+
+ private attrPrefix: keyof FileDocument = 'file';
+
+ async list({ page, perPage }: ListArg = {}): Promise>> {
+ const result = await this.esClient.search>({
+ index: this.index,
+ expand_wildcards: 'hidden',
+ query: toElasticsearchQuery(filterDeletedFiles({ attrPrefix: this.attrPrefix })),
+ ...this.paginationToES({ page, perPage }),
+ sort: 'file.created',
+ });
+
+ return result.hits.hits.map((hit) => {
+ return {
+ id: hit._id,
+ metadata: hit._source?.file!,
+ };
+ });
+ }
+
+ async find({ page, perPage, ...filterArgs }: FindFileArgs): Promise>> {
+ const result = await this.esClient.search>({
+ index: this.index,
+ expand_wildcards: 'hidden',
+ query: filterArgsToESQuery({ ...filterArgs, attrPrefix: this.attrPrefix }),
+ ...this.paginationToES({ page, perPage }),
+ sort: 'file.created',
+ });
+
+ return result.hits.hits.map((r) => ({ id: r._id, metadata: r._source?.file! }));
+ }
+
+ async getUsageMetrics(arg: GetUsageMetricsArgs): Promise {
+ throw new Error('Not implemented');
+ }
+}
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/index.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/index.ts
new file mode 100644
index 0000000000000..9e7273b685f89
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { SavedObjectsFileMetadataClient } from './saved_objects';
+export { EsIndexFilesMetadataClient } from './es_index';
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/query_filters.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/query_filters.ts
new file mode 100644
index 0000000000000..4b33c60f320a4
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/query_filters.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { pipe, forEach } from 'lodash/fp';
+import { escapeKuery, KueryNode, nodeBuilder, nodeTypes } from '@kbn/es-query';
+
+import { getFlattenedObject } from '@kbn/std';
+
+import { FileMetadata, FileStatus } from '../../../../common/types';
+import { FindFileArgs } from '../../../file_service';
+
+const { buildNode } = nodeTypes.function;
+
+const deletedStatus: FileStatus = 'DELETED';
+
+export function filterDeletedFiles({ attrPrefix }: { attrPrefix: string }): KueryNode {
+ return buildNode('not', nodeBuilder.is(`${attrPrefix}.Status`, deletedStatus));
+}
+
+export function filterArgsToKuery({
+ extension,
+ kind,
+ meta,
+ name,
+ status,
+ attrPrefix = '',
+}: Omit & { attrPrefix?: string }): KueryNode {
+ const kueryExpressions: KueryNode[] = [filterDeletedFiles({ attrPrefix })];
+
+ const addFilters = (fieldName: keyof FileMetadata, values: string[] = []): void => {
+ if (values.length) {
+ const orExpressions = values
+ .filter(Boolean)
+ .map((value) => nodeBuilder.is(`${attrPrefix}.${fieldName}`, escapeKuery(value)));
+ kueryExpressions.push(nodeBuilder.or(orExpressions));
+ }
+ };
+
+ addFilters('name', name);
+ addFilters('FileKind', kind);
+ addFilters('Status', status);
+ addFilters('extension', extension);
+
+ if (meta) {
+ const addMetaFilters = pipe(
+ getFlattenedObject,
+ Object.entries,
+ forEach(([fieldName, value]) => {
+ addFilters(
+ `Meta.${fieldName}` as keyof FileMetadata,
+ Array.isArray(value) ? value : [value]
+ );
+ })
+ );
+ addMetaFilters(meta);
+ }
+
+ return nodeBuilder.and(kueryExpressions);
+}
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/saved_objects.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/saved_objects.ts
new file mode 100644
index 0000000000000..9afd12689acbf
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/adapters/saved_objects.ts
@@ -0,0 +1,160 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { reduce } from 'lodash';
+import type { Logger } from '@kbn/core/server';
+import type {
+ SavedObjectsClientContract,
+ ISavedObjectsRepository,
+ SavedObjectsOpenPointInTimeResponse,
+} from '@kbn/core-saved-objects-api-server';
+import { AggregationsSumAggregate } from '@elastic/elasticsearch/lib/api/types';
+import { escapeKuery } from '@kbn/es-query';
+
+import { FindFileArgs } from '../../../file_service/file_action_types';
+import { ES_FIXED_SIZE_INDEX_BLOB_STORE } from '../../../../common/constants';
+import type { FileMetadata, FilesMetrics, FileStatus, Pagination } from '../../../../common/types';
+import type {
+ FileMetadataClient,
+ UpdateArgs,
+ FileDescriptor,
+ GetUsageMetricsArgs,
+} from '../file_metadata_client';
+
+import { filterArgsToKuery } from './query_filters';
+
+interface TermsAgg {
+ buckets: Array<{ key: string; doc_count: number }>;
+}
+interface FilesMetricsAggs {
+ bytesUsed: AggregationsSumAggregate;
+ status: TermsAgg;
+ extension: TermsAgg;
+}
+
+export class SavedObjectsFileMetadataClient implements FileMetadataClient {
+ constructor(
+ private readonly soType: string,
+ private readonly soClient: SavedObjectsClientContract | ISavedObjectsRepository,
+ private readonly logger: Logger
+ ) {}
+
+ async create({ id, metadata }: FileDescriptor): Promise {
+ const result = await this.soClient.create(this.soType, metadata, { id });
+ return { id: result.id, metadata: result.attributes };
+ }
+ async update({ id, metadata }: UpdateArgs): Promise {
+ const result = await this.soClient.update(this.soType, id, metadata);
+ return {
+ id: result.id,
+ metadata: result.attributes as FileDescriptor['metadata'],
+ };
+ }
+ async get({ id }: { id: string }): Promise {
+ const result = await this.soClient.get(this.soType, id);
+ return {
+ id: result.id,
+ metadata: result.attributes as FileDescriptor['metadata'],
+ };
+ }
+ async list({ fileKind, page, perPage }: { fileKind?: string } & Pagination = {}): Promise<
+ FileDescriptor[]
+ > {
+ let filter = `NOT ${this.soType}.attributes.Status: DELETED`;
+ if (fileKind) {
+ filter = `${this.soType}.attributes.FileKind: ${escapeKuery(fileKind)} AND ${filter}`;
+ }
+ const result = await this.soClient.find({
+ type: this.soType,
+ filter,
+ page,
+ perPage,
+ });
+ return result.saved_objects.map((file) => ({
+ id: file.id,
+ metadata: file.attributes as FileDescriptor['metadata'],
+ }));
+ }
+
+ async find({ page, perPage, ...filterArgs }: FindFileArgs): Promise {
+ const result = await this.soClient.find({
+ type: this.soType,
+ filter: filterArgsToKuery({ ...filterArgs, attrPrefix: `${this.soType}.attributes` }),
+ page,
+ perPage,
+ sortOrder: 'desc',
+ sortField: 'created',
+ });
+ return result.saved_objects.map((so) => ({
+ id: so.id,
+ metadata: so.attributes as FileMetadata,
+ }));
+ }
+
+ async delete({ id }: { id: string }): Promise {
+ await this.soClient.delete(this.soType, id);
+ }
+
+ async getUsageMetrics({
+ esFixedSizeIndex: { capacity },
+ }: GetUsageMetricsArgs): Promise {
+ let pit: undefined | SavedObjectsOpenPointInTimeResponse;
+ try {
+ pit = await this.soClient.openPointInTimeForType(this.soType);
+ const { aggregations } = await this.soClient.find({
+ type: this.soType,
+ pit,
+ aggs: {
+ bytesUsed: {
+ sum: {
+ field: `${this.soType}.attributes.size`,
+ },
+ },
+ status: {
+ terms: {
+ field: `${this.soType}.attributes.Status`,
+ },
+ },
+ extension: {
+ terms: {
+ field: `${this.soType}.attributes.extension`,
+ },
+ },
+ },
+ });
+
+ if (aggregations) {
+ const used = aggregations.bytesUsed!.value!;
+ return {
+ storage: {
+ [ES_FIXED_SIZE_INDEX_BLOB_STORE]: {
+ capacity,
+ available: capacity - used,
+ used,
+ },
+ },
+ countByExtension: reduce(
+ aggregations.extension.buckets,
+ (acc, { key, doc_count: docCount }) => ({ ...acc, [key]: docCount }),
+ {}
+ ),
+ countByStatus: reduce(
+ aggregations.status.buckets,
+ (acc, { key, doc_count: docCount }) => ({ ...acc, [key]: docCount }),
+ {} as Record
+ ),
+ };
+ }
+
+ throw new Error('Could not retrieve usage metrics');
+ } finally {
+ if (pit) {
+ await this.soClient.closePointInTime(pit.id).catch(this.logger.error.bind(this.logger));
+ }
+ }
+ }
+}
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts
new file mode 100644
index 0000000000000..5934ac1f422b8
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/file_metadata_client.ts
@@ -0,0 +1,137 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { ES_FIXED_SIZE_INDEX_BLOB_STORE } from '../../../common/constants';
+import type { FileMetadata, FilesMetrics, Pagination } from '../../../common/types';
+import type { FindFileArgs } from '../../file_service/file_action_types';
+
+/**
+ * Args to get usage metrics
+ */
+export interface GetUsageMetricsArgs {
+ /**
+ * The ES backed fixed size storage
+ */
+ [ES_FIXED_SIZE_INDEX_BLOB_STORE]: {
+ /**
+ * Use this number to calculate free space when calculating metrics
+ */
+ capacity: number;
+ };
+}
+
+/**
+ * Meta description of a file.
+ */
+export interface FileDescriptor {
+ /**
+ * Unique ID of a file, used to locate a file.
+ */
+ id: string;
+ /**
+ * The file's metadata.
+ */
+ metadata: FileMetadata;
+}
+
+/**
+ * Update a file args
+ */
+export interface UpdateArgs {
+ /**
+ * A unique file ID.
+ */
+ id: string;
+ /**
+ * The file's metadata.
+ */
+ metadata: Partial>;
+}
+
+/**
+ * Get a file
+ */
+export interface GetArg {
+ /**
+ * Unique ID of file metadata
+ */
+ id: string;
+}
+
+export interface DeleteArg {
+ /**
+ * Unique ID of file metadata to delete
+ *
+ * @note Deleting file metadata should only be done once all other related
+ * file objects have been deleted
+ */
+ id: string;
+}
+
+export interface ListArg extends Pagination {
+ /**
+ * The file kind to scope this query to
+ */
+ fileKind?: string;
+}
+
+export interface FindArg extends Pagination {
+ /**
+ * The file kind to scope this query to
+ */
+ fileKind?: string;
+}
+
+/**
+ * An abstraction of storage implementation of file object's (i.e., metadata)
+ */
+export interface FileMetadataClient {
+ /**
+ * Create an instance of file metadata
+ *
+ * @param arg - Provide an ID and metadata
+ */
+ create(arg: FileDescriptor): Promise;
+
+ /**
+ * Get file metadata
+ *
+ * @param arg - Arguments to retrieve file metadata
+ */
+ get(arg: GetArg): Promise;
+
+ /**
+ * The file metadata to update
+ *
+ * @param arg - Arguments to update file metadata
+ */
+ update(arg: UpdateArgs): Promise;
+ /**
+ * Delete an instance of file metadata
+ *
+ * @param arg - Arguments to delete file metadata
+ */
+ delete(arg: DeleteArg): Promise;
+ /**
+ * List all instances of metadata for a file kind.
+ *
+ * @param arg - Arguments to list file metadata
+ */
+ list(arg?: ListArg): Promise;
+ /**
+ * Search for a set of file kind instances that match the filters.
+ *
+ * @param arg - Filters and other settings to match against
+ */
+ find(arg: FindFileArgs): Promise;
+ /**
+ * Prepare a set of metrics based on the file metadata.
+ *
+ * @param arg - Argument to get usage metrics
+ */
+ getUsageMetrics(arg: GetUsageMetricsArgs): Promise;
+}
diff --git a/x-pack/plugins/files/server/file_client/file_metadata_client/index.ts b/x-pack/plugins/files/server/file_client/file_metadata_client/index.ts
new file mode 100644
index 0000000000000..e4b84a1c6cb04
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/file_metadata_client/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export type {
+ FileMetadataClient,
+ FileDescriptor,
+ DeleteArg as DeleteMetedataArg,
+ FindArg as FindMetadataArg,
+ GetArg as GetMetadataArg,
+ GetUsageMetricsArgs,
+ ListArg as ListMetadataArg,
+ UpdateArgs as UpdateMetadataArg,
+} from './file_metadata_client';
+export { SavedObjectsFileMetadataClient, EsIndexFilesMetadataClient } from './adapters';
diff --git a/x-pack/plugins/files/server/file_client/index.ts b/x-pack/plugins/files/server/file_client/index.ts
new file mode 100644
index 0000000000000..2f764a53224e4
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/index.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { EsIndexFilesMetadataClient, SavedObjectsFileMetadataClient } from './file_metadata_client';
+export type {
+ FileMetadataClient,
+ DeleteMetedataArg,
+ FileDescriptor,
+ FindMetadataArg,
+ GetMetadataArg,
+ GetUsageMetricsArgs,
+ ListMetadataArg,
+ UpdateMetadataArg,
+} from './file_metadata_client';
+export { FileClientImpl } from './file_client';
+export type { FileClient } from './file_client';
+export { createEsFileClient } from './create_es_file_client';
+export type { CreateEsFileClientArgs } from './create_es_file_client';
diff --git a/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts b/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts
new file mode 100644
index 0000000000000..3ab200533c6da
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/integration_tests/es_file_client.test.ts
@@ -0,0 +1,217 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { Readable } from 'stream';
+import { loggingSystemMock } from '@kbn/core/server/mocks';
+import { TestEnvironmentUtils, setupIntegrationEnvironment } from '../../test_utils';
+import { createEsFileClient } from '../create_es_file_client';
+import { FileClient } from '../file_client';
+
+/**
+ * This file client is using Elasticsearch interfaces directly to manage files.
+ */
+describe('ES-index-backed file client', () => {
+ let esClient: TestEnvironmentUtils['esClient'];
+ let fileClient: FileClient;
+ let testHarness: TestEnvironmentUtils;
+
+ beforeAll(async () => {
+ testHarness = await setupIntegrationEnvironment();
+ ({ esClient } = testHarness);
+ });
+
+ beforeEach(() => {
+ fileClient = createEsFileClient({
+ blobStorageIndex: '.kibana-test-blob',
+ metadataIndex: '.kibana-test-metadata',
+ elasticsearchClient: esClient,
+ logger: loggingSystemMock.create().get(),
+ });
+ });
+
+ afterAll(async () => {
+ await testHarness.cleanupAfterAll();
+ });
+
+ test('create a new file', async () => {
+ const file = await fileClient.create({
+ id: '123',
+ metadata: {
+ Status: 'AWAITING_UPLOAD',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name',
+ },
+ });
+ expect(file).toEqual(
+ expect.objectContaining({
+ id: '123',
+ metadata: {
+ FileKind: 'none',
+ Status: 'AWAITING_UPLOAD',
+ Updated: expect.any(String),
+ created: expect.any(String),
+ name: 'cool name',
+ },
+ })
+ );
+ await fileClient.delete({ id: file.id, hasContent: false });
+ });
+
+ test('uploads and downloads file content', async () => {
+ let { id, metadata } = await fileClient.create({
+ id: '123',
+ metadata: {
+ Status: 'AWAITING_UPLOAD',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name',
+ },
+ });
+
+ const { size } = await fileClient.upload(id, Readable.from([Buffer.from('test')]));
+ ({ id, metadata } = await fileClient.update({
+ id,
+ metadata: { ...metadata, size, Status: 'READY' },
+ }));
+
+ const file = await fileClient.get({ id });
+ const rs = await fileClient.download({ id: file.id, size: file.metadata.size });
+ const chunks: Buffer[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(Buffer.concat(chunks).toString('utf-8')).toBe('test');
+
+ await fileClient.delete({ id, hasContent: true });
+ });
+
+ test('searches across files', async () => {
+ const { id: id1 } = await fileClient.create({
+ id: '123',
+ metadata: {
+ Status: 'AWAITING_UPLOAD',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name 1',
+ Meta: {
+ test: '1',
+ },
+ },
+ });
+ const { id: id2 } = await fileClient.create({
+ id: '1234',
+ metadata: {
+ Status: 'UPLOADING',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name 2',
+ Meta: {
+ test: '2',
+ },
+ },
+ });
+ const { id: id3 } = await fileClient.create({
+ id: '12345',
+ metadata: {
+ Status: 'READY',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name 3',
+ Meta: {
+ test: '3',
+ },
+ },
+ });
+
+ {
+ const results = await fileClient.find({
+ status: ['READY'],
+ meta: { test: '3' },
+ });
+
+ expect(results).toHaveLength(1);
+
+ expect(results[0]).toEqual(
+ expect.objectContaining({
+ id: id3,
+ })
+ );
+ }
+
+ {
+ const results = await fileClient.find({
+ status: ['READY', 'AWAITING_UPLOAD'],
+ });
+
+ expect(results).toHaveLength(2);
+
+ expect(results[0]).toEqual(
+ expect.objectContaining({
+ id: id1,
+ })
+ );
+
+ expect(results[1]).toEqual(
+ expect.objectContaining({
+ id: id3,
+ })
+ );
+ }
+
+ await Promise.all([
+ fileClient.delete({ id: id1 }),
+ fileClient.delete({ id: id2 }),
+ fileClient.delete({ id: id3 }),
+ ]);
+ });
+
+ test('does not list deleted files', async () => {
+ const { id: id1 } = await fileClient.create({
+ id: '123',
+ metadata: {
+ Status: 'AWAITING_UPLOAD',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name 1',
+ Meta: {
+ test: '1',
+ },
+ },
+ });
+ const { id: id2 } = await fileClient.create({
+ id: '1234',
+ metadata: {
+ Status: 'DELETED',
+ created: new Date().toISOString(),
+ Updated: new Date().toISOString(),
+ name: 'cool name 2',
+ Meta: {
+ test: '2',
+ },
+ },
+ });
+
+ const list = await fileClient.list();
+
+ expect(list).toHaveLength(1);
+ expect(list[0]).toEqual(
+ expect.objectContaining({
+ id: '123',
+ metadata: {
+ FileKind: 'none',
+ Meta: { test: '1' },
+ Status: 'AWAITING_UPLOAD',
+ Updated: expect.any(String),
+ created: expect.any(String),
+ name: 'cool name 1',
+ },
+ })
+ );
+
+ await Promise.all([fileClient.delete({ id: id1 }), fileClient.delete({ id: id2 })]);
+ });
+});
diff --git a/x-pack/plugins/files/server/file_client/stream_transforms/index.ts b/x-pack/plugins/files/server/file_client/stream_transforms/index.ts
new file mode 100644
index 0000000000000..b3a82e897a02c
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/stream_transforms/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { enforceMaxByteSizeTransform } from './max_byte_size_transform';
diff --git a/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/errors.ts b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/errors.ts
new file mode 100644
index 0000000000000..3b2c236e8a287
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/errors.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export class MaxByteSizeExceededError extends Error {
+ constructor(expectedSize: number) {
+ super(`Maximum of ${expectedSize} bytes exceeded`);
+ Error.captureStackTrace(this);
+ }
+}
diff --git a/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/index.ts b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/index.ts
new file mode 100644
index 0000000000000..b3a82e897a02c
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/index.ts
@@ -0,0 +1,8 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { enforceMaxByteSizeTransform } from './max_byte_size_transform';
diff --git a/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.test.ts b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.test.ts
new file mode 100644
index 0000000000000..9697624edb471
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.test.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { Readable, Writable, pipeline } from 'stream';
+import { promisify } from 'util';
+import { enforceMaxByteSizeTransform } from './max_byte_size_transform';
+
+const pipe = promisify(pipeline);
+
+class DummyWrite extends Writable {
+ public chunks: string[] = [];
+ _write(chunk: any, encoding: BufferEncoding, cb: (error?: Error | null) => void): void {
+ this.chunks.push(chunk.toString());
+ cb(null);
+ }
+}
+
+describe('Max byte size transform', () => {
+ it('should allow data to stream through it', async () => {
+ const data = 'abc'.repeat(10);
+ const dataStream = [data, data, data];
+ const src = Readable.from(dataStream);
+ const dest = new DummyWrite();
+ await pipe(src, enforceMaxByteSizeTransform(Infinity), dest);
+ expect(dest.chunks.join('')).toEqual(dataStream.join(''));
+ });
+ it('should throw an error when the max number of bytes has been reached', async () => {
+ const data = 'abc'.repeat(10);
+ const dataStream = [data, data, data];
+ const src = Readable.from(dataStream);
+ const dest = new DummyWrite();
+ await expect(() => pipe(src, enforceMaxByteSizeTransform(5), dest)).rejects.toThrowError(
+ new Error('Maximum of 5 bytes exceeded')
+ );
+ });
+});
diff --git a/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.ts b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.ts
new file mode 100644
index 0000000000000..c2634bcbf8fe2
--- /dev/null
+++ b/x-pack/plugins/files/server/file_client/stream_transforms/max_byte_size_transform/max_byte_size_transform.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { Transform } from 'stream';
+import { MaxByteSizeExceededError } from './errors';
+
+export function enforceMaxByteSizeTransform(maxByteSize: number) {
+ let bytesSeen: number = 0;
+ return new Transform({
+ transform(chunk: Buffer, _, cb) {
+ if (!Buffer.isBuffer(chunk))
+ throw new Error(`Received a non-buffer chunk. All chunk must be buffers.`);
+
+ bytesSeen += chunk.byteLength;
+ if (bytesSeen > maxByteSize) {
+ cb(new MaxByteSizeExceededError(maxByteSize));
+ } else {
+ cb(null, chunk);
+ }
+ },
+ });
+}
diff --git a/x-pack/plugins/files/server/file_kinds_registry/index.ts b/x-pack/plugins/files/server/file_kinds_registry/index.ts
new file mode 100644
index 0000000000000..bd550e43dc4b7
--- /dev/null
+++ b/x-pack/plugins/files/server/file_kinds_registry/index.ts
@@ -0,0 +1,66 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { createGetterSetter } from '@kbn/kibana-utils-plugin/common';
+import assert from 'assert';
+import { FileKind } from '../../common';
+
+import { registerFileKindRoutes } from '../routes/file_kind';
+import { FilesRouter } from '../routes/types';
+
+export interface FileKindsRegistry {
+ /**
+ * Register a new file kind.
+ */
+ register(fileKind: FileKind): void;
+
+ /**
+ * Gets a {@link FileKind} or throws.
+ */
+ get(id: string): FileKind;
+
+ /**
+ * Return all registered {@link FileKind}s.
+ */
+ getAll(): FileKind[];
+}
+
+/**
+ * @internal
+ */
+export class FileKindsRegistryImpl implements FileKindsRegistry {
+ constructor(private readonly router: FilesRouter) {}
+
+ private readonly fileKinds = new Map();
+
+ register(fileKind: FileKind) {
+ if (this.fileKinds.get(fileKind.id)) {
+ throw new Error(`File kind "${fileKind.id}" already registered.`);
+ }
+
+ if (fileKind.id !== encodeURIComponent(fileKind.id)) {
+ throw new Error(
+ `File kind id "${fileKind.id}" is not a valid file kind ID. Choose an ID that does not need to be URI encoded.`
+ );
+ }
+
+ this.fileKinds.set(fileKind.id, fileKind);
+ registerFileKindRoutes(this.router, fileKind);
+ }
+
+ get(id: string): FileKind {
+ const fileKind = this.fileKinds.get(id);
+ assert(fileKind, `File kind with id "${id}" not found.`);
+ return fileKind;
+ }
+
+ getAll(): FileKind[] {
+ return Array.from(this.fileKinds.values());
+ }
+}
+
+export const [getFileKindsRegistry, setFileKindsRegistry] =
+ createGetterSetter('fileKindsRegistry');
diff --git a/x-pack/plugins/files/server/file_service/errors.ts b/x-pack/plugins/files/server/file_service/errors.ts
new file mode 100644
index 0000000000000..905f26cf8fe14
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/errors.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export class FileNotFoundError extends Error {
+ constructor(message: string) {
+ super(message);
+ Error.captureStackTrace(this);
+ }
+}
diff --git a/x-pack/plugins/files/server/file_service/file_action_types.ts b/x-pack/plugins/files/server/file_service/file_action_types.ts
new file mode 100644
index 0000000000000..c3d3a67ec6c66
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/file_action_types.ts
@@ -0,0 +1,118 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Pagination, UpdatableFileMetadata } from '../../common/types';
+
+/**
+ * Arguments to create a new file.
+ */
+export interface CreateFileArgs {
+ /**
+ * File name
+ */
+ name: string;
+ /**
+ * File kind, must correspond to a registered {@link FileKind}.
+ */
+ fileKind: string;
+ /**
+ * Alternate text for accessibility and display purposes.
+ */
+ alt?: string;
+ /**
+ * Custom metadata like tags or identifiers for the file.
+ */
+ meta?: Meta;
+ /**
+ * The MIME type of the file.
+ */
+ mime?: string;
+}
+
+/**
+ * Arguments to update a file
+ */
+export interface UpdateFileArgs {
+ /**
+ * File ID.
+ */
+ id: string;
+ /**
+ * File kind, must correspond to a registered {@link FileKind}.
+ */
+ fileKind: string;
+ /**
+ * Attributes to update.
+ */
+ attributes: UpdatableFileMetadata;
+}
+
+/**
+ * Arguments to delete a file.
+ */
+export interface DeleteFileArgs {
+ /**
+ * File ID.
+ */
+ id: string;
+ /**
+ * File kind, must correspond to a registered {@link FileKind}.
+ */
+ fileKind: string;
+}
+
+/**
+ * Arguments list files.
+ */
+export interface ListFilesArgs extends Pagination {
+ /**
+ * File kind, must correspond to a registered {@link FileKind}.
+ */
+ fileKind: string;
+}
+
+/**
+ * Arguments to get a file by ID.
+ */
+export interface GetByIdArgs {
+ /**
+ * File ID.
+ */
+ id: string;
+ /**
+ * File kind, must correspond to a registered {@link FileKind}.
+ */
+ fileKind: string;
+}
+
+/**
+ * Arguments to filter for files.
+ *
+ * @note Individual values in a filter are "OR"ed together filters are "AND"ed together.
+ */
+export interface FindFileArgs extends Pagination {
+ /**
+ * File kind(s), see {@link FileKind}.
+ */
+ kind?: string[];
+ /**
+ * File name(s).
+ */
+ name?: string[];
+ /**
+ * File extension(s).
+ */
+ extension?: string[];
+ /**
+ * File status(es).
+ */
+ status?: string[];
+ /**
+ * File metadata values. These values are governed by the consumer.
+ */
+ meta?: Record;
+}
diff --git a/x-pack/plugins/files/server/file_service/file_service.ts b/x-pack/plugins/files/server/file_service/file_service.ts
new file mode 100644
index 0000000000000..90303ac715437
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/file_service.ts
@@ -0,0 +1,108 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { File, FileJSON, FilesMetrics } from '../../common';
+import type { FileShareServiceStart } from '../file_share_service/types';
+import type {
+ CreateFileArgs,
+ UpdateFileArgs,
+ DeleteFileArgs,
+ GetByIdArgs,
+ ListFilesArgs,
+ FindFileArgs,
+} from './file_action_types';
+
+/**
+ * Public file service interface.
+ */
+export interface FileServiceStart {
+ /**
+ * Create a new file.
+ *
+ * Once created, the file content can be uploaded. See {@link File}.
+ *
+ * @param args - create file arg
+ */
+ create(args: CreateFileArgs): Promise>;
+
+ /**
+ * Update updatable file attributes like name and meta.
+ *
+ * @param args - update file args
+ */
+ update(args: UpdateFileArgs): Promise>;
+
+ /**
+ * Delete a file.
+ *
+ * @param args - delete file args
+ */
+ delete(args: DeleteFileArgs): Promise;
+
+ /**
+ * Get a file by ID. Will throw if file cannot be found.
+ *
+ * @param args - get file by ID args
+ */
+ getById(args: GetByIdArgs): Promise>;
+
+ /**
+ * Find files given a set of parameters.
+ *
+ * @param args - find files args
+ */
+ find(args: FindFileArgs): Promise>>;
+
+ /**
+ * List all files of specific file kind.
+ *
+ * @param args - list files args
+ */
+ list(args: ListFilesArgs): Promise>>;
+
+ /**
+ * Get an instance of a share object
+ *
+ * @param arg - get share args
+ */
+ getShareObject: FileShareServiceStart['get'];
+
+ /**
+ * List share objects
+ *
+ * @param arg - list share objects args
+ */
+ listShareObjects: FileShareServiceStart['list'];
+
+ /**
+ * Update an instance of a share object
+ *
+ * @param args - update share args
+ */
+ updateShareObject: FileShareServiceStart['update'];
+
+ /**
+ * Delete a share instance
+ *
+ * @param args - delete share args
+ */
+ deleteShareObject: FileShareServiceStart['delete'];
+
+ /**
+ * Get the current usage metrics for all storage media.
+ *
+ * Returns diagnostics or `undefined` if metrics could not be retrieved.
+ */
+ getUsageMetrics(): Promise;
+
+ /**
+ * Get a file by a secret token.
+ *
+ * @param token - secret token
+ */
+ getByToken(token: string): Promise>;
+}
diff --git a/x-pack/plugins/files/server/file_service/file_service_factory.ts b/x-pack/plugins/files/server/file_service/file_service_factory.ts
new file mode 100644
index 0000000000000..bed007b00e507
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/file_service_factory.ts
@@ -0,0 +1,140 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ SavedObjectsServiceSetup,
+ SavedObjectsServiceStart,
+ Logger,
+ KibanaRequest,
+} from '@kbn/core/server';
+import { SecurityPluginSetup } from '@kbn/security-plugin/server';
+
+import type { File, FileJSON, FileMetadata } from '../../common';
+import { fileObjectType, fileShareObjectType } from '../saved_objects';
+import { BlobStorageService } from '../blob_storage_service';
+import { InternalFileShareService } from '../file_share_service';
+import {
+ CreateFileArgs,
+ FindFileArgs,
+ GetByIdArgs,
+ ListFilesArgs,
+ UpdateFileArgs,
+} from './file_action_types';
+import { InternalFileService } from './internal_file_service';
+import { FileServiceStart } from './file_service';
+import { FileKindsRegistry } from '../file_kinds_registry';
+import { SavedObjectsFileMetadataClient } from '../file_client';
+
+/**
+ * A simple interface for getting an instance of {@link FileServiceStart}
+ */
+export interface FileServiceFactory {
+ /**
+ * Get a file service instance that is scoped to the current user request.
+ *
+ * @param req - the Kibana request to scope the service to
+ */
+ asScoped(req: KibanaRequest): FileServiceStart;
+
+ /**
+ * Get a file service instance that is scoped to the internal user.
+ *
+ * @note
+ * Do not use this to drive interactions with files that are initiated by a
+ * user.
+ */
+ asInternal(): FileServiceStart;
+}
+
+/**
+ * Factory for creating {@link FileServiceStart} instances.
+ */
+export class FileServiceFactoryImpl implements FileServiceFactory {
+ constructor(
+ private readonly savedObjectsService: SavedObjectsServiceStart,
+ private readonly blobStorageService: BlobStorageService,
+ private readonly security: undefined | SecurityPluginSetup,
+ private readonly fileKindRegistry: FileKindsRegistry,
+ private readonly logger: Logger
+ ) {}
+
+ private createFileService(req?: KibanaRequest): FileServiceStart {
+ const hiddenTypes = [fileObjectType.name, fileShareObjectType.name];
+ const soClient = req
+ ? this.savedObjectsService.getScopedClient(req, {
+ includedHiddenTypes: hiddenTypes,
+ })
+ : this.savedObjectsService.createInternalRepository(hiddenTypes);
+
+ const auditLogger = req
+ ? this.security?.audit.asScoped(req)
+ : this.security?.audit.withoutRequest;
+
+ const internalFileShareService = new InternalFileShareService(soClient);
+ const soMetadataClient = new SavedObjectsFileMetadataClient(
+ fileObjectType.name,
+ soClient,
+ this.logger.get('so-metadata-client')
+ );
+
+ const internalFileService = new InternalFileService(
+ soMetadataClient,
+ this.blobStorageService,
+ internalFileShareService,
+ auditLogger,
+ this.fileKindRegistry,
+ this.logger
+ );
+
+ return {
+ async create(args: CreateFileArgs) {
+ return internalFileService.createFile(args) as Promise>;
+ },
+ async update(args: UpdateFileArgs) {
+ return internalFileService.updateFile(args) as Promise>;
+ },
+ async delete(args) {
+ return internalFileService.deleteFile(args);
+ },
+ async getById(args: GetByIdArgs) {
+ return internalFileService.getById(args) as Promise>;
+ },
+ async find(args: FindFileArgs) {
+ return internalFileService.findFilesJSON(args) as Promise>>;
+ },
+ async list(args: ListFilesArgs) {
+ return internalFileService.list(args) as Promise>>;
+ },
+ async getUsageMetrics() {
+ return internalFileService.getUsageMetrics();
+ },
+ async getByToken(token: string) {
+ return internalFileService.getByToken(token) as Promise>;
+ },
+ getShareObject: internalFileShareService.get.bind(internalFileShareService),
+ updateShareObject: internalFileShareService.update.bind(internalFileShareService),
+ deleteShareObject: internalFileShareService.delete.bind(internalFileShareService),
+ listShareObjects: internalFileShareService.list.bind(internalFileShareService),
+ };
+ }
+
+ public asScoped(req: KibanaRequest): FileServiceStart {
+ return this.createFileService(req);
+ }
+
+ public asInternal(): FileServiceStart {
+ return this.createFileService();
+ }
+
+ /**
+ * This function can only called during Kibana's setup phase
+ */
+ public static setup(savedObjectsSetup: SavedObjectsServiceSetup): void {
+ savedObjectsSetup.registerType>(fileObjectType);
+ savedObjectsSetup.registerType(fileShareObjectType);
+ }
+}
diff --git a/x-pack/plugins/files/server/file_service/index.ts b/x-pack/plugins/files/server/file_service/index.ts
new file mode 100644
index 0000000000000..c094c9f2d056b
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { FileServiceFactoryImpl as FileServiceFactory } from './file_service_factory';
+export type {
+ CreateFileArgs,
+ DeleteFileArgs,
+ FindFileArgs,
+ GetByIdArgs,
+ ListFilesArgs,
+ UpdateFileArgs,
+} from './file_action_types';
+export type { FileServiceStart } from './file_service';
+export * as errors from './errors';
diff --git a/x-pack/plugins/files/server/file_service/internal_file_service.ts b/x-pack/plugins/files/server/file_service/internal_file_service.ts
new file mode 100644
index 0000000000000..567df3e137848
--- /dev/null
+++ b/x-pack/plugins/files/server/file_service/internal_file_service.ts
@@ -0,0 +1,156 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { Logger, SavedObjectsErrorHelpers } from '@kbn/core/server';
+import { AuditEvent, AuditLogger } from '@kbn/security-plugin/server';
+
+import { BlobStorageService } from '../blob_storage_service';
+import { InternalFileShareService } from '../file_share_service';
+import { FileMetadata, File as IFile, FileKind, FileJSON, FilesMetrics } from '../../common';
+import { File, toJSON } from '../file';
+import { FileKindsRegistry } from '../file_kinds_registry';
+import { FileNotFoundError } from './errors';
+import type { FileMetadataClient } from '../file_client';
+import type {
+ CreateFileArgs,
+ UpdateFileArgs,
+ DeleteFileArgs,
+ FindFileArgs,
+ GetByIdArgs,
+ ListFilesArgs,
+} from './file_action_types';
+import { FileClientImpl } from '../file_client/file_client';
+/**
+ * Service containing methods for working with files.
+ *
+ * All file business logic is encapsulated in the {@link File} class.
+ *
+ * @internal
+ */
+export class InternalFileService {
+ constructor(
+ private readonly metadataClient: FileMetadataClient,
+ private readonly blobStorageService: BlobStorageService,
+ private readonly fileShareService: InternalFileShareService,
+ private readonly auditLogger: undefined | AuditLogger,
+ private readonly fileKindRegistry: FileKindsRegistry,
+ private readonly logger: Logger
+ ) {}
+
+ public async createFile(args: CreateFileArgs): Promise {
+ const fileKind = this.getFileKind(args.fileKind);
+ return await File.create(
+ { ...args, fileKind },
+ this,
+ new FileClientImpl(
+ fileKind,
+ this.metadataClient,
+ this.blobStorageService.createBlobStorageClient(fileKind.blobStoreSettings)
+ )
+ );
+ }
+
+ public writeAuditLog(event: AuditEvent) {
+ if (this.auditLogger) {
+ this.auditLogger.log(event);
+ } else {
+ // Otherwise just log to info
+ this.logger.info(event.message);
+ }
+ }
+
+ public async updateFile({ attributes, fileKind, id }: UpdateFileArgs): Promise {
+ const file = await this.getById({ fileKind, id });
+ return await file.update(attributes);
+ }
+
+ public async deleteFile({ id, fileKind }: DeleteFileArgs): Promise {
+ const file = await this.getById({ id, fileKind });
+ await file.delete();
+ }
+
+ private async get(id: string) {
+ try {
+ const { metadata } = await this.metadataClient.get({ id });
+ if (metadata.Status === 'DELETED') {
+ throw new FileNotFoundError('File has been deleted');
+ }
+ return this.toFile(id, metadata, this.getFileKind(metadata.FileKind));
+ } catch (e) {
+ if (SavedObjectsErrorHelpers.isNotFoundError(e)) {
+ throw new FileNotFoundError('File not found');
+ }
+ this.logger.error(`Could not retrieve file: ${e}`);
+ throw e;
+ }
+ }
+
+ public async getById({ fileKind, id }: GetByIdArgs): Promise {
+ const file = await this.get(id);
+ if (file.fileKind !== fileKind) {
+ throw new Error(`Unexpected file kind "${file.fileKind}", expected "${fileKind}".`);
+ }
+ return file;
+ }
+
+ public async list({
+ fileKind: fileKindId,
+ page = 1,
+ perPage = 100,
+ }: ListFilesArgs): Promise {
+ const fileKind = this.getFileKind(fileKindId);
+ const result = await this.metadataClient.list({
+ fileKind: fileKind.id,
+ page,
+ perPage,
+ });
+ return result.map((file) => this.toFile(file.id, file.metadata, fileKind));
+ }
+
+ public toFile(
+ id: string,
+ fileMetadata: FileMetadata,
+ fileKind: FileKind,
+ fileClient?: FileClientImpl
+ ): IFile {
+ return new File(
+ id,
+ fileMetadata,
+ fileClient ??
+ new FileClientImpl(
+ fileKind,
+ this.metadataClient,
+ this.blobStorageService.createBlobStorageClient(fileKind.blobStoreSettings)
+ ),
+ this,
+ this.fileShareService,
+ this.logger.get(`file-${id}`)
+ );
+ }
+
+ public getFileKind(id: string): FileKind {
+ return this.fileKindRegistry.get(id);
+ }
+
+ public async findFilesJSON(args: FindFileArgs): Promise {
+ const result = await this.metadataClient.find(args);
+ return result.map((r) => toJSON(r.id, r.metadata));
+ }
+
+ public async getUsageMetrics(): Promise {
+ return this.metadataClient.getUsageMetrics({
+ esFixedSizeIndex: {
+ capacity: this.blobStorageService.getStaticBlobStorageSettings().esFixedSizeIndex.capacity,
+ },
+ });
+ }
+
+ public async getByToken(token: string) {
+ const { fileId } = await this.fileShareService.getByToken(token);
+ return this.get(fileId);
+ }
+}
diff --git a/x-pack/plugins/files/server/file_share_service/errors.ts b/x-pack/plugins/files/server/file_share_service/errors.ts
new file mode 100644
index 0000000000000..89979f0689979
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/errors.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/* eslint-disable max-classes-per-file */
+
+abstract class FileShareError extends Error {
+ constructor(message: string) {
+ super(message);
+ Error.captureStackTrace(this);
+ }
+}
+
+export class ExpiryDateInThePastError extends FileShareError {}
+export class FileShareNotFoundError extends FileShareError {}
+export class FileShareTokenInvalidError extends FileShareError {}
diff --git a/x-pack/plugins/files/server/file_share_service/generate_share_token.test.ts b/x-pack/plugins/files/server/file_share_service/generate_share_token.test.ts
new file mode 100644
index 0000000000000..93767c7484986
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/generate_share_token.test.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { generateShareToken } from './generate_share_token';
+
+describe('generateShareToken', () => {
+ it('should contain only expected chars of a given length', () => {
+ for (let i = 0; i < 50; i++) {
+ expect(generateShareToken()).toMatch(/^[a-zA-O0-9]{40}$/);
+ }
+ });
+});
diff --git a/x-pack/plugins/files/server/file_share_service/generate_share_token.ts b/x-pack/plugins/files/server/file_share_service/generate_share_token.ts
new file mode 100644
index 0000000000000..ef779db49223a
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/generate_share_token.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import crypto from 'crypto';
+
+/**
+ * Char set of 51 characters gets an even distribution for each byte of randomness
+ * generated because 255 (max number) % 51 = 0.
+ */
+const CHAR_SET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO0123456789';
+
+/**
+ * Generate 40 random characters of a pre-checked charset for share tokens.
+ *
+ * Samples:
+ *
+ * a7EyHf1LrK37uCx4ld3m7Lhkgl2kxuMrIn6umkjz
+ * 72wq34jHgkix9noCbEKIjfmivD1pBypxmbs3wzEn
+ * mtr9Eq5w06rIhDHzM73vBumL4joKjkaILK9a5ikI
+ * 6cbikArFgx1gwjcBc9v3FxdGojzjdpKbCGJspCHA
+ * sOi94wwygidgKozwfDnoeIhpFywMwyMkBFcd5oCi
+ */
+export function generateShareToken(): string {
+ return [...crypto.randomBytes(40)].reduce((acc, nr) => {
+ return acc + CHAR_SET[nr % CHAR_SET.length];
+ }, '');
+}
diff --git a/x-pack/plugins/files/server/file_share_service/index.ts b/x-pack/plugins/files/server/file_share_service/index.ts
new file mode 100644
index 0000000000000..dd52ec05777c1
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { InternalFileShareService } from './internal_file_share_service';
+export type {
+ CreateShareArgs,
+ DeleteArgs as DeleteShareArgs,
+ DeleteForFileArgs as DeleteSharesForFileArgs,
+ GetArgs as GetShareArgs,
+ ListArgs as ListSharesArgs,
+ UpdateArgs as UpdateShareArgs,
+} from './internal_file_share_service';
+export type { FileShareServiceStart } from './types';
diff --git a/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts
new file mode 100644
index 0000000000000..7b6f8498b0e3e
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/internal_file_share_service.ts
@@ -0,0 +1,233 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import moment from 'moment';
+import {
+ SavedObjectsClientContract,
+ SavedObject,
+ ISavedObjectsRepository,
+ SavedObjectsErrorHelpers,
+} from '@kbn/core/server';
+import { nodeBuilder, escapeKuery } from '@kbn/es-query';
+import type {
+ Pagination,
+ FileShareJSON,
+ FileShareJSONWithToken,
+ FileShare,
+ UpdatableFileShareMetadata,
+} from '../../common/types';
+import { FILE_SO_TYPE } from '../../common/constants';
+import type { File } from '../../common/types';
+import { fileShareObjectType } from '../saved_objects';
+import { generateShareToken } from './generate_share_token';
+import { FileShareServiceStart } from './types';
+import {
+ ExpiryDateInThePastError,
+ FileShareNotFoundError,
+ FileShareTokenInvalidError,
+} from './errors';
+
+/**
+ * Arguments for a creating a file share
+ */
+export interface CreateShareArgs {
+ /**
+ * Optionally provide a name for this file share instance
+ */
+ name?: string;
+ /**
+ * Optionally set an expiration date as unix timestamp for this file share instance
+ *
+ * @note If not specified the file share will expire after 30 days
+ */
+ validUntil?: number;
+
+ /**
+ * The file object to create the share for
+ */
+ file: File;
+}
+
+/**
+ * Arguments for listing file shares.
+ */
+export interface ListArgs extends Pagination {
+ /**
+ * The file ID for scope the list to.
+ */
+ fileId?: string;
+}
+
+/**
+ * ID argument
+ */
+interface IdArg {
+ /**
+ * File share ID.
+ */
+ id: string;
+}
+
+/**
+ * Delete file share arguments.
+ */
+export type DeleteArgs = IdArg;
+/**
+ * Get file share arguments.
+ */
+export type GetArgs = IdArg;
+
+/**
+ * Delete file shares for file arguments.
+ */
+export interface DeleteForFileArgs {
+ /**
+ * The file object to delete the shares for.
+ */
+ file: File;
+}
+
+/**
+ * Update file share arguments.
+ */
+export interface UpdateArgs {
+ /**
+ * The file share ID.
+ */
+ id: string;
+ /**
+ * The updated attributes to store.
+ */
+ attributes: UpdatableFileShareMetadata;
+}
+
+function toFileShareJSON(so: SavedObject): FileShareJSON {
+ return {
+ id: so.id,
+ fileId: so.references[0]?.id, // Assuming a single file reference
+ created: so.attributes.created,
+ validUntil: so.attributes.valid_until,
+ name: so.attributes.name,
+ };
+}
+
+function validateCreateArgs({ validUntil }: CreateShareArgs): void {
+ if ((validUntil || validUntil === 0) && validUntil < Date.now()) {
+ throw new ExpiryDateInThePastError('Share expiry date must be in the future.');
+ }
+}
+
+/**
+ * Service for managing file shares and associated Saved Objects.
+ *
+ * @internal
+ */
+export class InternalFileShareService implements FileShareServiceStart {
+ private readonly savedObjectsType = fileShareObjectType.name;
+
+ constructor(
+ private readonly savedObjects: SavedObjectsClientContract | ISavedObjectsRepository
+ ) {}
+
+ public async share(args: CreateShareArgs): Promise {
+ validateCreateArgs(args);
+ const { file, name, validUntil } = args;
+ const so = await this.savedObjects.create(
+ this.savedObjectsType,
+ {
+ created: new Date().toISOString(),
+ name,
+ valid_until: validUntil ? validUntil : Number(moment().add(30, 'days')),
+ token: generateShareToken(),
+ },
+ {
+ references: [{ name: file.name, id: file.id, type: FILE_SO_TYPE }],
+ }
+ );
+
+ return { ...toFileShareJSON(so), token: so.attributes.token };
+ }
+
+ public async delete({ id }: DeleteArgs): Promise {
+ try {
+ await this.savedObjects.delete(this.savedObjectsType, id);
+ } catch (e) {
+ if (SavedObjectsErrorHelpers.isNotFoundError(e)) {
+ throw new FileShareNotFoundError(`File share with id "${id}" not found.`);
+ }
+ throw e;
+ }
+ }
+
+ private async internalList({
+ fileId,
+ perPage,
+ page,
+ }: ListArgs): Promise>> {
+ const result = await this.savedObjects.find({
+ type: this.savedObjectsType,
+ hasReference: fileId
+ ? {
+ type: FILE_SO_TYPE,
+ id: fileId,
+ }
+ : undefined,
+ perPage,
+ page,
+ sortField: 'created',
+ sortOrder: 'desc',
+ });
+ return result.saved_objects;
+ }
+
+ public async deleteForFile({ file }: DeleteForFileArgs): Promise {
+ const savedObjects = await this.internalList({ fileId: file.id });
+ await Promise.all(savedObjects.map(({ id }) => this.delete({ id })));
+ }
+
+ /**
+ * Get a share token and also check whether it is valid.
+ */
+ public async getByToken(token: string): Promise {
+ const {
+ saved_objects: [share],
+ } = await this.savedObjects.find({
+ type: this.savedObjectsType,
+ filter: nodeBuilder.is(`${this.savedObjectsType}.attributes.token`, escapeKuery(token)),
+ });
+
+ if (!share) {
+ throw new FileShareNotFoundError(`Could not find file share with token "${token}".`);
+ }
+ if (share.attributes.valid_until < Date.now() / 1000) {
+ throw new FileShareTokenInvalidError(`Share "${token}" has expired.`);
+ }
+ return toFileShareJSON(share);
+ }
+
+ public async get({ id }: GetArgs): Promise {
+ try {
+ return toFileShareJSON(await this.savedObjects.get(this.savedObjectsType, id));
+ } catch (e) {
+ if (SavedObjectsErrorHelpers.isNotFoundError(e)) {
+ throw new FileShareNotFoundError(e);
+ }
+ throw e;
+ }
+ }
+
+ public async update({ id, attributes }: UpdateArgs): Promise {
+ const result = await this.savedObjects.update(this.savedObjectsType, id, attributes);
+ return { id, ...(result.attributes as FileShare) };
+ }
+
+ public async list(args: ListArgs): Promise<{ shares: FileShareJSON[] }> {
+ const savedObjects = await this.internalList(args);
+ return {
+ shares: savedObjects.map(toFileShareJSON),
+ };
+ }
+}
diff --git a/x-pack/plugins/files/server/file_share_service/types.ts b/x-pack/plugins/files/server/file_share_service/types.ts
new file mode 100644
index 0000000000000..bf3147d933083
--- /dev/null
+++ b/x-pack/plugins/files/server/file_share_service/types.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { FileShareJSON, FileShare } from '../../common/types';
+import type { GetArgs, UpdateArgs, DeleteArgs, ListArgs } from './internal_file_share_service';
+
+/**
+ * We only expose functionality here that do not require you to have a {@link File}
+ * instance loaded.
+ */
+export interface FileShareServiceStart {
+ /**
+ * Get a share instance
+ *
+ * @param {GetArgs} arg - the arguments to get the share instance
+ */
+ get(arg: GetArgs): Promise;
+
+ /**
+ * List share objects
+ *
+ * @param {ListArgs} arg - the arguments to list share objects
+ */
+ list(arg: ListArgs): Promise<{ shares: FileShareJSON[] }>;
+
+ /**
+ * Update a share instance.
+ *
+ * @param {UpdateArgs} args - the arguments to update a share instance
+ */
+ update(args: UpdateArgs): Promise;
+
+ /**
+ * Delete a share instance.
+ *
+ * @param {DeleteArgs} args - the arguments to delete a share instance
+ */
+ delete(args: DeleteArgs): Promise;
+}
diff --git a/x-pack/plugins/files/server/index.ts b/x-pack/plugins/files/server/index.ts
new file mode 100755
index 0000000000000..7b1ecc5ac89ce
--- /dev/null
+++ b/x-pack/plugins/files/server/index.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { PluginInitializerContext } from '@kbn/core/server';
+import { FilesPlugin } from './plugin';
+
+export type {
+ FileClient,
+ FileDescriptor,
+ GetMetadataArg,
+ FindMetadataArg,
+ ListMetadataArg,
+ UpdateMetadataArg,
+ DeleteMetedataArg,
+ FileMetadataClient,
+ GetUsageMetricsArgs,
+ CreateEsFileClientArgs,
+} from './file_client';
+export { createEsFileClient } from './file_client';
+
+export type { FilesSetup, FilesStart } from './types';
+export type {
+ FileShareServiceStart,
+ CreateShareArgs,
+ DeleteShareArgs,
+ DeleteSharesForFileArgs,
+ GetShareArgs,
+ ListSharesArgs,
+ UpdateShareArgs,
+} from './file_share_service';
+export type {
+ GetByIdArgs,
+ FindFileArgs,
+ ListFilesArgs,
+ CreateFileArgs,
+ DeleteFileArgs,
+ UpdateFileArgs,
+ FileServiceStart,
+} from './file_service';
+export type { FileServiceFactory } from './file_service/file_service_factory';
+
+export function plugin(initializerContext: PluginInitializerContext) {
+ return new FilesPlugin(initializerContext);
+}
diff --git a/x-pack/plugins/files/server/integration_tests/README.md b/x-pack/plugins/files/server/integration_tests/README.md
new file mode 100644
index 0000000000000..fb35bc3f0ecc9
--- /dev/null
+++ b/x-pack/plugins/files/server/integration_tests/README.md
@@ -0,0 +1,10 @@
+## File service integration tests
+
+The set of tests for File Service integration should cover all file service
+functionality. These tests run against an actual Kibana and ES.
+
+File service is the top-level entry-point for working with files. These integration
+tests are closer to functional tests for all of Blob store service, file objects,
+file sharing service and file service itself.
+
+These tests do not include HTTP endpoint tests.
diff --git a/x-pack/plugins/files/server/integration_tests/file_service.test.ts b/x-pack/plugins/files/server/integration_tests/file_service.test.ts
new file mode 100644
index 0000000000000..0547fe0ed30fb
--- /dev/null
+++ b/x-pack/plugins/files/server/integration_tests/file_service.test.ts
@@ -0,0 +1,346 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CoreStart, ElasticsearchClient } from '@kbn/core/server';
+import { httpServiceMock } from '@kbn/core/server/mocks';
+import {
+ createTestServers,
+ createRootWithCorePlugins,
+ TestElasticsearchUtils,
+} from '@kbn/core/test_helpers/kbn_server';
+import { securityMock } from '@kbn/security-plugin/server/mocks';
+import type { AuditLogger } from '@kbn/security-plugin/server';
+import { Readable } from 'stream';
+
+import type { FileStatus, File } from '../../common';
+
+import {
+ FileKindsRegistryImpl,
+ getFileKindsRegistry,
+ setFileKindsRegistry,
+} from '../file_kinds_registry';
+import { BlobStorageService } from '../blob_storage_service';
+import { FileServiceStart, FileServiceFactory } from '../file_service';
+import type { CreateFileArgs } from '../file_service/file_action_types';
+
+describe('FileService', () => {
+ const fileKind: string = 'test';
+ const fileKindNonDefault: string = 'test-non-default';
+ const fileKindTinyFiles: string = 'tiny-files';
+ const nonDefaultIndex = '.kibana-test-files';
+
+ let manageES: TestElasticsearchUtils;
+ let kbnRoot: ReturnType;
+ let fileService: FileServiceStart;
+ let blobStorageService: BlobStorageService;
+ let esClient: ElasticsearchClient;
+ let coreSetup: Awaited>;
+ let coreStart: CoreStart;
+ let fileServiceFactory: FileServiceFactory;
+ let security: ReturnType;
+ let auditLogger: AuditLogger;
+
+ beforeAll(async () => {
+ const { startES } = createTestServers({ adjustTimeout: jest.setTimeout });
+ manageES = await startES();
+ kbnRoot = createRootWithCorePlugins();
+ await kbnRoot.preboot();
+ coreSetup = await kbnRoot.setup();
+ FileServiceFactory.setup(coreSetup.savedObjects);
+ coreStart = await kbnRoot.start();
+ setFileKindsRegistry(new FileKindsRegistryImpl(httpServiceMock.createRouter()));
+ const fileKindsRegistry = getFileKindsRegistry();
+ fileKindsRegistry.register({
+ id: fileKind,
+ http: {},
+ });
+ fileKindsRegistry.register({
+ id: fileKindNonDefault,
+ http: {},
+ blobStoreSettings: { esFixedSizeIndex: { index: nonDefaultIndex } },
+ });
+ fileKindsRegistry.register({
+ id: fileKindTinyFiles,
+ maxSizeBytes: 10,
+ http: {},
+ });
+ esClient = coreStart.elasticsearch.client.asInternalUser;
+ });
+
+ afterAll(async () => {
+ await kbnRoot.shutdown();
+ await manageES.stop();
+ });
+
+ beforeEach(() => {
+ security = securityMock.createSetup();
+ auditLogger = { enabled: true, log: jest.fn() };
+ (security.audit.asScoped as jest.Mock).mockReturnValue(auditLogger);
+ security.audit.withoutRequest = auditLogger;
+ blobStorageService = new BlobStorageService(esClient, kbnRoot.logger.get('test-blob-service'));
+ fileServiceFactory = new FileServiceFactory(
+ coreStart.savedObjects,
+ blobStorageService,
+ security,
+ getFileKindsRegistry(),
+ kbnRoot.logger.get('test-file-service')
+ );
+ fileService = fileServiceFactory.asInternal();
+ });
+
+ let disposables: File[] = [];
+ async function createDisposableFile(args: CreateFileArgs) {
+ const file = await fileService.create(args);
+ disposables.push(file);
+ return file;
+ }
+ afterEach(async () => {
+ await Promise.all(disposables.map((file) => file.delete()));
+ const results = await fileService.list({ fileKind });
+ expect(results.length).toBe(0);
+ disposables = [];
+ });
+
+ it('creates file metadata awaiting upload', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ expect(file.name).toEqual('test');
+ expect(file.fileKind).toEqual(fileKind);
+ expect(file.status).toBe('AWAITING_UPLOAD' as FileStatus);
+ expect(auditLogger.log).toHaveBeenCalledTimes(1);
+ expect(auditLogger.log).toHaveBeenCalledWith({
+ error: undefined,
+ event: {
+ action: 'create',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Created file "test"'),
+ });
+ });
+
+ it('uploads file content', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ expect(file.status).toBe('AWAITING_UPLOAD' as FileStatus);
+ await file.uploadContent(Readable.from(['upload this']));
+ expect(file.status).toBe('READY' as FileStatus);
+ const rs = await file.downloadContent();
+ const chunks: string[] = [];
+ for await (const chunk of rs) {
+ chunks.push(chunk);
+ }
+ expect(chunks.join('')).toBe('upload this');
+ });
+
+ it('retrieves a file', async () => {
+ const { id } = await createDisposableFile({ fileKind, name: 'test' });
+ const myFile = await fileService.getById({ id, fileKind });
+ expect(myFile?.id).toMatch(id);
+ });
+
+ it('lists files', async () => {
+ await Promise.all([
+ createDisposableFile({ fileKind, name: 'test-1' }),
+ createDisposableFile({ fileKind, name: 'test-2' }),
+ createDisposableFile({ fileKind, name: 'test-3' }),
+ createDisposableFile({ fileKind, name: 'test-3' /* Also test file with same name */ }),
+ ]);
+ const result = await fileService.list({ fileKind });
+ expect(result.length).toBe(4);
+ });
+
+ it('deletes files', async () => {
+ const file = await fileService.create({ fileKind, name: 'test' });
+ const files = await fileService.list({ fileKind });
+ expect(files.length).toBe(1);
+ await file.delete();
+ expect(await fileService.list({ fileKind })).toEqual([]);
+ });
+
+ interface CustomMeta {
+ some: string;
+ }
+ it('updates files', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ const updatableFields = {
+ name: 'new name',
+ alt: 'my alt text',
+ meta: { some: 'data' },
+ };
+ const updatedFile1 = await file.update(updatableFields);
+ expect(updatedFile1.meta).toEqual(expect.objectContaining(updatableFields.meta));
+ expect(updatedFile1.name).toBe(updatableFields.name);
+ expect(updatedFile1.alt).toBe(updatableFields.alt);
+
+ // Fetch the file anew to be doubly sure
+ const updatedFile2 = await fileService.getById({ fileKind, id: file.id });
+ expect(updatedFile2.meta).toEqual(expect.objectContaining(updatableFields.meta));
+ // Below also tests that our meta type is work as expected by using `some` field.
+ expect(updatedFile2.meta?.some).toBe(updatableFields.meta.some);
+ expect(updatedFile2.name).toBe(updatableFields.name);
+ expect(updatedFile2.alt).toBe(updatableFields.alt);
+ });
+
+ it('enforces max size settings', async () => {
+ const file = await createDisposableFile({ fileKind: fileKindTinyFiles, name: 'test' });
+ const tinyContent = Readable.from(['ok']);
+ await file.uploadContent(tinyContent);
+
+ const file2 = await createDisposableFile({ fileKind: fileKindTinyFiles, name: 'test' });
+ const notSoTinyContent = Readable.from(['nok'.repeat(10)]);
+ await expect(() => file2.uploadContent(notSoTinyContent)).rejects.toThrow(
+ new Error('Maximum of 10 bytes exceeded')
+ );
+ });
+
+ describe('ES blob integration and file kinds', () => {
+ it('passes blob store settings', async () => {
+ const file = await createDisposableFile({ fileKind: fileKindNonDefault, name: 'test' });
+ expect(await esClient.indices.exists({ index: nonDefaultIndex })).toBe(false);
+ await file.uploadContent(Readable.from(['test']));
+ expect(await esClient.indices.exists({ index: nonDefaultIndex })).toBe(true);
+ });
+ });
+
+ describe('Sharing files', () => {
+ it('creates a file share object', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ const shareObject = await file.share({ name: 'test name' });
+ expect(shareObject).toEqual(
+ expect.objectContaining({
+ id: expect.any(String),
+ name: 'test name',
+ validUntil: expect.any(Number),
+ created: expect.any(String),
+ token: expect.any(String),
+ fileId: file.id,
+ })
+ );
+ expect(auditLogger.log).toHaveBeenCalledTimes(2);
+ expect(auditLogger.log).toHaveBeenNthCalledWith(1, {
+ error: undefined,
+ event: {
+ action: 'create',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Created file "test"'),
+ });
+ expect(auditLogger.log).toHaveBeenNthCalledWith(2, {
+ error: undefined,
+ event: {
+ action: 'create',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Shared file "test"'),
+ });
+ });
+
+ it('retrieves a a file share object', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ const { id } = await file.share({ name: 'my-file-share' });
+ // Check if a file share exists without using an {@link File} object
+ const result = await fileService.getShareObject({ id });
+ expect(result).toEqual(
+ expect.objectContaining({
+ id: expect.any(String),
+ name: 'my-file-share',
+ validUntil: expect.any(Number),
+ created: expect.any(String),
+ fileId: file.id,
+ })
+ );
+ });
+
+ it('updates a file share object', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'test' });
+ const { id } = await file.share({ name: 'my file share 1' });
+ // Check if a file share exists without using an {@link File} object
+ await fileService.updateShareObject({ id, attributes: { name: 'my file share 2' } });
+ const result = await fileService.getShareObject({ id });
+ expect(result).toEqual(
+ expect.objectContaining({
+ id: expect.any(String),
+ name: 'my file share 2',
+ validUntil: expect.any(Number),
+ created: expect.any(String),
+ fileId: file.id,
+ })
+ );
+ });
+
+ it('lists all file share objects for a file', async () => {
+ const [file, file2] = await Promise.all([
+ createDisposableFile({ fileKind, name: 'test' }),
+ createDisposableFile({ fileKind, name: 'anothertest' }),
+ ]);
+
+ const [share1] = await Promise.all([
+ file.share({ name: 'my-file-share-1' }),
+ file.share({ name: 'my-file-share-2' }),
+ file.share({ name: 'my-file-share-3' }),
+
+ file2.share({ name: 'my-file-share-1' }),
+ file2.share({ name: 'my-file-share-2' }),
+ file2.share({ name: 'my-file-share-3' }),
+ ]);
+
+ // Check whether updating file attributes interferes with SO references.
+ await fileService.updateShareObject({
+ id: share1.id,
+ attributes: { name: 'my-file-share-X' },
+ });
+
+ const shares1 = await file.listShares();
+ expect(shares1).toHaveLength(3);
+ expect(shares1[0]).toEqual(
+ expect.objectContaining({
+ id: expect.any(String),
+ fileId: file.id,
+ })
+ );
+ const shares2 = await file2.listShares();
+ expect(await file2.listShares()).toHaveLength(3);
+ expect(shares2[0]).toEqual(
+ expect.objectContaining({
+ id: expect.any(String),
+ fileId: file2.id,
+ })
+ );
+ });
+
+ it('deletes a file share object', async () => {
+ const file = await createDisposableFile({ fileKind, name: 'myfile' });
+ const { id } = await file.share({ name: 'my file share' });
+ expect(await file.listShares()).toHaveLength(1);
+ await file.unshare({ shareId: id });
+ expect(await file.listShares()).toEqual([]);
+ expect(auditLogger.log).toHaveBeenCalledTimes(3);
+ expect(auditLogger.log).toHaveBeenNthCalledWith(1, {
+ error: undefined,
+ event: {
+ action: 'create',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Created file "myfile"'),
+ });
+ expect(auditLogger.log).toHaveBeenNthCalledWith(2, {
+ error: undefined,
+ event: {
+ action: 'create',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Shared file "myfile"'),
+ });
+ expect(auditLogger.log).toHaveBeenNthCalledWith(3, {
+ error: undefined,
+ event: {
+ action: 'delete',
+ outcome: 'success',
+ },
+ message: expect.stringContaining('Removed share for "myfile"'),
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/files/server/plugin.ts b/x-pack/plugins/files/server/plugin.ts
new file mode 100755
index 0000000000000..61dd86c6d9e15
--- /dev/null
+++ b/x-pack/plugins/files/server/plugin.ts
@@ -0,0 +1,87 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type {
+ PluginInitializerContext,
+ CoreSetup,
+ Plugin,
+ Logger,
+ CoreStart,
+} from '@kbn/core/server';
+
+import { PLUGIN_ID } from '../common/constants';
+
+import { BlobStorageService } from './blob_storage_service';
+import { FileServiceFactory } from './file_service';
+import type { FilesPluginSetupDependencies, FilesSetup, FilesStart } from './types';
+import {
+ setFileKindsRegistry,
+ getFileKindsRegistry,
+ FileKindsRegistryImpl,
+} from './file_kinds_registry';
+import type { FilesRequestHandlerContext, FilesRouter } from './routes/types';
+import { registerRoutes } from './routes';
+
+export class FilesPlugin implements Plugin {
+ private readonly logger: Logger;
+ private fileServiceFactory: undefined | FileServiceFactory;
+ private securitySetup: FilesPluginSetupDependencies['security'];
+
+ constructor(initializerContext: PluginInitializerContext) {
+ this.logger = initializerContext.logger.get();
+ }
+
+ public setup(core: CoreSetup, deps: FilesPluginSetupDependencies): FilesSetup {
+ FileServiceFactory.setup(core.savedObjects);
+ this.securitySetup = deps.security;
+
+ core.http.registerRouteHandlerContext(
+ PLUGIN_ID,
+ async (ctx, req) => {
+ return {
+ fileService: {
+ asCurrentUser: () => this.fileServiceFactory!.asScoped(req),
+ asInternalUser: () => this.fileServiceFactory!.asInternal(),
+ logger: this.logger.get('files-routes'),
+ },
+ };
+ }
+ );
+
+ const router: FilesRouter = core.http.createRouter();
+ registerRoutes(router);
+ setFileKindsRegistry(new FileKindsRegistryImpl(router));
+
+ return {
+ registerFileKind(fileKind) {
+ getFileKindsRegistry().register(fileKind);
+ },
+ };
+ }
+
+ public start(coreStart: CoreStart): FilesStart {
+ const { savedObjects } = coreStart;
+ const esClient = coreStart.elasticsearch.client.asInternalUser;
+ const blobStorageService = new BlobStorageService(
+ esClient,
+ this.logger.get('blob-storage-service')
+ );
+ this.fileServiceFactory = new FileServiceFactory(
+ savedObjects,
+ blobStorageService,
+ this.securitySetup,
+ getFileKindsRegistry(),
+ this.logger.get('files-service')
+ );
+
+ return {
+ fileServiceFactory: this.fileServiceFactory,
+ };
+ }
+
+ public stop() {}
+}
diff --git a/x-pack/plugins/files/server/routes/api_routes.ts b/x-pack/plugins/files/server/routes/api_routes.ts
new file mode 100644
index 0000000000000..b40696bfe61e7
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/api_routes.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ FILES_API_BASE_PATH,
+ FILES_SHARE_API_BASE_PATH,
+ FILES_PUBLIC_API_BASE_PATH,
+ API_BASE_PATH,
+} from '../../common/api_routes';
+
+export * from '../../common/api_routes';
+
+export const FILES_API_ROUTES = {
+ find: `${API_BASE_PATH}/find`,
+ metrics: `${API_BASE_PATH}/metrics`,
+ public: {
+ download: `${FILES_PUBLIC_API_BASE_PATH}/blob/{fileName?}`,
+ },
+ fileKind: {
+ getCreateFileRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}`,
+ getUploadRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}/{id}/blob`,
+ getDownloadRoute: (fileKind: string) =>
+ `${FILES_API_BASE_PATH}/${fileKind}/{id}/blob/{fileName?}`,
+ getUpdateRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}/{id}`,
+ getDeleteRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}/{id}`,
+ getListRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}/list`,
+ getByIdRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}/{id}`,
+ getShareRoute: (fileKind: string) => `${FILES_SHARE_API_BASE_PATH}/${fileKind}/{fileId}`,
+ getUnshareRoute: (fileKind: string) => `${FILES_SHARE_API_BASE_PATH}/${fileKind}/{id}`,
+ getGetShareRoute: (fileKind: string) => `${FILES_SHARE_API_BASE_PATH}/${fileKind}/{id}`,
+ getListShareRoute: (fileKind: string) => `${FILES_SHARE_API_BASE_PATH}/${fileKind}`,
+ },
+};
diff --git a/x-pack/plugins/files/server/routes/common.test.ts b/x-pack/plugins/files/server/routes/common.test.ts
new file mode 100644
index 0000000000000..cda57b5b6bf13
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/common.test.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { File } from '../file';
+import { getDownloadHeadersForFile } from './common';
+
+describe('getDownloadHeadersForFile', () => {
+ function t({ cd, ct }: { cd: string; ct: string }) {
+ return {
+ 'content-type': ct,
+ 'content-disposition': `attachment; filename="${cd}"`,
+ };
+ }
+
+ const file = { name: 'test', mimeType: undefined } as unknown as File;
+ test('no mime type and name from file object', () => {
+ expect(getDownloadHeadersForFile(file, undefined)).toEqual(
+ t({ ct: 'application/octet-stream', cd: 'test' })
+ );
+ });
+
+ test('no mime type and name (without ext)', () => {
+ expect(getDownloadHeadersForFile(file, 'myfile')).toEqual(
+ t({ ct: 'application/octet-stream', cd: 'myfile' })
+ );
+ });
+ test('no mime type and name (with ext)', () => {
+ expect(getDownloadHeadersForFile(file, 'myfile.png')).toEqual(
+ t({ ct: 'image/png', cd: 'myfile.png' })
+ );
+ });
+ test('mime type and no name', () => {
+ const fileWithMime = { ...file, mimeType: 'application/pdf' } as File;
+ expect(getDownloadHeadersForFile(fileWithMime, undefined)).toEqual(
+ t({ ct: 'application/pdf', cd: 'test' })
+ );
+ });
+ test('mime type and name', () => {
+ const fileWithMime = { ...file, mimeType: 'application/pdf' } as File;
+ expect(getDownloadHeadersForFile(fileWithMime, 'a cool file.pdf')).toEqual(
+ t({ ct: 'application/pdf', cd: 'a cool file.pdf' })
+ );
+ });
+});
diff --git a/x-pack/plugins/files/server/routes/common.ts b/x-pack/plugins/files/server/routes/common.ts
new file mode 100644
index 0000000000000..23f702493c92d
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/common.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import mime from 'mime';
+import type { ResponseHeaders } from '@kbn/core/server';
+import type { File } from '../../common/types';
+
+export function getDownloadHeadersForFile(file: File, fileName?: string): ResponseHeaders {
+ return {
+ 'content-type':
+ (fileName && mime.getType(fileName)) ?? file.mimeType ?? 'application/octet-stream',
+ // Note, this name can be overridden by the client if set via a "download" attribute on the HTML tag.
+ 'content-disposition': `attachment; filename="${fileName || getDownloadedFileName(file)}"`,
+ };
+}
+
+export function getDownloadedFileName(file: File): string {
+ // When creating a file we also calculate the extension so the `file.extension`
+ // check is not really necessary except for type checking.
+ if (file.mimeType && file.extension) {
+ return `${file.name}.${file.extension}`;
+ }
+ return file.name;
+}
diff --git a/x-pack/plugins/files/server/routes/common_schemas.ts b/x-pack/plugins/files/server/routes/common_schemas.ts
new file mode 100644
index 0000000000000..cd254c5c106c9
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/common_schemas.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema } from '@kbn/config-schema';
+
+const ALPHA_NUMERIC_WITH_SPACES_REGEX = /^[a-z0-9\s]+$/i;
+const ALPHA_NUMERIC_WITH_SPACES_EXT_REGEX = /^[a-z0-9\s\.]+$/i;
+
+function alphanumericValidation(v: string) {
+ return ALPHA_NUMERIC_WITH_SPACES_REGEX.test(v)
+ ? undefined
+ : 'Only alphanumeric characters are allowed as file names';
+}
+
+function alphanumericWithExtValidation(v: string) {
+ return ALPHA_NUMERIC_WITH_SPACES_EXT_REGEX.test(v)
+ ? undefined
+ : 'Only alphanumeric characters, spaces (" ") and dots (".") are allowed';
+}
+
+export const fileName = schema.string({
+ minLength: 1,
+ maxLength: 256,
+ validate: alphanumericValidation,
+});
+
+export const fileNameWithExt = schema.string({
+ minLength: 1,
+ maxLength: 256,
+ validate: alphanumericWithExtValidation,
+});
+
+export const fileAlt = schema.maybe(
+ schema.string({
+ minLength: 1,
+ maxLength: 256,
+ validate: alphanumericValidation,
+ })
+);
+
+export const fileMeta = schema.maybe(schema.object({}, { unknowns: 'allow' }));
diff --git a/x-pack/plugins/files/server/routes/file_kind/create.ts b/x-pack/plugins/files/server/routes/file_kind/create.ts
new file mode 100644
index 0000000000000..985b1e8b05a54
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/create.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import { Ensure } from '@kbn/utility-types';
+import type { CreateFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKind } from '../../../common/types';
+import { FILES_API_ROUTES } from '../api_routes';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+import * as commonSchemas from '../common_schemas';
+
+export const method = 'post' as const;
+
+export const bodySchema = schema.object({
+ name: commonSchemas.fileName,
+ alt: commonSchemas.fileAlt,
+ meta: commonSchemas.fileMeta,
+ mimeType: schema.maybe(schema.string()),
+});
+
+type Body = Ensure>;
+
+type Response = CreateFileKindHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { fileKind, files },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ body: { name, alt, meta, mimeType },
+ } = req;
+ const file = await fileService
+ .asCurrentUser()
+ .create({ fileKind, name, alt, meta, mime: mimeType });
+ const body: Response = {
+ file: file.toJSON(),
+ };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.create) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getCreateFileRoute(fileKind.id),
+ validate: {
+ body: bodySchema,
+ },
+ options: {
+ tags: fileKind.http.create.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/delete.ts b/x-pack/plugins/files/server/routes/file_kind/delete.ts
new file mode 100644
index 0000000000000..154ae7efe448a
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/delete.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+import type { DeleteFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKind } from '../../../common/types';
+import { fileErrors } from '../../file';
+import { FILES_API_ROUTES } from '../api_routes';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+
+import { getById } from './helpers';
+
+export const method = 'delete' as const;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+
+type Params = Ensure>;
+
+type Response = DeleteFileKindHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async ({ files, fileKind }, req, res) => {
+ const {
+ params: { id },
+ } = req;
+ const { fileService } = await files;
+ const { error, result: file } = await getById(fileService.asCurrentUser(), id, fileKind);
+ if (error) return error;
+ try {
+ await file.delete();
+ } catch (e) {
+ if (
+ e instanceof fileErrors.AlreadyDeletedError ||
+ e instanceof fileErrors.UploadInProgressError
+ ) {
+ return res.badRequest({ body: { message: e.message } });
+ }
+ throw e;
+ }
+ const body: Response = {
+ ok: true,
+ };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.delete) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getDeleteRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.delete.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/download.ts b/x-pack/plugins/files/server/routes/file_kind/download.ts
new file mode 100644
index 0000000000000..d1ff70d17355f
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/download.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import { Ensure } from '@kbn/utility-types';
+import { Readable } from 'stream';
+
+import type { DownloadFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKind } from '../../../common/types';
+import { fileNameWithExt } from '../common_schemas';
+import { fileErrors } from '../../file';
+import { getDownloadHeadersForFile } from '../common';
+import { getById } from './helpers';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+import { FILES_API_ROUTES } from '../api_routes';
+
+export const method = 'get' as const;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+ fileName: schema.maybe(fileNameWithExt),
+});
+
+type Params = Ensure>;
+
+type Response = Readable;
+
+export const handler: FileKindsRequestHandler = async (
+ { files, fileKind },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ params: { id, fileName },
+ } = req;
+ const { error, result: file } = await getById(fileService.asCurrentUser(), id, fileKind);
+ if (error) return error;
+ try {
+ const body: Response = await file.downloadContent();
+ return res.ok({
+ body,
+ headers: getDownloadHeadersForFile(file, fileName),
+ });
+ } catch (e) {
+ if (e instanceof fileErrors.NoDownloadAvailableError) {
+ return res.notFound({ body: { message: e.message } });
+ }
+ throw e;
+ }
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.download) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getDownloadRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.download.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/enhance_router.ts b/x-pack/plugins/files/server/routes/file_kind/enhance_router.ts
new file mode 100644
index 0000000000000..b2a4f58fb8fd1
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/enhance_router.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { RequestHandler, RouteMethod, RouteRegistrar } from '@kbn/core/server';
+
+import { FilesRouter } from '../types';
+import { FileKindRouter, FileKindsRequestHandlerContext } from './types';
+
+interface Args {
+ router: FilesRouter;
+ fileKind: string;
+}
+
+type FileKindHandler = RequestHandler;
+
+/**
+ * Wraps {@link FilesRouter}, adding a middle man for injecting file-kind into
+ * route handler context
+ */
+export function enhanceRouter({ router, fileKind }: Args): FileKindRouter {
+ const handlerWrapper: (handler: FileKindHandler) => FileKindHandler =
+ (handler) => async (ctx, req, res) => {
+ return handler(
+ Object.create(ctx, { fileKind: { value: fileKind, enumerable: true, writeable: false } }),
+ req,
+ res
+ );
+ };
+
+ return new Proxy(router as FileKindRouter, {
+ get(target, prop, receiver) {
+ if (['get', 'post', 'put', 'patch', 'delete'].includes(prop as string)) {
+ const manInTheMiddleRegistrar: RouteRegistrar<
+ RouteMethod,
+ FileKindsRequestHandlerContext
+ > = (opts, handler): void => {
+ return Reflect.apply(target[prop as keyof FileKindRouter] as Function, target, [
+ opts,
+ handlerWrapper(handler as FileKindHandler),
+ ]);
+ };
+ return manInTheMiddleRegistrar;
+ }
+ return Reflect.get(target, prop, receiver);
+ },
+ });
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/get_by_id.ts b/x-pack/plugins/files/server/routes/file_kind/get_by_id.ts
new file mode 100644
index 0000000000000..02c4df0685aea
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/get_by_id.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+import type { GetByIdFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKind } from '../../../common/types';
+import { FILES_API_ROUTES } from '../api_routes';
+import { getById } from './helpers';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+
+type Response = GetByIdFileKindHttpEndpoint['output'];
+
+export const method = 'get' as const;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+type Params = Ensure>;
+
+export const handler: FileKindsRequestHandler = async ({ files, fileKind }, req, res) => {
+ const { fileService } = await files;
+ const {
+ params: { id },
+ } = req;
+ const { error, result: file } = await getById(fileService.asCurrentUser(), id, fileKind);
+ if (error) return error;
+ const body: Response = {
+ file: file.toJSON(),
+ };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.getById) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getByIdRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.getById.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/helpers.ts b/x-pack/plugins/files/server/routes/file_kind/helpers.ts
new file mode 100644
index 0000000000000..12006fb87837b
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/helpers.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { IKibanaResponse, kibanaResponseFactory } from '@kbn/core/server';
+import type { File } from '../../../common';
+import { errors, FileServiceStart } from '../../file_service';
+
+type ResultOrHttpError =
+ | { result: File; error?: undefined }
+ | { result?: undefined; error: IKibanaResponse };
+
+/**
+ * A helper that given an ID will return a file or map errors to an http response.
+ */
+export async function getById(
+ fileService: FileServiceStart,
+ id: string,
+ fileKind: string
+): Promise {
+ let result: undefined | File;
+ try {
+ result = await fileService.getById({ id, fileKind });
+ } catch (e) {
+ let error: undefined | IKibanaResponse;
+ if (e instanceof errors.FileNotFoundError) {
+ error = kibanaResponseFactory.notFound({ body: { message: e.message } });
+ } else {
+ error = kibanaResponseFactory.custom({ statusCode: 500, body: { message: e.message } });
+ }
+ return { error };
+ }
+
+ return { result };
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/index.ts b/x-pack/plugins/files/server/routes/file_kind/index.ts
new file mode 100644
index 0000000000000..2a85b289f4ea6
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/index.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { FileKind } from '../../../common/types';
+
+import { FilesRouter } from '../types';
+
+import { enhanceRouter } from './enhance_router';
+import * as create from './create';
+import * as upload from './upload';
+import * as update from './update';
+import * as deleteEndpoint from './delete';
+import * as list from './list';
+import * as download from './download';
+import * as getById from './get_by_id';
+import * as share from './share/share';
+import * as unshare from './share/unshare';
+import * as listShare from './share/list';
+import * as getShare from './share/get';
+
+/**
+ * Register a single file kind's routes
+ */
+export function registerFileKindRoutes(router: FilesRouter, fileKind: FileKind) {
+ const fileKindRouter = enhanceRouter({ router, fileKind: fileKind.id });
+ [
+ create,
+ upload,
+ update,
+ deleteEndpoint,
+ list,
+ download,
+ getById,
+ share,
+ unshare,
+ getShare,
+ listShare,
+ ].forEach((route) => {
+ route.register(fileKindRouter, fileKind);
+ });
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/integration_tests/file_kind_http.test.ts b/x-pack/plugins/files/server/routes/file_kind/integration_tests/file_kind_http.test.ts
new file mode 100644
index 0000000000000..e4d4bbdf0b297
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/integration_tests/file_kind_http.test.ts
@@ -0,0 +1,229 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { UpdatableFileMetadata } from '../../../../common/types';
+import { setupIntegrationEnvironment, TestEnvironmentUtils } from '../../../test_utils';
+
+describe('File kind HTTP API', () => {
+ let fileKind: string;
+ let createFile: TestEnvironmentUtils['createFile'];
+ let root: TestEnvironmentUtils['root'];
+ let request: TestEnvironmentUtils['request'];
+ let testHarness: TestEnvironmentUtils;
+
+ beforeAll(async () => {
+ testHarness = await setupIntegrationEnvironment();
+ ({ createFile, root, request, fileKind } = testHarness);
+ });
+
+ afterAll(async () => {
+ await testHarness.cleanupAfterAll();
+ });
+
+ afterEach(async () => {
+ await testHarness.cleanupAfterEach();
+ });
+
+ test('create a file and return the expected payload', async () => {
+ expect(await createFile()).toEqual({
+ id: expect.any(String),
+ created: expect.any(String),
+ updated: expect.any(String),
+ name: 'myFile',
+ fileKind,
+ status: 'AWAITING_UPLOAD',
+ mimeType: 'image/png',
+ extension: 'png',
+ meta: {},
+ alt: 'a picture of my dog',
+ });
+ });
+
+ test('upload a file', async () => {
+ const { id } = await createFile();
+ const result = await request
+ .put(root, `/api/files/files/${fileKind}/${id}/blob`)
+ .set('Content-Type', 'application/octet-stream')
+ .send('what have you')
+ .expect(200);
+ expect(result.body).toEqual({ ok: true, size: 13 });
+ });
+
+ test('download a file with the expected header values', async () => {
+ const { id } = await createFile({ name: 'test' });
+ await request
+ .put(root, `/api/files/files/${fileKind}/${id}/blob`)
+ .set('content-type', 'application/octet-stream')
+ .send('what have you')
+ .expect(200);
+
+ const { body: buffer, header } = await request
+ .get(root, `/api/files/files/${fileKind}/${id}/blob`)
+ .set('accept', 'application/octet-stream')
+ .buffer()
+ .expect(200);
+
+ expect(header['content-type']).toEqual('image/png');
+ expect(header['content-disposition']).toEqual('attachment; filename="test.png"');
+ expect(buffer.toString('utf8')).toEqual('what have you');
+ });
+
+ test('update a file', async () => {
+ const { id } = await createFile({ name: 'acoolfilename' });
+
+ const {
+ body: { file },
+ } = await request.get(root, `/api/files/files/${fileKind}/${id}`).expect(200);
+ expect(file.name).toBe('acoolfilename');
+
+ const updatedFileAttrs: UpdatableFileMetadata = {
+ name: 'anothercoolfilename',
+ alt: 'a picture of my cat',
+ meta: {
+ something: 'new',
+ },
+ };
+
+ const {
+ body: { file: updatedFile },
+ } = await request
+ .patch(root, `/api/files/files/${fileKind}/${id}`)
+ .send(updatedFileAttrs)
+ .expect(200);
+
+ expect(updatedFile).toEqual(expect.objectContaining(updatedFileAttrs));
+
+ const {
+ body: { file: file2 },
+ } = await request.get(root, `/api/files/files/${fileKind}/${id}`).expect(200);
+
+ expect(file2).toEqual(expect.objectContaining(updatedFileAttrs));
+ });
+
+ test('list current files', async () => {
+ const nrOfFiles = 10;
+ await Promise.all([...Array(nrOfFiles).keys()].map(() => createFile({ name: 'test' })));
+
+ const {
+ body: { files },
+ } = await request.get(root, `/api/files/files/${fileKind}/list`).expect(200);
+
+ expect(files).toHaveLength(nrOfFiles);
+ expect(files[0]).toEqual(expect.objectContaining({ name: 'test' }));
+
+ const {
+ body: { files: files2 },
+ } = await request.get(root, `/api/files/files/${fileKind}/list?page=1&perPage=5`).expect(200);
+ expect(files2).toHaveLength(5);
+ });
+
+ const twoDaysFromNow = (): number => Date.now() + 2 * (1000 * 60 * 60 * 24);
+
+ test('gets a single share object', async () => {
+ const { id } = await createFile();
+ const validUntil = twoDaysFromNow();
+ const {
+ body: { id: shareId },
+ } = await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({ validUntil, name: 'my-share' })
+ .expect(200);
+
+ const {
+ body: { share },
+ } = await request.get(root, `/api/files/shares/${fileKind}/${shareId}`).expect(200);
+
+ expect(share).toEqual(
+ expect.objectContaining({
+ id: shareId,
+ name: 'my-share',
+ validUntil,
+ created: expect.any(String),
+ fileId: id,
+ })
+ );
+ });
+
+ test('return a share token after sharing a file', async () => {
+ const { id } = await createFile();
+
+ const { body: error } = await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({
+ validUntil: 1,
+ })
+ .expect(400);
+
+ expect(error.message).toContain('must be in the future');
+
+ const { body: share } = await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({ validUntil: twoDaysFromNow(), name: 'my-share' })
+ .expect(200);
+
+ expect(share).toEqual(
+ expect.objectContaining({
+ token: expect.any(String),
+ })
+ );
+ });
+
+ test('delete a file share after it was created', async () => {
+ await request.delete(root, `/api/files/shares/${fileKind}/bogus`).expect(404);
+
+ const { id } = await createFile();
+ const {
+ body: { id: shareId },
+ } = await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({ validUntil: twoDaysFromNow(), name: 'my-share' })
+ .expect(200);
+
+ await request.delete(root, `/api/files/shares/${fileKind}/${shareId}`).expect(200);
+ await request.get(root, `/api/files/shares/${fileKind}/${shareId}`).expect(404);
+ });
+
+ test('list shares', async () => {
+ {
+ const {
+ body: { shares },
+ } = await request.get(root, `/api/files/shares/${fileKind}`).expect(200);
+ expect(shares).toEqual([]);
+ }
+
+ const { id } = await createFile();
+ await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({ validUntil: twoDaysFromNow(), name: 'my-share-1' })
+ .expect(200);
+ await request
+ .post(root, `/api/files/shares/${fileKind}/${id}`)
+ .send({ validUntil: twoDaysFromNow(), name: 'my-share-2' })
+ .expect(200);
+
+ const { id: id2 } = await createFile();
+ await request
+ .post(root, `/api/files/shares/${fileKind}/${id2}`)
+ .send({ validUntil: twoDaysFromNow(), name: 'my-share-3' })
+ .expect(200);
+
+ {
+ const {
+ body: { shares },
+ } = await request.get(root, `/api/files/shares/${fileKind}?forFileId=${id}`).expect(200);
+ expect(shares).toHaveLength(2);
+ // When we list file shares we do not get the file token back
+ expect(shares[0]).toEqual({
+ id: expect.any(String),
+ created: expect.any(String),
+ validUntil: expect.any(Number),
+ name: 'my-share-2',
+ fileId: id,
+ });
+ }
+ });
+});
diff --git a/x-pack/plugins/files/server/routes/file_kind/list.ts b/x-pack/plugins/files/server/routes/file_kind/list.ts
new file mode 100644
index 0000000000000..3eaa183869b6c
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/list.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+import type { ListFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKind } from '../../../common/types';
+import { FILES_API_ROUTES } from '../api_routes';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+
+export const method = 'get' as const;
+
+export const querySchema = schema.object({
+ page: schema.maybe(schema.number({ defaultValue: 1 })),
+ perPage: schema.maybe(schema.number({ defaultValue: 100 })),
+});
+
+type Query = Ensure>;
+
+type Response = ListFileKindHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files, fileKind },
+ req,
+ res
+) => {
+ const {
+ query: { page, perPage },
+ } = req;
+ const { fileService } = await files;
+ const response = await fileService.asCurrentUser().list({ fileKind, page, perPage });
+ const body: Response = {
+ files: response.map((result) => result.toJSON()),
+ };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.list) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getListRoute(fileKind.id),
+ validate: {
+ query: querySchema,
+ },
+ options: {
+ tags: fileKind.http.list.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/share/get.ts b/x-pack/plugins/files/server/routes/file_kind/share/get.ts
new file mode 100644
index 0000000000000..7ed01ff444a1f
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/share/get.ts
@@ -0,0 +1,64 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { Ensure } from '@kbn/utility-types';
+import { schema, TypeOf } from '@kbn/config-schema';
+
+import { FileShareNotFoundError } from '../../../file_share_service/errors';
+import { FileGetShareHttpEndpoint, FILES_API_ROUTES } from '../../api_routes';
+import type { FileKind } from '../../../../common/types';
+
+import { FileKindRouter, FileKindsRequestHandler } from '../types';
+
+export const method = 'get' as const;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+
+type Params = Ensure>;
+
+type Response = FileGetShareHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ params: { id },
+ } = req;
+
+ try {
+ const body: Response = { share: await fileService.asCurrentUser().getShareObject({ id }) };
+ return res.ok({
+ body,
+ });
+ } catch (e) {
+ if (e instanceof FileShareNotFoundError) {
+ return res.notFound({ body: { message: `File share with id "${id}" not found` } });
+ }
+ throw e;
+ }
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.share) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getGetShareRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.share.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/share/list.ts b/x-pack/plugins/files/server/routes/file_kind/share/list.ts
new file mode 100644
index 0000000000000..017f99db9b2e7
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/share/list.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+
+import { FileListSharesHttpEndpoint, FILES_API_ROUTES } from '../../api_routes';
+import type { FileKind } from '../../../../common/types';
+import { FileKindRouter, FileKindsRequestHandler } from '../types';
+
+export const method = 'get' as const;
+
+export const querySchema = schema.object({
+ page: schema.maybe(schema.number()),
+ perPage: schema.maybe(schema.number()),
+ forFileId: schema.maybe(schema.string()),
+});
+
+type Query = Ensure>;
+
+type Response = FileListSharesHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ query: { forFileId, page, perPage },
+ } = req;
+
+ const result = await fileService
+ .asCurrentUser()
+ .listShareObjects({ fileId: forFileId, page, perPage });
+
+ const body: Response = result;
+ return res.ok({
+ body,
+ });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.share) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getListShareRoute(fileKind.id),
+ validate: {
+ query: querySchema,
+ },
+ options: {
+ tags: fileKind.http.share.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/share/share.ts b/x-pack/plugins/files/server/routes/file_kind/share/share.ts
new file mode 100644
index 0000000000000..0ac43abdb0353
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/share/share.ts
@@ -0,0 +1,95 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+
+import { ExpiryDateInThePastError } from '../../../file_share_service/errors';
+import { FileKindRouter, FileKindsRequestHandler } from '../types';
+
+import { FileShareHttpEndpoint, FILES_API_ROUTES } from '../../api_routes';
+import type { FileKind } from '../../../../common/types';
+import { getById } from '../helpers';
+
+export const method = 'post' as const;
+
+export const paramsSchema = schema.object({
+ fileId: schema.string(),
+});
+
+const nameRegex = /^[a-z0-9-_]+$/i;
+
+export const bodySchema = schema.object({
+ validUntil: schema.maybe(schema.number()),
+ name: schema.maybe(
+ schema.string({
+ maxLength: 256,
+ validate: (v) =>
+ nameRegex.test(v) ? undefined : 'Only alphanumeric, "-" and "_" characters are allowed.',
+ })
+ ),
+});
+
+type Body = Ensure>;
+
+type Params = Ensure>;
+
+type Response = FileShareHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files, fileKind },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ params: { fileId },
+ body: { validUntil, name },
+ } = req;
+
+ const { error, result: file } = await getById(fileService.asCurrentUser(), fileId, fileKind);
+ if (error) return error;
+
+ try {
+ const share = await file.share({ name, validUntil });
+ const body: Response = {
+ id: share.id,
+ created: share.created,
+ fileId: share.fileId,
+ token: share.token,
+ validUntil: share.validUntil,
+ name: share.name,
+ };
+ return res.ok({
+ body,
+ });
+ } catch (e) {
+ if (e instanceof ExpiryDateInThePastError) {
+ return res.badRequest({
+ body: e,
+ });
+ }
+ throw e;
+ }
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.share) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getShareRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ body: bodySchema,
+ },
+ options: {
+ tags: fileKind.http.share.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/share/unshare.ts b/x-pack/plugins/files/server/routes/file_kind/share/unshare.ts
new file mode 100644
index 0000000000000..ec7cbfb09213e
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/share/unshare.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+
+import { FILES_API_ROUTES, FileUnshareHttpEndpoint } from '../../api_routes';
+import type { FileKind } from '../../../../common/types';
+import { FileKindRouter, FileKindsRequestHandler } from '../types';
+import { FileShareNotFoundError } from '../../../file_share_service/errors';
+
+export const method = 'delete' as const;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+
+type Params = Ensure>;
+
+type Response = FileUnshareHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ params: { id },
+ } = req;
+
+ try {
+ await fileService.asCurrentUser().deleteShareObject({ id });
+ } catch (e) {
+ if (e instanceof FileShareNotFoundError) {
+ return res.notFound({ body: { message: e.message } });
+ }
+ throw e;
+ }
+
+ const body: Response = {
+ ok: true,
+ };
+ return res.ok({
+ body,
+ });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.share) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getUnshareRoute(fileKind.id),
+ validate: {
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.share.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/types.ts b/x-pack/plugins/files/server/routes/file_kind/types.ts
new file mode 100644
index 0000000000000..19e00663a1d39
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/types.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { IRouter, RequestHandler } from '@kbn/core/server';
+import type { FilesRequestHandlerContext } from '../types';
+
+export type FileKindRouter = IRouter;
+
+export interface FileKindsRequestHandlerContext extends FilesRequestHandlerContext {
+ fileKind: string;
+}
+
+export type FileKindsRequestHandler = RequestHandler<
+ P,
+ Q,
+ B,
+ FileKindsRequestHandlerContext
+>;
diff --git a/x-pack/plugins/files/server/routes/file_kind/update.ts b/x-pack/plugins/files/server/routes/file_kind/update.ts
new file mode 100644
index 0000000000000..91a4bcb63d751
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/update.ts
@@ -0,0 +1,71 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Ensure } from '@kbn/utility-types';
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { FileKind } from '../../../common/types';
+import type { UpdateFileKindHttpEndpoint } from '../../../common/api_routes';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+import { FILES_API_ROUTES } from '../api_routes';
+import { getById } from './helpers';
+
+import * as commonSchemas from '../common_schemas';
+
+export const method = 'patch' as const;
+
+export const bodySchema = schema.object({
+ name: schema.maybe(commonSchemas.fileName),
+ alt: schema.maybe(commonSchemas.fileAlt),
+ meta: schema.maybe(commonSchemas.fileMeta),
+});
+
+type Body = Ensure>;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+
+type Params = Ensure>;
+
+type Response = UpdateFileKindHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files, fileKind },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ params: { id },
+ body: attrs,
+ } = req;
+ const { error, result: file } = await getById(fileService.asCurrentUser(), id, fileKind);
+ if (error) return error;
+ await file.update(attrs);
+ const body: Response = {
+ file: file.toJSON(),
+ };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.update) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getUpdateRoute(fileKind.id),
+ validate: {
+ body: bodySchema,
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.update.tags,
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/file_kind/upload.ts b/x-pack/plugins/files/server/routes/file_kind/upload.ts
new file mode 100644
index 0000000000000..7b3db76ad38ad
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/file_kind/upload.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+import { Readable } from 'stream';
+import type { FileKind } from '../../../common/types';
+import type { UploadFileKindHttpEndpoint } from '../../../common/api_routes';
+import { FILES_API_ROUTES } from '../api_routes';
+import { fileErrors } from '../../file';
+import { getById } from './helpers';
+import type { FileKindRouter, FileKindsRequestHandler } from './types';
+
+export const method = 'put' as const;
+
+export const bodySchema = schema.stream();
+type Body = TypeOf;
+
+export const paramsSchema = schema.object({
+ id: schema.string(),
+});
+type Params = Ensure>;
+
+type Response = UploadFileKindHttpEndpoint['output'];
+
+export const handler: FileKindsRequestHandler = async (
+ { files, fileKind },
+ req,
+ res
+) => {
+ const { fileService } = await files;
+ const {
+ body: stream,
+ params: { id },
+ } = req;
+ const { error, result: file } = await getById(fileService.asCurrentUser(), id, fileKind);
+ if (error) return error;
+ try {
+ await file.uploadContent(stream as Readable);
+ } catch (e) {
+ if (
+ e instanceof fileErrors.ContentAlreadyUploadedError ||
+ e instanceof fileErrors.UploadInProgressError
+ ) {
+ return res.badRequest({ body: { message: e.message } });
+ }
+ throw e;
+ }
+ const body: Response = { ok: true, size: file.size! };
+ return res.ok({ body });
+};
+
+export function register(fileKindRouter: FileKindRouter, fileKind: FileKind) {
+ if (fileKind.http.create) {
+ fileKindRouter[method](
+ {
+ path: FILES_API_ROUTES.fileKind.getUploadRoute(fileKind.id),
+ validate: {
+ body: bodySchema,
+ params: paramsSchema,
+ },
+ options: {
+ tags: fileKind.http.create.tags,
+ body: {
+ output: 'stream',
+ parse: false,
+ accepts: fileKind.allowedMimeTypes ?? 'application/octet-stream',
+ },
+ },
+ },
+ handler
+ );
+ }
+}
diff --git a/x-pack/plugins/files/server/routes/find.ts b/x-pack/plugins/files/server/routes/find.ts
new file mode 100644
index 0000000000000..6841e4a019841
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/find.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { schema, TypeOf } from '@kbn/config-schema';
+import type { Ensure } from '@kbn/utility-types';
+import type { FilesRouter } from './types';
+
+import { FindFilesHttpEndpoint, FILES_API_ROUTES } from './api_routes';
+import type { FilesRequestHandler } from './types';
+
+const method = 'post' as const;
+
+const string64 = schema.string({ maxLength: 64 });
+const string256 = schema.string({ maxLength: 256 });
+
+const stringOrArrayOfStrings = schema.oneOf([string64, schema.arrayOf(string64)]);
+const nameStringOrArrayOfNameStrings = schema.oneOf([string256, schema.arrayOf(string256)]);
+
+const bodySchema = schema.object({
+ kind: schema.maybe(stringOrArrayOfStrings),
+ status: schema.maybe(stringOrArrayOfStrings),
+ name: schema.maybe(nameStringOrArrayOfNameStrings),
+ meta: schema.maybe(schema.object({}, { unknowns: 'allow' })),
+});
+
+const querySchema = schema.object({
+ page: schema.maybe(schema.number()),
+ perPage: schema.maybe(schema.number({ defaultValue: 100 })),
+});
+
+type Body = Ensure>;
+
+type Query = Ensure>;
+
+type Response = FindFilesHttpEndpoint['output'];
+
+function toArray(val: string | string[]) {
+ return Array.isArray(val) ? val : [val];
+}
+
+const handler: FilesRequestHandler = async ({ files }, req, res) => {
+ const { fileService } = await files;
+ const {
+ body: { meta, extension, kind, name, status },
+ query,
+ } = req;
+
+ const body: Response = {
+ files: await fileService.asCurrentUser().find({
+ kind: kind && toArray(kind),
+ name: name && toArray(name),
+ status: status && toArray(status),
+ extension: extension && toArray(extension),
+ meta,
+ ...query,
+ }),
+ };
+ return res.ok({
+ body,
+ });
+};
+
+// TODO: Find out whether we want to add stricter access controls to this route.
+// Currently this is giving read-access to all files which bypasses the
+// security we set up on a per route level for the "getById" and "list" endpoints.
+// Alternatively, we can remove the access controls on the "file kind" endpoints
+// or remove them entirely.
+export function register(router: FilesRouter) {
+ router[method](
+ {
+ path: FILES_API_ROUTES.find,
+ validate: {
+ body: bodySchema,
+ },
+ },
+ handler
+ );
+}
diff --git a/x-pack/plugins/files/server/routes/index.ts b/x-pack/plugins/files/server/routes/index.ts
new file mode 100644
index 0000000000000..5d17cb2292e4c
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FilesRouter } from './types';
+
+import * as find from './find';
+import * as metrics from './metrics';
+import * as publicDownload from './public_facing/download';
+
+export function registerRoutes(router: FilesRouter) {
+ [find, metrics, publicDownload].forEach((endpoint) => {
+ endpoint.register(router);
+ });
+}
diff --git a/x-pack/plugins/files/server/routes/integration_tests/routes.test.ts b/x-pack/plugins/files/server/routes/integration_tests/routes.test.ts
new file mode 100644
index 0000000000000..a01f377a0364b
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/integration_tests/routes.test.ts
@@ -0,0 +1,245 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { CreateFileKindHttpEndpoint } from '../../../common/api_routes';
+import { setupIntegrationEnvironment, TestEnvironmentUtils } from '../../test_utils';
+
+describe('File HTTP API', () => {
+ let testHarness: TestEnvironmentUtils;
+ let root: TestEnvironmentUtils['root'];
+ let request: TestEnvironmentUtils['request'];
+ let createFile: TestEnvironmentUtils['createFile'];
+ let fileKind: string;
+
+ beforeAll(async () => {
+ testHarness = await setupIntegrationEnvironment();
+ ({ request, createFile, root, fileKind } = testHarness);
+ });
+
+ afterAll(async () => {
+ await testHarness.cleanupAfterAll();
+ });
+
+ describe('find', () => {
+ beforeEach(async () => {
+ const args: Array = [
+ {
+ name: 'firstFile',
+ alt: 'my first alt',
+ meta: {
+ cool: 'beans',
+ },
+ mimeType: 'image/png',
+ },
+ {
+ name: 'secondFile',
+ alt: 'my second alt',
+ meta: {
+ other: 'beans',
+ },
+ mimeType: 'application/pdf',
+ },
+ {
+ name: 'thirdFile',
+ alt: 'my first alt',
+ meta: {
+ cool: 'bones',
+ },
+ mimeType: 'image/png',
+ },
+ ];
+
+ const files = await Promise.all(args.map((arg) => createFile(arg)));
+
+ for (const file of files.slice(0, 2)) {
+ await request
+ .put(root, `/api/files/files/${testHarness.fileKind}/${file.id}/blob`)
+ .set('Content-Type', 'application/octet-stream')
+ .send('hello world')
+ .expect(200);
+ }
+ });
+ afterEach(async () => {
+ await testHarness.cleanupAfterEach();
+ });
+
+ test('without filters', async () => {
+ const result = await request.post(root, '/api/files/find').send({}).expect(200);
+ expect(result.body.files).toHaveLength(3);
+ });
+
+ test('names', async () => {
+ const result = await request
+ .post(root, '/api/files/find')
+ .send({ name: ['firstFile', 'secondFile'] })
+ .expect(200);
+ expect(result.body.files).toHaveLength(2);
+ });
+
+ test('file kind', async () => {
+ {
+ const result = await request
+ .post(root, `/api/files/find`)
+ .send({ kind: 'non-existent' })
+ .expect(200);
+ expect(result.body.files).toHaveLength(0);
+ }
+
+ {
+ const result = await request
+ .post(root, '/api/files/find')
+ .send({ kind: testHarness.fileKind })
+ .expect(200);
+ expect(result.body.files).toHaveLength(3);
+ }
+ });
+
+ test('status', async () => {
+ const result = await request
+ .post(root, '/api/files/find')
+ .send({
+ status: 'READY',
+ })
+ .expect(200);
+ expect(result.body.files).toHaveLength(2);
+ });
+
+ test('combination', async () => {
+ const result = await request
+ .post(root, '/api/files/find')
+ .send({
+ kind: testHarness.fileKind,
+ name: ['firstFile', 'secondFile'],
+ meta: { cool: 'beans' },
+ })
+ .expect(200);
+ expect(result.body.files).toHaveLength(1);
+ });
+ });
+
+ describe('metrics', () => {
+ const esMaxCapacity = 50 * 1024 * 1024 * 1024;
+ afterEach(async () => {
+ await testHarness.cleanupAfterEach();
+ });
+ test('returns usage metrics', async () => {
+ {
+ const { body: metrics } = await request.get(root, '/api/files/metrics').expect(200);
+ expect(metrics).toEqual({
+ countByExtension: {},
+ countByStatus: {},
+ storage: {
+ esFixedSizeIndex: {
+ capacity: esMaxCapacity,
+ available: esMaxCapacity,
+ used: 0,
+ },
+ },
+ });
+ }
+
+ const [file1, file2] = await Promise.all([createFile(), createFile(), createFile()]);
+
+ {
+ const { body: metrics } = await request.get(root, '/api/files/metrics').expect(200);
+ expect(metrics).toEqual({
+ countByExtension: {
+ png: 3,
+ },
+ countByStatus: {
+ AWAITING_UPLOAD: 3,
+ },
+ storage: {
+ esFixedSizeIndex: {
+ capacity: esMaxCapacity,
+ available: esMaxCapacity,
+ used: 0,
+ },
+ },
+ });
+ }
+
+ const {
+ body: { size: size1 },
+ } = await request
+ .put(root, `/api/files/files/${fileKind}/${file1.id}/blob`)
+ .set('Content-Type', 'application/octet-stream')
+ .send('what have you')
+ .expect(200);
+ const {
+ body: { size: size2 },
+ } = await request
+ .put(root, `/api/files/files/${fileKind}/${file2.id}/blob`)
+ .set('Content-Type', 'application/octet-stream')
+ .send('what have you')
+ .expect(200);
+
+ {
+ const { body: metrics } = await request.get(root, '/api/files/metrics').expect(200);
+ expect(metrics).toEqual({
+ countByExtension: {
+ png: 3,
+ },
+ countByStatus: {
+ AWAITING_UPLOAD: 1,
+ READY: 2,
+ },
+ storage: {
+ esFixedSizeIndex: {
+ capacity: esMaxCapacity,
+ available: esMaxCapacity - size1 - size2,
+ used: size1 + size2,
+ },
+ },
+ });
+ }
+ });
+ });
+
+ describe('public download', () => {
+ afterEach(async () => {
+ await testHarness.cleanupAfterEach();
+ });
+ test('it returns 400 for an invalid token', async () => {
+ await request.get(root, `/api/files/public/blob/myfilename.pdf`).expect(400);
+ const { body: response } = await request
+ .get(root, `/api/files/public/blob/myfilename.pdf?token=notavalidtoken`)
+ .expect(400);
+
+ expect(response.message).toMatch('Invalid token');
+ });
+
+ test('it downloads a publicly shared file', async () => {
+ const { id } = await createFile();
+
+ const {
+ body: { token },
+ } = await request.post(root, `/api/files/shares/${fileKind}/${id}`).send({}).expect(200);
+
+ await request
+ .get(root, `/api/files/public/blob/myfilename.pdf?token=${token}`)
+ .buffer()
+ .expect(400);
+
+ await request
+ .put(root, `/api/files/files/${fileKind}/${id}/blob`)
+ .set('Content-Type', 'application/octet-stream')
+ .send('test')
+ .expect(200);
+
+ const { body: buffer, header } = await request
+ // By providing a file name like "myfilename.pdf" we imply that we want a pdf
+ .get(root, `/api/files/public/blob/myfilename.pdf?token=${token}`)
+ .buffer()
+ .expect(200);
+
+ expect(header['content-type']).toEqual('application/pdf');
+ expect(header['content-disposition']).toEqual('attachment; filename="myfilename.pdf"');
+ expect(buffer.toString('utf8')).toEqual('test');
+ });
+ });
+});
diff --git a/x-pack/plugins/files/server/routes/metrics.ts b/x-pack/plugins/files/server/routes/metrics.ts
new file mode 100644
index 0000000000000..5d7e08773c04e
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/metrics.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { FilesRouter } from './types';
+
+import { FilesMetricsHttpEndpoint, FILES_API_ROUTES } from './api_routes';
+import type { FilesRequestHandler } from './types';
+
+const method = 'get' as const;
+
+type Response = FilesMetricsHttpEndpoint['output'];
+
+const handler: FilesRequestHandler = async ({ files }, req, res) => {
+ const { fileService } = await files;
+ const body: Response = await fileService.asCurrentUser().getUsageMetrics();
+ return res.ok({
+ body,
+ });
+};
+
+export function register(router: FilesRouter) {
+ router[method](
+ {
+ path: FILES_API_ROUTES.metrics,
+ validate: {},
+ },
+ handler
+ );
+}
diff --git a/x-pack/plugins/files/server/routes/public_facing/download.ts b/x-pack/plugins/files/server/routes/public_facing/download.ts
new file mode 100644
index 0000000000000..fd908c2ca8abd
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/public_facing/download.ts
@@ -0,0 +1,86 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { Ensure } from '@kbn/utility-types';
+import { schema, TypeOf } from '@kbn/config-schema';
+
+import { NoDownloadAvailableError } from '../../file/errors';
+import { FileNotFoundError } from '../../file_service/errors';
+import {
+ FileShareNotFoundError,
+ FileShareTokenInvalidError,
+} from '../../file_share_service/errors';
+import type { FilesRouter, FilesRequestHandler } from '../types';
+import { FilePublicDownloadHttpEndpoint, FILES_API_ROUTES } from '../api_routes';
+import { getDownloadHeadersForFile } from '../common';
+import { fileNameWithExt } from '../common_schemas';
+
+const method = 'get' as const;
+
+const querySchema = schema.object({
+ token: schema.string(),
+});
+
+export const paramsSchema = schema.object({
+ fileName: schema.maybe(fileNameWithExt),
+});
+
+type Query = Ensure>;
+
+type Params = Ensure<
+ FilePublicDownloadHttpEndpoint['inputs']['params'],
+ TypeOf
+>;
+
+type Response = FilePublicDownloadHttpEndpoint['output'];
+
+const handler: FilesRequestHandler = async ({ files }, req, res) => {
+ const { fileService } = await files;
+ const {
+ query: { token },
+ params: { fileName },
+ } = req;
+
+ try {
+ const file = await fileService.asInternalUser().getByToken(token);
+ const body: Response = await file.downloadContent();
+ return res.ok({
+ body,
+ headers: getDownloadHeadersForFile(file, fileName),
+ });
+ } catch (e) {
+ if (
+ e instanceof FileNotFoundError ||
+ e instanceof FileShareNotFoundError ||
+ e instanceof FileShareTokenInvalidError
+ ) {
+ return res.badRequest({ body: { message: 'Invalid token' } });
+ }
+ if (e instanceof NoDownloadAvailableError) {
+ return res.badRequest({
+ body: { message: 'No download available. Try uploading content to the file first.' },
+ });
+ }
+
+ throw e;
+ }
+};
+
+export function register(router: FilesRouter) {
+ router[method](
+ {
+ path: FILES_API_ROUTES.public.download,
+ validate: {
+ query: querySchema,
+ params: paramsSchema,
+ },
+ options: {
+ authRequired: false,
+ },
+ },
+ handler
+ );
+}
diff --git a/x-pack/plugins/files/server/routes/types.ts b/x-pack/plugins/files/server/routes/types.ts
new file mode 100644
index 0000000000000..eccc55e769e58
--- /dev/null
+++ b/x-pack/plugins/files/server/routes/types.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type {
+ RequestHandlerContext,
+ IRouter,
+ RequestHandler,
+ RouteMethod,
+ KibanaResponseFactory,
+ IKibanaResponse,
+ Logger,
+} from '@kbn/core/server';
+import type { FileServiceStart } from '../file_service';
+
+export interface FilesRequestHandlerContext extends RequestHandlerContext {
+ files: Promise<{
+ fileService: {
+ asCurrentUser: () => FileServiceStart;
+ asInternalUser: () => FileServiceStart;
+ logger: Logger;
+ };
+ }>;
+}
+
+export type FilesRouter = IRouter;
+
+export type FilesRequestHandler<
+ P = unknown,
+ Q = unknown,
+ B = unknown,
+ Method extends RouteMethod = any
+> = RequestHandler;
+
+export type AsyncResponse = Promise>;
diff --git a/x-pack/plugins/files/server/saved_objects/file.ts b/x-pack/plugins/files/server/saved_objects/file.ts
new file mode 100644
index 0000000000000..352a00016f86d
--- /dev/null
+++ b/x-pack/plugins/files/server/saved_objects/file.ts
@@ -0,0 +1,58 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { SavedObjectsType, SavedObjectsFieldMapping } from '@kbn/core/server';
+import { FILE_SO_TYPE } from '../../common';
+import type { FileMetadata } from '../../common';
+
+type Properties = Record<
+ keyof Omit,
+ SavedObjectsFieldMapping
+>;
+
+const properties: Properties = {
+ created: {
+ type: 'date',
+ },
+ Updated: {
+ type: 'date',
+ },
+ name: {
+ type: 'text',
+ },
+ Status: {
+ type: 'keyword',
+ },
+ mime_type: {
+ type: 'keyword',
+ },
+ extension: {
+ type: 'keyword',
+ },
+ size: {
+ type: 'long',
+ },
+ Meta: {
+ type: 'flattened',
+ },
+ FileKind: {
+ type: 'keyword',
+ },
+};
+
+export const fileObjectType: SavedObjectsType = {
+ name: FILE_SO_TYPE,
+ hidden: true,
+ namespaceType: 'multiple-isolated',
+ management: {
+ importableAndExportable: false,
+ },
+ mappings: {
+ dynamic: false,
+ properties,
+ },
+};
diff --git a/x-pack/plugins/files/server/saved_objects/file_share.ts b/x-pack/plugins/files/server/saved_objects/file_share.ts
new file mode 100644
index 0000000000000..e71253582b381
--- /dev/null
+++ b/x-pack/plugins/files/server/saved_objects/file_share.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { SavedObjectsFieldMapping, SavedObjectsType } from '@kbn/core/server';
+import type { FileShare } from '../../common/types';
+import { FILE_SHARE_SO_TYPE } from '../../common/constants';
+
+/**
+ * This saved object represents an instance of a publicly shared file.
+ *
+ * This file should be accessible to anyone who can access this Kibana over the
+ * Internet.
+ */
+
+type Properties = Record;
+
+const properties: Properties = {
+ created: {
+ type: 'date',
+ },
+ valid_until: {
+ type: 'long',
+ },
+ token: {
+ type: 'keyword',
+ },
+ name: {
+ type: 'keyword',
+ },
+};
+
+export const fileShareObjectType: SavedObjectsType = {
+ name: FILE_SHARE_SO_TYPE,
+ hidden: true,
+ namespaceType: 'agnostic', // These saved objects should be visible everywhere
+ mappings: {
+ dynamic: false,
+ properties,
+ },
+};
diff --git a/x-pack/plugins/files/server/saved_objects/index.ts b/x-pack/plugins/files/server/saved_objects/index.ts
new file mode 100644
index 0000000000000..42fda22db97c1
--- /dev/null
+++ b/x-pack/plugins/files/server/saved_objects/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { fileObjectType } from './file';
+export { fileShareObjectType } from './file_share';
diff --git a/x-pack/plugins/files/server/test_utils/index.ts b/x-pack/plugins/files/server/test_utils/index.ts
new file mode 100644
index 0000000000000..98215f70649db
--- /dev/null
+++ b/x-pack/plugins/files/server/test_utils/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export { setupIntegrationEnvironment } from './setup_integration_environment';
+export type { TestEnvironmentUtils } from './setup_integration_environment';
diff --git a/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts b/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts
new file mode 100644
index 0000000000000..81d04c23bdc96
--- /dev/null
+++ b/x-pack/plugins/files/server/test_utils/setup_integration_environment.ts
@@ -0,0 +1,131 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { defaults } from 'lodash';
+import {
+ createRootWithCorePlugins,
+ createTestServers,
+ request,
+} from '@kbn/core/test_helpers/kbn_server';
+import pRetry from 'p-retry';
+import { FileJSON } from '../../common';
+import { getFileKindsRegistry } from '../file_kinds_registry';
+
+export type TestEnvironmentUtils = Awaited>;
+
+export async function setupIntegrationEnvironment() {
+ const fileKind: string = 'test-file-kind';
+ const testIndex = '.kibana-test-files';
+ const testConfig = {
+ xpack: {
+ reporting: { enabled: false },
+ },
+ };
+
+ /**
+ * Functionality to create files easily
+ */
+ let disposables: Array<() => Promise> = [];
+ const createFile = async (
+ fileAttrs: Partial<{
+ name: string;
+ alt: string;
+ meta: Record;
+ mimeType: string;
+ }> = {}
+ ): Promise => {
+ const result = await request
+ .post(root, `/api/files/files/${fileKind}`)
+ .send(
+ defaults(fileAttrs, {
+ name: 'myFile',
+ alt: 'a picture of my dog',
+ meta: {},
+ mimeType: 'image/png',
+ })
+ )
+ .expect(200);
+ disposables.push(async () => {
+ await request
+ .delete(root, `/api/files/files/${fileKind}/${result.body.file.id}`)
+ .send()
+ .expect(200);
+ });
+ return result.body.file;
+ };
+
+ const { startES } = createTestServers({
+ adjustTimeout: jest.setTimeout,
+ settings: {
+ es: {
+ license: 'basic',
+ },
+ },
+ });
+
+ /**
+ * Clean up methods
+ */
+ const cleanupAfterEach = async () => {
+ await Promise.all(disposables.map((dispose) => dispose()));
+ disposables = [];
+ await esClient.indices.delete({ index: testIndex, ignore_unavailable: true });
+ };
+ const cleanupAfterAll = async () => {
+ await root.shutdown();
+ await manageES.stop();
+ };
+
+ /**
+ * Start the servers and set them up
+ */
+ const manageES = await startES();
+
+ const root = createRootWithCorePlugins(testConfig, { oss: false });
+ await root.preboot();
+ await root.setup();
+
+ /**
+ * Register a test file type
+ */
+ const testHttpConfig = { tags: ['access:myapp'] };
+ getFileKindsRegistry().register({
+ id: fileKind,
+ blobStoreSettings: {
+ esFixedSizeIndex: { index: testIndex },
+ },
+ http: {
+ create: testHttpConfig,
+ delete: testHttpConfig,
+ update: testHttpConfig,
+ download: testHttpConfig,
+ getById: testHttpConfig,
+ list: testHttpConfig,
+ share: testHttpConfig,
+ },
+ });
+ const coreStart = await root.start();
+ const esClient = coreStart.elasticsearch.client.asInternalUser;
+
+ /**
+ * Wait for endpoints to be available
+ */
+ await pRetry(() => request.get(root, '/api/licensing/info').expect(200), { retries: 5 });
+
+ return {
+ manageES,
+ esClient,
+ root,
+ coreStart,
+ fileKind,
+ testIndex,
+ request,
+ createFile,
+ cleanupAfterEach,
+ cleanupAfterAll,
+ };
+}
diff --git a/x-pack/plugins/files/server/types.ts b/x-pack/plugins/files/server/types.ts
new file mode 100644
index 0000000000000..86ff4e5ae3c19
--- /dev/null
+++ b/x-pack/plugins/files/server/types.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import type { SecurityPluginSetup } from '@kbn/security-plugin/server';
+import { FileKind } from '../common';
+import { FileServiceFactory } from './file_service/file_service_factory';
+
+/**
+ * Files plugin setup contract
+ */
+export interface FilesSetup {
+ /**
+ * Register a {@link FileKind} which allows for specifying details about the files
+ * that will be uploaded.
+ *
+ * @param {FileKind} fileKind - the file kind to register
+ */
+ registerFileKind(fileKind: FileKind): void;
+}
+
+export interface FilesPluginSetupDependencies {
+ security?: SecurityPluginSetup;
+}
+
+/**
+ * Files plugin start contract
+ */
+export interface FilesStart {
+ /**
+ * Create an instance of {@link FileServiceStart}.
+ */
+ fileServiceFactory: FileServiceFactory;
+}
diff --git a/x-pack/plugins/files/tsconfig.json b/x-pack/plugins/files/tsconfig.json
new file mode 100644
index 0000000000000..a2c2e1e8ebd3f
--- /dev/null
+++ b/x-pack/plugins/files/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "./target/types",
+ "emitDeclarationOnly": true,
+ "declaration": true,
+ "declarationMap": true
+ },
+ "include": ["common/**/*", "public/**/*", "server/**/*"],
+ "references": [
+ { "path": "../../../src/core/tsconfig.json" },
+ { "path": "../security/tsconfig.json" },
+ ]
+}
diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json
index 357ceb3192e6f..f7d5054f53224 100644
--- a/x-pack/plugins/fleet/common/openapi/bundled.json
+++ b/x-pack/plugins/fleet/common/openapi/bundled.json
@@ -2961,6 +2961,48 @@
"$ref": "#/components/parameters/kbn_xsrf"
}
]
+ },
+ "delete": {
+ "summary": "Package policy - Delete",
+ "tags": [],
+ "operationId": "delete-package-policy",
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "id"
+ ]
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "schema": {
+ "type": "string"
+ },
+ "name": "packagePolicyId",
+ "in": "path",
+ "required": true
+ },
+ {
+ "schema": {
+ "type": "boolean"
+ },
+ "name": "force",
+ "in": "query"
+ }
+ ]
}
},
"/outputs": {
@@ -4306,6 +4348,10 @@
"description": "list of agent IDs"
}
]
+ },
+ "force": {
+ "type": "boolean",
+ "description": "Force upgrade, skipping validation (should be used with caution)"
}
},
"required": [
@@ -4315,32 +4361,21 @@
},
"upgrade_agent": {
"title": "Upgrade agent",
- "oneOf": [
- {
- "type": "object",
- "properties": {
- "version": {
- "type": "string"
- }
- },
- "required": [
- "version"
- ]
+ "type": "object",
+ "properties": {
+ "version": {
+ "type": "string"
},
- {
- "type": "object",
- "properties": {
- "version": {
- "type": "string"
- },
- "source_uri": {
- "type": "string"
- }
- },
- "required": [
- "version"
- ]
+ "source_uri": {
+ "type": "string"
+ },
+ "force": {
+ "type": "boolean",
+ "description": "Force upgrade, skipping validation (should be used with caution)"
}
+ },
+ "required": [
+ "version"
]
},
"agent_action": {
diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml
index b902f130b2e18..60827666ca5e8 100644
--- a/x-pack/plugins/fleet/common/openapi/bundled.yaml
+++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml
@@ -1820,6 +1820,32 @@ paths:
- sucess
parameters:
- $ref: '#/components/parameters/kbn_xsrf'
+ delete:
+ summary: Package policy - Delete
+ tags: []
+ operationId: delete-package-policy
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: string
+ required:
+ - id
+ parameters:
+ - schema:
+ type: string
+ name: packagePolicyId
+ in: path
+ required: true
+ - schema:
+ type: boolean
+ name: force
+ in: query
/outputs:
get:
summary: Outputs
@@ -2716,26 +2742,25 @@ components:
items:
type: string
description: list of agent IDs
+ force:
+ type: boolean
+ description: Force upgrade, skipping validation (should be used with caution)
required:
- agents
- version
upgrade_agent:
title: Upgrade agent
- oneOf:
- - type: object
- properties:
- version:
- type: string
- required:
- - version
- - type: object
- properties:
- version:
- type: string
- source_uri:
- type: string
- required:
- - version
+ type: object
+ properties:
+ version:
+ type: string
+ source_uri:
+ type: string
+ force:
+ type: boolean
+ description: Force upgrade, skipping validation (should be used with caution)
+ required:
+ - version
agent_action:
title: Agent action
oneOf:
diff --git a/x-pack/plugins/fleet/common/openapi/paths/package_policies@{package_policy_id}.yaml b/x-pack/plugins/fleet/common/openapi/paths/package_policies@{package_policy_id}.yaml
index 7bd20ab17fdd3..8dda212c409eb 100644
--- a/x-pack/plugins/fleet/common/openapi/paths/package_policies@{package_policy_id}.yaml
+++ b/x-pack/plugins/fleet/common/openapi/paths/package_policies@{package_policy_id}.yaml
@@ -45,3 +45,29 @@ put:
- sucess
parameters:
- $ref: ../components/headers/kbn_xsrf.yaml
+delete:
+ summary: Package policy - Delete
+ tags: []
+ operationId: delete-package-policy
+ responses:
+ '200':
+ description: OK
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: string
+ required:
+ - id
+ parameters:
+ - schema:
+ type: string
+ name: packagePolicyId
+ in: path
+ required: true
+ - schema:
+ type: boolean
+ name: force
+ in: query
diff --git a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts
index aa39266b4f7a9..260c8ebc8142f 100644
--- a/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts
+++ b/x-pack/plugins/fleet/common/types/rest_spec/package_policy.ts
@@ -59,6 +59,11 @@ export type DeletePackagePoliciesResponse = Array<{
success: boolean;
package?: PackagePolicyPackage;
policy_id?: string;
+ // Support generic errors
+ statusCode?: number;
+ body?: {
+ message: string;
+ };
}>;
export interface UpgradePackagePolicyBaseResponse {
diff --git a/x-pack/plugins/fleet/cypress/integration/install_assets.spec.ts b/x-pack/plugins/fleet/cypress/integration/install_assets.spec.ts
new file mode 100644
index 0000000000000..1c6268d2cf66a
--- /dev/null
+++ b/x-pack/plugins/fleet/cypress/integration/install_assets.spec.ts
@@ -0,0 +1,65 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { Interception } from 'cypress/types/net-stubbing';
+
+describe('Install unverified package assets', () => {
+ beforeEach(() => {
+ cy.intercept('POST', '/api/fleet/epm/packages/fleet_server/*', (req) => {
+ if (!req.body.force) {
+ return req.reply({
+ statusCode: 400,
+ body: {
+ message: 'Package is not verified.',
+ attributes: {
+ type: 'verification_failed',
+ },
+ },
+ });
+ }
+
+ req.reply({
+ items: [
+ { id: 'fleet_server-1234', type: 'dashboard' },
+ { id: 'fleet_server-5678', type: 'dashboard' },
+ ],
+ _meta: { install_source: 'registry' },
+ });
+ }).as('installAssets');
+
+ // save mocking out the whole package response, but make it so that fleet server is always uninstalled
+ cy.intercept('GET', '/api/fleet/epm/packages/fleet_server', (req) => {
+ req.continue((res) => {
+ if (res.body?.item?.savedObject) {
+ delete res.body.item.savedObject;
+ }
+ if (res.body?.item?.status) {
+ res.body.item.status = 'not_installed';
+ }
+ });
+ });
+ });
+
+ it('should show force install modal if package is unverified', () => {
+ cy.visit('app/integrations/detail/fleet_server/settings');
+ cy.getBySel('installAssetsButton').click();
+ // this action will install x assets modal
+ const confirmInstall = cy.getBySel('confirmModalConfirmButton');
+ confirmInstall.click();
+
+ // unverified integration force install modal
+ const installAnyway = cy.getBySel('confirmModalConfirmButton').contains('Install anyway');
+ installAnyway.click();
+
+ // cypress 'hack' to get all requests made to an intercepted request
+ cy.get('@installAssets.all').then((interceptions) => {
+ const castInterceptions = interceptions as unknown as Interception[];
+ // expect latest request to have used force
+ expect(castInterceptions.at(-1)?.request?.body?.force).to.equal(true);
+ });
+ });
+});
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx
index a4a06e1ff5512..69c6f3c12823e 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx
@@ -108,6 +108,27 @@ describe('TagsAddRemove', () => {
);
});
+ it('should show allow to add new tag when agent do not have any tags', () => {
+ allTags = [];
+ selectedTags = [];
+ const result = renderComponent('agent1');
+ const searchInput = result.getByTestId('addRemoveTags');
+
+ fireEvent.input(searchInput, {
+ target: { value: 'tag' },
+ });
+
+ fireEvent.click(result.getByTestId('createTagBtn'));
+
+ expect(mockUpdateTags).toHaveBeenCalledWith(
+ 'agent1',
+ ['tag'],
+ expect.anything(),
+ 'Tag created',
+ 'Tag creation failed'
+ );
+ });
+
it('should add new tag when not found in search and button clicked', () => {
const result = renderComponent('agent1');
const searchInput = result.getByRole('combobox');
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx
index 55272497a6960..ccbb50d3eec71 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx
@@ -212,7 +212,7 @@ export const TagsAddRemove: React.FC = ({
)}
- {!isExactMatch && labels.length && searchValue !== '' ? createTagButton : null}
+ {(!isExactMatch || labels.length === 0) && searchValue !== '' ? createTagButton : null}
>
);
diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/install_button.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/install_button.tsx
index d4560812853fd..28ad351b865f7 100644
--- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/install_button.tsx
+++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/settings/install_button.tsx
@@ -52,7 +52,12 @@ export function InstallButton(props: InstallationButtonProps) {
return canInstallPackages ? (
-
+
{isInstalling ? (
,
+ TypeOf,
+ unknown
+> = async (context, request, response) => {
+ const coreContext = await context.core;
+ const soClient = coreContext.savedObjects.client;
+ const esClient = coreContext.elasticsearch.client.asInternalUser;
+ const user = appContextService.getSecurity()?.authc.getCurrentUser(request) || undefined;
+ try {
+ const res = await packagePolicyService.delete(
+ soClient,
+ esClient,
+ [request.params.packagePolicyId],
+ { user, force: request.query.force, skipUnassignFromAgentPolicies: request.query.force }
+ );
+
+ if (
+ res[0] &&
+ res[0].success === false &&
+ res[0].statusCode !== 404 // ignore 404 to allow that call to be idempotent
+ ) {
+ return response.customError({
+ statusCode: res[0].statusCode ?? 500,
+ body: res[0].body,
+ });
+ }
+ try {
+ await packagePolicyService.runExternalCallbacks(
+ 'postPackagePolicyDelete',
+ res,
+ context,
+ request
+ );
+ } catch (error) {
+ const logger = appContextService.getLogger();
+ logger.error(`An error occurred executing external callback: ${error}`);
+ logger.error(error);
+ }
+ return response.ok({
+ body: { id: request.params.packagePolicyId },
+ });
+ } catch (error) {
+ return defaultIngestErrorHandler({ error, response });
+ }
+};
+
export const upgradePackagePolicyHandler: RequestHandler<
unknown,
unknown,
diff --git a/x-pack/plugins/fleet/server/routes/package_policy/index.ts b/x-pack/plugins/fleet/server/routes/package_policy/index.ts
index 2b2ae190b80bb..cf52b740245f8 100644
--- a/x-pack/plugins/fleet/server/routes/package_policy/index.ts
+++ b/x-pack/plugins/fleet/server/routes/package_policy/index.ts
@@ -14,6 +14,7 @@ import {
DeletePackagePoliciesRequestSchema,
UpgradePackagePoliciesRequestSchema,
DryRunPackagePoliciesRequestSchema,
+ DeleteOnePackagePolicyRequestSchema,
} from '../../types';
import type { FleetAuthzRouter } from '../security';
@@ -26,6 +27,7 @@ import {
upgradePackagePolicyHandler,
dryRunUpgradePackagePolicyHandler,
getOrphanedPackagePolicies,
+ deleteOnePackagePolicyHandler,
} from './handlers';
export const registerRoutes = (router: FleetAuthzRouter) => {
@@ -100,6 +102,17 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
deletePackagePolicyHandler
);
+ router.delete(
+ {
+ path: PACKAGE_POLICY_API_ROUTES.INFO_PATTERN,
+ validate: DeleteOnePackagePolicyRequestSchema,
+ fleetAuthz: {
+ integrations: { writeIntegrationPolicies: true },
+ },
+ },
+ deleteOnePackagePolicyHandler
+ );
+
// Upgrade
router.post(
{
diff --git a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts
index 7f54b9c742d08..b085060286d05 100644
--- a/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts
+++ b/x-pack/plugins/fleet/server/types/rest_spec/package_policy.ts
@@ -40,6 +40,15 @@ export const DeletePackagePoliciesRequestSchema = {
}),
};
+export const DeleteOnePackagePolicyRequestSchema = {
+ params: schema.object({
+ packagePolicyId: schema.string(),
+ }),
+ query: schema.object({
+ force: schema.maybe(schema.boolean()),
+ }),
+};
+
export const UpgradePackagePoliciesRequestSchema = {
body: schema.object({
packagePolicyIds: schema.arrayOf(schema.string()),
diff --git a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/styles.ts b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/styles.ts
index ec0f02bebdf1a..1ebe6347994ee 100644
--- a/x-pack/plugins/kubernetes_security/public/components/container_name_widget/styles.ts
+++ b/x-pack/plugins/kubernetes_security/public/components/container_name_widget/styles.ts
@@ -24,7 +24,7 @@ export const useStyles = () => {
border: euiTheme.border.thin,
borderRadius: euiTheme.border.radius.medium,
overflow: 'auto',
- height: '239px',
+ height: '228px',
position: 'relative',
marginBottom: size.l,
};
diff --git a/x-pack/plugins/kubernetes_security/public/components/count_widget/styles.ts b/x-pack/plugins/kubernetes_security/public/components/count_widget/styles.ts
index 921c78674c392..c5d3adf43d838 100644
--- a/x-pack/plugins/kubernetes_security/public/components/count_widget/styles.ts
+++ b/x-pack/plugins/kubernetes_security/public/components/count_widget/styles.ts
@@ -25,16 +25,15 @@ export const useStyles = () => {
};
const title: CSSObject = {
- marginBottom: size.m,
+ marginBottom: size.s,
fontSize: size.m,
fontWeight: font.weight.bold,
whiteSpace: 'nowrap',
};
const dataInfo: CSSObject = {
- marginBottom: size.xs,
- height: '18px',
- fontSize: size.l,
+ fontSize: `calc(${size.l} - ${size.xxs})`,
+ lineHeight: size.l,
fontWeight: font.weight.bold,
};
diff --git a/x-pack/plugins/kubernetes_security/public/components/kubernetes_security_routes/styles.ts b/x-pack/plugins/kubernetes_security/public/components/kubernetes_security_routes/styles.ts
index 9f7b9c184cdcd..7c2e2dcffa85f 100644
--- a/x-pack/plugins/kubernetes_security/public/components/kubernetes_security_routes/styles.ts
+++ b/x-pack/plugins/kubernetes_security/public/components/kubernetes_security_routes/styles.ts
@@ -13,7 +13,7 @@ export const useStyles = () => {
const { euiTheme } = useEuiTheme();
const cached = useMemo(() => {
- const { size, font, border } = euiTheme;
+ const { size, font } = euiTheme;
const titleSection: CSSObject = {
marginBottom: size.l,
@@ -85,16 +85,6 @@ export const useStyles = () => {
fontWeight: font.weight.bold,
};
- const widgetHolder: CSSObject = {
- position: 'relative',
- width: '332px',
- height: '235px',
- borderRadius: border.radius.medium,
- fontWeight: font.weight.bold,
- fontSize: size.m,
- lineHeight: size.base,
- };
-
const widgetsGroup: CSSObject = {
[`@media (max-width:${euiTheme.breakpoint.xl}px)`]: {
flexDirection: 'column',
@@ -117,7 +107,6 @@ export const useStyles = () => {
rightWidgetsGroup,
widgetsBottomSpacing,
percentageChartTitle,
- widgetHolder,
widgetsGroup,
betaBadge,
};
diff --git a/x-pack/plugins/kubernetes_security/public/components/percent_widget/index.tsx b/x-pack/plugins/kubernetes_security/public/components/percent_widget/index.tsx
index 181ff9629c4ee..c8846f45ff9cc 100644
--- a/x-pack/plugins/kubernetes_security/public/components/percent_widget/index.tsx
+++ b/x-pack/plugins/kubernetes_security/public/components/percent_widget/index.tsx
@@ -123,7 +123,7 @@ export const PercentWidget = ({
/>
)}
{title}
-
+
{Object.keys(dataValueMap).map((groupedByValue, idx) => {
const value = data?.[groupedByValue] || 0;
return (
diff --git a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/index.tsx b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/index.tsx
index 0d1f83cfc2c56..1089ee11e98c5 100644
--- a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/index.tsx
+++ b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/index.tsx
@@ -53,24 +53,29 @@ export const Breadcrumb = ({ treeNavSelection, onSelect }: BreadcrumbDeps) => {
icon: JSX.Element,
isBolded: boolean,
hasRightArrow: boolean = true
- ) => (
- <>
- {hasRightArrow && }
- {icon}
-
- onBreadCrumbClick(collectionType)}
- >
- {collectionType === KubernetesCollection.clusterId
- ? treeNavSelection[KubernetesCollection.clusterName] ||
- treeNavSelection[KubernetesCollection.clusterId]
- : treeNavSelection[collectionType]}
-
-
- >
- ),
+ ) => {
+ const content =
+ collectionType === KubernetesCollection.clusterId
+ ? treeNavSelection[KubernetesCollection.clusterName] ||
+ treeNavSelection[KubernetesCollection.clusterId]
+ : treeNavSelection[collectionType];
+
+ return (
+ <>
+ {hasRightArrow && }
+ {icon}
+
+ onBreadCrumbClick(collectionType)}
+ >
+ {content}
+
+
+ >
+ );
+ },
[
onBreadCrumbClick,
styles.breadcrumbButton,
diff --git a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/styles.ts b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/styles.ts
index e2a5f297b04f0..247d31f0c0f51 100644
--- a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/styles.ts
+++ b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/breadcrumb/styles.ts
@@ -25,6 +25,7 @@ export const useStyles = () => {
const breadcrumbButton: CSSObject = {
height: 'fit-content',
maxWidth: '248px',
+ fontSize: size.m,
fontWeight: font.weight.regular,
'.euiButtonEmpty__content': {
paddingLeft: size.xs,
diff --git a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.tsx b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.tsx
index df6c7b03d5cc2..05a471a596a7c 100644
--- a/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.tsx
+++ b/x-pack/plugins/kubernetes_security/public/components/tree_view_container/dynamic_tree_view/index.tsx
@@ -66,7 +66,7 @@ export const DynamicTreeView = ({
}: DynamicTreeViewProps) => {
const styles = useStyles(depth);
- const { indexPattern, hasSelection, setNoResults } = useTreeViewContext();
+ const { indexPattern, setNoResults } = useTreeViewContext();
const { data, fetchNextPage, isFetchingNextPage, hasNextPage, isLoading } =
useFetchDynamicTreeView(query, tree[depth].key, indexPattern, expanded);
@@ -103,7 +103,7 @@ export const DynamicTreeView = ({
}, [fetchNextPage, expanded]);
useEffect(() => {
- if (!hasSelection && !depth && data && data.pages?.[0].buckets?.[0]?.key) {
+ if (!selected && !depth && data && data.pages?.[0].buckets?.[0]?.key) {
onSelect(
{},
tree[depth].type,
@@ -111,7 +111,7 @@ export const DynamicTreeView = ({
data.pages[0].buckets[0].key_as_string
);
}
- }, [data, depth, hasSelection, onSelect, tree]);
+ }, [data, depth, selected, onSelect, tree]);
const onClickNextPageHandler = () => {
fetchNextPage();
@@ -297,11 +297,18 @@ const DynamicTreeViewItem = ({
const isSelected = useMemo(() => {
return (
selected ===
- Object.entries({ ...selectionDepth, [tree[depth].type]: aggData.key })
+ Object.entries({
+ ...selectionDepth,
+ [tree[depth].type]: aggData.key,
+ ...(tree[depth].type === KubernetesCollection.clusterId &&
+ aggData.key_as_string && {
+ [KubernetesCollection.clusterName]: aggData.key_as_string,
+ }),
+ })
.map(([k, v]) => `${k}.${v}`)
.join()
);
- }, [aggData.key, depth, selected, selectionDepth, tree]);
+ }, [aggData.key, aggData.key_as_string, depth, selected, selectionDepth, tree]);
return (
(buttonRef.current[aggData.key] = el)}
+ css={isLastNode ? styles.leafNodeButton : undefined}
>
{!isLastNode && (
{
const loadMoreTextLeft: CSSObject = {
marginLeft: size.s,
};
+ const leafNodeButton: CSSObject = {
+ marginLeft: size.l,
+ width: `calc(100% - ${size.l})`,
+ paddingLeft: 0,
+ };
const labelIcon: CSSObject = {
marginRight: size.s,
marginLeft: size.s,
@@ -54,6 +59,13 @@ export const useStyles = (depth: number) => {
'.euiTreeView__node--expanded': {
maxHeight: '100%',
},
+ '.euiTreeView__nodeInner .euiToolTipAnchor': {
+ maxWidth: '100%',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ wordWrap: 'normal',
+ },
});
return {
@@ -61,6 +73,7 @@ export const useStyles = (depth: number) => {
loadMoreButtonWrapper,
loadMoreText,
loadMoreTextLeft,
+ leafNodeButton,
labelIcon,
treeViewWrapper,
};
diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx
index 293c8cbf539d0..115cd4691ad67 100644
--- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx
+++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx
@@ -17,6 +17,7 @@ import {
TimefilterContract,
FilterManager,
getEsQueryConfig,
+ mapAndFlattenFilters,
} from '@kbn/data-plugin/public';
import type { Start as InspectorStart } from '@kbn/inspector-plugin/public';
@@ -41,6 +42,7 @@ import {
SavedObjectEmbeddableInput,
ReferenceOrValueEmbeddable,
SelfStyledEmbeddable,
+ FilterableEmbeddable,
} from '@kbn/embeddable-plugin/public';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { DataViewsContract, DataView } from '@kbn/data-views-plugin/public';
@@ -213,7 +215,8 @@ export class Embeddable
extends AbstractEmbeddable
implements
ReferenceOrValueEmbeddable,
- SelfStyledEmbeddable
+ SelfStyledEmbeddable,
+ FilterableEmbeddable
{
type = DOC_TYPE;
@@ -869,6 +872,27 @@ export class Embeddable
return this.savedVis && this.savedVis.description;
}
+ /**
+ * Gets the Lens embeddable's local filters
+ * @returns Local/panel-level array of filters for Lens embeddable
+ */
+ public async getFilters() {
+ return mapAndFlattenFilters(
+ this.deps.injectFilterReferences(
+ this.savedVis?.state.filters ?? [],
+ this.savedVis?.references ?? []
+ )
+ );
+ }
+
+ /**
+ * Gets the Lens embeddable's local query
+ * @returns Local/panel-level query for Lens embeddable
+ */
+ public async getQuery() {
+ return this.savedVis?.state.query;
+ }
+
public getSavedVis(): Readonly {
return this.savedVis;
}
diff --git a/x-pack/plugins/lens/public/state_management/lens_slice.ts b/x-pack/plugins/lens/public/state_management/lens_slice.ts
index 2a71cd9aaab48..14510a47b9d1d 100644
--- a/x-pack/plugins/lens/public/state_management/lens_slice.ts
+++ b/x-pack/plugins/lens/public/state_management/lens_slice.ts
@@ -11,7 +11,6 @@ import { mapValues } from 'lodash';
import { Query } from '@kbn/es-query';
import { History } from 'history';
import { LensEmbeddableInput } from '..';
-import { getDatasourceLayers } from '../editor_frame_service/editor_frame';
import { TableInspectorAdapter } from '../editor_frame_service/types';
import type { VisualizeEditorContext, Suggestion } from '../types';
import { getInitialDatasourceId, getResolvedDateRange, getRemoveOperation } from '../utils';
@@ -22,6 +21,7 @@ import type { LayerType } from '../../common/types';
import { getLayerType } from '../editor_frame_service/editor_frame/config_panel/add_layer';
import { getVisualizeFieldSuggestions } from '../editor_frame_service/editor_frame/suggestion_helpers';
import { FramePublicAPI, LensEditContextMapping, LensEditEvent } from '../types';
+import { selectFramePublicAPI } from './selectors';
export const initialState: LensAppState = {
persistedDoc: undefined,
@@ -628,14 +628,7 @@ export const makeLensReducer = (storeDeps: LensStoreDeps) => {
layerType
);
- const framePublicAPI = {
- // any better idea to avoid `as`?
- activeData: state.activeData
- ? (current(state.activeData) as TableInspectorAdapter)
- : undefined,
- datasourceLayers: getDatasourceLayers(state.datasourceStates, datasourceMap),
- dateRange: current(state.resolvedDateRange),
- };
+ const framePublicAPI = selectFramePublicAPI({ lens: current(state) }, datasourceMap);
const activeDatasource = datasourceMap[state.activeDatasourceId];
const { noDatasource } =
@@ -687,14 +680,7 @@ export const makeLensReducer = (storeDeps: LensStoreDeps) => {
const { activeDatasourceState, activeVisualizationState } = addInitialValueIfAvailable({
datasourceState: state.datasourceStates[state.activeDatasourceId].state,
visualizationState: state.visualization.state,
- framePublicAPI: {
- // any better idea to avoid `as`?
- activeData: state.activeData
- ? (current(state.activeData) as TableInspectorAdapter)
- : undefined,
- datasourceLayers: getDatasourceLayers(state.datasourceStates, datasourceMap),
- dateRange: current(state.resolvedDateRange),
- },
+ framePublicAPI: selectFramePublicAPI({ lens: current(state) }, datasourceMap),
activeVisualization,
activeDatasource,
layerId,
diff --git a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx
index 0388dcd86d397..d271ee053d8c7 100644
--- a/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx
+++ b/x-pack/plugins/maps/public/embeddable/map_embeddable.tsx
@@ -23,6 +23,7 @@ import {
genericEmbeddableInputIsEqual,
VALUE_CLICK_TRIGGER,
omitGenericEmbeddableInput,
+ FilterableEmbeddable,
} from '@kbn/embeddable-plugin/public';
import { ActionExecutionContext } from '@kbn/ui-actions-plugin/public';
import { APPLY_FILTER_TRIGGER } from '@kbn/data-plugin/public';
@@ -103,7 +104,7 @@ function getIsRestore(searchSessionId?: string) {
export class MapEmbeddable
extends Embeddable
- implements ReferenceOrValueEmbeddable
+ implements ReferenceOrValueEmbeddable, FilterableEmbeddable
{
type = MAP_SAVED_OBJECT_TYPE;
deferEmbeddableLoad = true;
@@ -248,6 +249,22 @@ export class MapEmbeddable
return this._isInitialized ? this._savedMap.getAttributes().description : '';
}
+ /**
+ * TODO: Implement this function once https://github.com/elastic/kibana/issues/91282 is resolved
+ * @returns []
+ */
+ public async getFilters() {
+ return [];
+ }
+
+ /**
+ * TODO: Implement this function once https://github.com/elastic/kibana/issues/91282 is resolved
+ * @returns undefined
+ */
+ public async getQuery() {
+ return undefined;
+ }
+
public supportedTriggers(): string[] {
return [APPLY_FILTER_TRIGGER, VALUE_CLICK_TRIGGER];
}
diff --git a/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
index 14063f382f913..72593235264d3 100644
--- a/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
+++ b/x-pack/plugins/observability/public/pages/alerts/components/alerts_flyout/alerts_flyout.tsx
@@ -45,7 +45,7 @@ export function AlertsFlyout({
}
return (
-
+
diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss
index cee2ea31a0ea8..13787ccd00c16 100644
--- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss
+++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/styles.scss
@@ -4,7 +4,7 @@ $fullscreenFlyoutTop: 72px;
top: $fullscreenFlyoutTop;
}
- .euiFlyout,
+ .euiFlyout.oblt__flyout,
.euiCollapsibleNav {
top: $fullscreenFlyoutTop;
height: calc(100% - #{$fullscreenFlyoutTop});
diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx
index 08a70f6206802..902dd3707d2f8 100644
--- a/x-pack/plugins/observability/public/pages/overview/index.tsx
+++ b/x-pack/plugins/observability/public/pages/overview/index.tsx
@@ -219,6 +219,7 @@ export function OverviewPage() {
>
{isFlyoutVisible && (
setIsFlyoutVisible(false)}
diff --git a/x-pack/plugins/security/common/model/user_profile.ts b/x-pack/plugins/security/common/model/user_profile.ts
index c6156982aab7e..68ec11bf1ede4 100644
--- a/x-pack/plugins/security/common/model/user_profile.ts
+++ b/x-pack/plugins/security/common/model/user_profile.ts
@@ -28,6 +28,11 @@ export interface UserProfile {
*/
uid: string;
+ /**
+ * Indicates whether user profile is enabled or not.
+ */
+ enabled: boolean;
+
/**
* Information about the user that owns profile.
*/
diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts
index ca42685709844..4fdb482a2cbae 100644
--- a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts
+++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.test.ts
@@ -39,4 +39,11 @@ describe('UserProfileAPIClient', () => {
body: '{"avatar":{"imageUrl":"avatar.png"}}',
});
});
+
+ it('should get user profiles in bulk', async () => {
+ await apiClient.bulkGet({ uids: new Set(['UID-1', 'UID-2']), dataPath: '*' });
+ expect(coreStart.http.post).toHaveBeenCalledWith('/internal/security/user_profile/_bulk_get', {
+ body: '{"uids":["UID-1","UID-2"],"dataPath":"*"}',
+ });
+ });
});
diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts
index 6c4c53ef4ec30..a2fc60f7b4d75 100644
--- a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts
+++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts
@@ -94,7 +94,8 @@ export class UserProfileAPIClient {
*/
public bulkGet(params: UserProfileBulkGetParams) {
return this.http.post>>('/internal/security/user_profile/_bulk_get', {
- body: JSON.stringify(params),
+ // Convert `Set` with UIDs to an array to make it serializable.
+ body: JSON.stringify({ ...params, uids: [...params.uids] }),
});
}
diff --git a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts
index c11b1fe85da57..9254a46c0e8c5 100644
--- a/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts
+++ b/x-pack/plugins/security/server/user_profile/user_profile_service.test.ts
@@ -81,7 +81,7 @@ describe('UserProfileService', () => {
});
mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
- [mockUserProfile.uid]: mockUserProfile,
+ profiles: [mockUserProfile],
} as unknown as SecurityGetUserProfileResponse);
});
@@ -160,6 +160,33 @@ describe('UserProfileService', () => {
});
});
+ it('fails if cannot find user profile', async () => {
+ mockStartParams.session.get.mockResolvedValue(
+ sessionMock.createValue({ userProfileId: mockUserProfile.uid })
+ );
+
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
+ profiles: [],
+ } as unknown as SecurityGetUserProfileResponse);
+
+ const startContract = userProfileService.start(mockStartParams);
+ await expect(
+ startContract.getCurrent({ request: mockRequest })
+ ).rejects.toMatchInlineSnapshot(`[Error: User profile is not found.]`);
+
+ expect(mockStartParams.session.get).toHaveBeenCalledTimes(1);
+ expect(mockStartParams.session.get).toHaveBeenCalledWith(mockRequest);
+
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledTimes(1);
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledWith({
+ uid: 'UID',
+ });
+ });
+
it('properly parses returned profile', async () => {
mockStartParams.session.get.mockResolvedValue(
sessionMock.createValue({ userProfileId: mockUserProfile.uid })
@@ -206,10 +233,12 @@ describe('UserProfileService', () => {
);
mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
- [mockUserProfile.uid]: userProfileMock.createWithSecurity({
- ...mockUserProfile,
- data: { kibana: { avatar: 'fun.gif' }, other_app: { secret: 'data' } },
- }),
+ profiles: [
+ userProfileMock.createWithSecurity({
+ ...mockUserProfile,
+ data: { kibana: { avatar: 'fun.gif' }, other_app: { secret: 'data' } },
+ }),
+ ],
} as unknown as SecurityGetUserProfileResponse);
const startContract = userProfileService.start(mockStartParams);
@@ -460,32 +489,32 @@ describe('UserProfileService', () => {
describe('#bulkGet', () => {
it('properly parses and sorts returned profiles', async () => {
- mockStartParams.clusterClient.asInternalUser.transport.request.mockResolvedValue({
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
profiles: [
userProfileMock.createWithSecurity({
- uid: 'UID-2',
+ uid: 'UID-1',
user: {
- username: 'user-2',
- display_name: 'display-name-2',
- full_name: 'full-name-2',
+ username: 'user-1',
+ display_name: 'display-name-1',
+ full_name: 'full-name-1',
realm_name: 'some-realm',
realm_domain: 'some-domain',
- roles: ['role-2'],
+ roles: ['role-1'],
},
}),
userProfileMock.createWithSecurity({
- uid: 'UID-1',
+ uid: 'UID-2',
user: {
- username: 'user-1',
- display_name: 'display-name-1',
- full_name: 'full-name-1',
+ username: 'user-2',
+ display_name: 'display-name-2',
+ full_name: 'full-name-2',
realm_name: 'some-realm',
realm_domain: 'some-domain',
- roles: ['role-1'],
+ roles: ['role-2'],
},
}),
],
- });
+ } as unknown as SecurityGetUserProfileResponse);
const startContract = userProfileService.start(mockStartParams);
await expect(startContract.bulkGet({ uids: new Set(['UID-1', 'UID-2']) })).resolves
@@ -515,72 +544,25 @@ describe('UserProfileService', () => {
},
]
`);
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledTimes(
- 1
- );
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({
- method: 'POST',
- path: '_security/profile/_suggest',
- body: { hint: { uids: ['UID-1', 'UID-2'] }, size: 2 },
- });
- });
-
- it('filters out not requested profiles', async () => {
- mockStartParams.clusterClient.asInternalUser.transport.request.mockResolvedValue({
- profiles: [
- userProfileMock.createWithSecurity({ uid: 'UID-2' }),
- userProfileMock.createWithSecurity({ uid: 'UID-NOT-REQUESTED' }),
- userProfileMock.createWithSecurity({ uid: 'UID-1' }),
- ],
- });
-
- const startContract = userProfileService.start(mockStartParams);
- await expect(startContract.bulkGet({ uids: new Set(['UID-1', 'UID-2', 'UID-3']) })).resolves
- .toMatchInlineSnapshot(`
- Array [
- Object {
- "data": Object {},
- "enabled": true,
- "uid": "UID-1",
- "user": Object {
- "display_name": undefined,
- "email": "some@email",
- "full_name": undefined,
- "username": "some-username",
- },
- },
- Object {
- "data": Object {},
- "enabled": true,
- "uid": "UID-2",
- "user": Object {
- "display_name": undefined,
- "email": "some@email",
- "full_name": undefined,
- "username": "some-username",
- },
- },
- ]
- `);
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledTimes(
- 1
- );
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({
- method: 'POST',
- path: '_security/profile/_suggest',
- body: { hint: { uids: ['UID-1', 'UID-2', 'UID-3'] }, size: 3 },
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledTimes(1);
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledWith({
+ uid: 'UID-1,UID-2',
});
});
it('should request data if data path is specified', async () => {
- mockStartParams.clusterClient.asInternalUser.transport.request.mockResolvedValue({
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockResolvedValue({
profiles: [
userProfileMock.createWithSecurity({
uid: 'UID-1',
data: { some: 'data', kibana: { some: 'kibana-data' } },
}),
],
- });
+ } as unknown as SecurityGetUserProfileResponse);
const startContract = userProfileService.start(mockStartParams);
await expect(startContract.bulkGet({ uids: new Set(['UID-1']), dataPath: '*' })).resolves
@@ -601,17 +583,14 @@ describe('UserProfileService', () => {
},
]
`);
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledTimes(
- 1
- );
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({
- method: 'POST',
- path: '_security/profile/_suggest',
- body: {
- hint: { uids: ['UID-1'] },
- data: 'kibana.*',
- size: 1,
- },
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledTimes(1);
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledWith({
+ uid: 'UID-1',
+ data: 'kibana.*',
});
});
@@ -619,7 +598,7 @@ describe('UserProfileService', () => {
const failureReason = new errors.ResponseError(
securityMock.createApiResponse({ statusCode: 500, body: 'some message' })
);
- mockStartParams.clusterClient.asInternalUser.transport.request.mockRejectedValue(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile.mockRejectedValue(
failureReason
);
@@ -627,13 +606,13 @@ describe('UserProfileService', () => {
await expect(startContract.bulkGet({ uids: new Set(['UID-1', 'UID-2']) })).rejects.toBe(
failureReason
);
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledTimes(
- 1
- );
- expect(mockStartParams.clusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({
- method: 'POST',
- path: '_security/profile/_suggest',
- body: { hint: { uids: ['UID-1', 'UID-2'] }, size: 2 },
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledTimes(1);
+ expect(
+ mockStartParams.clusterClient.asInternalUser.security.getUserProfile
+ ).toHaveBeenCalledWith({
+ uid: 'UID-1,UID-2',
});
});
});
diff --git a/x-pack/plugins/security/server/user_profile/user_profile_service.ts b/x-pack/plugins/security/server/user_profile/user_profile_service.ts
index 32dc1ec51cd88..7be2abe07a24a 100644
--- a/x-pack/plugins/security/server/user_profile/user_profile_service.ts
+++ b/x-pack/plugins/security/server/user_profile/user_profile_service.ts
@@ -7,7 +7,7 @@
import type {
SecurityActivateUserProfileRequest,
- SecuritySuggestUserProfilesResponse,
+ SecurityUserProfileWithMetadata,
} from '@elastic/elasticsearch/lib/api/types';
import type { SecurityUserProfile } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
@@ -179,8 +179,10 @@ function parseUserProfile(
): UserProfile