Add csp.disableUnsafeEval config option to remove the unsafe-eval CSP (#124484)

Adds a new experimental Kibana setting called `csp.disableUnsafeEval` which will default to `false`. When set to `true`, it will remove `unsafe-eval` from our CSP.

Also introduces a new module called `@kbn/handlebars` which is a replacement for the official `handlebars` module used in the frontend. This new module is necessary in order to avoid calling `eval`/`new Function` from within `handlebars` which is not allowed once `unsafe-eval` is removed from our CSP.

The `@kbn/handlebars` module is simply an extension of the main `handlebars` module which adds a new compile function called `compileAST` (as an alternative to the regular `compile` function). This new function will not use code-generation from strings to compile the template but will instead generate an AST and return a render function with the same API as the function returned by the regular `compile` function.

This is a little bit slower method, but since this is only meant to be used client-side, the slowdown should not be an issue.

The following limitations exists when using `@kbn/handlebars`:

The Inline partials handlebars template feature is not supported.

Only the following compile options will be supported:
- `knownHelpers`
- `knownHelpersOnly`
- `strict`
- `assumeObjects`
- `noEscape`
- `data`

Only the following runtime options will be supported:
- `helpers`
- `blockParams`
- `data`

Closes #36311
This commit is contained in:
Thomas Watson 2022-05-23 20:01:56 +02:00 committed by GitHub
parent f540c5e392
commit dc9f2732a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 11036 additions and 309 deletions

View file

@ -94,6 +94,22 @@ const SAFER_LODASH_SET_DEFINITELYTYPED_HEADER = `
*/
`;
const KBN_HANDLEBARS_HEADER = `
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See \`packages/kbn-handlebars/LICENSE\` for more information.
*/
`;
const KBN_HANDLEBARS_HANDLEBARS_HEADER = `
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See \`packages/kbn-handlebars/LICENSE\` for more information.
*/
`;
const packagePkgJsons = globby.sync('*/package.json', {
cwd: Path.resolve(__dirname, 'packages'),
absolute: true,
@ -293,6 +309,8 @@ module.exports = {
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
@ -325,6 +343,8 @@ module.exports = {
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
@ -364,6 +384,8 @@ module.exports = {
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
@ -393,6 +415,8 @@ module.exports = {
OLD_ELASTIC_LICENSE_HEADER,
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
@ -418,6 +442,8 @@ module.exports = {
OLD_ELASTIC_LICENSE_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
@ -443,6 +469,66 @@ module.exports = {
OLD_DUAL_LICENSE_HEADER,
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
KBN_HANDLEBARS_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
},
},
/**
* @kbn/handlebars package requires special license headers
*/
{
files: ['packages/kbn-handlebars/**/*.{js,mjs,ts,tsx}'],
rules: {
'@kbn/eslint/require-license-header': [
'error',
{
license: KBN_HANDLEBARS_HEADER,
},
],
'@kbn/eslint/disallow-license-headers': [
'error',
{
licenses: [
APACHE_2_0_LICENSE_HEADER,
DUAL_LICENSE_HEADER,
ELASTIC_LICENSE_HEADER,
OLD_DUAL_LICENSE_HEADER,
OLD_ELASTIC_LICENSE_HEADER,
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HANDLEBARS_HEADER,
],
},
],
},
},
{
files: ['packages/kbn-handlebars/src/upstream/**/*.{js,mjs,ts,tsx}'],
rules: {
'@kbn/eslint/require-license-header': [
'error',
{
license: KBN_HANDLEBARS_HANDLEBARS_HEADER,
},
],
'@kbn/eslint/disallow-license-headers': [
'error',
{
licenses: [
APACHE_2_0_LICENSE_HEADER,
DUAL_LICENSE_HEADER,
ELASTIC_LICENSE_HEADER,
OLD_DUAL_LICENSE_HEADER,
OLD_ELASTIC_LICENSE_HEADER,
SAFER_LODASH_SET_HEADER,
SAFER_LODASH_SET_LODASH_HEADER,
SAFER_LODASH_SET_DEFINITELYTYPED_HEADER,
KBN_HANDLEBARS_HEADER,
],
},
],

1
.github/CODEOWNERS vendored
View file

@ -324,6 +324,7 @@
# Kibana Platform Security
/packages/kbn-crypto/ @elastic/kibana-security
/packages/kbn-handlebars/ @elastic/kibana-security
/src/core/server/csp/ @elastic/kibana-security @elastic/kibana-core
/src/plugins/interactive_setup/ @elastic/kibana-security
/test/interactive_setup_api_integration/ @elastic/kibana-security

View file

@ -3,7 +3,7 @@ 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-04-26
date: 2022-05-23
tags: ['contributor', 'dev', 'apidocs', 'kibana']
warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
@ -14,14 +14,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Deprecated API | Referencing plugin(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsService" text="IndexPatternsService"/> | dataViews, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, unifiedSearch, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | dataViews, discover, ux, savedObjects, dataViewEditor, maps, visDefaultEditor, data | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | dataViews, dataViewEditor, maps, visDefaultEditor, data | - |
| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | dataViews, unifiedSearch | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, canvas | - |
| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | dataViews, unifiedSearch, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | dataViews, canvas, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, unifiedSearch, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | dataViews, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | dataViews, dataViewEditor, maps, visDefaultEditor, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | dataViews, maps, data | - |
| <DocLink id="kibDataPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | dataViews | - |
@ -38,16 +38,17 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibDataPluginApi" section="def-server.DataView.removeScriptedField" text="removeScriptedField"/> | dataViewManagement, dataViews | - |
| <DocLink id="kibDataPluginApi" section="def-server.DataView.getNonScriptedFields" text="getNonScriptedFields"/> | visTypeTimeseries, graph, dataViewManagement, dataViews | - |
| <DocLink id="kibDataPluginApi" section="def-server.DataView.getScriptedFields" text="getScriptedFields"/> | dataViews, dataViewManagement | - |
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | discover, visualizations, dashboard, lens, maps, monitoring | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | unifiedSearch, discover, maps, infra, graph, securitySolution, stackAlerts, inputControlVis, savedObjects | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataView.flattenHit" text="flattenHit"/> | maps | - |
| <DocLink id="kibDataViewsPluginApi" section="def-server.DataViewsServerPluginStart.indexPatternsServiceFactory" text="indexPatternsServiceFactory"/> | data, infra, maps | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | discover | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | discover | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | alerting, discover, securitySolution | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | alerting, discover, securitySolution | - |
| <DocLink id="kibUiActionsPluginApi" section="def-public.UiActionsService.executeTriggerActions" text="executeTriggerActions"/> | data, discover, embeddable | - |
| <DocLink id="kibCorePluginApi" section="def-public.UiSettingsParams.metric" text="metric"/> | advancedSettings, discover | - |
| <DocLink id="kibCorePluginApi" section="def-server.UiSettingsParams.metric" text="metric"/> | advancedSettings, discover | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplateProps" text="KibanaPageTemplateProps"/> | management, observability, infra, apm, cloudSecurityPosture, enterpriseSearch, securitySolution, synthetics, ux, kibanaOverview | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | esUiShared, home, spaces, fleet, visualizations, lens, observability, dataEnhanced, ml, apm, cloudSecurityPosture, indexLifecycleManagement, synthetics, upgradeAssistant, ux, kibanaOverview, savedObjectsManagement | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplateProps" text="KibanaPageTemplateProps"/> | management, observability, infra, apm, cloudSecurityPosture, enterpriseSearch, synthetics, ux, kibanaOverview | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | esUiShared, home, data, spaces, fleet, visualizations, lens, observability, ml, apm, cloudSecurityPosture, indexLifecycleManagement, synthetics, upgradeAssistant, ux, kibanaOverview, savedObjectsManagement | - |
| <DocLink id="kibExpressionsPluginApi" section="def-public.ExpressionFunctionDefinition.context" text="context"/> | canvas, visTypeXy | - |
| <DocLink id="kibExpressionsPluginApi" section="def-public.ExpressionsServiceSetup.getFunction" text="getFunction"/> | canvas | - |
| <DocLink id="kibExpressionsPluginApi" section="def-public.ExpressionsServiceSetup.getFunctions" text="getFunctions"/> | canvas | - |
@ -58,11 +59,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibExpressionsPluginApi" section="def-common.ExpressionsServiceSetup.getFunctions" text="getFunctions"/> | canvas | - |
| <DocLink id="kibExpressionsPluginApi" section="def-common.ExpressionsServiceSetup.getTypes" text="getTypes"/> | canvas | - |
| <DocLink id="kibExpressionsPluginApi" section="def-server.ExpressionFunctionDefinition.context" text="context"/> | canvas, visTypeXy | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplate" text="KibanaPageTemplate"/> | management, spaces, observability, ml, canvas, cloudSecurityPosture, enterpriseSearch, osquery, securitySolution, kibanaOverview | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplate" text="KibanaPageTemplate"/> | management, spaces, observability, ml, canvas, cloudSecurityPosture, enterpriseSearch, osquery, kibanaOverview | - |
| <DocLink id="kibTaskManagerPluginApi" section="def-server.TaskManagerSetupContract.index" text="index"/> | actions, alerting | - |
| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | encryptedSavedObjects, actions, data, cloud, ml, logstash, securitySolution | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | dashboard, lens, stackAlerts, visTypeTable, visTypeTimeseries, visTypeXy, visTypeVislib, expressionPartitionVis | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataView.getNonScriptedFields" text="getNonScriptedFields"/> | visTypeTimeseries, graph, dataViewManagement | - |
| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | encryptedSavedObjects, actions, cloud, ml, dataEnhanced, logstash, securitySolution | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.ExitFullScreenButton" text="ExitFullScreenButton"/> | dashboard | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataView.getNonScriptedFields" text="getNonScriptedFields"/> | visTypeTimeseries, graph, dataViewManagement | - |
| <DocLink id="kibDataPluginApi" section="def-server.DataPluginStart.fieldFormats" text="fieldFormats"/> | visTypeTimeseries | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataView.removeScriptedField" text="removeScriptedField"/> | dataViewManagement | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataView.getScriptedFields" text="getScriptedFields"/> | dataViewManagement | - |
@ -72,44 +74,36 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibExpressionGaugePluginApi" section="def-common.GaugeState.percentageMode" text="percentageMode"/> | visTypeGauge | - |
| <DocLink id="kibExpressionPartitionVisPluginApi" section="def-common.LabelsParams.truncate" text="truncate"/> | visTypePie | - |
| <DocLink id="kibExpressionPartitionVisPluginApi" section="def-common.LabelsParams.last_level" text="last_level"/> | visTypePie | - |
| <DocLink id="kibTaskManagerPluginApi" section="def-server.TaskManagerSetupContract.index" text="index"/> | actions, alerting | - |
| <DocLink id="kibCorePluginApi" section="def-server.ElasticsearchServiceSetup.legacy" text="legacy"/> | console | - |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | discover, dashboard, lens, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | discover, dashboard, lens, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | discover, dashboard, lens, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.esFilters" text="esFilters"/> | unifiedSearch | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | unifiedSearch, dataEnhanced | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.FILTERS" text="FILTERS"/> | unifiedSearch | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.toggleFilterNegated" text="toggleFilterNegated"/> | unifiedSearch | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | unifiedSearch, dataEnhanced | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | unifiedSearch, discover, dashboard, urlDrilldown, stackAlerts | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | unifiedSearch, dataEnhanced | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | discover, stackAlerts, inputControlVis | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | discover, stackAlerts, inputControlVis | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.nodeBuilder" text="nodeBuilder"/> | dataEnhanced | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | stackAlerts, alerting, securitySolution, inputControlVis | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | stackAlerts, alerting, securitySolution, inputControlVis | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.esKuery" text="esKuery"/> | apm | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | dataViews, unifiedSearch | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | dataViews, unifiedSearch, data | 8.2 |
| <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | visualizations, dashboard, lens, maps, ml, securitySolution, security | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | lens, dashboard, maps | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | dashboard, maps | 8.8.0 |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | embeddable, discover, presentationUtil, dashboard, graph | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getKibanaFeatures" text="getKibanaFeatures"/> | spaces, security, alerting | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-public.PublicLicense.mode" text="mode"/> | apm, security, securitySolution | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-server.PublicLicense.mode" text="mode"/> | apm, security, securitySolution | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.AppLeaveHandler" text="AppLeaveHandler"/> | securitySolution | 8.8.0 |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | savedObjectsTaggingOss, visualizations, dashboard, lens | 8.8.0 |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectsStart.SavedObjectClass" text="SavedObjectClass"/> | dashboard | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | monitoring | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.OpsMetrics.process" text="process"/> | monitoring, kibanaUsageCollection | 8.8.0 |
| <DocLink id="kibHomePluginApi" section="def-public.HomePublicPluginSetup.environment" text="environment"/> | cloud, apm | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-public.LicensingPluginSetup.license$" text="license$"/> | security, licenseManagement, ml, apm, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.appBasePath" text="appBasePath"/> | management, fleet, security, kibanaOverview | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getKibanaFeatures" text="getKibanaFeatures"/> | spaces, security, alerting | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-public.FeatureKibanaPrivileges.disabled" text="disabled"/> | security, fleet | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-common.FeatureKibanaPrivileges.disabled" text="disabled"/> | security, fleet | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-server.FeatureKibanaPrivileges.disabled" text="disabled"/> | security, fleet | 8.8.0 |
| <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getElasticsearchFeatures" text="getElasticsearchFeatures"/> | security | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.refresh" text="refresh"/> | mapsEms | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.CoreSetup.injectedMetadata" text="injectedMetadata"/> | visTypeVega | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | monitoring, visTypeVega | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.OpsMetrics.process" text="process"/> | monitoring, kibanaUsageCollection | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.IHttpFetchError.req" text="req"/> | ml | 8.8.0
Note to maintainers: when looking at usages, mind that typical use could be inside a `catch` block,
@ -132,6 +126,7 @@ Safe to remove.
| ---------------|------------|
| <DocLink id="kibDataPluginApi" section="def-public.AggConfig.toJSON" text="toJSON"/> | data |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSourceFields.fieldsFromSource" text="fieldsFromSource"/> | data |
| <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | data |
| <DocLink id="kibDataPluginApi" section="def-public.RangeFilter" text="RangeFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-public.RangeFilterParams" text="RangeFilterParams"/> | data |
| <DocLink id="kibDataPluginApi" section="def-public.ExistsFilter" text="ExistsFilter"/> | data |
@ -168,12 +163,15 @@ Safe to remove.
| <DocLink id="kibDataPluginApi" section="def-common.isFilterPinned" text="isFilterPinned"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.isMatchAllFilter" text="isMatchAllFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.COMPARE_ALL_OPTIONS" text="COMPARE_ALL_OPTIONS"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.FILTERS" text="FILTERS"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.luceneStringToDsl" text="luceneStringToDsl"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.nodeBuilder" text="nodeBuilder"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.nodeTypes" text="nodeTypes"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.onlyDisabledFiltersChanged" text="onlyDisabledFiltersChanged"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.pinFilter" text="pinFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.toElasticsearchQuery" text="toElasticsearchQuery"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.toggleFilterDisabled" text="toggleFilterDisabled"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.toggleFilterNegated" text="toggleFilterNegated"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.uniqFilters" text="uniqFilters"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.ExistsFilter" text="ExistsFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.MatchAllFilter" text="MatchAllFilter"/> | data |
@ -181,11 +179,13 @@ Safe to remove.
| <DocLink id="kibDataPluginApi" section="def-common.PhraseFilter" text="PhraseFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.RangeFilter" text="RangeFilter"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.RangeFilterParams" text="RangeFilterParams"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.EsQueryConfig" text="EsQueryConfig"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.AggConfig.toJSON" text="toJSON"/> | data |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSourceFields.fieldsFromSource" text="fieldsFromSource"/> | data |
| <DocLink id="kibDataPluginApi" section="def-server.DataPluginSetup.fieldFormats" text="fieldFormats"/> | data |
| <DocLink id="kibDataPluginApi" section="def-server.EsQueryConfig" text="EsQueryConfig"/> | data |
| <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | data |
| <DocLink id="kibDataViewsPluginApi" section="def-public.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | dataViews |
| <DocLink id="kibDataViewsPluginApi" section="def-common.DataViewsService.ensureDefaultDataView" text="ensureDefaultDataView"/> | dataViews |
| <DocLink id="kibExpressionsPluginApi" section="def-public.ExpressionExecutor" text="ExpressionExecutor"/> | expressions |
@ -211,5 +211,6 @@ Safe to remove.
| <DocLink id="kibReportingPluginApi" section="def-common.JobAppParamsPDF" text="JobAppParamsPDF"/> | reporting |
| <DocLink id="kibTaskManagerPluginApi" section="def-server.ConcreteTaskInstance.interval" text="interval"/> | taskManager |
| <DocLink id="kibCorePluginApi" section="def-public.IHttpFetchError.res" text="res"/> | core |
| <DocLink id="kibCorePluginApi" section="def-public.CoreSetup.injectedMetadata" text="injectedMetadata"/> | core |
| <DocLink id="kibCorePluginApi" section="def-server.AsyncPlugin" text="AsyncPlugin"/> | core |
| <DocLink id="kibCorePluginApi" section="def-server.PluginManifest.extraPublicDirs" text="extraPublicDirs"/> | core |

View file

@ -3,7 +3,7 @@ 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-04-26
date: 2022-05-23
tags: ['contributor', 'dev', 'apidocs', 'kibana']
warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
@ -33,6 +33,10 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.ts#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getKibanaFeatures" text="getKibanaFeatures"/> | [plugin.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/plugin.test.ts#:~:text=getKibanaFeatures) | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/plugin.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24) | 8.8.0 |
| <DocLink id="kibTaskManagerPluginApi" section="def-server.TaskManagerSetupContract.index" text="index"/> | [task.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/usage/task.ts#:~:text=index) | - |
@ -113,6 +117,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [sync_dashboard_filter_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_filter_state.ts#:~:text=syncQueryStateWithUrl), [sync_dashboard_filter_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/sync_dashboard_filter_state.ts#:~:text=syncQueryStateWithUrl), [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=syncQueryStateWithUrl), [dashboard_listing.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | [export_csv_action.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/actions/export_csv_action.tsx#:~:text=fieldFormats) | - |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter)+ 5 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [filter_utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/lib/filter_utils.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [saved_dashboard.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/saved_dashboards/saved_dashboard.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter), [dashboard_state_slice.ts](https://github.com/elastic/kibana/tree/master/src/plugins/dashboard/public/application/state/dashboard_state_slice.ts#:~:text=Filter)+ 5 more | 8.1 |
@ -130,32 +135,21 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataViewsPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField)+ 16 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternField), [agg_config.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=IndexPatternField), [agg_config.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=IndexPatternField)+ 16 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [create_search_source.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.test.ts#:~:text=IndexPatternsContract)+ 19 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.IndexPatternsService" text="IndexPatternsService"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternsService) | - |
| <DocLink id="kibDataViewsPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern)+ 89 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType)+ 6 more | 8.2 |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [mapping.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/param_types/mapping.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField)+ 16 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [normalize_sort_request.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/normalize_sort_request.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IIndexPattern)+ 23 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [date_histogram.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/buckets/date_histogram.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType), [create_filters_from_range_select.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/actions/filters/create_filters_from_range_select.ts#:~:text=IFieldType)+ 6 more | 8.2 |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [kibana_context_type.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/kibana_context_type.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternField), [agg_config.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=IndexPatternField), [agg_config.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/aggs/agg_config.test.ts#:~:text=IndexPatternField)+ 16 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [get_time.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/query/timefilter/get_time.ts#:~:text=IIndexPattern), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IIndexPattern), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IIndexPattern), [generate_filters.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts#:~:text=IIndexPattern), [timefilter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/timefilter/timefilter.ts#:~:text=IIndexPattern), [timefilter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/query/timefilter/timefilter.ts#:~:text=IIndexPattern)+ 23 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternAttributes), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternAttributes), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternAttributes) | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [create_search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [search_source_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source_service.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [esaggs_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/expressions/esaggs/esaggs_fn.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/types.ts#:~:text=IndexPatternsContract), [create_search_source.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/create_search_source.test.ts#:~:text=IndexPatternsContract)+ 19 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPatternsService" text="IndexPatternsService"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/index.ts#:~:text=IndexPatternsService) | - |
| <DocLink id="kibDataViewsPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/index.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/types.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [search_source.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/search_source/search_source.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern), [tabify_docs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/common/search/tabify/tabify_docs.ts#:~:text=IndexPattern)+ 89 more | - |
| <DocLink id="kibDataViewsPluginApi" section="def-server.DataViewsServerPluginStart.indexPatternsServiceFactory" text="indexPatternsServiceFactory"/> | [aggs_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/search/aggs/aggs_service.ts#:~:text=indexPatternsServiceFactory), [esaggs.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/search/expressions/esaggs.ts#:~:text=indexPatternsServiceFactory), [search_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/search/search_service.ts#:~:text=indexPatternsServiceFactory) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/session_indicator/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/search/session/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks) | - |
| <DocLink id="kibUiActionsPluginApi" section="def-public.UiActionsService.executeTriggerActions" text="executeTriggerActions"/> | [data_table.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions), [data_table.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/data/public/utils/table_inspector_view/components/data_table.tsx#:~:text=executeTriggerActions) | - |
## dataEnhanced
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.nodeBuilder" text="nodeBuilder"/> | [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder)+ 2 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [get_columns.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [get_columns.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks), [connected_search_session_indicator.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/public/search/ui/connected_search_session_indicator/connected_search_session_indicator.tsx#:~:text=RedirectAppLinks) | - |
| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | [session_service.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/session_service.ts#:~:text=authc) | - |
| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | [session_service.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data/server/search/session/session_service.ts#:~:text=authc) | - |
@ -197,9 +191,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternField), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPatternField)+ 2 more | - |
| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IFieldType), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternAttributes) | - |
| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IFieldType), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IIndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternAttributes" text="IndexPatternAttributes"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternAttributes) | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsContract) | - |
@ -228,13 +222,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/services/discover_state.ts#:~:text=syncQueryStateWithUrl), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/services/discover_state.ts#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=indexPatterns) | - |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPattern" text="IndexPattern"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.IndexPattern" text="IndexPattern"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=IndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 |
@ -372,11 +365,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/app.tsx#:~:text=syncQueryStateWithUrl), [app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/app.tsx#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | [ranges.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx#:~:text=fieldFormats), [droppable.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts#:~:text=fieldFormats) | - |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks), [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks), [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks) | - |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning), [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning) | 8.8.0 |
@ -415,6 +411,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPattern" text="IndexPattern"/> | [es_tooltip_property.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts#:~:text=IndexPattern), [es_tooltip_property.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts#:~:text=IndexPattern), [percentile_agg_field.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts#:~:text=IndexPattern), [percentile_agg_field.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts#:~:text=IndexPattern), [get_docvalue_source_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts#:~:text=IndexPattern), [get_docvalue_source_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts#:~:text=IndexPattern), [get_docvalue_source_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.test.ts#:~:text=IndexPattern), [es_tooltip_property.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts#:~:text=IndexPattern), [es_tooltip_property.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.test.ts#:~:text=IndexPattern), [percentile_agg_field.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.test.ts#:~:text=IndexPattern)+ 4 more | - |
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternField" text="IndexPatternField"/> | [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField)+ 84 more | - |
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [global_sync.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/url_state/global_sync.ts#:~:text=syncQueryStateWithUrl), [global_sync.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/map_page/url_state/global_sync.ts#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [kibana_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/kibana_services.ts#:~:text=indexPatterns) | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract) | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternField" text="IndexPatternField"/> | [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField), [single_field_select.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/components/single_field_select.tsx#:~:text=IndexPatternField)+ 84 more | - |
@ -463,6 +460,7 @@ so TS and code-reference navigation might not highlight them. |
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [url_state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/url_state.ts#:~:text=syncQueryStateWithUrl), [url_state.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/url_state.ts#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | [legacy_shims.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/public/legacy_shims.ts#:~:text=injectedMetadata) | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-server.OpsMetrics.process" text="process"/> | [bulk_uploader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/monitoring/server/kibana_monitoring/bulk_uploader.ts#:~:text=process) | 8.8.0 |
@ -595,9 +593,11 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.ts#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [middleware.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=indexPatterns), [dependencies_start_mock.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts#:~:text=indexPatterns) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplateProps" text="KibanaPageTemplateProps"/> | [use_primary_navigation.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx#:~:text=KibanaPageTemplateProps), [use_primary_navigation.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx#:~:text=KibanaPageTemplateProps), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=KibanaPageTemplateProps), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=KibanaPageTemplateProps) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplate" text="KibanaPageTemplate"/> | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=KibanaPageTemplate), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=KibanaPageTemplate) | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.create" text="create"/> | [wrap_search_source_client.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.ts#:~:text=create) | - |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibLicensingPluginApi" section="def-public.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 |
| <DocLink id="kibLicensingPluginApi" section="def-server.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 |
| <DocLink id="kibSecurityPluginApi" section="def-server.SecurityPluginSetup.authc" text="authc"/> | [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [open_close_signals_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts#:~:text=authc), [preview_rules_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - |
@ -634,10 +634,10 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [entity_index_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx#:~:text=indexPatterns), [boundary_index_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns) | - |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.fieldFormats" text="fieldFormats"/> | [expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx#:~:text=fieldFormats) | - |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
@ -645,8 +645,8 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplateProps" text="KibanaPageTemplateProps"/> | [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts#:~:text=KibanaPageTemplateProps), [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/use_no_data_config.ts#:~:text=KibanaPageTemplateProps) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/uptime_app.tsx#:~:text=RedirectAppLinks) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.KibanaPageTemplateProps" text="KibanaPageTemplateProps"/> | [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts#:~:text=KibanaPageTemplateProps), [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/app/use_no_data_config.ts#:~:text=KibanaPageTemplateProps), [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_no_data_config.ts#:~:text=KibanaPageTemplateProps), [use_no_data_config.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/synthetics/hooks/use_no_data_config.ts#:~:text=KibanaPageTemplateProps) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [alert_messages.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/lib/alert_types/alert_messages.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx#:~:text=RedirectAppLinks), [uptime_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/legacy_uptime/app/uptime_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks), [synthetics_app.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/synthetics/public/apps/synthetics/synthetics_app.tsx#:~:text=RedirectAppLinks) | - |
@ -662,22 +662,12 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.IndexPatternsContract" text="IndexPatternsContract"/> | [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 25 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-public.IIndexPattern" text="IIndexPattern"/> | [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern) | - |
| <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType) | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-public.DataPublicPluginStart.indexPatterns" text="indexPatterns"/> | [query_string_input.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/query_string_input/query_string_input.tsx#:~:text=indexPatterns) | - |
| <DocLink id="kibDataPluginApi" section="def-public.esFilters" text="esFilters"/> | [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.FILTERS" text="FILTERS"/> | [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.toggleFilterNegated" text="toggleFilterNegated"/> | [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated) | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 60 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern)+ 4 more | - |
| <DocLink id="kibDataPluginApi" section="def-common.IndexPatternsContract" text="IndexPatternsContract"/> | [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract), [create_index_pattern_select.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/index_pattern_select/create_index_pattern_select.tsx#:~:text=IndexPatternsContract) | - |
| <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType)+ 8 more | 8.2 |
| <DocLink id="kibDataPluginApi" section="def-common.IIndexPattern" text="IIndexPattern"/> | [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IIndexPattern), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IIndexPattern)+ 4 more | - |
@ -762,15 +752,6 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
## visTypeVega
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibCorePluginApi" section="def-public.CoreSetup.injectedMetadata" text="injectedMetadata"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | [search_api.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/data_model/search_api.ts#:~:text=injectedMetadata), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 |
## visTypeVislib
| Deprecated API | Reference location(s) | Remove By |
@ -795,6 +776,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Deprecated API | Reference location(s) | Remove By |
| ---------------|-----------|-----------|
| <DocLink id="kibDataPluginApi" section="def-public.syncQueryStateWithUrl" text="syncQueryStateWithUrl"/> | [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=syncQueryStateWithUrl), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=syncQueryStateWithUrl) | - |
| <DocLink id="kibKibanaReactPluginApi" section="def-public.RedirectAppLinks" text="RedirectAppLinks"/> | [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks), [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks), [get_table_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/utils/get_table_columns.tsx#:~:text=RedirectAppLinks) | - |
| <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 |
| <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 |

View file

@ -3,7 +3,7 @@ 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-04-26
date: 2022-05-23
tags: ['contributor', 'dev', 'apidocs', 'kibana']
warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system.
---
@ -25,12 +25,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| dataViews | <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| dataViews | <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/types.ts#:~:text=IFieldType)+ 23 more | 8.2 |
| dataEnhanced | <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| dataEnhanced | <DocLink id="kibDataPluginApi" section="def-common.nodeBuilder" text="nodeBuilder"/> | [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=nodeBuilder)+ 2 more | 8.1 |
| dataEnhanced | <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| dataEnhanced | <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/types.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [get_search_session_page.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/get_search_session_page.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [check_non_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/check_non_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode), [expire_persisted_sessions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_enhanced/server/search/session/expire_persisted_sessions.ts#:~:text=KueryNode) | 8.1 |
| dataViews | <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IFieldType), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IFieldType)+ 7 more | 8.2 |
| dataViews | <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/utils.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [data_view_field.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [field_list.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/field_list.ts#:~:text=IFieldType), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IFieldType), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=IFieldType)+ 23 more | 8.2 |
| urlDrilldown | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter) | 8.1 |
| urlDrilldown | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter) | 8.1 |
| urlDrilldown | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [context_variables.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/variables/context_variables.ts#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [url_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter), [data.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/drilldowns/url_drilldown/public/lib/test/data.ts#:~:text=Filter) | 8.1 |
@ -42,10 +38,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| discover | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 |
| discover | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| discover | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| discover | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/context/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 |
| discover | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter), [view_alert_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/view_alert/view_alert_route.tsx#:~:text=Filter) | 8.1 |
| discover | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObjectSaveModal" text="SavedObjectSaveModal"/> | [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 |
| graph | <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/graph/server/plugin.ts#:~:text=license%24) | 8.8.0 |
@ -161,13 +155,13 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [read_only_filter_items.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/read_only_filter_items.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter), [search_source_expression.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression.tsx#:~:text=Filter) | 8.1 |
| alerting | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| alerting | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/wrap_search_source_client.test.ts#:~:text=fetch), [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch), [alert_type.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/server/alert_types/es_query/alert_type.test.ts#:~:text=fetch) | 8.1 |
| alerting | <DocLink id="kibFeaturesPluginApi" section="def-server.PluginSetupContract.getKibanaFeatures" text="getKibanaFeatures"/> | [plugin.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/plugin.test.ts#:~:text=getKibanaFeatures) | 8.8.0 |
| alerting | <DocLink id="kibLicensingPluginApi" section="def-server.LicensingPluginSetup.license$" text="license$"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/plugin.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting/server/lib/license_state.test.ts#:~:text=license%24), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/actions/server/plugin.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/actions/server/lib/license_state.test.ts#:~:text=license%24), [license_state.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/actions/server/lib/license_state.test.ts#:~:text=license%24) | 8.8.0 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
| stackAlerts | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter), [search_source_expression_form.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/stack_alerts/public/alert_types/es_query/expression/search_source_expression_form.tsx#:~:text=Filter) | 8.1 |
@ -175,6 +169,8 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| securitySolution | <DocLink id="kibDataPluginApi" section="def-public.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| securitySolution | <DocLink id="kibDataPluginApi" section="def-common.SearchSource.fetch" text="fetch"/> | [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch), [wrap_search_source_client.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts#:~:text=fetch) | 8.1 |
| securitySolution | <DocLink id="kibLicensingPluginApi" section="def-public.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 |
| securitySolution | <DocLink id="kibLicensingPluginApi" section="def-server.PublicLicense.mode" text="mode"/> | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 2 more | 8.8.0 |
| securitySolution | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/index.tsx#:~:text=onAppLeave) | 8.8.0 |
@ -204,17 +200,9 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 25 more | 8.2 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-public.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType) | 8.2 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-public.esFilters" text="esFilters"/> | [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=esFilters) | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-public.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.FILTERS" text="FILTERS"/> | [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=FILTERS) | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.toggleFilterNegated" text="toggleFilterNegated"/> | [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated), [filter_editor_utils.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts#:~:text=toggleFilterNegated) | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [query_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/query_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType)+ 60 more | 8.2 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [use_filter_manager.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/search_bar/lib/use_filter_manager.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [apply_filter_action.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/actions/apply_filter_action.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [get_stub_filter.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/test_helpers/get_stub_filter.ts#:~:text=Filter), [filter_label.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/filter_bar/filter_editor/lib/filter_label.tsx#:~:text=Filter)+ 10 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-server.KueryNode" text="KueryNode"/> | [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [conjunction.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/conjunction.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [operator.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/operator.test.ts#:~:text=KueryNode), [value.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.test.ts#:~:text=KueryNode)+ 2 more | 8.1 |
| unifiedSearch | <DocLink id="kibDataPluginApi" section="def-common.IFieldType" text="IFieldType"/> | [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value_suggestion_provider.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/value_suggestion_provider.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [value.ts](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/value.ts#:~:text=IFieldType), [field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/unified_search/public/autocomplete/providers/kql_query_suggestion/field.tsx#:~:text=IFieldType)+ 8 more | 8.2 |
@ -222,9 +210,9 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/
| Plugin | Deprecated API | Reference location(s) | Remove By |
| --------|-------|-----------|-----------|
| lens | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 |
| lens | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave), [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave) | 8.8.0 |
| lens | <DocLink id="kibCorePluginApi" section="def-server.SavedObjectsMigrationLogger.warning" text="warning"/> | [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning), [saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts#:~:text=warning) | 8.8.0 |
| management | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.appBasePath" text="appBasePath"/> | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 |
| visTypeVega | <DocLink id="kibCorePluginApi" section="def-public.CoreSetup.injectedMetadata" text="injectedMetadata"/> | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 |
| visTypeVega | <DocLink id="kibCorePluginApi" section="def-public.CoreStart.injectedMetadata" text="injectedMetadata"/> | [search_api.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/data_model/search_api.ts#:~:text=injectedMetadata), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/vega/public/plugin.ts#:~:text=injectedMetadata) | 8.8.0 |
| visualizations | <DocLink id="kibSavedObjectsPluginApi" section="def-public.SavedObject" text="SavedObject"/> | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 |
| visualizations | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.onAppLeave" text="onAppLeave"/> | [visualize_top_nav.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_top_nav.tsx#:~:text=onAppLeave), [visualize_editor_common.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/components/visualize_editor_common.tsx#:~:text=onAppLeave), [app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/app.tsx#:~:text=onAppLeave), [index.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 |
| lens | <DocLink id="kibDataPluginApi" section="def-public.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| lens | <DocLink id="kibDataPluginApi" section="def-common.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| lens | <DocLink id="kibDataPluginApi" section="def-server.Filter" text="Filter"/> | [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter), [open_in_discover_drilldown.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/trigger_actions/open_in_discover_drilldown.tsx#:~:text=Filter) | 8.1 |
| management | <DocLink id="kibCorePluginApi" section="def-public.AppMountParameters.appBasePath" text="appBasePath"/> | [application.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/management/public/application.tsx#:~:text=appBasePath) | 8.8.0 |

View file

@ -0,0 +1,153 @@
{
"id": "@kbn/handlebars",
"client": {
"classes": [],
"functions": [],
"interfaces": [],
"enums": [],
"misc": [],
"objects": []
},
"server": {
"classes": [],
"functions": [],
"interfaces": [],
"enums": [],
"misc": [],
"objects": []
},
"common": {
"classes": [],
"functions": [
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.create",
"type": "Function",
"tags": [],
"label": "create",
"description": [
"\nCreates an isolated Handlebars environment.\n\nEach environment has its own helpers.\nThis is only necessary for use cases that demand distinct helpers.\nMost use cases can use the root Handlebars environment directly.\n"
],
"signature": [
"() => typeof ",
{
"pluginId": "@kbn/handlebars",
"scope": "common",
"docId": "kibKbnHandlebarsPluginApi",
"section": "def-common.ExtendedHandlebars",
"text": "ExtendedHandlebars"
},
" & typeof Handlebars"
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"children": [],
"returnComment": [
"A sandboxed/scoped version of the"
],
"initialIsOpen": false
}
],
"interfaces": [],
"enums": [],
"misc": [
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.compileFnName",
"type": "CompoundType",
"tags": [],
"label": "compileFnName",
"description": [
"\nIf the `unsafe-eval` CSP is set, this string constant will be `compile`,\notherwise `compileAST`.\n\nThis can be used to call the more optimized `compile` function in\nenvironments that support it, or fall back to `compileAST` on environments\nthat don't."
],
"signature": [
"\"compile\" | \"compileAST\""
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"initialIsOpen": false
},
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.ExtendedCompileOptions",
"type": "Type",
"tags": [],
"label": "ExtendedCompileOptions",
"description": [
"\nSupported Handlebars compile options.\n\nThis is a subset of all the compile options supported by the upstream\nHandlebars module."
],
"signature": [
"{ data?: boolean | undefined; strict?: boolean | undefined; knownHelpers?: KnownHelpers | undefined; knownHelpersOnly?: boolean | undefined; assumeObjects?: boolean | undefined; noEscape?: boolean | undefined; }"
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"initialIsOpen": false
},
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.ExtendedRuntimeOptions",
"type": "Type",
"tags": [],
"label": "ExtendedRuntimeOptions",
"description": [
"\nSupported Handlebars runtime options\n\nThis is a subset of all the runtime options supported by the upstream\nHandlebars module."
],
"signature": [
"{ data?: any; helpers?: { [name: string]: Function; } | undefined; blockParams?: any[] | undefined; }"
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"initialIsOpen": false
},
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.Handlebars",
"type": "CompoundType",
"tags": [],
"label": "Handlebars",
"description": [
"\nA custom version of the Handlesbars module with an extra `compileAST` function."
],
"signature": [
"typeof ",
{
"pluginId": "@kbn/handlebars",
"scope": "common",
"docId": "kibKbnHandlebarsPluginApi",
"section": "def-common.ExtendedHandlebars",
"text": "ExtendedHandlebars"
},
" & typeof Handlebars"
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"initialIsOpen": false
}
],
"objects": [
{
"parentPluginId": "@kbn/handlebars",
"id": "def-common.ExtendedHandlebars",
"type": "Object",
"tags": [],
"label": "ExtendedHandlebars",
"description": [
"\nNormally this namespace isn't used directly. It's required to be present by\nTypeScript when calling the `Handlebars.create()` function."
],
"signature": [
"typeof ",
{
"pluginId": "@kbn/handlebars",
"scope": "common",
"docId": "kibKbnHandlebarsPluginApi",
"section": "def-common.ExtendedHandlebars",
"text": "ExtendedHandlebars"
}
],
"path": "packages/kbn-handlebars/src/index.ts",
"deprecated": false,
"initialIsOpen": false
}
]
}
}

View file

@ -0,0 +1,33 @@
---
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-05-23
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';
Contact [Owner missing] for questions regarding this plugin.
**Code health stats**
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
| 6 | 0 | 0 | 0 |
## Common
### Objects
<DocDefinitionList data={kbnHandlebarsObj.common.objects}/>
### Functions
<DocDefinitionList data={kbnHandlebarsObj.common.functions}/>
### Consts, variables and types
<DocDefinitionList data={kbnHandlebarsObj.common.misc}/>

View file

@ -3,7 +3,7 @@ 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-04-26
date: 2022-05-23
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.
---
@ -12,123 +12,123 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| Count | Plugins or Packages with a <br /> public API | Number of teams |
|--------------|----------|------------------------|
| 247 | 201 | 35 |
| 258 | 209 | 35 |
### Public API health stats
| API Count | Any Count | Missing comments | Missing exports |
|--------------|----------|-----------------|--------|
| 25958 | 170 | 19687 | 1153 |
| 26222 | 171 | 19770 | 870 |
## Plugin Directory
| Plugin name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Maintaining team | Description | API Cnt | Any Cnt | Missing<br />comments | Missing<br />exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
| <DocLink id="kibActionsPluginApi" text="actions"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 195 | 0 | 191 | 11 |
| <DocLink id="kibActionsPluginApi" text="actions"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 240 | 0 | 235 | 19 |
| <DocLink id="kibAdvancedSettingsPluginApi" text="advancedSettings"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 23 | 0 | 19 | 1 |
| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 325 | 0 | 316 | 19 |
| <DocLink id="kibApmPluginApi" text="apm"/> | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 40 | 0 | 40 | 50 |
| <DocLink id="kibAiopsPluginApi" text="aiops"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 12 | 0 | 0 | 0 |
| <DocLink id="kibAlertingPluginApi" text="alerting"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 359 | 0 | 350 | 19 |
| <DocLink id="kibApmPluginApi" text="apm"/> | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 40 | 0 | 40 | 51 |
| <DocLink id="kibBannersPluginApi" text="banners"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 |
| <DocLink id="kibBfetchPluginApi" text="bfetch"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 78 | 1 | 69 | 2 |
| <DocLink id="kibCanvasPluginApi" text="canvas"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 |
| <DocLink id="kibCasesPluginApi" text="cases"/> | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 71 | 0 | 57 | 19 |
| <DocLink id="kibCasesPluginApi" text="cases"/> | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 66 | 0 | 52 | 22 |
| <DocLink id="kibChartsPluginApi" text="charts"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 272 | 2 | 253 | 9 |
| <DocLink id="kibCloudPluginApi" text="cloud"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 28 | 0 | 23 | 0 |
| <DocLink id="kibCloudPluginApi" text="cloud"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 29 | 0 | 24 | 0 |
| <DocLink id="kibCloudSecurityPosturePluginApi" text="cloudSecurityPosture"/> | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 14 | 0 | 14 | 0 |
| <DocLink id="kibConsolePluginApi" text="console"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 |
| <DocLink id="kibControlsPluginApi" text="controls"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 203 | 0 | 197 | 6 |
| <DocLink id="kibCorePluginApi" text="core"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2524 | 15 | 977 | 33 |
| <DocLink id="kibControlsPluginApi" text="controls"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 205 | 0 | 199 | 7 |
| <DocLink id="kibCorePluginApi" text="core"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2541 | 15 | 977 | 33 |
| crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibCustomIntegrationsPluginApi" text="customIntegrations"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 98 | 0 | 79 | 1 |
| <DocLink id="kibDashboardPluginApi" text="dashboard"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 142 | 0 | 140 | 12 |
| <DocLink id="kibCustomIntegrationsPluginApi" text="customIntegrations"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 101 | 0 | 82 | 1 |
| <DocLink id="kibDashboardPluginApi" text="dashboard"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 143 | 0 | 141 | 12 |
| <DocLink id="kibDashboardEnhancedPluginApi" text="dashboardEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 |
| <DocLink id="kibDataPluginApi" text="data"/> | [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. | 3414 | 38 | 2802 | 18 |
| <DocLink id="kibDataEnhancedPluginApi" text="dataEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Enhanced data plugin. (See src/plugins/data.) Enhances the main data plugin with a search session management UI. Includes a reusable search session indicator component to use in other applications. Exposes routes for managing search sessions. Includes a service that monitors, updates, and cleans up search session saved objects. | 16 | 0 | 16 | 2 |
| <DocLink id="kibDataViewEditorPluginApi" text="dataViewEditor"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout from any kibana app | 13 | 0 | 7 | 0 |
| <DocLink id="kibDataPluginApi" text="data"/> | [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. | 3482 | 38 | 2869 | 19 |
| <DocLink id="kibDataViewEditorPluginApi" text="dataViewEditor"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout from any kibana app | 14 | 0 | 7 | 0 |
| <DocLink id="kibDataViewFieldEditorPluginApi" text="dataViewFieldEditor"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 42 | 0 | 37 | 3 |
| <DocLink id="kibDataViewManagementPluginApi" text="dataViewManagement"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data view management app | 2 | 0 | 2 | 0 |
| <DocLink id="kibDataViewsPluginApi" text="dataViews"/> | [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. | 862 | 3 | 710 | 15 |
| <DocLink id="kibDataVisualizerPluginApi" text="dataVisualizer"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 23 | 2 | 19 | 1 |
| <DocLink id="kibDataViewsPluginApi" text="dataViews"/> | [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. | 866 | 3 | 714 | 15 |
| <DocLink id="kibDataVisualizerPluginApi" text="dataVisualizer"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 1 |
| <DocLink id="kibDevToolsPluginApi" text="devTools"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 |
| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 76 | 0 | 60 | 7 |
| <DocLink id="kibDiscoverPluginApi" text="discover"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 78 | 0 | 62 | 7 |
| <DocLink id="kibDiscoverEnhancedPluginApi" text="discoverEnhanced"/> | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 |
| <DocLink id="kibEmbeddablePluginApi" text="embeddable"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 476 | 0 | 386 | 4 |
| <DocLink id="kibEmbeddablePluginApi" text="embeddable"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 486 | 0 | 396 | 4 |
| <DocLink id="kibEmbeddableEnhancedPluginApi" text="embeddableEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 |
| <DocLink id="kibEncryptedSavedObjectsPluginApi" text="encryptedSavedObjects"/> | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 48 | 0 | 44 | 0 |
| <DocLink id="kibEncryptedSavedObjectsPluginApi" text="encryptedSavedObjects"/> | [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 | 44 | 0 |
| <DocLink id="kibEnterpriseSearchPluginApi" text="enterpriseSearch"/> | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 2 | 0 | 2 | 0 |
| <DocLink id="kibEsUiSharedPluginApi" text="esUiShared"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 112 | 3 | 108 | 3 |
| <DocLink id="kibEventAnnotationPluginApi" text="eventAnnotation"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 49 | 0 | 49 | 3 |
| <DocLink id="kibEventLogPluginApi" text="eventLog"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 91 | 0 | 91 | 9 |
| <DocLink id="kibEventAnnotationPluginApi" text="eventAnnotation"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 90 | 0 | 90 | 5 |
| <DocLink id="kibEventLogPluginApi" text="eventLog"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 100 | 0 | 100 | 9 |
| <DocLink id="kibExpressionErrorPluginApi" text="expressionError"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 |
| <DocLink id="kibExpressionGaugePluginApi" text="expressionGauge"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 61 | 0 | 61 | 2 |
| <DocLink id="kibExpressionHeatmapPluginApi" text="expressionHeatmap"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 104 | 0 | 100 | 3 |
| <DocLink id="kibExpressionHeatmapPluginApi" text="expressionHeatmap"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Heatmap plugin adds a `heatmap` renderer and function to the expression plugin. The renderer will display the `heatmap` chart. | 107 | 0 | 103 | 3 |
| <DocLink id="kibExpressionImagePluginApi" text="expressionImage"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'image' function and renderer to expressions | 26 | 0 | 26 | 0 |
| <DocLink id="kibExpressionMetricPluginApi" text="expressionMetric"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'metric' function and renderer to expressions | 32 | 0 | 27 | 0 |
| <DocLink id="kibExpressionMetricVisPluginApi" text="expressionMetricVis"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression MetricVis plugin adds a `metric` renderer and function to the expression plugin. The renderer will display the `metric` chart. | 46 | 0 | 46 | 1 |
| <DocLink id="kibExpressionMetricVisPluginApi" text="expressionMetricVis"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression MetricVis plugin adds a `metric` renderer and function to the expression plugin. The renderer will display the `metric` chart. | 48 | 0 | 48 | 1 |
| <DocLink id="kibExpressionPartitionVisPluginApi" text="expressionPartitionVis"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Partition Visualization plugin adds a `partitionVis` renderer and `pieVis`, `mosaicVis`, `treemapVis`, `waffleVis` functions to the expression plugin. The renderer will display the `pie`, `waffle`, `treemap` and `mosaic` charts. | 70 | 0 | 70 | 2 |
| <DocLink id="kibExpressionRepeatImagePluginApi" text="expressionRepeatImage"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'repeatImage' function and renderer to expressions | 32 | 0 | 32 | 0 |
| <DocLink id="kibExpressionRevealImagePluginApi" text="expressionRevealImage"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 14 | 0 | 14 | 3 |
| <DocLink id="kibExpressionShapePluginApi" text="expressionShape"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 0 |
| <DocLink id="kibExpressionTagcloudPluginApi" text="expressionTagcloud"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 |
| <DocLink id="kibExpressionXYPluginApi" text="expressionXY"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 473 | 0 | 463 | 0 |
| <DocLink id="kibExpressionsPluginApi" text="expressions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2158 | 17 | 1713 | 5 |
| <DocLink id="kibExpressionXYPluginApi" text="expressionXY"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 143 | 0 | 133 | 14 |
| <DocLink id="kibExpressionsPluginApi" text="expressions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2176 | 17 | 1722 | 5 |
| <DocLink id="kibFeaturesPluginApi" text="features"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 |
| <DocLink id="kibFieldFormatsPluginApi" text="fieldFormats"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 286 | 6 | 247 | 3 |
| <DocLink id="kibFileUploadPluginApi" text="fileUpload"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 |
| <DocLink id="kibFleetPluginApi" text="fleet"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1385 | 8 | 1268 | 10 |
| <DocLink id="kibFleetPluginApi" text="fleet"/> | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1403 | 8 | 1281 | 10 |
| <DocLink id="kibGlobalSearchPluginApi" text="globalSearch"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 |
| globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 |
| globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 |
| graph | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 0 | 0 | 0 | 0 |
| grokdebugger | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibHomePluginApi" text="home"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 140 | 0 | 102 | 0 |
| <DocLink id="kibHomePluginApi" text="home"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 141 | 0 | 102 | 0 |
| <DocLink id="kibIndexLifecycleManagementPluginApi" text="indexLifecycleManagement"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 |
| <DocLink id="kibIndexManagementPluginApi" text="indexManagement"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 175 | 0 | 170 | 3 |
| <DocLink id="kibInfraPluginApi" text="infra"/> | [Logs and Metrics UI](https://github.com/orgs/elastic/teams/logs-metrics-ui) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 31 | 0 | 28 | 5 |
| <DocLink id="kibInfraPluginApi" text="infra"/> | [Logs and Metrics UI](https://github.com/orgs/elastic/teams/logs-metrics-ui) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 34 | 0 | 31 | 5 |
| ingestPipelines | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| inputControlVis | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 |
| <DocLink id="kibInspectorPluginApi" text="inspector"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 123 | 2 | 96 | 4 |
| <DocLink id="kibInteractiveSetupPluginApi" text="interactiveSetup"/> | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 28 | 0 | 18 | 0 |
| <DocLink id="kibKibanaOverviewPluginApi" text="kibanaOverview"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 6 | 0 |
| <DocLink id="kibKibanaReactPluginApi" text="kibanaReact"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 240 | 0 | 204 | 5 |
| <DocLink id="kibKibanaReactPluginApi" text="kibanaReact"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 248 | 0 | 212 | 5 |
| kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibKibanaUtilsPluginApi" text="kibanaUtils"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 420 | 9 |
| <DocLink id="kibLensPluginApi" text="lens"/> | [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. | 527 | 0 | 452 | 30 |
| <DocLink id="kibLensPluginApi" text="lens"/> | [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. | 574 | 0 | 497 | 35 |
| <DocLink id="kibLicenseApiGuardPluginApi" text="licenseApiGuard"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 |
| <DocLink id="kibLicenseManagementPluginApi" text="licenseManagement"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 |
| <DocLink id="kibLicensingPluginApi" text="licensing"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 |
| <DocLink id="kibListsPluginApi" text="lists"/> | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 198 | 0 | 90 | 49 |
| logstash | [Logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibManagementPluginApi" text="management"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 41 | 0 | 41 | 6 |
| <DocLink id="kibMapsPluginApi" text="maps"/> | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 224 | 0 | 223 | 25 |
| <DocLink id="kibMapsPluginApi" text="maps"/> | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 226 | 0 | 225 | 25 |
| <DocLink id="kibMapsEmsPluginApi" text="mapsEms"/> | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 |
| <DocLink id="kibMlPluginApi" text="ml"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 196 | 8 | 79 | 30 |
| <DocLink id="kibMlPluginApi" text="ml"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 254 | 10 | 81 | 31 |
| <DocLink id="kibMonitoringPluginApi" text="monitoring"/> | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 11 | 0 | 9 | 1 |
| <DocLink id="kibMonitoringCollectionPluginApi" text="monitoringCollection"/> | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 |
| <DocLink id="kibNavigationPluginApi" text="navigation"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 |
| <DocLink id="kibNewsfeedPluginApi" text="newsfeed"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 |
| <DocLink id="kibObservabilityPluginApi" text="observability"/> | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 373 | 2 | 370 | 30 |
| <DocLink id="kibObservabilityPluginApi" text="observability"/> | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 376 | 2 | 373 | 30 |
| <DocLink id="kibOsqueryPluginApi" text="osquery"/> | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 13 | 0 | 13 | 0 |
| painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibPresentationUtilPluginApi" text="presentationUtil"/> | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 228 | 2 | 177 | 11 |
| <DocLink id="kibRemoteClustersPluginApi" text="remoteClusters"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 |
| <DocLink id="kibReportingPluginApi" text="reporting"/> | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 36 | 0 | 16 | 0 |
| <DocLink id="kibRollupPluginApi" text="rollup"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 0 | 21 | 0 |
| <DocLink id="kibRuleRegistryPluginApi" text="ruleRegistry"/> | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 194 | 0 | 167 | 8 |
| <DocLink id="kibRuleRegistryPluginApi" text="ruleRegistry"/> | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 202 | 0 | 174 | 9 |
| <DocLink id="kibRuntimeFieldsPluginApi" text="runtimeFields"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 24 | 0 | 19 | 2 |
| <DocLink id="kibSavedObjectsPluginApi" text="savedObjects"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 192 | 2 | 151 | 5 |
| <DocLink id="kibSavedObjectsManagementPluginApi" text="savedObjectsManagement"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 110 | 0 | 97 | 0 |
| <DocLink id="kibSavedObjectsTaggingPluginApi" text="savedObjectsTagging"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 54 | 0 | 50 | 0 |
| <DocLink id="kibSavedObjectsTaggingPluginApi" text="savedObjectsTagging"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 76 | 0 | 70 | 3 |
| <DocLink id="kibSavedObjectsTaggingOssPluginApi" text="savedObjectsTaggingOss"/> | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 90 | 0 | 45 | 0 |
| <DocLink id="kibScreenshotModePluginApi" text="screenshotMode"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 32 | 0 | 13 | 0 |
| <DocLink id="kibScreenshottingPluginApi" text="screenshotting"/> | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 7 | 4 |
| <DocLink id="kibScreenshottingPluginApi" text="screenshotting"/> | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 28 | 0 | 8 | 4 |
| searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibSecurityPluginApi" text="security"/> | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 183 | 0 | 103 | 0 |
| <DocLink id="kibSecuritySolutionPluginApi" text="securitySolution"/> | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 46 | 0 | 46 | 19 |
| <DocLink id="kibSessionViewPluginApi" text="sessionView"/> | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 |
| <DocLink id="kibSharePluginApi" text="share"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 113 | 0 | 54 | 10 |
| <DocLink id="kibSharedUXPluginApi" text="sharedUX"/> | [Shared UX](https://github.com/orgs/elastic/teams/shared-ux) | A plugin providing components and services for shared user experiences in Kibana. | 4 | 0 | 0 | 0 |
| <DocLink id="kibSnapshotRestorePluginApi" text="snapshotRestore"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 1 | 21 | 1 |
| <DocLink id="kibSnapshotRestorePluginApi" text="snapshotRestore"/> | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 |
| <DocLink id="kibSpacesPluginApi" text="spaces"/> | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 260 | 0 | 64 | 0 |
| <DocLink id="kibStackAlertsPluginApi" text="stackAlerts"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 4 | 0 | 4 | 0 |
| synthetics | [Uptime](https://github.com/orgs/elastic/teams/uptime) | This plugin visualizes data from Synthetics and Heartbeat, and integrates with other Observability solutions. | 0 | 0 | 0 | 0 |
@ -137,13 +137,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibTelemetryCollectionManagerPluginApi" text="telemetryCollectionManager"/> | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 32 | 0 | 32 | 6 |
| <DocLink id="kibTelemetryCollectionXpackPluginApi" text="telemetryCollectionXpack"/> | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 |
| <DocLink id="kibTelemetryManagementSectionPluginApi" text="telemetryManagementSection"/> | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 11 | 0 | 10 | 0 |
| <DocLink id="kibTimelinesPluginApi" text="timelines"/> | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 434 | 1 | 330 | 35 |
| <DocLink id="kibTimelinesPluginApi" text="timelines"/> | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 435 | 1 | 331 | 35 |
| <DocLink id="kibTransformPluginApi" text="transform"/> | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 |
| translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 |
| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 321 | 0 | 307 | 25 |
| <DocLink id="kibTriggersActionsUiPluginApi" text="triggersActionsUi"/> | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 374 | 0 | 360 | 34 |
| <DocLink id="kibUiActionsPluginApi" text="uiActions"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 130 | 0 | 91 | 11 |
| <DocLink id="kibUiActionsEnhancedPluginApi" text="uiActionsEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 203 | 0 | 141 | 9 |
| <DocLink id="kibUnifiedSearchPluginApi" text="unifiedSearch"/> | [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. | 79 | 2 | 75 | 11 |
| <DocLink id="kibUiActionsEnhancedPluginApi" text="uiActionsEnhanced"/> | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 205 | 0 | 142 | 9 |
| <DocLink id="kibUnifiedSearchPluginApi" text="unifiedSearch"/> | [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. | 82 | 2 | 78 | 13 |
| 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 |
| <DocLink id="kibUrlForwardingPluginApi" text="urlForwarding"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 12 | 0 | 12 | 0 |
@ -162,35 +162,40 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibVisTypeVegaPluginApi" text="visTypeVega"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 |
| <DocLink id="kibVisTypeVislibPluginApi" text="visTypeVislib"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 |
| <DocLink id="kibVisTypeXyPluginApi" text="visTypeXy"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 57 | 0 | 51 | 5 |
| <DocLink id="kibVisualizationsPluginApi" text="visualizations"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 365 | 12 | 344 | 14 |
| <DocLink id="kibVisualizationsPluginApi" text="visualizations"/> | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 372 | 12 | 351 | 14 |
| watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 |
## Package Directory
| Package name &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Maintaining team | Description | API Cnt | Any Cnt | Missing<br />comments | Missing<br />exports |
|--------------|----------------|-----------|--------------|----------|---------------|--------|
| <DocLink id="kibElasticApmSynthtracePluginApi" text="@elastic/apm-synthtrace"/> | [Owner missing] | Elastic APM trace data generator | 70 | 0 | 70 | 10 |
| <DocLink id="kibElasticApmSynthtracePluginApi" text="@elastic/apm-synthtrace"/> | [Owner missing] | Elastic APM trace data generator | 74 | 0 | 74 | 11 |
| <DocLink id="kibKbnAcePluginApi" text="@kbn/ace"/> | [Owner missing] | - | 11 | 5 | 11 | 0 |
| <DocLink id="kibKbnAlertsPluginApi" text="@kbn/alerts"/> | [Owner missing] | Alerts components and hooks | 9 | 1 | 9 | 0 |
| <DocLink id="kibKbnAnalyticsPluginApi" text="@kbn/analytics"/> | Ahmad Bamieh ahmadbamieh@gmail.com | Kibana Analytics tool | 69 | 0 | 69 | 2 |
| <DocLink id="kibKbnAnalyticsClientPluginApi" text="@kbn/analytics-client"/> | [Owner missing] | - | 88 | 1 | 10 | 0 |
| <DocLink id="kibKbnAnalyticsShippersFullstoryPluginApi" text="@kbn/analytics-shippers-fullstory"/> | [Owner missing] | - | 18 | 0 | 13 | 0 |
| <DocLink id="kibKbnAnalyticsClientPluginApi" text="@kbn/analytics-client"/> | [Owner missing] | - | 95 | 0 | 7 | 0 |
| <DocLink id="kibKbnAnalyticsShippersElasticV3BrowserPluginApi" text="@kbn/analytics-shippers-elastic-v3-browser"/> | [Owner missing] | - | 18 | 0 | 13 | 0 |
| <DocLink id="kibKbnAnalyticsShippersElasticV3CommonPluginApi" text="@kbn/analytics-shippers-elastic-v3-common"/> | [Owner missing] | - | 22 | 0 | 13 | 0 |
| <DocLink id="kibKbnAnalyticsShippersElasticV3ServerPluginApi" text="@kbn/analytics-shippers-elastic-v3-server"/> | [Owner missing] | - | 18 | 0 | 13 | 0 |
| <DocLink id="kibKbnAnalyticsShippersFullstoryPluginApi" text="@kbn/analytics-shippers-fullstory"/> | [Owner missing] | - | 20 | 0 | 4 | 0 |
| <DocLink id="kibKbnApmConfigLoaderPluginApi" text="@kbn/apm-config-loader"/> | [Owner missing] | - | 16 | 0 | 16 | 0 |
| <DocLink id="kibKbnApmUtilsPluginApi" text="@kbn/apm-utils"/> | [Owner missing] | - | 11 | 0 | 11 | 0 |
| <DocLink id="kibKbnAxeConfigPluginApi" text="@kbn/axe-config"/> | [Owner missing] | - | 10 | 0 | 10 | 0 |
| <DocLink id="kibKbnBazelPackagesPluginApi" text="@kbn/bazel-packages"/> | [Owner missing] | - | 18 | 0 | 9 | 1 |
| <DocLink id="kibKbnBazelRunnerPluginApi" text="@kbn/bazel-runner"/> | [Owner missing] | - | 4 | 0 | 4 | 0 |
| <DocLink id="kibKbnCiStatsClientPluginApi" text="@kbn/ci-stats-client"/> | [Owner missing] | - | 8 | 0 | 7 | 0 |
| <DocLink id="kibKbnCiStatsCorePluginApi" text="@kbn/ci-stats-core"/> | [Owner missing] | - | 7 | 0 | 2 | 0 |
| <DocLink id="kibKbnCiStatsReporterPluginApi" text="@kbn/ci-stats-reporter"/> | [Owner missing] | - | 59 | 0 | 15 | 0 |
| <DocLink id="kibKbnCiStatsReporterPluginApi" text="@kbn/ci-stats-reporter"/> | [Owner missing] | - | 60 | 0 | 15 | 0 |
| <DocLink id="kibKbnCliDevModePluginApi" text="@kbn/cli-dev-mode"/> | [Owner missing] | - | 2 | 0 | 2 | 0 |
| <DocLink id="kibKbnColoringPluginApi" text="@kbn/coloring"/> | [Owner missing] | - | 106 | 0 | 80 | 1 |
| <DocLink id="kibKbnConfigPluginApi" text="@kbn/config"/> | [Owner missing] | - | 64 | 0 | 44 | 2 |
| <DocLink id="kibKbnConfigPluginApi" text="@kbn/config"/> | [Owner missing] | - | 65 | 0 | 44 | 2 |
| <DocLink id="kibKbnConfigSchemaPluginApi" text="@kbn/config-schema"/> | [Owner missing] | - | 129 | 3 | 127 | 17 |
| <DocLink id="kibKbnCryptoPluginApi" text="@kbn/crypto"/> | [Owner missing] | - | 13 | 0 | 7 | 0 |
| <DocLink id="kibKbnDatemathPluginApi" text="@kbn/datemath"/> | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 |
| <DocLink id="kibKbnDevUtilsPluginApi" text="@kbn/dev-utils"/> | [Owner missing] | - | 120 | 3 | 109 | 0 |
| <DocLink id="kibKbnDocLinksPluginApi" text="@kbn/doc-links"/> | [Owner missing] | - | 64 | 0 | 64 | 2 |
| <DocLink id="kibKbnDevCliErrorsPluginApi" text="@kbn/dev-cli-errors"/> | [Owner missing] | - | 9 | 1 | 9 | 0 |
| <DocLink id="kibKbnDevCliRunnerPluginApi" text="@kbn/dev-cli-runner"/> | [Owner missing] | - | 65 | 0 | 64 | 0 |
| <DocLink id="kibKbnDevProcRunnerPluginApi" text="@kbn/dev-proc-runner"/> | [Owner missing] | - | 15 | 0 | 9 | 0 |
| <DocLink id="kibKbnDevUtilsPluginApi" text="@kbn/dev-utils"/> | [Owner missing] | - | 31 | 2 | 27 | 0 |
| <DocLink id="kibKbnDocLinksPluginApi" text="@kbn/doc-links"/> | [Owner missing] | - | 65 | 0 | 65 | 2 |
| <DocLink id="kibKbnDocsUtilsPluginApi" text="@kbn/docs-utils"/> | [Owner missing] | - | 1 | 0 | 1 | 0 |
| <DocLink id="kibKbnEsArchiverPluginApi" text="@kbn/es-archiver"/> | [Owner missing] | - | 27 | 0 | 14 | 1 |
| <DocLink id="kibKbnEsQueryPluginApi" text="@kbn/es-query"/> | [Owner missing] | - | 213 | 1 | 159 | 11 |
@ -198,6 +203,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibKbnFieldTypesPluginApi" text="@kbn/field-types"/> | [Owner missing] | - | 20 | 0 | 16 | 0 |
| <DocLink id="kibKbnFindUsedNodeModulesPluginApi" text="@kbn/find-used-node-modules"/> | [Owner missing] | - | 2 | 0 | 0 | 0 |
| <DocLink id="kibKbnGeneratePluginApi" text="@kbn/generate"/> | [Owner missing] | - | 1 | 0 | 0 | 0 |
| <DocLink id="kibKbnHandlebarsPluginApi" text="@kbn/handlebars"/> | [Owner missing] | - | 6 | 0 | 0 | 0 |
| <DocLink id="kibKbnI18nPluginApi" text="@kbn/i18n"/> | [Owner missing] | - | 51 | 0 | 48 | 0 |
| <DocLink id="kibKbnImportResolverPluginApi" text="@kbn/import-resolver"/> | [Owner missing] | - | 43 | 0 | 36 | 0 |
| <DocLink id="kibKbnInterpreterPluginApi" text="@kbn/interpreter"/> | App Services | - | 35 | 4 | 35 | 0 |
@ -208,11 +214,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibKbnLoggingMocksPluginApi" text="@kbn/logging-mocks"/> | [Owner missing] | - | 8 | 0 | 8 | 0 |
| <DocLink id="kibKbnMapboxGlPluginApi" text="@kbn/mapbox-gl"/> | [Owner missing] | - | 494 | 1 | 1 | 0 |
| <DocLink id="kibKbnMonacoPluginApi" text="@kbn/monaco"/> | [Owner missing] | - | 55 | 0 | 55 | 2 |
| <DocLink id="kibKbnOptimizerPluginApi" text="@kbn/optimizer"/> | [Owner missing] | - | 45 | 0 | 45 | 10 |
| <DocLink id="kibKbnOptimizerPluginApi" text="@kbn/optimizer"/> | [Owner missing] | - | 47 | 0 | 46 | 10 |
| <DocLink id="kibKbnPerformanceTestingDatasetExtractorPluginApi" text="@kbn/performance-testing-dataset-extractor"/> | [Owner missing] | A library to convert APM traces into JSON format for performance testing. | 3 | 0 | 3 | 0 |
| <DocLink id="kibKbnPluginDiscoveryPluginApi" text="@kbn/plugin-discovery"/> | [Owner missing] | - | 30 | 0 | 29 | 0 |
| <DocLink id="kibKbnPluginGeneratorPluginApi" text="@kbn/plugin-generator"/> | [Owner missing] | - | 1 | 0 | 1 | 0 |
| <DocLink id="kibKbnPluginHelpersPluginApi" text="@kbn/plugin-helpers"/> | [Owner missing] | Just some helpers for kibana plugin devs. | 1 | 0 | 1 | 0 |
| <DocLink id="kibKbnPmPluginApi" text="@kbn/pm"/> | [Owner missing] | - | 47 | 0 | 35 | 5 |
| <DocLink id="kibKbnPmPluginApi" text="@kbn/pm"/> | [Owner missing] | - | 45 | 0 | 33 | 5 |
| <DocLink id="kibKbnReactFieldPluginApi" text="@kbn/react-field"/> | [Owner missing] | - | 21 | 0 | 10 | 0 |
| <DocLink id="kibKbnRuleDataUtilsPluginApi" text="@kbn/rule-data-utils"/> | [Owner missing] | - | 74 | 0 | 71 | 0 |
| <DocLink id="kibKbnSecuritysolutionAutocompletePluginApi" text="@kbn/securitysolution-autocomplete"/> | [Owner missing] | Security Solution auto complete | 50 | 1 | 35 | 0 |
@ -232,17 +239,18 @@ warning: This document is auto-generated and is meant to be viewed inside our ex
| <DocLink id="kibKbnServerHttpToolsPluginApi" text="@kbn/server-http-tools"/> | [Owner missing] | - | 53 | 0 | 50 | 1 |
| <DocLink id="kibKbnServerRouteRepositoryPluginApi" text="@kbn/server-route-repository"/> | [Owner missing] | - | 25 | 0 | 24 | 1 |
| <DocLink id="kibKbnSharedUxButtonExitFullScreenPluginApi" text="@kbn/shared-ux-button-exit-full-screen"/> | [Owner missing] | - | 12 | 0 | 2 | 3 |
| <DocLink id="kibKbnSharedUxComponentsPluginApi" text="@kbn/shared-ux-components"/> | [Owner missing] | - | 34 | 0 | 6 | 6 |
| <DocLink id="kibKbnSharedUxServicesPluginApi" text="@kbn/shared-ux-services"/> | [Owner missing] | - | 67 | 0 | 43 | 0 |
| <DocLink id="kibKbnSharedUxStorybookPluginApi" text="@kbn/shared-ux-storybook"/> | [Owner missing] | - | 10 | 0 | 2 | 0 |
| <DocLink id="kibKbnSharedUxComponentsPluginApi" text="@kbn/shared-ux-components"/> | [Owner missing] | - | 23 | 0 | 6 | 3 |
| <DocLink id="kibKbnSharedUxPageAnalyticsNoDataPluginApi" text="@kbn/shared-ux-page-analytics-no-data"/> | [Owner missing] | - | 8 | 0 | 2 | 3 |
| <DocLink id="kibKbnSharedUxServicesPluginApi" text="@kbn/shared-ux-services"/> | [Owner missing] | - | 78 | 0 | 49 | 2 |
| <DocLink id="kibKbnSharedUxStorybookPluginApi" text="@kbn/shared-ux-storybook"/> | [Owner missing] | - | 16 | 0 | 7 | 0 |
| <DocLink id="kibKbnSharedUxUtilityPluginApi" text="@kbn/shared-ux-utility"/> | [Owner missing] | - | 9 | 0 | 3 | 0 |
| <DocLink id="kibKbnSortPackageJsonPluginApi" text="@kbn/sort-package-json"/> | [Owner missing] | - | 2 | 0 | 2 | 0 |
| <DocLink id="kibKbnStdPluginApi" text="@kbn/std"/> | [Owner missing] | - | 92 | 1 | 59 | 1 |
| <DocLink id="kibKbnStdioDevHelpersPluginApi" text="@kbn/stdio-dev-helpers"/> | [Owner missing] | - | 4 | 0 | 2 | 0 |
| <DocLink id="kibKbnStorybookPluginApi" text="@kbn/storybook"/> | Operations | - | 22 | 2 | 21 | 0 |
| <DocLink id="kibKbnStorybookPluginApi" text="@kbn/storybook"/> | Operations | - | 38 | 2 | 21 | 0 |
| <DocLink id="kibKbnTelemetryToolsPluginApi" text="@kbn/telemetry-tools"/> | [Owner missing] | - | 2 | 0 | 2 | 0 |
| <DocLink id="kibKbnTestPluginApi" text="@kbn/test"/> | Operations | - | 252 | 6 | 214 | 9 |
| <DocLink id="kibKbnTestJestHelpersPluginApi" text="@kbn/test-jest-helpers"/> | [Owner missing] | - | 132 | 8 | 103 | 2 |
| <DocLink id="kibKbnTestPluginApi" text="@kbn/test"/> | Operations | - | 240 | 5 | 201 | 9 |
| <DocLink id="kibKbnTestJestHelpersPluginApi" text="@kbn/test-jest-helpers"/> | [Owner missing] | - | 135 | 8 | 103 | 2 |
| <DocLink id="kibKbnToolingLogPluginApi" text="@kbn/tooling-log"/> | [Owner missing] | - | 72 | 0 | 55 | 0 |
| <DocLink id="kibKbnTypeSummarizerPluginApi" text="@kbn/type-summarizer"/> | [Owner missing] | - | 29 | 0 | 2 | 0 |
| <DocLink id="kibKbnTypedReactRouterConfigPluginApi" text="@kbn/typed-react-router-config"/> | [Owner missing] | - | 83 | 0 | 83 | 1 |

View file

@ -26,12 +26,19 @@ which may cause a delay before pages start being served.
Set to `false` to disable Console. *Default: `true`*
| `csp.rules:`
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
| deprecated:[7.14.0,"In 8.0 and later, this setting will no longer be supported."]
A https://w3c.github.io/webappsec-csp/[Content Security Policy] template
that disables certain unnecessary and potentially insecure capabilities in
the browser. It is strongly recommended that you keep the default CSP rules
that ship with {kib}.
| `csp.disableUnsafeEval`
| experimental[] Set this to `true` to remove the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_eval_expressions[`unsafe-eval`] source expression from the `script-src` directive. *Default: `false`*
By enabling `csp.disableUnsafeEval`, Kibana will use a custom version of the Handlebars template library which doesn't support https://handlebarsjs.com/guide/partials.html#inline-partials[inline partials].
Handlebars is used in various locations in the Kibana frontend where custom templates can be supplied by the user when for instance setting up a visualisation.
If you experience any issues rendering Handlebars templates after turning on `csp.disableUnsafeEval`, or if you rely on inline partials, please revert this setting to `false` and https://github.com/elastic/kibana/issues/new/choose[open an issue] in the Kibana GitHub repository.
| `csp.script_src:`
| Add sources for the https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src[Content Security Policy `script-src` directive].

View file

@ -152,6 +152,7 @@
"@kbn/eslint-plugin-imports": "link:bazel-bin/packages/kbn-eslint-plugin-imports",
"@kbn/field-types": "link:bazel-bin/packages/kbn-field-types",
"@kbn/flot-charts": "link:bazel-bin/packages/kbn-flot-charts",
"@kbn/handlebars": "link:bazel-bin/packages/kbn-handlebars",
"@kbn/i18n": "link:bazel-bin/packages/kbn-i18n",
"@kbn/i18n-react": "link:bazel-bin/packages/kbn-i18n-react",
"@kbn/interpreter": "link:bazel-bin/packages/kbn-interpreter",
@ -646,6 +647,7 @@
"@types/kbn__field-types": "link:bazel-bin/packages/kbn-field-types/npm_module_types",
"@types/kbn__find-used-node-modules": "link:bazel-bin/packages/kbn-find-used-node-modules/npm_module_types",
"@types/kbn__generate": "link:bazel-bin/packages/kbn-generate/npm_module_types",
"@types/kbn__handlebars": "link:bazel-bin/packages/kbn-handlebars/npm_module_types",
"@types/kbn__i18n": "link:bazel-bin/packages/kbn-i18n/npm_module_types",
"@types/kbn__i18n-react": "link:bazel-bin/packages/kbn-i18n-react/npm_module_types",
"@types/kbn__import-resolver": "link:bazel-bin/packages/kbn-import-resolver/npm_module_types",

View file

@ -53,6 +53,7 @@ filegroup(
"//packages/kbn-find-used-node-modules:build",
"//packages/kbn-flot-charts:build",
"//packages/kbn-generate:build",
"//packages/kbn-handlebars:build",
"//packages/kbn-i18n-react:build",
"//packages/kbn-i18n:build",
"//packages/kbn-import-resolver:build",
@ -159,6 +160,7 @@ filegroup(
"//packages/kbn-field-types:build_types",
"//packages/kbn-find-used-node-modules:build_types",
"//packages/kbn-generate:build_types",
"//packages/kbn-handlebars:build_types",
"//packages/kbn-i18n-react:build_types",
"//packages/kbn-i18n:build_types",
"//packages/kbn-import-resolver:build_types",

1
packages/kbn-handlebars/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.tmp

View file

@ -0,0 +1,612 @@
1,11c1,21
< global.handlebarsEnv = null;
<
< beforeEach(function() {
< global.handlebarsEnv = Handlebars.create();
< });
<
< describe('basic context', function() {
< it('most basic', function() {
< expectTemplate('{{foo}}')
< .withInput({ foo: 'foo' })
< .toCompileTo('foo');
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('basic context', () => {
> it('most basic', () => {
> expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
> });
>
> it('escaping', () => {
> expectTemplate('\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('{{foo}}');
> expectTemplate('content \\{{foo}}').withInput({ foo: 'food' }).toCompileTo('content {{foo}}');
> expectTemplate('\\\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('\\food');
> expectTemplate('content \\\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('content \\food');
> expectTemplate('\\\\ {{foo}}').withInput({ foo: 'food' }).toCompileTo('\\\\ food');
14,36c24
< it('escaping', function() {
< expectTemplate('\\{{foo}}')
< .withInput({ foo: 'food' })
< .toCompileTo('{{foo}}');
<
< expectTemplate('content \\{{foo}}')
< .withInput({ foo: 'food' })
< .toCompileTo('content {{foo}}');
<
< expectTemplate('\\\\{{foo}}')
< .withInput({ foo: 'food' })
< .toCompileTo('\\food');
<
< expectTemplate('content \\\\{{foo}}')
< .withInput({ foo: 'food' })
< .toCompileTo('content \\food');
<
< expectTemplate('\\\\ {{foo}}')
< .withInput({ foo: 'food' })
< .toCompileTo('\\\\ food');
< });
<
< it('compiling with a basic context', function() {
---
> it('compiling with a basic context', () => {
40c28
< world: 'world'
---
> world: 'world',
42d29
< .withMessage('It works if all the required keys are provided')
46,49c33,34
< it('compiling with a string context', function() {
< expectTemplate('{{.}}{{length}}')
< .withInput('bye')
< .toCompileTo('bye3');
---
> it('compiling with a string context', () => {
> expectTemplate('{{.}}{{length}}').withInput('bye').toCompileTo('bye3');
52c37
< it('compiling with an undefined context', function() {
---
> it('compiling with an undefined context', () => {
62c47
< it('comments', function() {
---
> it('comments', () => {
66c51
< world: 'world'
---
> world: 'world',
68d52
< .withMessage('comments are ignored')
72,76c56
<
< expectTemplate(' {{~!-- long-comment --~}} blah').toCompileTo(
< 'blah'
< );
<
---
> expectTemplate(' {{~!-- long-comment --~}} blah').toCompileTo('blah');
78,82c58
<
< expectTemplate(' {{!-- long-comment --~}} blah').toCompileTo(
< ' blah'
< );
<
---
> expectTemplate(' {{!-- long-comment --~}} blah').toCompileTo(' blah');
84,87c60
<
< expectTemplate(' {{~!-- long-comment --}} blah').toCompileTo(
< ' blah'
< );
---
> expectTemplate(' {{~!-- long-comment --}} blah').toCompileTo(' blah');
90,91c63,64
< it('boolean', function() {
< var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
---
> it('boolean', () => {
> const string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
95c68
< world: 'world'
---
> world: 'world',
97d69
< .withMessage('booleans show the contents when true')
103c75
< world: 'world'
---
> world: 'world',
105d76
< .withMessage('booleans do not show the contents when false')
109c80
< it('zeros', function() {
---
> it('zeros', () => {
113c84
< num2: 0
---
> num2: 0,
117,119c88
< expectTemplate('num: {{.}}')
< .withInput(0)
< .toCompileTo('num: 0');
---
> expectTemplate('num: {{.}}').withInput(0).toCompileTo('num: 0');
126c95
< it('false', function() {
---
> it('false', () => {
131c100
< val2: new Boolean(false)
---
> val2: new Boolean(false),
135,137c104
< expectTemplate('val: {{.}}')
< .withInput(false)
< .toCompileTo('val: false');
---
> expectTemplate('val: {{.}}').withInput(false).toCompileTo('val: false');
146c113
< val2: new Boolean(false)
---
> val2: new Boolean(false),
156c123
< it('should handle undefined and null', function() {
---
> it('should handle undefined and null', () => {
159,167c126,128
< awesome: function(_undefined, _null, options) {
< return (
< (_undefined === undefined) +
< ' ' +
< (_null === null) +
< ' ' +
< typeof options
< );
< }
---
> awesome(_undefined: any, _null: any, options: any) {
> return (_undefined === undefined) + ' ' + (_null === null) + ' ' + typeof options;
> },
173c134
< undefined: function() {
---
> undefined() {
175c136
< }
---
> },
181c142
< null: function() {
---
> null() {
183c144
< }
---
> },
188c149
< it('newlines', function() {
---
> it('newlines', () => {
190d150
<
194,223c154,160
< it('escaping text', function() {
< expectTemplate("Awesome's")
< .withMessage(
< "text is escaped so that it doesn't get caught on single quotes"
< )
< .toCompileTo("Awesome's");
<
< expectTemplate('Awesome\\')
< .withMessage("text is escaped so that the closing quote can't be ignored")
< .toCompileTo('Awesome\\');
<
< expectTemplate('Awesome\\\\ foo')
< .withMessage("text is escaped so that it doesn't mess up backslashes")
< .toCompileTo('Awesome\\\\ foo');
<
< expectTemplate('Awesome {{foo}}')
< .withInput({ foo: '\\' })
< .withMessage("text is escaped so that it doesn't mess up backslashes")
< .toCompileTo('Awesome \\');
<
< expectTemplate(" ' ' ")
< .withMessage('double quotes never produce invalid javascript')
< .toCompileTo(" ' ' ");
< });
<
< it('escaping expressions', function() {
< expectTemplate('{{{awesome}}}')
< .withInput({ awesome: "&'\\<>" })
< .withMessage("expressions with 3 handlebars aren't escaped")
< .toCompileTo("&'\\<>");
---
> it('escaping text', () => {
> expectTemplate("Awesome's").toCompileTo("Awesome's");
> expectTemplate('Awesome\\').toCompileTo('Awesome\\');
> expectTemplate('Awesome\\\\ foo').toCompileTo('Awesome\\\\ foo');
> expectTemplate('Awesome {{foo}}').withInput({ foo: '\\' }).toCompileTo('Awesome \\');
> expectTemplate(" ' ' ").toCompileTo(" ' ' ");
> });
225,228c162,165
< expectTemplate('{{&awesome}}')
< .withInput({ awesome: "&'\\<>" })
< .withMessage("expressions with {{& handlebars aren't escaped")
< .toCompileTo("&'\\<>");
---
> it('escaping expressions', () => {
> expectTemplate('{{{awesome}}}').withInput({ awesome: "&'\\<>" }).toCompileTo("&'\\<>");
>
> expectTemplate('{{&awesome}}').withInput({ awesome: "&'\\<>" }).toCompileTo("&'\\<>");
232d168
< .withMessage('by default expressions should be escaped')
237d172
< .withMessage('escaping should properly handle amperstands')
241c176
< it("functions returning safestrings shouldn't be escaped", function() {
---
> it("functions returning safestrings shouldn't be escaped", () => {
244c179
< awesome: function() {
---
> awesome() {
246c181
< }
---
> },
248d182
< .withMessage("functions returning safestrings aren't escaped")
252c186
< it('functions', function() {
---
> it('functions', () => {
255c189
< awesome: function() {
---
> awesome() {
257c191
< }
---
> },
259d192
< .withMessage('functions are called and render their output')
264c197
< awesome: function() {
---
> awesome() {
267c200
< more: 'More awesome'
---
> more: 'More awesome',
269d201
< .withMessage('functions are bound to the context')
273c205
< it('functions with context argument', function() {
---
> it('functions with context argument', () => {
276c208
< awesome: function(context) {
---
> awesome(context: any) {
279c211
< frank: 'Frank'
---
> frank: 'Frank',
281d212
< .withMessage('functions are called with context arguments')
285c216
< it('pathed functions with context argument', function() {
---
> it('pathed functions with context argument', () => {
289c220
< awesome: function(context) {
---
> awesome(context: any) {
291c222
< }
---
> },
293c224
< frank: 'Frank'
---
> frank: 'Frank',
295d225
< .withMessage('functions are called with context arguments')
299c229
< it('depthed functions with context argument', function() {
---
> it('depthed functions with context argument', () => {
302c232
< awesome: function(context) {
---
> awesome(context: any) {
305c235
< frank: 'Frank'
---
> frank: 'Frank',
307d236
< .withMessage('functions are called with context arguments')
311c240
< it('block functions with context argument', function() {
---
> it('block functions with context argument', () => {
314c243
< awesome: function(context, options) {
---
> awesome(context: any, options: any) {
316c245
< }
---
> },
318d246
< .withMessage('block functions are called with context and options')
322,325c250,251
< it('depthed block functions with context argument', function() {
< expectTemplate(
< '{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}'
< )
---
> it('depthed block functions with context argument', () => {
> expectTemplate('{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}')
328c254
< awesome: function(context, options) {
---
> awesome(context: any, options: any) {
330c256
< }
---
> },
332d257
< .withMessage('block functions are called with context and options')
336c261
< it('block functions without context argument', function() {
---
> it('block functions without context argument', () => {
339c264
< awesome: function(options) {
---
> awesome(options: any) {
341c266
< }
---
> },
343d267
< .withMessage('block functions are called with options')
347c271
< it('pathed block functions without context argument', function() {
---
> it('pathed block functions without context argument', () => {
351c275
< awesome: function() {
---
> awesome() {
353,354c277,278
< }
< }
---
> },
> },
356d279
< .withMessage('block functions are called with options')
360,363c283,284
< it('depthed block functions without context argument', function() {
< expectTemplate(
< '{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}'
< )
---
> it('depthed block functions without context argument', () => {
> expectTemplate('{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}')
366c287
< awesome: function() {
---
> awesome() {
368c289
< }
---
> },
370d290
< .withMessage('block functions are called with options')
374,378c294,295
< it('paths with hyphens', function() {
< expectTemplate('{{foo-bar}}')
< .withInput({ 'foo-bar': 'baz' })
< .withMessage('Paths can contain hyphens (-)')
< .toCompileTo('baz');
---
> it('paths with hyphens', () => {
> expectTemplate('{{foo-bar}}').withInput({ 'foo-bar': 'baz' }).toCompileTo('baz');
382d298
< .withMessage('Paths can contain hyphens (-)')
387d302
< .withMessage('Paths can contain hyphens (-)')
391c306
< it('nested paths', function() {
---
> it('nested paths', () => {
394d308
< .withMessage('Nested paths access nested objects')
398c312
< it('nested paths with empty string value', function() {
---
> it('nested paths with empty string value', () => {
401d314
< .withMessage('Nested paths access nested objects with empty string')
405c318
< it('literal paths', function() {
---
> it('literal paths', () => {
408d320
< .withMessage('Literal paths can be used')
413d324
< .withMessage('Literal paths can be used')
417c328
< it('literal references', function() {
---
> it('literal references', () => {
443c354
< it("that current context path ({{.}}) doesn't hit helpers", function() {
---
> it("that current context path ({{.}}) doesn't hit helpers", () => {
445a357
> // @ts-expect-error Setting the helper to a string instead of a function doesn't make sense normally, but here it doesn't matter
450c362
< it('complex but empty paths', function() {
---
> it('complex but empty paths', () => {
455,457c367
< expectTemplate('{{person/name}}')
< .withInput({ person: {} })
< .toCompileTo('');
---
> expectTemplate('{{person/name}}').withInput({ person: {} }).toCompileTo('');
460c370
< it('this keyword in paths', function() {
---
> it('this keyword in paths', () => {
463d372
< .withMessage('This keyword in paths evaluates to current context')
468c377
< hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
---
> hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
470d378
< .withMessage('This keyword evaluates in more complex paths')
474c382
< it('this keyword nested inside path', function() {
---
> it('this keyword nested inside path', () => {
476d383
< Error,
480,482c387
< expectTemplate('{{[this]}}')
< .withInput({ this: 'bar' })
< .toCompileTo('bar');
---
> expectTemplate('{{[this]}}').withInput({ this: 'bar' }).toCompileTo('bar');
489,491c394,396
< it('this keyword in helpers', function() {
< var helpers = {
< foo: function(value) {
---
> it('this keyword in helpers', () => {
> const helpers = {
> foo(value: any) {
493c398
< }
---
> },
499d403
< .withMessage('This keyword in paths evaluates to current context')
504c408
< hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
---
> hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
507d410
< .withMessage('This keyword evaluates in more complex paths')
511c414
< it('this keyword nested inside helpers param', function() {
---
> it('this keyword nested inside helpers param', () => {
513d415
< Error,
519c421
< foo: function(value) {
---
> foo(value: any) {
522c424
< this: 'bar'
---
> this: 'bar',
528c430
< foo: function(value) {
---
> foo(value: any) {
531c433
< text: { this: 'bar' }
---
> text: { this: 'bar' },
536c438
< it('pass string literals', function() {
---
> it('pass string literals', () => {
538,541c440
<
< expectTemplate('{{"foo"}}')
< .withInput({ foo: 'bar' })
< .toCompileTo('bar');
---
> expectTemplate('{{"foo"}}').withInput({ foo: 'bar' }).toCompileTo('bar');
545c444
< foo: ['bar', 'baz']
---
> foo: ['bar', 'baz'],
550c449
< it('pass number literals', function() {
---
> it('pass number literals', () => {
552,556c451
<
< expectTemplate('{{12}}')
< .withInput({ '12': 'bar' })
< .toCompileTo('bar');
<
---
> expectTemplate('{{12}}').withInput({ '12': 'bar' }).toCompileTo('bar');
558,562c453
<
< expectTemplate('{{12.34}}')
< .withInput({ '12.34': 'bar' })
< .toCompileTo('bar');
<
---
> expectTemplate('{{12.34}}').withInput({ '12.34': 'bar' }).toCompileTo('bar');
565c456
< '12.34': function(arg) {
---
> '12.34'(arg: any) {
567c458
< }
---
> },
572c463
< it('pass boolean literals', function() {
---
> it('pass boolean literals', () => {
574,581c465,466
<
< expectTemplate('{{true}}')
< .withInput({ '': 'foo' })
< .toCompileTo('');
<
< expectTemplate('{{false}}')
< .withInput({ false: 'foo' })
< .toCompileTo('foo');
---
> expectTemplate('{{true}}').withInput({ '': 'foo' }).toCompileTo('');
> expectTemplate('{{false}}').withInput({ false: 'foo' }).toCompileTo('foo');
584c469
< it('should handle literals in subexpression', function() {
---
> it('should handle literals in subexpression', () => {
587c472
< false: function() {
---
> false() {
589c474
< }
---
> },
591c476
< .withHelper('foo', function(arg) {
---
> .withHelper('foo', function (arg) {

View file

@ -0,0 +1,461 @@
1,3c1,12
< describe('blocks', function() {
< it('array', function() {
< var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('blocks', () => {
> it('array', () => {
> const string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
7,12c16,17
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
14d18
< .withMessage('Arrays iterate over the contents when not empty')
20c24
< world: 'world'
---
> world: 'world',
22d25
< .withMessage('Arrays ignore the contents when empty')
26,29c29,30
< it('array without data', function() {
< expectTemplate(
< '{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}'
< )
---
> it('array without data', () => {
> expectTemplate('{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}')
31,36c32,33
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
38d34
< .withCompileOptions({ compat: false })
42,45c38,39
< it('array with @index', function() {
< expectTemplate(
< '{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!'
< )
---
> it('array with @index', () => {
> expectTemplate('{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!')
47,52c41,42
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
54d43
< .withMessage('The @index variable is used')
58,59c47,48
< it('empty block', function() {
< var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
---
> it('empty block', () => {
> const string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
63,68c52,53
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
70d54
< .withMessage('Arrays iterate over the contents when not empty')
76c60
< world: 'world'
---
> world: 'world',
78d61
< .withMessage('Arrays ignore the contents when empty')
82c65
< it('block with complex lookup', function() {
---
> it('block with complex lookup', () => {
86,90c69
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ]
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
92,97c71
< .withMessage(
< 'Templates can access variables in contexts up the stack with relative path syntax'
< )
< .toCompileTo(
< 'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! '
< );
---
> .toCompileTo('goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ');
100c74
< it('multiple blocks with complex lookup', function() {
---
> it('multiple blocks with complex lookup', () => {
104,108c78
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ]
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
113,116c83,84
< it('block with complex lookup using nested context', function() {
< expectTemplate(
< '{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}'
< ).toThrow(Error);
---
> it('block with complex lookup using nested context', () => {
> expectTemplate('{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}').toThrow(Error);
119c87
< it('block with deep nested complex lookup', function() {
---
> it('block with deep nested complex lookup', () => {
125c93
< outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }]
---
> outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }],
130,133c98,99
< it('works with cached blocks', function() {
< expectTemplate(
< '{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}'
< )
---
> it('works with cached blocks', () => {
> expectTemplate('{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}')
138,139c104,105
< { first: 'Alan', last: 'Johnson' }
< ]
---
> { first: 'Alan', last: 'Johnson' },
> ],
144,145c110,111
< describe('inverted sections', function() {
< it('inverted sections with unset value', function() {
---
> describe('inverted sections', () => {
> it('inverted sections with unset value', () => {
148,150c114
< )
< .withMessage("Inverted section rendered when value isn't set.")
< .toCompileTo('Right On!');
---
> ).toCompileTo('Right On!');
153,156c117,118
< it('inverted section with false value', function() {
< expectTemplate(
< '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
< )
---
> it('inverted section with false value', () => {
> expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}')
158d119
< .withMessage('Inverted section rendered when value is false.')
162,165c123,124
< it('inverted section with empty set', function() {
< expectTemplate(
< '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
< )
---
> it('inverted section with empty set', () => {
> expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}')
167d125
< .withMessage('Inverted section rendered when value is empty set.')
171c129
< it('block inverted sections', function() {
---
> it('block inverted sections', () => {
177c135
< it('chained inverted sections', function() {
---
> it('chained inverted sections', () => {
188,190c146
< expectTemplate(
< '{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}'
< )
---
> expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}')
195,198c151,152
< it('chained inverted sections with mismatch', function() {
< expectTemplate(
< '{{#people}}{{name}}{{else if none}}{{none}}{{/if}}'
< ).toThrow(Error);
---
> it('chained inverted sections with mismatch', () => {
> expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/if}}').toThrow(Error);
201c155
< it('block inverted sections with empty arrays', function() {
---
> it('block inverted sections with empty arrays', () => {
205c159
< people: []
---
> people: [],
211,212c165,166
< describe('standalone sections', function() {
< it('block standalone else sections', function() {
---
> describe('standalone sections', () => {
> it('block standalone else sections', () => {
226,241c180,181
< it('block standalone else sections can be disabled', function() {
< expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
< .withInput({ none: 'No people' })
< .withCompileOptions({ ignoreStandalone: true })
< .toCompileTo('\nNo people\n\n');
<
< expectTemplate('{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n')
< .withInput({ none: 'No people' })
< .withCompileOptions({ ignoreStandalone: true })
< .toCompileTo('\nNo people\n\n');
< });
<
< it('block standalone chained else sections', function() {
< expectTemplate(
< '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n'
< )
---
> it('block standalone chained else sections', () => {
> expectTemplate('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n')
245,247c185
< expectTemplate(
< '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n'
< )
---
> expectTemplate('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n')
252c190
< it('should handle nesting', function() {
---
> it('should handle nesting', () => {
255c193
< data: [1, 3, 5]
---
> data: [1, 3, 5],
260,455d197
<
< describe('compat mode', function() {
< it('block with deep recursive lookup lookup', function() {
< expectTemplate(
< '{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}'
< )
< .withInput({ omg: 'OMG!', outer: [{ inner: [{ text: 'goodbye' }] }] })
< .withCompileOptions({ compat: true })
< .toCompileTo('Goodbye cruel OMG!');
< });
<
< it('block with deep recursive pathed lookup', function() {
< expectTemplate(
< '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
< )
< .withInput({
< omg: { yes: 'OMG!' },
< outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
< })
< .withCompileOptions({ compat: true })
< .toCompileTo('Goodbye cruel OMG!');
< });
<
< it('block with missed recursive lookup', function() {
< expectTemplate(
< '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}'
< )
< .withInput({
< omg: { no: 'OMG!' },
< outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
< })
< .withCompileOptions({ compat: true })
< .toCompileTo('Goodbye cruel ');
< });
< });
<
< describe('decorators', function() {
< it('should apply mustache decorators', function() {
< expectTemplate('{{#helper}}{{*decorator}}{{/helper}}')
< .withHelper('helper', function(options) {
< return options.fn.run;
< })
< .withDecorator('decorator', function(fn) {
< fn.run = 'success';
< return fn;
< })
< .toCompileTo('success');
< });
<
< it('should apply allow undefined return', function() {
< expectTemplate('{{#helper}}{{*decorator}}suc{{/helper}}')
< .withHelper('helper', function(options) {
< return options.fn() + options.fn.run;
< })
< .withDecorator('decorator', function(fn) {
< fn.run = 'cess';
< })
< .toCompileTo('success');
< });
<
< it('should apply block decorators', function() {
< expectTemplate(
< '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}'
< )
< .withHelper('helper', function(options) {
< return options.fn.run;
< })
< .withDecorator('decorator', function(fn, props, container, options) {
< fn.run = options.fn();
< return fn;
< })
< .toCompileTo('success');
< });
<
< it('should support nested decorators', function() {
< expectTemplate(
< '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}'
< )
< .withHelper('helper', function(options) {
< return options.fn.run;
< })
< .withDecorators({
< decorator: function(fn, props, container, options) {
< fn.run = options.fn.nested + options.fn();
< return fn;
< },
< nested: function(fn, props, container, options) {
< props.nested = options.fn();
< }
< })
< .toCompileTo('success');
< });
<
< it('should apply multiple decorators', function() {
< expectTemplate(
< '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}'
< )
< .withHelper('helper', function(options) {
< return options.fn.run;
< })
< .withDecorator('decorator', function(fn, props, container, options) {
< fn.run = (fn.run || '') + options.fn();
< return fn;
< })
< .toCompileTo('success');
< });
<
< it('should access parent variables', function() {
< expectTemplate('{{#helper}}{{*decorator foo}}{{/helper}}')
< .withHelper('helper', function(options) {
< return options.fn.run;
< })
< .withDecorator('decorator', function(fn, props, container, options) {
< fn.run = options.args;
< return fn;
< })
< .withInput({ foo: 'success' })
< .toCompileTo('success');
< });
<
< it('should work with root program', function() {
< var run;
< expectTemplate('{{*decorator "success"}}')
< .withDecorator('decorator', function(fn, props, container, options) {
< equals(options.args[0], 'success');
< run = true;
< return fn;
< })
< .withInput({ foo: 'success' })
< .toCompileTo('');
< equals(run, true);
< });
<
< it('should fail when accessing variables from root', function() {
< var run;
< expectTemplate('{{*decorator foo}}')
< .withDecorator('decorator', function(fn, props, container, options) {
< equals(options.args[0], undefined);
< run = true;
< return fn;
< })
< .withInput({ foo: 'fail' })
< .toCompileTo('');
< equals(run, true);
< });
<
< describe('registration', function() {
< it('unregisters', function() {
< handlebarsEnv.decorators = {};
<
< handlebarsEnv.registerDecorator('foo', function() {
< return 'fail';
< });
<
< equals(!!handlebarsEnv.decorators.foo, true);
< handlebarsEnv.unregisterDecorator('foo');
< equals(handlebarsEnv.decorators.foo, undefined);
< });
<
< it('allows multiple globals', function() {
< handlebarsEnv.decorators = {};
<
< handlebarsEnv.registerDecorator({
< foo: function() {},
< bar: function() {}
< });
<
< equals(!!handlebarsEnv.decorators.foo, true);
< equals(!!handlebarsEnv.decorators.bar, true);
< handlebarsEnv.unregisterDecorator('foo');
< handlebarsEnv.unregisterDecorator('bar');
< equals(handlebarsEnv.decorators.foo, undefined);
< equals(handlebarsEnv.decorators.bar, undefined);
< });
<
< it('fails with multiple and args', function() {
< shouldThrow(
< function() {
< handlebarsEnv.registerDecorator(
< {
< world: function() {
< return 'world!';
< },
< testHelper: function() {
< return 'found it!';
< }
< },
< {}
< );
< },
< Error,
< 'Arg not supported with multiple decorators'
< );
< });
< });
< });

View file

@ -0,0 +1,872 @@
1,4c1,16
< describe('builtin helpers', function() {
< describe('#if', function() {
< it('if', function() {
< var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> /* eslint-disable max-classes-per-file */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('builtin helpers', () => {
> describe('#if', () => {
> it('if', () => {
> const string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
9c21
< world: 'world'
---
> world: 'world',
11d22
< .withMessage('if with boolean argument shows the contents when true')
17c28
< world: 'world'
---
> world: 'world',
19d29
< .withMessage('if with string argument shows the contents')
25c35
< world: 'world'
---
> world: 'world',
27,29d36
< .withMessage(
< 'if with boolean argument does not show the contents when false'
< )
32,35c39
< expectTemplate(string)
< .withInput({ world: 'world' })
< .withMessage('if with undefined does not show the contents')
< .toCompileTo('cruel world!');
---
> expectTemplate(string).withInput({ world: 'world' }).toCompileTo('cruel world!');
40c44
< world: 'world'
---
> world: 'world',
42d45
< .withMessage('if with non-empty array shows the contents')
48c51
< world: 'world'
---
> world: 'world',
50d52
< .withMessage('if with empty array does not show the contents')
56c58
< world: 'world'
---
> world: 'world',
58d59
< .withMessage('if with zero does not show the contents')
61,63c62
< expectTemplate(
< '{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!'
< )
---
> expectTemplate('{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!')
66c65
< world: 'world'
---
> world: 'world',
68d66
< .withMessage('if with zero does not show the contents')
72,73c70,71
< it('if with function argument', function() {
< var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
---
> it('if with function argument', () => {
> const string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
77c75
< goodbye: function() {
---
> goodbye() {
80c78
< world: 'world'
---
> world: 'world',
82,84d79
< .withMessage(
< 'if with function shows the contents when function returns true'
< )
89c84
< goodbye: function() {
---
> goodbye() {
92c87
< world: 'world'
---
> world: 'world',
94,96d88
< .withMessage(
< 'if with function shows the contents when function returns string'
< )
101c93
< goodbye: function() {
---
> goodbye() {
104c96
< world: 'world'
---
> world: 'world',
106,108d97
< .withMessage(
< 'if with function does not show the contents when returns false'
< )
113c102
< goodbye: function() {
---
> goodbye() {
116c105
< world: 'world'
---
> world: 'world',
118,120d106
< .withMessage(
< 'if with function does not show the contents when returns undefined'
< )
124,127c110,111
< it('should not change the depth list', function() {
< expectTemplate(
< '{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}'
< )
---
> it('should not change the depth list', () => {
> expectTemplate('{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}')
130c114
< world: 'world'
---
> world: 'world',
136,137c120,121
< describe('#with', function() {
< it('with', function() {
---
> describe('#with', () => {
> it('with', () => {
142,143c126,127
< last: 'Johnson'
< }
---
> last: 'Johnson',
> },
148c132
< it('with with function argument', function() {
---
> it('with with function argument', () => {
151c135
< person: function() {
---
> person() {
154c138
< last: 'Johnson'
---
> last: 'Johnson',
156c140
< }
---
> },
161c145
< it('with with else', function() {
---
> it('with with else', () => {
167c151
< it('with provides block parameter', function() {
---
> it('with provides block parameter', () => {
172,173c156,157
< last: 'Johnson'
< }
---
> last: 'Johnson',
> },
178c162
< it('works when data is disabled', function() {
---
> it('works when data is disabled', () => {
186,194c170,172
< describe('#each', function() {
< beforeEach(function() {
< handlebarsEnv.registerHelper('detectDataInsideEach', function(options) {
< return options.data && options.data.exclaim;
< });
< });
<
< it('each', function() {
< var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
---
> describe('#each', () => {
> it('each', () => {
> const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
198,203c176,177
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
205,207d178
< .withMessage(
< 'each with array argument iterates over the contents when not empty'
< )
213c184
< world: 'world'
---
> world: 'world',
215d185
< .withMessage('each with array argument ignores the contents when empty')
219c189
< it('each without data', function() {
---
> it('each without data', () => {
222,227c192,193
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
240c206
< it('each without context', function() {
---
> it('each without context', () => {
246,248c212,213
< it('each with an object and @key', function() {
< var string =
< '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
---
> it('each with an object and @key', () => {
> const string = '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
250c215
< function Clazz() {
---
> function Clazz(this: any) {
255c220
< var hash = { goodbyes: new Clazz(), world: 'world' };
---
> const hash = { goodbyes: new (Clazz as any)(), world: 'world' };
260,270c225,233
< var actual = compileWithPartials(string, hash);
< var expected1 =
< '&lt;b&gt;#1&lt;/b&gt;. goodbye! 2. GOODBYE! cruel world!';
< var expected2 =
< '2. GOODBYE! &lt;b&gt;#1&lt;/b&gt;. goodbye! cruel world!';
<
< equals(
< actual === expected1 || actual === expected2,
< true,
< 'each with object argument iterates over the contents when not empty'
< );
---
> try {
> expectTemplate(string)
> .withInput(hash)
> .toCompileTo('&lt;b&gt;#1&lt;/b&gt;. goodbye! 2. GOODBYE! cruel world!');
> } catch (e) {
> expectTemplate(string)
> .withInput(hash)
> .toCompileTo('2. GOODBYE! &lt;b&gt;#1&lt;/b&gt;. goodbye! cruel world!');
> }
275c238
< world: 'world'
---
> world: 'world',
280,283c243,244
< it('each with @index', function() {
< expectTemplate(
< '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
< )
---
> it('each with @index', () => {
> expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
285,290c246,247
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
292d248
< .withMessage('The @index variable is used')
296c252
< it('each with nested @index', function() {
---
> it('each with nested @index', () => {
301,306c257,258
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
308d259
< .withMessage('The @index variable is used')
314c265
< it('each with block params', function() {
---
> it('each with block params', () => {
320c271
< world: 'world'
---
> world: 'world',
322,324c273
< .toCompileTo(
< '0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!'
< );
---
> .toCompileTo('0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!');
327,330c276,277
< it('each object with @index', function() {
< expectTemplate(
< '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
< )
---
> it('each object with @index', () => {
> expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
335c282
< c: { text: 'GOODBYE' }
---
> c: { text: 'GOODBYE' },
337c284
< world: 'world'
---
> world: 'world',
339d285
< .withMessage('The @index variable is used')
343,346c289,290
< it('each with @first', function() {
< expectTemplate(
< '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
< )
---
> it('each with @first', () => {
> expectTemplate('{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
348,353c292,293
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
355d294
< .withMessage('The @first variable is used')
359c298
< it('each with nested @first', function() {
---
> it('each with nested @first', () => {
364,369c303,304
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
371,374c306
< .withMessage('The @first variable is used')
< .toCompileTo(
< '(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!'
< );
---
> .toCompileTo('(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!');
377,380c309,310
< it('each object with @first', function() {
< expectTemplate(
< '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
< )
---
> it('each object with @first', () => {
> expectTemplate('{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
383c313
< world: 'world'
---
> world: 'world',
385d314
< .withMessage('The @first variable is used')
389,392c318,319
< it('each with @last', function() {
< expectTemplate(
< '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
< )
---
> it('each with @last', () => {
> expectTemplate('{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
394,399c321,322
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
401d323
< .withMessage('The @last variable is used')
405,408c327,328
< it('each object with @last', function() {
< expectTemplate(
< '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!'
< )
---
> it('each object with @last', () => {
> expectTemplate('{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
411c331
< world: 'world'
---
> world: 'world',
413d332
< .withMessage('The @last variable is used')
417c336
< it('each with nested @last', function() {
---
> it('each with nested @last', () => {
422,427c341,342
< goodbyes: [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ],
< world: 'world'
---
> goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
> world: 'world',
429,432c344
< .withMessage('The @last variable is used')
< .toCompileTo(
< '(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!'
< );
---
> .toCompileTo('(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!');
435,436c347,348
< it('each with function argument', function() {
< var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
---
> it('each with function argument', () => {
> const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
440,445c352,353
< goodbyes: function() {
< return [
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ];
---
> goodbyes() {
> return [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }];
447c355
< world: 'world'
---
> world: 'world',
449,451d356
< .withMessage(
< 'each with array function argument iterates over the contents when not empty'
< )
457c362
< world: 'world'
---
> world: 'world',
459,461d363
< .withMessage(
< 'each with array function argument ignores the contents when empty'
< )
465,468c367,368
< it('each object when last key is an empty string', function() {
< expectTemplate(
< '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
< )
---
> it('each object when last key is an empty string', () => {
> expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
473c373
< '': { text: 'GOODBYE' }
---
> '': { text: 'GOODBYE' },
475c375
< world: 'world'
---
> world: 'world',
477d376
< .withMessage('Empty string key is not skipped')
481,484c380,381
< it('data passed to helpers', function() {
< expectTemplate(
< '{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}'
< )
---
> it('data passed to helpers', () => {
> expectTemplate('{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}')
486c383,385
< .withMessage('should output data')
---
> .withHelper('detectDataInsideEach', function (options) {
> return options.data && options.data.exclaim;
> })
489,490c388,389
< exclaim: '!'
< }
---
> exclaim: '!',
> },
495,499c394,395
< it('each on implicit context', function() {
< expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(
< handlebarsEnv.Exception,
< 'Must pass iterator to #each'
< );
---
> it('each on implicit context', () => {
> expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(Handlebars.Exception);
502,504c398,403
< if (global.Symbol && global.Symbol.iterator) {
< it('each on iterable', function() {
< function Iterator(arr) {
---
> it('each on iterable', () => {
> class Iterator {
> private arr: any[];
> private index: number = 0;
>
> constructor(arr: any[]) {
506d404
< this.index = 0;
508,510c406,409
< Iterator.prototype.next = function() {
< var value = this.arr[this.index];
< var done = this.index === this.arr.length;
---
>
> next() {
> const value = this.arr[this.index];
> const done = this.index === this.arr.length;
514,516c413,420
< return { value: value, done: done };
< };
< function Iterable(arr) {
---
> return { value, done };
> }
> }
>
> class Iterable {
> private arr: any[];
>
> constructor(arr: any[]) {
519c423,424
< Iterable.prototype[global.Symbol.iterator] = function() {
---
>
> [Symbol.iterator]() {
521,522c426,427
< };
< var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
---
> }
> }
524,536c429
< expectTemplate(string)
< .withInput({
< goodbyes: new Iterable([
< { text: 'goodbye' },
< { text: 'Goodbye' },
< { text: 'GOODBYE' }
< ]),
< world: 'world'
< })
< .withMessage(
< 'each with array argument iterates over the contents when not empty'
< )
< .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
---
> const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
538,548c431,444
< expectTemplate(string)
< .withInput({
< goodbyes: new Iterable([]),
< world: 'world'
< })
< .withMessage(
< 'each with array argument ignores the contents when empty'
< )
< .toCompileTo('cruel world!');
< });
< }
---
> expectTemplate(string)
> .withInput({
> goodbyes: new Iterable([{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }]),
> world: 'world',
> })
> .toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
>
> expectTemplate(string)
> .withInput({
> goodbyes: new Iterable([]),
> world: 'world',
> })
> .toCompileTo('cruel world!');
> });
551c447
< describe('#log', function() {
---
> describe('#log', function () {
553,555c449,451
< if (typeof console === 'undefined') {
< return;
< }
---
> let $log: typeof console.log;
> let $info: typeof console.info;
> let $error: typeof console.error;
557,558c453
< var $log, $info, $error;
< beforeEach(function() {
---
> beforeEach(function () {
561a457,458
>
> global.kbnHandlebarsEnv = Handlebars.create();
563c460,461
< afterEach(function() {
---
>
> afterEach(function () {
569,571c467,470
< it('should call logger at default level', function() {
< var levelArg, logArg;
< handlebarsEnv.log = function(level, arg) {
---
> it('should call logger at default level', function () {
> let levelArg;
> let logArg;
> kbnHandlebarsEnv!.log = function (level, arg) {
576,581c475,477
< expectTemplate('{{log blah}}')
< .withInput({ blah: 'whee' })
< .withMessage('log should not display')
< .toCompileTo('');
< equals(1, levelArg, 'should call log with 1');
< equals('whee', logArg, "should call log with 'whee'");
---
> expectTemplate('{{log blah}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(1).toEqual(levelArg);
> expect('whee').toEqual(logArg);
584,586c480,483
< it('should call logger at data level', function() {
< var levelArg, logArg;
< handlebarsEnv.log = function(level, arg) {
---
> it('should call logger at data level', function () {
> let levelArg;
> let logArg;
> kbnHandlebarsEnv!.log = function (level, arg) {
596,597c493,494
< equals('03', levelArg);
< equals('whee', logArg);
---
> expect('03').toEqual(levelArg);
> expect('whee').toEqual(logArg);
600,601c497,498
< it('should output to info', function() {
< var called;
---
> it('should output to info', function () {
> let called;
603,604c500,501
< console.info = function(info) {
< equals('whee', info);
---
> console.info = function (info) {
> expect('whee').toEqual(info);
609,610c506,507
< console.log = function(log) {
< equals('whee', log);
---
> console.log = function (log) {
> expect('whee').toEqual(log);
616,619c513,514
< expectTemplate('{{log blah}}')
< .withInput({ blah: 'whee' })
< .toCompileTo('');
< equals(true, called);
---
> expectTemplate('{{log blah}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(true).toEqual(called);
622,623c517,518
< it('should log at data level', function() {
< var called;
---
> it('should log at data level', function () {
> let called;
625,626c520,521
< console.error = function(log) {
< equals('whee', log);
---
> console.error = function (log) {
> expect('whee').toEqual(log);
636c531
< equals(true, called);
---
> expect(true).toEqual(called);
639,640c534,535
< it('should handle missing logger', function() {
< var called = false;
---
> it('should handle missing logger', function () {
> let called = false;
641a537
> // @ts-expect-error
643,644c539,540
< console.log = function(log) {
< equals('whee', log);
---
> console.log = function (log) {
> expect('whee').toEqual(log);
654c550
< equals(true, called);
---
> expect(true).toEqual(called);
657,658c553,554
< it('should handle string log levels', function() {
< var called;
---
> it('should handle string log levels', function () {
> let called;
660,661c556,557
< console.error = function(log) {
< equals('whee', log);
---
> console.error = function (log) {
> expect('whee').toEqual(log);
670c566
< equals(true, called);
---
> expect(true).toEqual(called);
679c575
< equals(true, called);
---
> expect(true).toEqual(called);
682,683c578,579
< it('should handle hash log levels', function() {
< var called;
---
> it('should handle hash log levels [1]', function () {
> let called;
685,686c581,582
< console.error = function(log) {
< equals('whee', log);
---
> console.error = function (log) {
> expect('whee').toEqual(log);
690,693c586,587
< expectTemplate('{{log blah level="error"}}')
< .withInput({ blah: 'whee' })
< .toCompileTo('');
< equals(true, called);
---
> expectTemplate('{{log blah level="error"}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(true).toEqual(called);
696,697c590,591
< it('should handle hash log levels', function() {
< var called = false;
---
> it('should handle hash log levels [2]', function () {
> let called = false;
699,702c593,600
< console.info = console.log = console.error = console.debug = function() {
< called = true;
< console.info = console.log = console.error = console.debug = $log;
< };
---
> console.info =
> console.log =
> console.error =
> console.debug =
> function () {
> called = true;
> console.info = console.log = console.error = console.debug = $log;
> };
704,707c602,603
< expectTemplate('{{log blah level="debug"}}')
< .withInput({ blah: 'whee' })
< .toCompileTo('');
< equals(false, called);
---
> expectTemplate('{{log blah level="debug"}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(false).toEqual(called);
710,711c606,607
< it('should pass multiple log arguments', function() {
< var called;
---
> it('should pass multiple log arguments', function () {
> let called;
713,716c609,612
< console.info = console.log = function(log1, log2, log3) {
< equals('whee', log1);
< equals('foo', log2);
< equals(1, log3);
---
> console.info = console.log = function (log1, log2, log3) {
> expect('whee').toEqual(log1);
> expect('foo').toEqual(log2);
> expect(1).toEqual(log3);
721,724c617,618
< expectTemplate('{{log blah "foo" 1}}')
< .withInput({ blah: 'whee' })
< .toCompileTo('');
< equals(true, called);
---
> expectTemplate('{{log blah "foo" 1}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(true).toEqual(called);
727,728c621,622
< it('should pass zero log arguments', function() {
< var called;
---
> it('should pass zero log arguments', function () {
> let called;
730,731c624,625
< console.info = console.log = function() {
< expect(arguments.length).to.equal(0);
---
> console.info = console.log = function () {
> expect(arguments.length).toEqual(0);
736,739c630,631
< expectTemplate('{{log}}')
< .withInput({ blah: 'whee' })
< .toCompileTo('');
< expect(called).to.be.true();
---
> expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
> expect(called).toEqual(true);
744,745c636,637
< describe('#lookup', function() {
< it('should lookup arbitrary content', function() {
---
> describe('#lookup', () => {
> it('should lookup arbitrary content', () => {
751c643
< it('should not fail on undefined value', function() {
---
> it('should not fail on undefined value', () => {

View file

@ -0,0 +1,272 @@
1,92c1,24
< describe('compiler', function() {
< if (!Handlebars.compile) {
< return;
< }
<
< describe('#equals', function() {
< function compile(string) {
< var ast = Handlebars.parse(string);
< return new Handlebars.Compiler().compile(ast, {});
< }
<
< it('should treat as equal', function() {
< equal(compile('foo').equals(compile('foo')), true);
< equal(compile('{{foo}}').equals(compile('{{foo}}')), true);
< equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true);
< equal(
< compile('{{foo.bar baz "foo" true false bat=1}}').equals(
< compile('{{foo.bar baz "foo" true false bat=1}}')
< ),
< true
< );
< equal(
< compile('{{foo.bar (baz bat=1)}}').equals(
< compile('{{foo.bar (baz bat=1)}}')
< ),
< true
< );
< equal(
< compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}')),
< true
< );
< });
< it('should treat as not equal', function() {
< equal(compile('foo').equals(compile('bar')), false);
< equal(compile('{{foo}}').equals(compile('{{bar}}')), false);
< equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false);
< equal(
< compile('{{foo.bar baz bat=1}}').equals(
< compile('{{foo.bar bar bat=1}}')
< ),
< false
< );
< equal(
< compile('{{foo.bar (baz bat=1)}}').equals(
< compile('{{foo.bar (bar bat=1)}}')
< ),
< false
< );
< equal(
< compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}')),
< false
< );
< equal(
< compile('{{#foo}} {{/foo}}').equals(
< compile('{{#foo}} {{foo}}{{/foo}}')
< ),
< false
< );
< });
< });
<
< describe('#compile', function() {
< it('should fail with invalid input', function() {
< shouldThrow(
< function() {
< Handlebars.compile(null);
< },
< Error,
< 'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
< );
< shouldThrow(
< function() {
< Handlebars.compile({});
< },
< Error,
< 'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]'
< );
< });
<
< it('should include the location in the error (row and column)', function() {
< try {
< Handlebars.compile(' \n {{#if}}\n{{/def}}')();
< equal(
< true,
< false,
< 'Statement must throw exception. This line should not be executed.'
< );
< } catch (err) {
< equal(
< err.message,
< "if doesn't match def - 2:5",
< 'Checking error message'
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
>
> describe('compiler', () => {
> const compileFns = ['compile', 'compileAST'];
> if (process.env.AST) compileFns.splice(0, 1);
> else if (process.env.EVAL) compileFns.splice(1, 1);
>
> compileFns.forEach((compileName) => {
> // @ts-expect-error
> const compile = Handlebars[compileName];
>
> describe(`#${compileName}`, () => {
> it('should fail with invalid input', () => {
> expect(function () {
> compile(null);
> }).toThrow(
> `You must pass a string or Handlebars AST to Handlebars.${compileName}. You passed null`
94,102d25
< if (Object.getOwnPropertyDescriptor(err, 'column').writable) {
< // In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty,
< // its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482)
< // Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers.
< equal(err.column, 5, 'Checking error column');
< }
< equal(err.lineNumber, 2, 'Checking error row');
< }
< });
104,116c27,30
< it('should include the location as enumerable property', function() {
< try {
< Handlebars.compile(' \n {{#if}}\n{{/def}}')();
< equal(
< true,
< false,
< 'Statement must throw exception. This line should not be executed.'
< );
< } catch (err) {
< equal(
< Object.prototype.propertyIsEnumerable.call(err, 'column'),
< true,
< 'Checking error column'
---
> expect(function () {
> compile({});
> }).toThrow(
> `You must pass a string or Handlebars AST to Handlebars.${compileName}. You passed [object Object]`
118,129c32
< }
< });
<
< it('can utilize AST instance', function() {
< equal(
< Handlebars.compile({
< type: 'Program',
< body: [{ type: 'ContentStatement', value: 'Hello' }]
< })(),
< 'Hello'
< );
< });
---
> });
131,152c34,48
< it('can pass through an empty string', function() {
< equal(Handlebars.compile('')(), '');
< });
<
< it('should not modify the options.data property(GH-1327)', function() {
< var options = { data: [{ a: 'foo' }, { a: 'bar' }] };
< Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
< equal(
< JSON.stringify(options, 0, 2),
< JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, 0, 2)
< );
< });
<
< it('should not modify the options.knownHelpers property(GH-1327)', function() {
< var options = { knownHelpers: {} };
< Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
< equal(
< JSON.stringify(options, 0, 2),
< JSON.stringify({ knownHelpers: {} }, 0, 2)
< );
< });
< });
---
> it('should include the location in the error (row and column)', () => {
> try {
> compile(' \n {{#if}}\n{{/def}}')({});
> expect(true).toEqual(false);
> } catch (err) {
> expect(err.message).toEqual("if doesn't match def - 2:5");
> if (Object.getOwnPropertyDescriptor(err, 'column')!.writable) {
> // In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty,
> // its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482)
> // Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers.
> expect(err.column).toEqual(5);
> }
> expect(err.lineNumber).toEqual(2);
> }
> });
154,170c50,57
< describe('#precompile', function() {
< it('should fail with invalid input', function() {
< shouldThrow(
< function() {
< Handlebars.precompile(null);
< },
< Error,
< 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed null'
< );
< shouldThrow(
< function() {
< Handlebars.precompile({});
< },
< Error,
< 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed [object Object]'
< );
< });
---
> it('should include the location as enumerable property', () => {
> try {
> compile(' \n {{#if}}\n{{/def}}')({});
> expect(true).toEqual(false);
> } catch (err) {
> expect(Object.prototype.propertyIsEnumerable.call(err, 'column')).toEqual(true);
> }
> });
172,175c59,61
< it('can utilize AST instance', function() {
< equal(
< /return "Hello"/.test(
< Handlebars.precompile({
---
> it('can utilize AST instance', () => {
> expect(
> compile({
177,182c63,78
< body: [{ type: 'ContentStatement', value: 'Hello' }]
< })
< ),
< true
< );
< });
---
> body: [{ type: 'ContentStatement', value: 'Hello' }],
> })({})
> ).toEqual('Hello');
> });
>
> it('can pass through an empty string', () => {
> expect(compile('')({})).toEqual('');
> });
>
> it('should not modify the options.data property(GH-1327)', () => {
> const options = { data: [{ a: 'foo' }, { a: 'bar' }] };
> compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)({});
> expect(JSON.stringify(options, null, 2)).toEqual(
> JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, null, 2)
> );
> });
184,185c80,86
< it('can pass through an empty string', function() {
< equal(/return ""/.test(Handlebars.precompile('')), true);
---
> it('should not modify the options.knownHelpers property(GH-1327)', () => {
> const options = { knownHelpers: {} };
> compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)({});
> expect(JSON.stringify(options, null, 2)).toEqual(
> JSON.stringify({ knownHelpers: {} }, null, 2)
> );
> });

View file

@ -0,0 +1,273 @@
1,2c1,12
< describe('data', function() {
< it('passing in data to a compiled function that expects data - works with helpers', function() {
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('data', () => {
> it('passing in data to a compiled function that expects data - works with helpers', () => {
5c15
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (this: any, options) {
10d19
< .withMessage('Data output by helper')
14c23
< it('data can be looked up via @foo', function() {
---
> it('data can be looked up via @foo', () => {
17d25
< .withMessage('@foo retrieves template data')
21,22c29,31
< it('deep @foo triggers automatic top-level data', function() {
< var helpers = Handlebars.createFrame(handlebarsEnv.helpers);
---
> it('deep @foo triggers automatic top-level data', () => {
> global.kbnHandlebarsEnv = Handlebars.create();
> const helpers = Handlebars.createFrame(kbnHandlebarsEnv!.helpers);
24,25c33,34
< helpers.let = function(options) {
< var frame = Handlebars.createFrame(options.data);
---
> helpers.let = function (options: Handlebars.HelperOptions) {
> const frame = Handlebars.createFrame(options.data);
27c36
< for (var prop in options.hash) {
---
> for (const prop in options.hash) {
40d48
< .withMessage('Automatic data was triggered')
44c52
< it('parameter data can be looked up via @foo', function() {
---
> it('parameter data can be looked up via @foo', () => {
47c55
< .withHelper('hello', function(noun) {
---
> .withHelper('hello', function (noun) {
50d57
< .withMessage('@foo as a parameter retrieves template data')
54c61
< it('hash values can be looked up via @foo', function() {
---
> it('hash values can be looked up via @foo', () => {
57c64
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (options) {
60d66
< .withMessage('@foo as a parameter retrieves template data')
64c70
< it('nested parameter data can be looked up via @foo.bar', function() {
---
> it('nested parameter data can be looked up via @foo.bar', () => {
67c73
< .withHelper('hello', function(noun) {
---
> .withHelper('hello', function (noun) {
70d75
< .withMessage('@foo as a parameter retrieves template data')
74c79
< it('nested parameter data does not fail with @world.bar', function() {
---
> it('nested parameter data does not fail with @world.bar', () => {
77c82
< .withHelper('hello', function(noun) {
---
> .withHelper('hello', function (noun) {
80d84
< .withMessage('@foo as a parameter retrieves template data')
84,87c88,89
< it('parameter data throws when using complex scope references', function() {
< expectTemplate(
< '{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}'
< ).toThrow(Error);
---
> it('parameter data throws when using complex scope references', () => {
> expectTemplate('{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}').toThrow(Error);
90c92
< it('data can be functions', function() {
---
> it('data can be functions', () => {
94c96
< hello: function() {
---
> hello() {
96,97c98,99
< }
< }
---
> },
> },
102c104
< it('data can be functions with params', function() {
---
> it('data can be functions with params', () => {
106c108
< hello: function(arg) {
---
> hello(arg: any) {
108,109c110,111
< }
< }
---
> },
> },
114c116
< it('data is inherited downstream', function() {
---
> it('data is inherited downstream', () => {
120,122c122,124
< .withHelper('let', function(options) {
< var frame = Handlebars.createFrame(options.data);
< for (var prop in options.hash) {
---
> .withHelper('let', function (this: any, options) {
> const frame = Handlebars.createFrame(options.data);
> for (const prop in options.hash) {
130d131
< .withMessage('data variables are inherited downstream')
134,147c135
< it('passing in data to a compiled function that expects data - works with helpers in partials', function() {
< expectTemplate('{{>myPartial}}')
< .withCompileOptions({ data: true })
< .withPartial('myPartial', '{{hello}}')
< .withHelper('hello', function(options) {
< return options.data.adjective + ' ' + this.noun;
< })
< .withInput({ noun: 'cat' })
< .withRuntimeOptions({ data: { adjective: 'happy' } })
< .withMessage('Data output by helper inside partial')
< .toCompileTo('happy cat');
< });
<
< it('passing in data to a compiled function that expects data - works with helpers and parameters', function() {
---
> it('passing in data to a compiled function that expects data - works with helpers and parameters', () => {
150c138
< .withHelper('hello', function(noun, options) {
---
> .withHelper('hello', function (this: any, noun, options) {
155d142
< .withMessage('Data output by helper')
159c146
< it('passing in data to a compiled function that expects data - works with block helpers', function() {
---
> it('passing in data to a compiled function that expects data - works with block helpers', () => {
162c149
< data: true
---
> data: true,
164c151
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (this: any, options) {
167c154
< .withHelper('world', function(options) {
---
> .withHelper('world', function (this: any, options) {
172d158
< .withMessage('Data output by helper')
176c162
< it('passing in data to a compiled function that expects data - works with block helpers that use ..', function() {
---
> it('passing in data to a compiled function that expects data - works with block helpers that use ..', () => {
179c165
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (options) {
182c168
< .withHelper('world', function(thing, options) {
---
> .withHelper('world', function (this: any, thing, options) {
187d172
< .withMessage('Data output by helper')
191c176
< it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function() {
---
> it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', () => {
194c179
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (options) {
197c182
< .withHelper('world', function(thing, options) {
---
> .withHelper('world', function (this: any, thing, options) {
202d186
< .withMessage('Data output by helper')
206c190
< it('you can override inherited data when invoking a helper', function() {
---
> it('you can override inherited data when invoking a helper', () => {
209,213c193,194
< .withHelper('hello', function(options) {
< return options.fn(
< { exclaim: '?', zomg: 'world' },
< { data: { adjective: 'sad' } }
< );
---
> .withHelper('hello', function (options) {
> return options.fn({ exclaim: '?', zomg: 'world' }, { data: { adjective: 'sad' } });
215c196
< .withHelper('world', function(thing, options) {
---
> .withHelper('world', function (this: any, thing, options) {
220d200
< .withMessage('Overriden data output by helper')
224c204
< it('you can override inherited data when invoking a helper with depth', function() {
---
> it('you can override inherited data when invoking a helper with depth', () => {
227c207
< .withHelper('hello', function(options) {
---
> .withHelper('hello', function (options) {
230c210
< .withHelper('world', function(thing, options) {
---
> .withHelper('world', function (this: any, thing, options) {
235d214
< .withMessage('Overriden data output by helper')
239,240c218,219
< describe('@root', function() {
< it('the root context can be looked up via @root', function() {
---
> describe('@root', () => {
> it('the root context can be looked up via @root', () => {
246,248c225
< expectTemplate('{{@root.foo}}')
< .withInput({ foo: 'hello' })
< .toCompileTo('hello');
---
> expectTemplate('{{@root.foo}}').withInput({ foo: 'hello' }).toCompileTo('hello');
251c228
< it('passed root values take priority', function() {
---
> it('passed root values take priority', () => {
259,260c236,237
< describe('nesting', function() {
< it('the root context can be looked up via @root', function() {
---
> describe('nesting', () => {
> it('the root context can be looked up via @root', () => {
265,266c242,243
< .withHelper('helper', function(options) {
< var frame = Handlebars.createFrame(options.data);
---
> .withHelper('helper', function (this: any, options) {
> const frame = Handlebars.createFrame(options.data);
272,273c249,250
< depth: 0
< }
---
> depth: 0,
> },

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,518 @@
1,2c1,11
< describe('Regressions', function() {
< it('GH-94: Cannot read property of undefined', function() {
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('Regressions', () => {
> it('GH-94: Cannot read property of undefined', () => {
9,10c18,19
< name: 'Charles Darwin'
< }
---
> name: 'Charles Darwin',
> },
13,15c22,24
< title: 'Lazarillo de Tormes'
< }
< ]
---
> title: 'Lazarillo de Tormes',
> },
> ],
17d25
< .withMessage('Renders without an undefined property error')
21,43c29,34
< it("GH-150: Inverted sections print when they shouldn't", function() {
< var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
<
< expectTemplate(string)
< .withMessage(
< "inverted sections run when property isn't present in context"
< )
< .toCompileTo('not set :: ');
<
< expectTemplate(string)
< .withInput({ set: undefined })
< .withMessage('inverted sections run when property is undefined')
< .toCompileTo('not set :: ');
<
< expectTemplate(string)
< .withInput({ set: false })
< .withMessage('inverted sections run when property is false')
< .toCompileTo('not set :: ');
<
< expectTemplate(string)
< .withInput({ set: true })
< .withMessage("inverted sections don't run when property is true")
< .toCompileTo(' :: set');
---
> it("GH-150: Inverted sections print when they shouldn't", () => {
> const string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
> expectTemplate(string).toCompileTo('not set :: ');
> expectTemplate(string).withInput({ set: undefined }).toCompileTo('not set :: ');
> expectTemplate(string).withInput({ set: false }).toCompileTo('not set :: ');
> expectTemplate(string).withInput({ set: true }).toCompileTo(' :: set');
46c37
< it('GH-158: Using array index twice, breaks the template', function() {
---
> it('GH-158: Using array index twice, breaks the template', () => {
49d39
< .withMessage('it works as expected')
53,54c43,44
< it("bug reported by @fat where lambdas weren't being properly resolved", function() {
< var string =
---
> it("bug reported by @fat where lambdas weren't being properly resolved", () => {
> const string =
69,70c59,60
< var data = {
< thing: function() {
---
> const data = {
> thing() {
76c66
< { className: 'three', word: '@sayrer' }
---
> { className: 'three', word: '@sayrer' },
78c68
< hasThings: function() {
---
> hasThings() {
80c70
< }
---
> },
83c73
< var output =
---
> const output =
92,94c82
< expectTemplate(string)
< .withInput(data)
< .toCompileTo(output);
---
> expectTemplate(string).withInput(data).toCompileTo(output);
97,100c85,86
< it('GH-408: Multiple loops fail', function() {
< expectTemplate(
< '{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}'
< )
---
> it('GH-408: Multiple loops fail', () => {
> expectTemplate('{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}')
103c89
< { name: 'Jane Doe', location: { city: 'New York' } }
---
> { name: 'Jane Doe', location: { city: 'New York' } },
105d90
< .withMessage('It should output multiple times')
109,110c94,95
< it('GS-428: Nested if else rendering', function() {
< var succeedingTemplate =
---
> it('GS-428: Nested if else rendering', () => {
> const succeedingTemplate =
112c97
< var failingTemplate =
---
> const failingTemplate =
115,116c100,101
< var helpers = {
< blk: function(block) {
---
> const helpers = {
> blk(block: Handlebars.HelperOptions) {
119c104
< inverse: function(block) {
---
> inverse(block: Handlebars.HelperOptions) {
121c106
< }
---
> },
124,130c109,110
< expectTemplate(succeedingTemplate)
< .withHelpers(helpers)
< .toCompileTo(' Expected ');
<
< expectTemplate(failingTemplate)
< .withHelpers(helpers)
< .toCompileTo(' Expected ');
---
> expectTemplate(succeedingTemplate).withHelpers(helpers).toCompileTo(' Expected ');
> expectTemplate(failingTemplate).withHelpers(helpers).toCompileTo(' Expected ');
133,136c113,114
< it('GH-458: Scoped this identifier', function() {
< expectTemplate('{{./foo}}')
< .withInput({ foo: 'bar' })
< .toCompileTo('bar');
---
> it('GH-458: Scoped this identifier', () => {
> expectTemplate('{{./foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
139c117
< it('GH-375: Unicode line terminators', function() {
---
> it('GH-375: Unicode line terminators', () => {
143c121
< it('GH-534: Object prototype aliases', function() {
---
> it('GH-534: Object prototype aliases', () => {
144a123
> // @ts-expect-error
147,149c126
< expectTemplate('{{foo}}')
< .withInput({ foo: 'bar' })
< .toCompileTo('bar');
---
> expectTemplate('{{foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
150a128
> // @ts-expect-error
155,157c133,135
< it('GH-437: Matching escaping', function() {
< expectTemplate('{{{a}}').toThrow(Error, /Parse error on/);
< expectTemplate('{{a}}}').toThrow(Error, /Parse error on/);
---
> it('GH-437: Matching escaping', () => {
> expectTemplate('{{{a}}').toThrow(/Parse error on/);
> expectTemplate('{{a}}}').toThrow(/Parse error on/);
160,166c138,140
< it('GH-676: Using array in escaping mustache fails', function() {
< var data = { arr: [1, 2] };
<
< expectTemplate('{{arr}}')
< .withInput(data)
< .withMessage('it works as expected')
< .toCompileTo(data.arr.toString());
---
> it('GH-676: Using array in escaping mustache fails', () => {
> const data = { arr: [1, 2] };
> expectTemplate('{{arr}}').withInput(data).toCompileTo(data.arr.toString());
169c143
< it('Mustache man page', function() {
---
> it('Mustache man page', () => {
177c151
< in_ca: true
---
> in_ca: true,
179,182c153
< .withMessage('the hello world mustache example works')
< .toCompileTo(
< 'Hello Chris. You have just won $10000! Well, $6000, after taxes.'
< );
---
> .toCompileTo('Hello Chris. You have just won $10000! Well, $6000, after taxes.');
185c156
< it('GH-731: zero context rendering', function() {
---
> it('GH-731: zero context rendering', () => {
189c160
< bar: 'OK'
---
> bar: 'OK',
194,197c165,166
< it('GH-820: zero pathed rendering', function() {
< expectTemplate('{{foo.bar}}')
< .withInput({ foo: 0 })
< .toCompileTo('');
---
> it('GH-820: zero pathed rendering', () => {
> expectTemplate('{{foo.bar}}').withInput({ foo: 0 }).toCompileTo('');
200c169
< it('GH-837: undefined values for helpers', function() {
---
> it('GH-837: undefined values for helpers', () => {
203c172
< str: function(value) {
---
> str(value) {
205c174
< }
---
> },
210c179
< it('GH-926: Depths and de-dupe', function() {
---
> it('GH-926: Depths and de-dupe', () => {
217c186
< notData: [1]
---
> notData: [1],
222c191
< it('GH-1021: Each empty string key', function() {
---
> it('GH-1021: Each empty string key', () => {
228,229c197,198
< value: 10000
< }
---
> value: 10000,
> },
234,248c203,204
< it('GH-1054: Should handle simple safe string responses', function() {
< expectTemplate('{{#wrap}}{{>partial}}{{/wrap}}')
< .withHelpers({
< wrap: function(options) {
< return new Handlebars.SafeString(options.fn());
< }
< })
< .withPartials({
< partial: '{{#wrap}}<partial>{{/wrap}}'
< })
< .toCompileTo('<partial>');
< });
<
< it('GH-1065: Sparse arrays', function() {
< var array = [];
---
> it('GH-1065: Sparse arrays', () => {
> const array = [];
252c208
< .withInput({ array: array })
---
> .withInput({ array })
256c212
< it('GH-1093: Undefined helper context', function() {
---
> it('GH-1093: Undefined helper context', () => {
260c216
< helper: function() {
---
> helper(this: any) {
263c219
< for (var name in this) {
---
> for (const name in this) {
270c226
< }
---
> },
275,306c231
< it('should support multiple levels of inline partials', function() {
< expectTemplate(
< '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}'
< )
< .withPartials({
< doctype: 'doctype{{> content}}',
< layout:
< '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
< })
< .toCompileTo('doctypelayoutsubcontent');
< });
<
< it('GH-1089: should support failover content in multiple levels of inline partials', function() {
< expectTemplate('{{#> layout}}{{/layout}}')
< .withPartials({
< doctype: 'doctype{{> content}}',
< layout:
< '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}'
< })
< .toCompileTo('doctypelayoutsubcontent');
< });
<
< it('GH-1099: should support greater than 3 nested levels of inline partials', function() {
< expectTemplate('{{#> layout}}Outer{{/layout}}')
< .withPartials({
< layout: '{{#> inner}}Inner{{/inner}}{{> @partial-block }}',
< inner: ''
< })
< .toCompileTo('Outer');
< });
<
< it('GH-1135 : Context handling within each iteration', function() {
---
> it('GH-1135 : Context handling within each iteration', () => {
315c240
< myif: function(conditional, options) {
---
> myif(conditional, options) {
321c246
< }
---
> },
326,343c251,252
< it('GH-1186: Support block params for existing programs', function() {
< expectTemplate(
< '{{#*inline "test"}}{{> @partial-block }}{{/inline}}' +
< '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' +
< '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}'
< )
< .withInput({
< listOne: ['a'],
< listTwo: ['b']
< })
< .withMessage('')
< .toCompileTo('ab');
< });
<
< it('GH-1319: "unless" breaks when "each" value equals "null"', function() {
< expectTemplate(
< '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}'
< )
---
> it('GH-1319: "unless" breaks when "each" value equals "null"', () => {
> expectTemplate('{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}')
346c255
< list: [null, 'a']
---
> list: [null, 'a'],
348d256
< .withMessage('')
352,457c260
< it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function() {
< expectTemplate('template {{>partial}} template')
< .withPartials({
< partialWithBlock:
< '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
< partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}'
< })
< .toCompileTo('template block partial block template');
< });
<
< describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() {
< it('should compile and execute templates', function() {
< var newHandlebarsInstance = Handlebars.create();
<
< registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
< newHandlebarsInstance.registerHelper('loud', function(value) {
< return value.toUpperCase();
< });
< var result = newHandlebarsInstance.templates['test.hbs']({
< name: 'yehuda'
< });
< equals(result.trim(), 'YEHUDA');
< });
<
< it('should call "helperMissing" if a helper is missing', function() {
< var newHandlebarsInstance = Handlebars.create();
<
< shouldThrow(
< function() {
< registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
< newHandlebarsInstance.templates['test.hbs']({});
< },
< Handlebars.Exception,
< 'Missing helper: "loud"'
< );
< });
<
< it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function() {
< var newHandlebarsInstance = Handlebars.create();
< registerTemplate(
< newHandlebarsInstance,
< compiledTemplateVersion7_usingLookupHelper()
< );
<
< newHandlebarsInstance.templates['test.hbs']({});
<
< expect(
< newHandlebarsInstance.templates['test.hbs']({
< property: 'a',
< test: { a: 'b' }
< })
< ).to.equal('b');
< });
<
< function registerTemplate(Handlebars, compileTemplate) {
< var template = Handlebars.template,
< templates = (Handlebars.templates = Handlebars.templates || {});
< templates['test.hbs'] = template(compileTemplate);
< }
<
< function compiledTemplateVersion7() {
< return {
< compiler: [7, '>= 4.0.0'],
< main: function(container, depth0, helpers, partials, data) {
< return (
< container.escapeExpression(
< (
< helpers.loud ||
< (depth0 && depth0.loud) ||
< helpers.helperMissing
< ).call(
< depth0 != null ? depth0 : container.nullContext || {},
< depth0 != null ? depth0.name : depth0,
< { name: 'loud', hash: {}, data: data }
< )
< ) + '\n\n'
< );
< },
< useData: true
< };
< }
<
< function compiledTemplateVersion7_usingLookupHelper() {
< // This is the compiled version of "{{lookup test property}}"
< return {
< compiler: [7, '>= 4.0.0'],
< main: function(container, depth0, helpers, partials, data) {
< return container.escapeExpression(
< helpers.lookup.call(
< depth0 != null ? depth0 : container.nullContext || {},
< depth0 != null ? depth0.test : depth0,
< depth0 != null ? depth0.property : depth0,
< {
< name: 'lookup',
< hash: {},
< data: data
< }
< )
< );
< },
< useData: true
< };
< }
< });
<
< it('should allow hash with protected array names', function() {
---
> it('should allow hash with protected array names', () => {
461c264
< helpa: function(options) {
---
> helpa(options) {
463c266
< }
---
> },
468,496c271,272
< describe('GH-1598: Performance degradation for partials since v4.3.0', function() {
< // Do not run test for runs without compiler
< if (!Handlebars.compile) {
< return;
< }
<
< var newHandlebarsInstance;
< beforeEach(function() {
< newHandlebarsInstance = Handlebars.create();
< });
< afterEach(function() {
< sinon.restore();
< });
<
< it('should only compile global partials once', function() {
< var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
< newHandlebarsInstance.registerPartial({
< dude: 'I am a partial'
< });
< var string = 'Dudes: {{> dude}} {{> dude}}';
< newHandlebarsInstance.compile(string)(); // This should compile template + partial once
< newHandlebarsInstance.compile(string)(); // This should only compile template
< equal(templateSpy.callCount, 3);
< sinon.restore();
< });
< });
<
< describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", function() {
< it('should treat undefined helpers like non-existing helpers', function() {
---
> describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", () => {
> it('should treat undefined helpers like non-existing helpers', () => {

View file

@ -0,0 +1,443 @@
1,10c1,15
< describe('security issues', function() {
< describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
< it('should not allow constructors to be accessed', function() {
< expectTemplate('{{lookup (lookup this "constructor") "name"}}')
< .withInput({})
< .toCompileTo('');
<
< expectTemplate('{{constructor.name}}')
< .withInput({})
< .toCompileTo('');
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('security issues', () => {
> describe('GH-1495: Prevent Remote Code Execution via constructor', () => {
> it('should not allow constructors to be accessed', () => {
> expectTemplate('{{lookup (lookup this "constructor") "name"}}').withInput({}).toCompileTo('');
> expectTemplate('{{constructor.name}}').withInput({}).toCompileTo('');
13c18
< it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() {
---
> it('GH-1603: should not allow constructors to be accessed (lookup via toString)', () => {
16c21
< .withHelper('list', function(element) {
---
> .withHelper('list', function (element) {
22c27
< it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() {
---
> it('should allow the "constructor" property to be accessed if it is an "ownProperty"', () => {
32c37
< it('should allow the "constructor" property to be accessed if it is an "own property"', function() {
---
> it('should allow the "constructor" property to be accessed if it is an "own property"', () => {
39,45c44,46
< describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
< if (!Handlebars.compile) {
< return;
< }
<
< describe('without the option "allowExplicitCallOfHelperMissing"', function() {
< it('should throw an exception when calling "{{helperMissing}}" ', function() {
---
> describe('GH-1558: Prevent explicit call of helperMissing-helpers', () => {
> describe('without the option "allowExplicitCallOfHelperMissing"', () => {
> it('should throw an exception when calling "{{helperMissing}}" ', () => {
49c50
< it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
---
> it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', () => {
53,56c54,57
< it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
< var functionCalls = [];
< expect(function() {
< var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
---
> it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', () => {
> const functionCalls = [];
> expect(() => {
> const template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
58c59
< fn: function() {
---
> fn() {
60c61
< }
---
> },
62,63c63,64
< }).to.throw(Error);
< expect(functionCalls.length).to.equal(0);
---
> }).toThrow(Error);
> expect(functionCalls.length).toEqual(0);
66c67
< it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
---
> it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', () => {
69c70
< fn: function() {
---
> fn() {
71c72
< }
---
> },
76,110d76
<
< describe('with the option "allowCallsToHelperMissing" set to true', function() {
< it('should not throw an exception when calling "{{helperMissing}}" ', function() {
< var template = Handlebars.compile('{{helperMissing}}');
< template({}, { allowCallsToHelperMissing: true });
< });
<
< it('should not throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', function() {
< var template = Handlebars.compile(
< '{{#helperMissing}}{{/helperMissing}}'
< );
< template({}, { allowCallsToHelperMissing: true });
< });
<
< it('should not throw an exception when calling "{{blockHelperMissing "abc" .}}" ', function() {
< var functionCalls = [];
< var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
< template(
< {
< fn: function() {
< functionCalls.push('called');
< }
< },
< { allowCallsToHelperMissing: true }
< );
< equals(functionCalls.length, 1);
< });
<
< it('should not throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
< var template = Handlebars.compile(
< '{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
< );
< template({}, { allowCallsToHelperMissing: true });
< });
< });
113,114c79,81
< describe('GH-1563', function() {
< it('should not allow to access constructor after overriding via __defineGetter__', function() {
---
> describe('GH-1563', () => {
> it('should not allow to access constructor after overriding via __defineGetter__', () => {
> // @ts-expect-error
116c83
< return this.skip(); // Browser does not support this exploit anyway
---
> return; // Browser does not support this exploit anyway
130,131c97,98
< describe('GH-1595: dangerous properties', function() {
< var templates = [
---
> describe('GH-1595: dangerous properties', () => {
> const templates = [
141c108
< '{{lookup this "__proto__"}}'
---
> '{{lookup this "__proto__"}}',
144,257c111,114
< templates.forEach(function(template) {
< describe('access should be denied to ' + template, function() {
< it('by default', function() {
< expectTemplate(template)
< .withInput({})
< .toCompileTo('');
< });
< it(' with proto-access enabled', function() {
< expectTemplate(template)
< .withInput({})
< .withRuntimeOptions({
< allowProtoPropertiesByDefault: true,
< allowProtoMethodsByDefault: true
< })
< .toCompileTo('');
< });
< });
< });
< });
< describe('GH-1631: disallow access to prototype functions', function() {
< function TestClass() {}
<
< TestClass.prototype.aProperty = 'propertyValue';
< TestClass.prototype.aMethod = function() {
< return 'returnValue';
< };
<
< beforeEach(function() {
< handlebarsEnv.resetLoggedPropertyAccesses();
< });
<
< afterEach(function() {
< sinon.restore();
< });
<
< describe('control access to prototype methods via "allowedProtoMethods"', function() {
< checkProtoMethodAccess({});
<
< describe('in compat mode', function() {
< checkProtoMethodAccess({ compat: true });
< });
<
< function checkProtoMethodAccess(compileOptions) {
< it('should be prohibited by default and log a warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .toCompileTo('');
<
< expect(spy.calledOnce).to.be.true();
< expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
< });
<
< it('should only log the warning once', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .toCompileTo('');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .toCompileTo('');
<
< expect(spy.calledOnce).to.be.true();
< expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
< });
<
< it('can be allowed, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowedProtoMethods: {
< aMethod: true
< }
< })
< .toCompileTo('returnValue');
<
< expect(spy.callCount).to.equal(0);
< });
<
< it('can be turned on by default, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoMethodsByDefault: true
< })
< .toCompileTo('returnValue');
<
< expect(spy.callCount).to.equal(0);
< });
<
< it('can be turned off by default, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoMethodsByDefault: false
< })
< .toCompileTo('');
<
< expect(spy.callCount).to.equal(0);
---
> templates.forEach((template) => {
> describe('access should be denied to ' + template, () => {
> it('by default', () => {
> expectTemplate(template).withInput({}).toCompileTo('');
259,399d115
<
< it('can be turned off, if turned on by default', function() {
< expectTemplate('{{aMethod}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoMethodsByDefault: true,
< allowedProtoMethods: {
< aMethod: false
< }
< })
< .toCompileTo('');
< });
< }
<
< it('should cause the recursive lookup by default (in "compat" mode)', function() {
< expectTemplate('{{#aString}}{{trim}}{{/aString}}')
< .withInput({ aString: ' abc ', trim: 'trim' })
< .withCompileOptions({ compat: true })
< .toCompileTo('trim');
< });
<
< it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function() {
< expectTemplate('{{#aString}}{{trim}}{{/aString}}')
< .withInput({ aString: ' abc ', trim: 'trim' })
< .withCompileOptions({ compat: true })
< .withRuntimeOptions({
< allowedProtoMethods: {
< trim: true
< }
< })
< .toCompileTo('abc');
< });
< });
<
< describe('control access to prototype non-methods via "allowedProtoProperties" and "allowProtoPropertiesByDefault', function() {
< checkProtoPropertyAccess({});
<
< describe('in compat-mode', function() {
< checkProtoPropertyAccess({ compat: true });
< });
<
< describe('in strict-mode', function() {
< checkProtoPropertyAccess({ strict: true });
< });
<
< function checkProtoPropertyAccess(compileOptions) {
< it('should be prohibited by default and log a warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aProperty}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .toCompileTo('');
<
< expect(spy.calledOnce).to.be.true();
< expect(spy.args[0][0]).to.match(/Handlebars: Access has been denied/);
< });
<
< it('can be explicitly prohibited by default, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aProperty}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoPropertiesByDefault: false
< })
< .toCompileTo('');
<
< expect(spy.callCount).to.equal(0);
< });
<
< it('can be turned on, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aProperty}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowedProtoProperties: {
< aProperty: true
< }
< })
< .toCompileTo('propertyValue');
<
< expect(spy.callCount).to.equal(0);
< });
<
< it('can be turned on by default, which disables the warning', function() {
< var spy = sinon.spy(console, 'error');
<
< expectTemplate('{{aProperty}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoPropertiesByDefault: true
< })
< .toCompileTo('propertyValue');
<
< expect(spy.callCount).to.equal(0);
< });
<
< it('can be turned off, if turned on by default', function() {
< expectTemplate('{{aProperty}}')
< .withInput(new TestClass())
< .withCompileOptions(compileOptions)
< .withRuntimeOptions({
< allowProtoPropertiesByDefault: true,
< allowedProtoProperties: {
< aProperty: false
< }
< })
< .toCompileTo('');
< });
< }
< });
<
< describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function() {
< beforeEach(function simulateRuntimeWithoutLookupProperty() {
< var oldTemplateMethod = handlebarsEnv.template;
< sinon.replace(handlebarsEnv, 'template', function(templateSpec) {
< templateSpec.main = wrapToAdjustContainer(templateSpec.main);
< return oldTemplateMethod.call(this, templateSpec);
< });
< });
<
< afterEach(function() {
< sinon.restore();
< });
<
< it('should work with simple properties', function() {
< expectTemplate('{{aProperty}}')
< .withInput({ aProperty: 'propertyValue' })
< .toCompileTo('propertyValue');
< });
<
< it('should work with Array.prototype.length', function() {
< expectTemplate('{{anArray.length}}')
< .withInput({ anArray: ['a', 'b', 'c'] })
< .toCompileTo('3');
404,409c120,122
< describe('escapes template variables', function() {
< it('in compat mode', function() {
< expectTemplate("{{'a\\b'}}")
< .withCompileOptions({ compat: true })
< .withInput({ 'a\\b': 'c' })
< .toCompileTo('c');
---
> describe('escapes template variables', () => {
> it('in default mode', () => {
> expectTemplate("{{'a\\b'}}").withCompileOptions().withInput({ 'a\\b': 'c' }).toCompileTo('c');
412,418c125
< it('in default mode', function() {
< expectTemplate("{{'a\\b'}}")
< .withCompileOptions()
< .withInput({ 'a\\b': 'c' })
< .toCompileTo('c');
< });
< it('in default mode', function() {
---
> it('in strict mode', () => {
426,432d132
<
< function wrapToAdjustContainer(precompiledTemplateFunction) {
< return function templateFunctionWrapper(container /*, more args */) {
< delete container.lookupProperty;
< return precompiledTemplateFunction.apply(this, arguments);
< };
< }

View file

@ -0,0 +1,180 @@
1,5c1,12
< var Exception = Handlebars.Exception;
<
< describe('strict', function() {
< describe('strict mode', function() {
< it('should error on missing property lookup', function() {
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('strict', () => {
> describe('strict mode', () => {
> it('should error on missing property lookup', () => {
8c15
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
11c18
< it('should error on missing child', function() {
---
> it('should error on missing child', () => {
20c27
< .toThrow(Exception, /"bar" not defined in/);
---
> .toThrow(/"bar" not defined in/);
23c30
< it('should handle explicit undefined', function() {
---
> it('should handle explicit undefined', () => {
30c37
< it('should error on missing property lookup in known helpers mode', function() {
---
> it('should error on missing property lookup in known helpers mode', () => {
34c41
< knownHelpersOnly: true
---
> knownHelpersOnly: true,
36c43
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
39,42c46,47
< it('should error on missing context', function() {
< expectTemplate('{{hello}}')
< .withCompileOptions({ strict: true })
< .toThrow(Error);
---
> it('should error on missing context', () => {
> expectTemplate('{{hello}}').withCompileOptions({ strict: true }).toThrow(Error);
45,47c50,52
< it('should error on missing data lookup', function() {
< var xt = expectTemplate('{{@hello}}').withCompileOptions({
< strict: true
---
> it('should error on missing data lookup', () => {
> const xt = expectTemplate('{{@hello}}').withCompileOptions({
> strict: true,
55c60
< it('should not run helperMissing for helper calls', function() {
---
> it('should not run helperMissing for helper calls', () => {
59c64
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
64c69
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
67c72
< it('should throw on ambiguous blocks', function() {
---
> it('should throw on ambiguous blocks', () => {
70c75
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
74c79
< .toThrow(Exception, /"hello" not defined in/);
---
> .toThrow(/"hello" not defined in/);
79c84
< .toThrow(Exception, /"bar" not defined in/);
---
> .toThrow(/"bar" not defined in/);
82c87
< it('should allow undefined parameters when passed to helpers', function() {
---
> it('should allow undefined parameters when passed to helpers', () => {
88c93
< it('should allow undefined hash when passed to helpers', function() {
---
> it('should allow undefined hash when passed to helpers', () => {
91c96
< strict: true
---
> strict: true,
94,96c99,101
< helper: function(options) {
< equals('value' in options.hash, true);
< equals(options.hash.value, undefined);
---
> helper(options) {
> expect('value' in options.hash).toEqual(true);
> expect(options.hash.value).toBeUndefined();
98c103
< }
---
> },
103c108
< it('should show error location on missing property lookup', function() {
---
> it('should show error location on missing property lookup', () => {
106c111
< .toThrow(Exception, '"hello" not defined in [object Object] - 4:5');
---
> .toThrow('"hello" not defined in [object Object] - 4:5');
109c114
< it('should error contains correct location properties on missing property lookup', function() {
---
> it('should error contains correct location properties on missing property lookup', () => {
111,114c116,118
< var template = CompilerContext.compile('\n\n\n {{hello}}', {
< strict: true
< });
< template({});
---
> expectTemplate('\n\n\n {{hello}}')
> .withCompileOptions({ strict: true })
> .toCompileTo('throw before asserting this');
116,119c120,123
< equals(error.lineNumber, 4);
< equals(error.endLineNumber, 4);
< equals(error.column, 5);
< equals(error.endColumn, 10);
---
> expect(error.lineNumber).toEqual(4);
> expect(error.endLineNumber).toEqual(4);
> expect(error.column).toEqual(5);
> expect(error.endColumn).toEqual(10);
124,128c128,130
< describe('assume objects', function() {
< it('should ignore missing property', function() {
< expectTemplate('{{hello}}')
< .withCompileOptions({ assumeObjects: true })
< .toCompileTo('');
---
> describe('assume objects', () => {
> it('should ignore missing property', () => {
> expectTemplate('{{hello}}').withCompileOptions({ assumeObjects: true }).toCompileTo('');
131c133
< it('should ignore missing child', function() {
---
> it('should ignore missing child', () => {
138,141c140,141
< it('should error on missing object', function() {
< expectTemplate('{{hello.bar}}')
< .withCompileOptions({ assumeObjects: true })
< .toThrow(Error);
---
> it('should error on missing object', () => {
> expectTemplate('{{hello.bar}}').withCompileOptions({ assumeObjects: true }).toThrow(Error);
144c144
< it('should error on missing context', function() {
---
> it('should error on missing context', () => {
151c151
< it('should error on missing data lookup', function() {
---
> it('should error on missing data lookup', () => {
158c158
< it('should execute blockHelperMissing', function() {
---
> it('should execute blockHelperMissing', () => {

View file

@ -0,0 +1,318 @@
1,2c1,12
< describe('subexpressions', function() {
< it('arg-less helper', function() {
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('subexpressions', () => {
> it('arg-less helper', () => {
5c15
< foo: function(val) {
---
> foo(val) {
8c18
< bar: function() {
---
> bar() {
10c20
< }
---
> },
15c25
< it('helper w args', function() {
---
> it('helper w args', () => {
19c29
< blog: function(val) {
---
> blog(val) {
22c32
< equal: function(x, y) {
---
> equal(x, y) {
24c34
< }
---
> },
29c39
< it('mixed paths and helpers', function() {
---
> it('mixed paths and helpers', () => {
33c43
< blog: function(val, that, theOther) {
---
> blog(val, that, theOther) {
36c46
< equal: function(x, y) {
---
> equal(x, y) {
38c48
< }
---
> },
43c53
< it('supports much nesting', function() {
---
> it('supports much nesting', () => {
47c57
< blog: function(val) {
---
> blog(val) {
50c60
< equal: function(x, y) {
---
> equal(x, y) {
52c62
< }
---
> },
57,60c67,70
< it('GH-800 : Complex subexpressions', function() {
< var context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
< var helpers = {
< dash: function(a, b) {
---
> it('GH-800 : Complex subexpressions', () => {
> const context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
> const helpers = {
> dash(a: any, b: any) {
63c73
< concat: function(a, b) {
---
> concat(a: any, b: any) {
65c75
< }
---
> },
94,97c104,107
< it('provides each nested helper invocation its own options hash', function() {
< var lastOptions = null;
< var helpers = {
< equal: function(x, y, options) {
---
> it('provides each nested helper invocation its own options hash', () => {
> let lastOptions: Handlebars.HelperOptions;
> const helpers = {
> equal(x: any, y: any, options: Handlebars.HelperOptions) {
103c113
< }
---
> },
105,107c115
< expectTemplate('{{equal (equal true true) true}}')
< .withHelpers(helpers)
< .toCompileTo('true');
---
> expectTemplate('{{equal (equal true true) true}}').withHelpers(helpers).toCompileTo('true');
110c118
< it('with hashes', function() {
---
> it('with hashes', () => {
114c122
< blog: function(val) {
---
> blog(val) {
117c125
< equal: function(x, y) {
---
> equal(x, y) {
119c127
< }
---
> },
124c132
< it('as hashes', function() {
---
> it('as hashes', () => {
127c135
< blog: function(options) {
---
> blog(options) {
130c138
< equal: function(x, y) {
---
> equal(x, y) {
132c140
< }
---
> },
137,140c145,146
< it('multiple subexpressions in a hash', function() {
< expectTemplate(
< '{{input aria-label=(t "Name") placeholder=(t "Example User")}}'
< )
---
> it('multiple subexpressions in a hash', () => {
> expectTemplate('{{input aria-label=(t "Name") placeholder=(t "Example User")}}')
142,145c148,151
< input: function(options) {
< var hash = options.hash;
< var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
< var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
---
> input(options) {
> const hash = options.hash;
> const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
> const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
147,151c153
< '<input aria-label="' +
< ariaLabel +
< '" placeholder="' +
< placeholder +
< '" />'
---
> '<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />'
154c156
< t: function(defaultString) {
---
> t(defaultString) {
156c158
< }
---
> },
161,164c163,164
< it('multiple subexpressions in a hash with context', function() {
< expectTemplate(
< '{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}'
< )
---
> it('multiple subexpressions in a hash with context', () => {
> expectTemplate('{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}')
168,169c168,169
< placeholder: 'Example User'
< }
---
> placeholder: 'Example User',
> },
172,175c172,175
< input: function(options) {
< var hash = options.hash;
< var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
< var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
---
> input(options) {
> const hash = options.hash;
> const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
> const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
177,181c177
< '<input aria-label="' +
< ariaLabel +
< '" placeholder="' +
< placeholder +
< '" />'
---
> '<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />'
184c180
< t: function(defaultString) {
---
> t(defaultString) {
186,212d181
< }
< })
< .toCompileTo('<input aria-label="Name" placeholder="Example User" />');
< });
<
< it('in string params mode,', function() {
< expectTemplate('{{snog (blorg foo x=y) yeah a=b}}')
< .withCompileOptions({ stringParams: true })
< .withHelpers({
< snog: function(a, b, options) {
< equals(a, 'foo');
< equals(
< options.types.length,
< 2,
< 'string params for outer helper processed correctly'
< );
< equals(
< options.types[0],
< 'SubExpression',
< 'string params for outer helper processed correctly'
< );
< equals(
< options.types[1],
< 'PathExpression',
< 'string params for outer helper processed correctly'
< );
< return a + b;
214,231d182
<
< blorg: function(a, options) {
< equals(
< options.types.length,
< 1,
< 'string params for inner helper processed correctly'
< );
< equals(
< options.types[0],
< 'PathExpression',
< 'string params for inner helper processed correctly'
< );
< return a;
< }
< })
< .withInput({
< foo: {},
< yeah: {}
233,248c184
< .toCompileTo('fooyeah');
< });
<
< it('as hashes in string params mode', function() {
< expectTemplate('{{blog fun=(bork)}}')
< .withCompileOptions({ stringParams: true })
< .withHelpers({
< blog: function(options) {
< equals(options.hashTypes.fun, 'SubExpression');
< return 'val is ' + options.hash.fun;
< },
< bork: function() {
< return 'BORK';
< }
< })
< .toCompileTo('val is BORK');
---
> .toCompileTo('<input aria-label="Name" placeholder="Example User" />');
251c187
< it('subexpression functions on the context', function() {
---
> it('subexpression functions on the context', () => {
254c190
< bar: function() {
---
> bar() {
256c192
< }
---
> },
259c195
< foo: function(val) {
---
> foo(val) {
261c197
< }
---
> },
266c202
< it("subexpressions can't just be property lookups", function() {
---
> it("subexpressions can't just be property lookups", () => {
269c205
< bar: 'LOL'
---
> bar: 'LOL',
272c208
< foo: function(val) {
---
> foo(val) {
274c210
< }
---
> },

View file

@ -0,0 +1,109 @@
1,86c1,21
< describe('utils', function() {
< describe('#SafeString', function() {
< it('constructing a safestring from a string and checking its type', function() {
< var safe = new Handlebars.SafeString('testing 1, 2, 3');
< if (!(safe instanceof Handlebars.SafeString)) {
< throw new Error('Must be instance of SafeString');
< }
< equals(
< safe.toString(),
< 'testing 1, 2, 3',
< 'SafeString is equivalent to its underlying string'
< );
< });
<
< it('it should not escape SafeString properties', function() {
< var name = new Handlebars.SafeString('<em>Sean O&#x27;Malley</em>');
<
< expectTemplate('{{name}}')
< .withInput({ name: name })
< .toCompileTo('<em>Sean O&#x27;Malley</em>');
< });
< });
<
< describe('#escapeExpression', function() {
< it('shouhld escape html', function() {
< equals(
< Handlebars.Utils.escapeExpression('foo<&"\'>'),
< 'foo&lt;&amp;&quot;&#x27;&gt;'
< );
< equals(Handlebars.Utils.escapeExpression('foo='), 'foo&#x3D;');
< });
< it('should not escape SafeString', function() {
< var string = new Handlebars.SafeString('foo<&"\'>');
< equals(Handlebars.Utils.escapeExpression(string), 'foo<&"\'>');
<
< var obj = {
< toHTML: function() {
< return 'foo<&"\'>';
< }
< };
< equals(Handlebars.Utils.escapeExpression(obj), 'foo<&"\'>');
< });
< it('should handle falsy', function() {
< equals(Handlebars.Utils.escapeExpression(''), '');
< equals(Handlebars.Utils.escapeExpression(undefined), '');
< equals(Handlebars.Utils.escapeExpression(null), '');
<
< equals(Handlebars.Utils.escapeExpression(false), 'false');
< equals(Handlebars.Utils.escapeExpression(0), '0');
< });
< it('should handle empty objects', function() {
< equals(Handlebars.Utils.escapeExpression({}), {}.toString());
< equals(Handlebars.Utils.escapeExpression([]), [].toString());
< });
< });
<
< describe('#isEmpty', function() {
< it('should not be empty', function() {
< equals(Handlebars.Utils.isEmpty(undefined), true);
< equals(Handlebars.Utils.isEmpty(null), true);
< equals(Handlebars.Utils.isEmpty(false), true);
< equals(Handlebars.Utils.isEmpty(''), true);
< equals(Handlebars.Utils.isEmpty([]), true);
< });
<
< it('should be empty', function() {
< equals(Handlebars.Utils.isEmpty(0), false);
< equals(Handlebars.Utils.isEmpty([1]), false);
< equals(Handlebars.Utils.isEmpty('foo'), false);
< equals(Handlebars.Utils.isEmpty({ bar: 1 }), false);
< });
< });
<
< describe('#extend', function() {
< it('should ignore prototype values', function() {
< function A() {
< this.a = 1;
< }
< A.prototype.b = 4;
<
< var b = { b: 2 };
<
< Handlebars.Utils.extend(b, new A());
<
< equals(b.a, 1);
< equals(b.b, 2);
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import Handlebars from '..';
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('utils', function () {
> describe('#SafeString', function () {
> it('constructing a safestring from a string and checking its type', function () {
> const safe = new Handlebars.SafeString('testing 1, 2, 3');
> expect(safe).toBeInstanceOf(Handlebars.SafeString);
> expect(safe.toString()).toEqual('testing 1, 2, 3');
> });
>
> it('it should not escape SafeString properties', function () {
> const name = new Handlebars.SafeString('<em>Sean O&#x27;Malley</em>');
> expectTemplate('{{name}}').withInput({ name }).toCompileTo('<em>Sean O&#x27;Malley</em>');

View file

@ -0,0 +1,187 @@
1,24c1,17
< describe('whitespace control', function() {
< it('should strip whitespace around mustache calls', function() {
< var hash = { foo: 'bar<' };
<
< expectTemplate(' {{~foo~}} ')
< .withInput(hash)
< .toCompileTo('bar&lt;');
<
< expectTemplate(' {{~foo}} ')
< .withInput(hash)
< .toCompileTo('bar&lt; ');
<
< expectTemplate(' {{foo~}} ')
< .withInput(hash)
< .toCompileTo(' bar&lt;');
<
< expectTemplate(' {{~&foo~}} ')
< .withInput(hash)
< .toCompileTo('bar<');
<
< expectTemplate(' {{~{foo}~}} ')
< .withInput(hash)
< .toCompileTo('bar<');
<
---
> /*
> * This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
> * and may include modifications made by Elasticsearch B.V.
> * Elasticsearch B.V. licenses this file to you under the MIT License.
> * See `packages/kbn-handlebars/LICENSE` for more information.
> */
>
> import { expectTemplate } from '../__jest__/test_bench';
>
> describe('whitespace control', () => {
> it('should strip whitespace around mustache calls', () => {
> const hash = { foo: 'bar<' };
> expectTemplate(' {{~foo~}} ').withInput(hash).toCompileTo('bar&lt;');
> expectTemplate(' {{~foo}} ').withInput(hash).toCompileTo('bar&lt; ');
> expectTemplate(' {{foo~}} ').withInput(hash).toCompileTo(' bar&lt;');
> expectTemplate(' {{~&foo~}} ').withInput(hash).toCompileTo('bar<');
> expectTemplate(' {{~{foo}~}} ').withInput(hash).toCompileTo('bar<');
28,46c21,28
< describe('blocks', function() {
< it('should strip whitespace around simple block calls', function() {
< var hash = { foo: 'bar<' };
<
< expectTemplate(' {{~#if foo~}} bar {{~/if~}} ')
< .withInput(hash)
< .toCompileTo('bar');
<
< expectTemplate(' {{#if foo~}} bar {{/if~}} ')
< .withInput(hash)
< .toCompileTo(' bar ');
<
< expectTemplate(' {{~#if foo}} bar {{~/if}} ')
< .withInput(hash)
< .toCompileTo(' bar ');
<
< expectTemplate(' {{#if foo}} bar {{/if}} ')
< .withInput(hash)
< .toCompileTo(' bar ');
---
> describe('blocks', () => {
> it('should strip whitespace around simple block calls', () => {
> const hash = { foo: 'bar<' };
>
> expectTemplate(' {{~#if foo~}} bar {{~/if~}} ').withInput(hash).toCompileTo('bar');
> expectTemplate(' {{#if foo~}} bar {{/if~}} ').withInput(hash).toCompileTo(' bar ');
> expectTemplate(' {{~#if foo}} bar {{~/if}} ').withInput(hash).toCompileTo(' bar ');
> expectTemplate(' {{#if foo}} bar {{/if}} ').withInput(hash).toCompileTo(' bar ');
57c39
< it('should strip whitespace around inverse block calls', function() {
---
> it('should strip whitespace around inverse block calls', () => {
59d40
<
61d41
<
63d42
<
65,68c44
<
< expectTemplate(
< ' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n '
< ).toCompileTo('bar');
---
> expectTemplate(' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ').toCompileTo('bar');
71,80c47,48
< it('should strip whitespace around complex block calls', function() {
< var hash = { foo: 'bar<' };
<
< expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}')
< .withInput(hash)
< .toCompileTo('bar');
<
< expectTemplate('{{#if foo~}} bar {{^~}} baz {{/if}}')
< .withInput(hash)
< .toCompileTo('bar ');
---
> it('should strip whitespace around complex block calls', () => {
> const hash = { foo: 'bar<' };
82,84c50,54
< expectTemplate('{{#if foo}} bar {{~^~}} baz {{~/if}}')
< .withInput(hash)
< .toCompileTo(' bar');
---
> expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').withInput(hash).toCompileTo('bar');
> expectTemplate('{{#if foo~}} bar {{^~}} baz {{/if}}').withInput(hash).toCompileTo('bar ');
> expectTemplate('{{#if foo}} bar {{~^~}} baz {{~/if}}').withInput(hash).toCompileTo(' bar');
> expectTemplate('{{#if foo}} bar {{^~}} baz {{/if}}').withInput(hash).toCompileTo(' bar ');
> expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').withInput(hash).toCompileTo('bar');
86,90c56
< expectTemplate('{{#if foo}} bar {{^~}} baz {{/if}}')
< .withInput(hash)
< .toCompileTo(' bar ');
<
< expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}')
---
> expectTemplate('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n')
94,102c60
< expectTemplate(
< '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n'
< )
< .withInput(hash)
< .toCompileTo('bar');
<
< expectTemplate(
< '\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n'
< )
---
> expectTemplate('\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n')
106,109c64
< expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').toCompileTo(
< 'baz'
< );
<
---
> expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').toCompileTo('baz');
111,120c66,69
<
< expectTemplate('{{#if foo~}} bar {{~^}} baz {{~/if}}').toCompileTo(
< ' baz'
< );
<
< expectTemplate('{{#if foo~}} bar {{~^}} baz {{/if}}').toCompileTo(
< ' baz '
< );
<
< expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').toCompileTo(
---
> expectTemplate('{{#if foo~}} bar {{~^}} baz {{~/if}}').toCompileTo(' baz');
> expectTemplate('{{#if foo~}} bar {{~^}} baz {{/if}}').toCompileTo(' baz ');
> expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').toCompileTo('baz');
> expectTemplate('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n').toCompileTo(
123,126d71
<
< expectTemplate(
< '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n'
< ).toCompileTo('baz');
130,152c75
< it('should strip whitespace around partials', function() {
< expectTemplate('foo {{~> dude~}} ')
< .withPartials({ dude: 'bar' })
< .toCompileTo('foobar');
<
< expectTemplate('foo {{> dude~}} ')
< .withPartials({ dude: 'bar' })
< .toCompileTo('foo bar');
<
< expectTemplate('foo {{> dude}} ')
< .withPartials({ dude: 'bar' })
< .toCompileTo('foo bar ');
<
< expectTemplate('foo\n {{~> dude}} ')
< .withPartials({ dude: 'bar' })
< .toCompileTo('foobar');
<
< expectTemplate('foo\n {{> dude}} ')
< .withPartials({ dude: 'bar' })
< .toCompileTo('foo\n bar');
< });
<
< it('should only strip whitespace once', function() {
---
> it('should only strip whitespace once', () => {

View file

@ -0,0 +1,115 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_BASE_NAME = "kbn-handlebars"
PKG_REQUIRE_NAME = "@kbn/handlebars"
TYPES_PKG_REQUIRE_NAME = "@types/kbn__handlebars"
SOURCE_FILES = glob(
[
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
"**/__jest__/**",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
"README.md",
]
RUNTIME_DEPS = [
"@npm//handlebars",
]
TYPES_DEPS = [
"@npm//@types/jest",
"@npm//@types/node",
"@npm//handlebars",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
jsts_transpiler(
name = "target_web",
srcs = SRCS,
build_pkg_name = package_name(),
web = True,
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
emit_declaration_only = True,
out_dir = "target_types",
source_map = True,
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_BASE_NAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [
":%s" % PKG_BASE_NAME,
]
)
filegroup(
name = "build",
srcs = [
":npm_module",
],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = TYPES_PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [
":npm_module_types",
],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,29 @@
The MIT License (MIT)
Copyright (c) Elasticsearch BV
Copyright (c) Copyright (C) 2011-2019 by Yehuda Katz
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at the following locations:
- https://github.com/handlebars-lang/handlebars.js
- https://github.com/elastic/kibana/tree/main/packages/kbn-handlebars
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,192 @@
# @kbn/handlebars
A custom version of the handlebars package which, to improve security, does not use `eval` or `new Function`. This means that templates can't be compiled into JavaScript functions in advance and hence, rendering the templates is a lot slower.
## Limitations
- Only the following compile options are supported:
- `knownHelpers`
- `knownHelpersOnly`
- `strict`
- `assumeObjects`
- `noEscape`
- `data`
- Only the following runtime options are supported:
- `helpers`
- `blockParams`
- `data`
The [Inline partials](https://handlebarsjs.com/guide/partials.html#inline-partials) handlebars template feature is currently not supported by `@kbn/handlebars`.
## Implementation differences
The standard `handlebars` implementation:
1. When given a template string, e.g. `Hello {{x}}`, return a "render" function which takes an "input" object, e.g. `{ x: 'World' }`.
1. The first time the "render" function is called the following happens:
1. Turn the template string into an Abstract Syntax Tree (AST).
1. Convert the AST into a hyper optimized JavaScript function which takes the input object as an argument.
1. Call the generate JavaScript function with the given "input" object to produce and return the final output string (`Hello World`).
1. Subsequent calls to the "render" function will re-use the already generated JavaScript function.
The custom `@kbn/handlebars` implementation:
1. When given a template string, e.g. `Hello {{x}}`, return a "render" function which takes an "input" object, e.g. `{ x: 'World' }`.
1. The first time the "render" function is called the following happens:
1. Turn the template string into an Abstract Syntax Tree (AST).
1. Process the AST with the given "input" object to produce and return the final output string (`Hello World`).
1. Subsequent calls to the "render" function will re-use the already generated AST.
_Note: Not parsing of the template string until the first call to the "render" function is deliberate as it mimics the original `handlebars` implementation. This means that any errors that occur due to an invalid template string will not be thrown until the first call to the "render" function._
## Technical details
The `handlebars` library exposes the API for both [generating the AST](https://github.com/handlebars-lang/handlebars.js/blob/master/docs/compiler-api.md#ast) and walking it by implementing the [Visitor API](https://github.com/handlebars-lang/handlebars.js/blob/master/docs/compiler-api.md#ast-visitor). We can leverage that to our advantage and create our own "render" function, which internally calls this API to generate the AST and then the API to walk the AST.
The `@kbn/handlebars` implementation of the `Visitor` class implements all the necessary methods called by the parent `Visitor` code when instructed to walk the AST. They all start with an upppercase letter, e.g. `MustacheStatement` or `SubExpression`. We call this class `ElasticHandlebarsVisitor`.
To parse the template string to an AST representation, we call `Handlebars.parse(templateString)`, which returns an AST object.
The AST object contains a bunch of nodes, one for each element of the template string, all arranged in a tree-like structure. The root of the AST object is a node of type `Program`. This is a special node, which we do not need to worry about, but each of its direct children has a type named like the method which will be called when the walking algorithm reaches that node, e.g. `ContentStatement` or `BlockStatement`. These are the methods that our `Visitor` implementation implements.
To instruct our `ElasticHandlebarsVisitor` class to start walking the AST object, we call the `accept()` method inherited from the parent `Visitor` class with the main AST object. The `Visitor` will walk each node in turn that is directly attached to the root `Program` node. For each node it traverses, it will call the matching method in our `ElasticHandlebarsVisitor` class.
To instruct the `Visitor` code to traverse any child nodes of a given node, our implementation needs to manually call `accept(childNode)`, `acceptArray(arrayOfChildNodes)`, `acceptKey(node, childKeyName)`, or `acceptRequired(node, childKeyName)` from within any of the "node" methods, otherwise the child nodes are ignored.
### State
We keep state internally in the `ElasticHandlebarsVisitor` object using the following private properties:
- `scopes`: An array (stack) of `context` objects. In a simple template this array will always only contain a single element: The main `context` object. In more complicated scenarios, new `context` objects will be pushed and popped to and from the `scopes` stack as needed.
- `output`: An array containing the "rendered" output of each node (normally just one element per node). In the most simple template, this is simply joined together into a the final output string after the AST has been traversed. In more complicated templates, we use this array temporarily to collect parameters to give to helper functions (see the `getParams` function).
## Development
Some of the tests have been copied from the upstream `handlebars` project and modified to fit our use-case, test-suite, and coding conventions. They are all located under the `packages/kbn-handlebars/src/upstream` directory. To check if any of the copied files have received updates upstream that we might want to include in our copies, you can run the following script:
```sh
./packages/kbn-handlebars/scripts/check_for_test_changes.sh
```
If the script outputs a diff for a given file, it means that this file has been updated.
Once all updates have been manually merged with our versions of the files, run the following script to "lock" us into the new updates:
```sh
./packages/kbn-handlebars/scripts/update_test_patches.sh
```
This will update the `.patch` files inside the `packages/kbn-handlebars/.patches` directory. Make sure to commit those changes.
_Note: If we manually make changes to our test files in the `upstream` directory, we need to run the `update_test_patches.sh` script as well._
## Debugging
### Print AST
To output the generated AST object structure in a somewhat readable form, use the following script:
```sh
./packages/kbn-handlebars/scripts/print_ast.js
```
Example:
```sh
./packages/kbn-handlebars/scripts/print_ast.js '{{value}}'
```
Output:
```js
{
type: 'Program',
body: [
{
type: 'MustacheStatement',
path: {
type: 'PathExpression',
data: false,
depth: 0,
parts: [ 'value' ],
original: 'value'
},
params: [],
hash: undefined,
escaped: true,
strip: { open: false, close: false }
}
],
strip: {}
}
```
You can also filter which properties not to display, e.g:
```sh
./packages/kbn-handlebars/scripts/print_ast.js '{{#myBlock}}Hello {{name}}{{/myBlock}}' params,hash,loc,strip,data,depth,parts,inverse,openStrip,inverseStrip,closeStrip,blockParams,escaped
```
Output:
```js
{
type: 'Program',
body: [
{
type: 'BlockStatement',
path: { type: 'PathExpression', original: 'myBlock' },
program: {
type: 'Program',
body: [
{
type: 'ContentStatement',
original: 'Hello ',
value: 'Hello '
},
{
type: 'MustacheStatement',
path: { type: 'PathExpression', original: 'name' }
}
]
}
}
]
}
```
### Environment variables
By default each test will run both the original `handlebars` code and the modified `@kbn/handlebars` code to compare if the output of the two are identical. When debugging, it can be beneficial to isolate a test run to just one or the other. To control this, you can use the following environment variables:
- `EVAL=1` - Set to only run the original `handlebars` implementation that uses `eval`.
- `AST=1` - Set to only run the modified `@kbn/handlebars` implementation that doesn't use `eval`.
### Print generated code
It's possible to see the generated JavaScript code that `handlebars` create for a given template using the following command line tool:
```sh
./node_modules/handlebars/print-script <template> [options]
```
Options:
- `-v`: Enable verbose mode.
Example:
```sh
./node_modules/handlebars/print-script '{{value}}' -v
```
You can pretty print just the generated function using this command:
```sh
./node_modules/handlebars/print-script '{{value}}' | \
node -e 'process.stdin.on(`data`, c => console.log(`x=${eval(`(${eval(`(${c})`).code})`).main}`))' | \
npx prettier --write --stdin-filepath template.js | \
tail -c +5 | \
npx cli-highlight -l javascript
```

View file

@ -0,0 +1,10 @@
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-handlebars'],
};

View file

@ -0,0 +1,9 @@
{
"name": "@kbn/handlebars",
"version": "1.0.0",
"private": true,
"main": "./target_node/index.js",
"browser": "./target_web/index.js",
"types": "./target_types/index.d.ts",
"license": "MIT"
}

View file

@ -0,0 +1,33 @@
set -e
rm -fr .tmp
mkdir .tmp
echo "Cloning handlebars repo..."
git clone -q --depth 1 https://github.com/handlebars-lang/handlebars.js.git -b 4.x .tmp/handlebars
files=(packages/kbn-handlebars/src/upstream/index.*.test.ts)
for file in "${files[@]}"
do
tmp=${file#*.} # remove anything before first period
file=${tmp%.test.ts} # remove trailing .test.ts
echo "Checking for changes to spec/$file.js..."
set +e
diff .tmp/handlebars/spec/$file.js packages/kbn-handlebars/src/upstream/index.$file.test.ts > .tmp/$file.patch
error=$?
set -e
if [ $error -gt 1 ]
then
echo "Error executing diff!"
exit $error
fi
diff -u .tmp/$file.patch packages/kbn-handlebars/.patches/$file.patch
done
echo "No changes found :)"
rm -fr .tmp

View file

@ -0,0 +1,45 @@
#!/usr/bin/env node
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
'use strict'; // eslint-disable-line strict
const { inspect } = require('util');
const { parse } = require('handlebars');
const template = process.argv[2];
const filter = (process.argv[3] || 'loc').split(',');
const containsSubNodes = ['body', 'path', 'program', 'params'];
if (template === undefined) {
console.log(`Usage: ${process.argv[1]} <template> <filter>`);
console.log();
console.log(
'By default, <filter> will be "loc", but can be set to any comma separated list of keys to filter from the output'
);
process.exit(1);
}
console.log(inspect(reduce(parse(template, filter)), { colors: true, depth: null }));
function reduce(ast) {
if (Array.isArray(ast)) {
for (let i = 0; i < ast.length; i++) {
ast[i] = reduce(ast[i]);
}
} else {
for (const k of filter) {
delete ast[k];
}
for (const k of containsSubNodes) {
if (k in ast) {
ast[k] = reduce(ast[k]);
}
}
}
return ast;
}

View file

@ -0,0 +1,24 @@
set -e
rm -fr .tmp
mkdir .tmp
echo "Cloning handlebars repo..."
git clone -q --depth 1 https://github.com/handlebars-lang/handlebars.js.git -b 4.x .tmp/handlebars
files=(packages/kbn-handlebars/src/upstream/index.*.test.ts)
for file in "${files[@]}"
do
tmp=${file#*.} # remove anything before first period
file=${tmp%.test.ts} # remove trailing .test.ts
echo "Overwriting stored patch file for spec/$file.js..."
set +e
diff .tmp/handlebars/spec/$file.js packages/kbn-handlebars/src/upstream/index.$file.test.ts > packages/kbn-handlebars/.patches/$file.patch
set -e
done
echo "All patches updated :)"
rm -fr .tmp

View file

@ -0,0 +1,170 @@
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars, { ExtendedCompileOptions, ExtendedRuntimeOptions } from '..';
declare global {
var kbnHandlebarsEnv: typeof Handlebars | null; // eslint-disable-line no-var
}
global.kbnHandlebarsEnv = null;
interface TestOptions {
beforeEach?: Function;
}
export function expectTemplate(template: string, options?: TestOptions) {
return new HandlebarsTestBench(template, options);
}
class HandlebarsTestBench {
private template: string;
private options: TestOptions;
private compileOptions?: ExtendedCompileOptions;
private runtimeOptions?: ExtendedRuntimeOptions;
private helpers: { [key: string]: Handlebars.HelperDelegate | undefined } = {};
private input: any = {};
constructor(template: string, options: TestOptions = {}) {
this.template = template;
this.options = options;
}
withCompileOptions(compileOptions?: ExtendedCompileOptions) {
this.compileOptions = compileOptions;
return this;
}
withRuntimeOptions(runtimeOptions?: ExtendedRuntimeOptions) {
this.runtimeOptions = runtimeOptions;
return this;
}
withInput(input: any) {
this.input = input;
return this;
}
withHelper(name: string, helper?: Handlebars.HelperDelegate) {
this.helpers[name] = helper;
return this;
}
withHelpers(helperFunctions: { [key: string]: Handlebars.HelperDelegate }) {
for (const [name, helper] of Object.entries(helperFunctions)) {
this.withHelper(name, helper);
}
return this;
}
toCompileTo(outputExpected: string) {
const { outputEval, outputAST } = this.compileAndExecute();
if (process.env.EVAL) {
expect(outputEval).toEqual(outputExpected);
} else if (process.env.AST) {
expect(outputAST).toEqual(outputExpected);
} else {
expect(outputAST).toEqual(outputExpected);
expect(outputAST).toEqual(outputEval);
}
}
toThrow(error?: string | RegExp | jest.Constructable | Error | undefined) {
if (process.env.EVAL) {
expect(() => {
this.compileAndExecuteEval();
}).toThrowError(error);
} else if (process.env.AST) {
expect(() => {
this.compileAndExecuteAST();
}).toThrowError(error);
} else {
expect(() => {
this.compileAndExecuteEval();
}).toThrowError(error);
expect(() => {
this.compileAndExecuteAST();
}).toThrowError(error);
}
}
toThrowErrorMatchingSnapshot() {
const { renderEval, renderAST } = this.compile();
expect(() => renderEval(this.input)).toThrowErrorMatchingSnapshot();
expect(() => renderAST(this.input)).toThrowErrorMatchingSnapshot();
}
private compileAndExecute() {
if (process.env.EVAL) {
return {
outputEval: this.compileAndExecuteEval(),
};
} else if (process.env.AST) {
return {
outputAST: this.compileAndExecuteAST(),
};
} else {
return {
outputEval: this.compileAndExecuteEval(),
outputAST: this.compileAndExecuteAST(),
};
}
}
private compileAndExecuteEval() {
const renderEval = this.compileEval();
const runtimeOptions: ExtendedRuntimeOptions = Object.assign(
{
helpers: this.helpers,
},
this.runtimeOptions
);
return renderEval(this.input, runtimeOptions);
}
private compileAndExecuteAST() {
const renderAST = this.compileAST();
const runtimeOptions: ExtendedRuntimeOptions = Object.assign(
{
helpers: this.helpers,
},
this.runtimeOptions
);
return renderAST(this.input, runtimeOptions);
}
private compile() {
const handlebarsEnv = getHandlebarsEnv();
return {
renderEval: this.compileEval(handlebarsEnv),
renderAST: this.compileAST(handlebarsEnv),
};
}
private compileEval(handlebarsEnv = getHandlebarsEnv()) {
this.execBeforeEach();
return handlebarsEnv.compile(this.template, this.compileOptions);
}
private compileAST(handlebarsEnv = getHandlebarsEnv()) {
this.execBeforeEach();
return handlebarsEnv.compileAST(this.template, this.compileOptions);
}
private execBeforeEach() {
if (this.options.beforeEach) {
this.options.beforeEach();
}
}
}
function getHandlebarsEnv() {
return kbnHandlebarsEnv || Handlebars.create();
}

View file

@ -0,0 +1,105 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Handlebars.compileAST invalid template 1`] = `
"Parse error on line 1:
{{value
--^
Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'INVALID'"
`;
exports[`Handlebars.compileAST invalid template 2`] = `
"Parse error on line 1:
{{value
--^
Expecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'INVALID'"
`;
exports[`Handlebars.create 1`] = `
HandlebarsEnvironment {
"AST": Object {
"helpers": Object {
"helperExpression": [Function],
"scopedId": [Function],
"simpleId": [Function],
},
},
"COMPILER_REVISION": 8,
"Compiler": [Function],
"Exception": [Function],
"HandlebarsEnvironment": [Function],
"JavaScriptCompiler": [Function],
"LAST_COMPATIBLE_COMPILER_REVISION": 7,
"Parser": Object {
"yy": Object {},
},
"REVISION_CHANGES": Object {
"1": "<= 1.0.rc.2",
"2": "== 1.0.0-rc.3",
"3": "== 1.0.0-rc.4",
"4": "== 1.x.x",
"5": "== 2.0.0-alpha.x",
"6": ">= 2.0.0-beta.1",
"7": ">= 4.0.0 <4.3.0",
"8": ">= 4.3.0",
},
"SafeString": [Function],
"Utils": Object {
"__esModule": true,
"appendContextPath": [Function],
"blockParams": [Function],
"createFrame": [Function],
"escapeExpression": [Function],
"extend": [Function],
"indexOf": [Function],
"isArray": [Function],
"isEmpty": [Function],
"isFunction": [Function],
"toString": [Function],
},
"VERSION": "4.7.7",
"VM": Object {
"__esModule": true,
"checkRevision": [Function],
"invokePartial": [Function],
"noop": [Function],
"resolvePartial": [Function],
"template": [Function],
"wrapProgram": [Function],
},
"__esModule": true,
"compile": [Function],
"compileAST": [Function],
"createFrame": [Function],
"decorators": Object {
"inline": [Function],
},
"escapeExpression": [Function],
"helpers": Object {
"blockHelperMissing": [Function],
"each": [Function],
"helperMissing": [Function],
"if": [Function],
"log": [Function],
"lookup": [Function],
"unless": [Function],
"with": [Function],
},
"log": [Function],
"logger": Object {
"level": "info",
"log": [Function],
"lookupLevel": [Function],
"methodMap": Array [
"debug",
"info",
"warn",
"error",
],
},
"parse": [Function],
"parseWithoutProcessing": [Function],
"partials": Object {},
"precompile": [Function],
"template": [Function],
}
`;

View file

@ -0,0 +1,93 @@
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
/**
* ABOUT THIS FILE:
*
* This file is for tests not copied from the upstream handlebars project, but
* tests that we feel are needed in order to fully cover our use-cases.
*/
import Handlebars from '.';
import { expectTemplate } from './__jest__/test_bench';
it('Handlebars.create', () => {
expect(Handlebars.create()).toMatchSnapshot();
});
describe('Handlebars.compileAST', () => {
describe('compiler options', () => {
it('noEscape', () => {
expectTemplate('{{value}}').withInput({ value: '<foo>' }).toCompileTo('&lt;foo&gt;');
expectTemplate('{{value}}')
.withCompileOptions({ noEscape: false })
.withInput({ value: '<foo>' })
.toCompileTo('&lt;foo&gt;');
expectTemplate('{{value}}')
.withCompileOptions({ noEscape: true })
.withInput({ value: '<foo>' })
.toCompileTo('<foo>');
});
});
it('invalid template', () => {
expectTemplate('{{value').withInput({ value: 42 }).toThrowErrorMatchingSnapshot();
});
if (!process.env.EVAL) {
it('reassign', () => {
const fn = Handlebars.compileAST;
expect(fn('{{value}}')({ value: 42 })).toEqual('42');
});
}
});
it('Only provide options.fn/inverse to block helpers', () => {
function toHaveProperties(...args: any[]) {
toHaveProperties.calls++;
const options = args[args.length - 1];
expect(options).toHaveProperty('fn');
expect(options).toHaveProperty('inverse');
return 42;
}
toHaveProperties.calls = 0;
function toNotHaveProperties(...args: any[]) {
toNotHaveProperties.calls++;
const options = args[args.length - 1];
expect(options).not.toHaveProperty('fn');
expect(options).not.toHaveProperty('inverse');
return 42;
}
toNotHaveProperties.calls = 0;
const nonBlockTemplates = ['{{foo}}', '{{foo 1 2}}'];
const blockTemplates = ['{{#foo}}42{{/foo}}', '{{#foo 1 2}}42{{/foo}}'];
for (const template of nonBlockTemplates) {
expectTemplate(template)
.withInput({
foo: toNotHaveProperties,
})
.toCompileTo('42');
expectTemplate(template).withHelper('foo', toNotHaveProperties).toCompileTo('42');
}
for (const template of blockTemplates) {
expectTemplate(template)
.withInput({
foo: toHaveProperties,
})
.toCompileTo('42');
expectTemplate(template).withHelper('foo', toHaveProperties).toCompileTo('42');
}
expect(toNotHaveProperties.calls).toEqual(nonBlockTemplates.length * 2 * 2);
expect(toHaveProperties.calls).toEqual(blockTemplates.length * 2 * 2);
});

View file

@ -0,0 +1,710 @@
/*
* Elasticsearch B.V licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
// The handlebars module uses `export =`, so we should technically use `import OriginalHandlebars = require('handlebars')`, but Babel will not allow this.
import OriginalHandlebars from 'handlebars';
import {
createProtoAccessControl,
resultIsAllowed,
// @ts-expect-error: Could not find a declaration file for module
} from 'handlebars/dist/cjs/handlebars/internal/proto-access';
// @ts-expect-error: Could not find a declaration file for module
import AST from 'handlebars/dist/cjs/handlebars/compiler/ast';
// @ts-expect-error: Could not find a declaration file for module
import { indexOf, createFrame } from 'handlebars/dist/cjs/handlebars/utils';
// @ts-expect-error: Could not find a declaration file for module
import { moveHelperToHooks } from 'handlebars/dist/cjs/handlebars/helpers';
const originalCreate = OriginalHandlebars.create;
/**
* A custom version of the Handlesbars module with an extra `compileAST` function.
*/
const Handlebars: typeof ExtendedHandlebars & typeof OriginalHandlebars = OriginalHandlebars as any;
const kHelper = Symbol('helper');
const kAmbiguous = Symbol('ambiguous');
const kSimple = Symbol('simple');
type NodeType = typeof kHelper | typeof kAmbiguous | typeof kSimple;
type ProcessableNode = hbs.AST.MustacheStatement | hbs.AST.BlockStatement | hbs.AST.SubExpression;
type ProcessableNodeWithPathParts = ProcessableNode & { path: hbs.AST.PathExpression };
/**
* If the `unsafe-eval` CSP is set, this string constant will be `compile`,
* otherwise `compileAST`.
*
* This can be used to call the more optimized `compile` function in
* environments that support it, or fall back to `compileAST` on environments
* that don't.
*/
export const compileFnName: 'compile' | 'compileAST' = allowUnsafeEval() ? 'compile' : 'compileAST';
/**
* Supported Handlebars compile options.
*
* This is a subset of all the compile options supported by the upstream
* Handlebars module.
*/
export type ExtendedCompileOptions = Pick<
CompileOptions,
'knownHelpers' | 'knownHelpersOnly' | 'strict' | 'assumeObjects' | 'noEscape' | 'data'
>;
/**
* Supported Handlebars runtime options
*
* This is a subset of all the runtime options supported by the upstream
* Handlebars module.
*/
export type ExtendedRuntimeOptions = Pick<RuntimeOptions, 'helpers' | 'blockParams' | 'data'>;
/**
* Normally this namespace isn't used directly. It's required to be present by
* TypeScript when calling the `Handlebars.create()` function.
*/
// eslint-disable-next-line @typescript-eslint/no-namespace
export declare namespace ExtendedHandlebars {
export function compileAST(
input: string | hbs.AST.Program,
options?: ExtendedCompileOptions
): (context: any, options?: ExtendedRuntimeOptions) => string;
export function create(): typeof Handlebars; // eslint-disable-line @typescript-eslint/no-shadow
}
// The handlebars module uses `export =`, so it can't be re-exported using `export *`.
// However, because of Babel, we're not allowed to use `export =` ourselves.
// So we have to resort to using `exports default` even though eslint doesn't like it.
//
// eslint-disable-next-line import/no-default-export
export default Handlebars;
/**
* Creates an isolated Handlebars environment.
*
* Each environment has its own helpers.
* This is only necessary for use cases that demand distinct helpers.
* Most use cases can use the root Handlebars environment directly.
*
* @returns A sandboxed/scoped version of the @kbn/handlebars module
*/
export function create(): typeof Handlebars {
const SandboxedHandlebars = originalCreate.call(Handlebars) as typeof Handlebars;
// When creating new Handlebars environments, ensure the custom compileAST function is present in the new environment as well
SandboxedHandlebars.compileAST = Handlebars.compileAST;
return SandboxedHandlebars;
}
Handlebars.create = create;
/**
* Compiles the given Handlbars template without the use of `eval`.
*
* @returns A render function with the same API as the return value from the regular Handlebars `compile` function.
*/
Handlebars.compileAST = function (
input: string | hbs.AST.Program,
options?: ExtendedCompileOptions
) {
if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
throw new Handlebars.Exception(
`You must pass a string or Handlebars AST to Handlebars.compileAST. You passed ${input}`
);
}
// If `Handlebars.compileAST` is reassigned, `this` will be undefined.
const helpers = (this ?? Handlebars).helpers;
const visitor = new ElasticHandlebarsVisitor(input, options, helpers);
return (context: any, runtimeOptions?: ExtendedRuntimeOptions) =>
visitor.render(context, runtimeOptions);
};
interface Container {
helpers: { [name: string]: Handlebars.HelperDelegate };
strict: (obj: { [name: string]: any }, name: string, loc: hbs.AST.SourceLocation) => any;
lookupProperty: (parent: { [name: string]: any }, propertyName: string) => any;
lambda: (current: any, context: any) => any;
data: (value: any, depth: number) => any;
hooks: {
helperMissing?: Handlebars.HelperDelegate;
blockHelperMissing?: Handlebars.HelperDelegate;
};
}
class ElasticHandlebarsVisitor extends Handlebars.Visitor {
private scopes: any[] = [];
private output: any[] = [];
private template?: string;
private compileOptions: ExtendedCompileOptions;
private runtimeOptions?: ExtendedRuntimeOptions;
private initialHelpers: { [name: string]: Handlebars.HelperDelegate };
private blockParamNames: any[][] = [];
private blockParamValues: any[][] = [];
private ast?: hbs.AST.Program;
private container: Container;
// @ts-expect-error
private defaultHelperOptions: Handlebars.HelperOptions = {};
constructor(
input: string | hbs.AST.Program,
options: ExtendedCompileOptions = {},
helpers: { [name: string]: Handlebars.HelperDelegate }
) {
super();
if (typeof input !== 'string' && input.type === 'Program') {
this.ast = input;
} else {
this.template = input as string;
}
this.compileOptions = Object.assign(
{
data: true,
},
options
);
this.compileOptions.knownHelpers = Object.assign(
Object.create(null),
{
helperMissing: true,
blockHelperMissing: true,
each: true,
if: true,
unless: true,
with: true,
log: true,
lookup: true,
},
this.compileOptions.knownHelpers
);
this.initialHelpers = Object.assign({}, helpers);
const protoAccessControl = createProtoAccessControl({});
const container: Container = (this.container = {
helpers: {},
strict(obj, name, loc) {
if (!obj || !(name in obj)) {
throw new Handlebars.Exception('"' + name + '" not defined in ' + obj, {
loc,
} as hbs.AST.Node);
}
return container.lookupProperty(obj, name);
},
// this function is lifted from the handlebars source and slightly modified (lib/handlebars/runtime.js)
lookupProperty(parent, propertyName) {
const result = parent[propertyName];
if (result == null) {
return result;
}
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return result;
}
if (resultIsAllowed(result, protoAccessControl, propertyName)) {
return result;
}
return undefined;
},
// this function is lifted from the handlebars source and slightly modified (lib/handlebars/runtime.js)
lambda(current, context) {
return typeof current === 'function' ? current.call(context) : current;
},
data(value: any, depth: number) {
while (value && depth--) {
value = value._parent;
}
return value;
},
hooks: {},
});
// @ts-expect-error
this.defaultHelperOptions.lookupProperty = container.lookupProperty;
}
render(context: any, options: ExtendedRuntimeOptions = {}): string {
this.scopes = [context];
this.output = [];
this.runtimeOptions = options;
this.container.helpers = Object.assign(this.initialHelpers, options.helpers);
this.container.hooks = {};
if (this.compileOptions.data) {
this.runtimeOptions.data = initData(context, this.runtimeOptions.data);
}
const keepHelperInHelpers = false;
moveHelperToHooks(this.container, 'helperMissing', keepHelperInHelpers);
moveHelperToHooks(this.container, 'blockHelperMissing', keepHelperInHelpers);
if (!this.ast) {
this.ast = Handlebars.parse(this.template!);
}
this.accept(this.ast);
return this.output.join('');
}
// ********************************************** //
// *** Visitor AST Traversal Functions *** //
// ********************************************** //
Program(program: hbs.AST.Program) {
this.blockParamNames.unshift(program.blockParams);
super.Program(program);
this.blockParamNames.shift();
}
MustacheStatement(mustache: hbs.AST.MustacheStatement) {
this.processStatementOrExpression(mustache);
}
BlockStatement(block: hbs.AST.BlockStatement) {
this.processStatementOrExpression(block);
}
SubExpression(sexpr: hbs.AST.SubExpression) {
this.processStatementOrExpression(sexpr);
}
PathExpression(path: hbs.AST.PathExpression) {
const blockParamId =
!path.depth && !AST.helpers.scopedId(path) && this.blockParamIndex(path.parts[0]);
let result;
if (blockParamId) {
result = this.lookupBlockParam(blockParamId, path);
} else if (path.data) {
result = this.lookupData(this.runtimeOptions!.data, path);
} else {
result = this.resolvePath(this.scopes[path.depth], path);
}
this.output.push(result);
}
ContentStatement(content: hbs.AST.ContentStatement) {
this.output.push(content.value);
}
StringLiteral(string: hbs.AST.StringLiteral) {
this.output.push(string.value);
}
NumberLiteral(number: hbs.AST.NumberLiteral) {
this.output.push(number.value);
}
BooleanLiteral(bool: hbs.AST.BooleanLiteral) {
this.output.push(bool.value);
}
UndefinedLiteral() {
this.output.push(undefined);
}
NullLiteral() {
this.output.push(null);
}
// ********************************************** //
// *** Visitor AST Helper Functions *** //
// ********************************************** //
private processStatementOrExpression(node: ProcessableNode) {
transformLiteralToPath(node);
switch (this.classifyNode(node as ProcessableNodeWithPathParts)) {
case kSimple:
this.processSimpleNode(node as ProcessableNodeWithPathParts);
break;
case kHelper:
this.processHelperNode(node as ProcessableNodeWithPathParts);
break;
case kAmbiguous:
this.processAmbiguousNode(node as ProcessableNodeWithPathParts);
break;
}
}
// Liftet from lib/handlebars/compiler/compiler.js (original name: classifySexpr)
private classifyNode(node: { path: hbs.AST.PathExpression }): NodeType {
const isSimple = AST.helpers.simpleId(node.path);
const isBlockParam = isSimple && !!this.blockParamIndex(node.path.parts[0]);
// a mustache is an eligible helper if:
// * its id is simple (a single part, not `this` or `..`)
let isHelper = !isBlockParam && AST.helpers.helperExpression(node);
// if a mustache is an eligible helper but not a definite
// helper, it is ambiguous, and will be resolved in a later
// pass or at runtime.
let isEligible = !isBlockParam && (isHelper || isSimple);
// if ambiguous, we can possibly resolve the ambiguity now
// An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
if (isEligible && !isHelper) {
const name = node.path.parts[0];
const options = this.compileOptions;
if (options.knownHelpers && options.knownHelpers[name]) {
isHelper = true;
} else if (options.knownHelpersOnly) {
isEligible = false;
}
}
if (isHelper) {
return kHelper;
} else if (isEligible) {
return kAmbiguous;
} else {
return kSimple;
}
}
// Liftet from lib/handlebars/compiler/compiler.js
private blockParamIndex(name: string): [number, any] | undefined {
for (let depth = 0, len = this.blockParamNames.length; depth < len; depth++) {
const blockParams = this.blockParamNames[depth];
const param = blockParams && indexOf(blockParams, name);
if (blockParams && param >= 0) {
return [depth, param];
}
}
}
// Looks up the value of `parts` on the given block param and pushes
// it onto the stack.
private lookupBlockParam(blockParamId: [number, any], path: hbs.AST.PathExpression) {
const value = this.blockParamValues[blockParamId[0]][blockParamId[1]];
return this.resolvePath(value, path, 1);
}
// Push the data lookup operator
private lookupData(data: any, path: hbs.AST.PathExpression) {
if (path.depth) {
data = this.container.data(data, path.depth);
}
return this.resolvePath(data, path);
}
private processSimpleNode(node: ProcessableNodeWithPathParts) {
const path = node.path;
// @ts-expect-error strict is not a valid property on PathExpression, but we used in the same way it's also used in the original handlebars
path.strict = true;
const result = this.resolveNodes(path)[0];
const lambdaResult = this.container.lambda(result, this.scopes[0]);
if (isBlock(node)) {
this.blockValue(node, lambdaResult);
} else {
this.output.push(lambdaResult);
}
}
// The purpose of this opcode is to take a block of the form
// `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
// replace it on the stack with the result of properly
// invoking blockHelperMissing.
private blockValue(node: hbs.AST.BlockStatement, value: any) {
const name = node.path.original;
const options = this.setupParams(node, name);
const context = this.scopes[0];
const result = this.container.hooks.blockHelperMissing!.call(context, value, options);
this.output.push(result);
}
private processHelperNode(node: ProcessableNodeWithPathParts) {
const path = node.path;
const name = path.parts[0];
if (this.compileOptions.knownHelpers && this.compileOptions.knownHelpers[name]) {
this.invokeKnownHelper(node);
} else if (this.compileOptions.knownHelpersOnly) {
throw new Handlebars.Exception(
'You specified knownHelpersOnly, but used the unknown helper ' + name,
node
);
} else {
this.invokeHelper(node);
}
}
// This operation is used when the helper is known to exist,
// so a `helperMissing` fallback is not required.
private invokeKnownHelper(node: ProcessableNodeWithPathParts) {
const name = node.path.parts[0];
const helper = this.setupHelper(node, name);
const result = helper.fn.apply(helper.context, helper.params);
this.output.push(result);
}
// Pops off the helper's parameters, invokes the helper,
// and pushes the helper's return value onto the stack.
//
// If the helper is not found, `helperMissing` is called.
private invokeHelper(node: ProcessableNodeWithPathParts) {
const path = node.path;
const name = path.original;
const isSimple = AST.helpers.simpleId(path);
const helper = this.setupHelper(node, name);
const loc = isSimple && helper.fn ? node.loc : path.loc;
helper.fn = (isSimple && helper.fn) || this.resolveNodes(path)[0];
if (!helper.fn) {
if (this.compileOptions.strict) {
helper.fn = this.container.strict(helper.context, name, loc);
} else {
helper.fn = this.container.hooks.helperMissing;
}
}
const result = helper.fn.apply(helper.context, helper.params);
this.output.push(result);
}
private processAmbiguousNode(node: ProcessableNodeWithPathParts) {
const invokeResult = this.invokeAmbiguous(node);
if (isBlock(node)) {
const result = this.ambiguousBlockValue(node, invokeResult);
if (result != null) {
this.output.push(result);
}
} else {
if (
// @ts-expect-error: The `escaped` property is only on MustacheStatement nodes
node.escaped === false ||
this.compileOptions.noEscape === true ||
typeof invokeResult !== 'string'
) {
this.output.push(invokeResult);
} else {
this.output.push(Handlebars.escapeExpression(invokeResult));
}
}
}
// This operation is used when an expression like `{{foo}}`
// is provided, but we don't know at compile-time whether it
// is a helper or a path.
//
// This operation emits more code than the other options,
// and can be avoided by passing the `knownHelpers` and
// `knownHelpersOnly` flags at compile-time.
private invokeAmbiguous(node: ProcessableNodeWithPathParts) {
const name = node.path.parts[0];
const helper = this.setupHelper(node, name);
const loc = helper.fn ? node.loc : node.path.loc;
helper.fn = helper.fn ?? this.resolveNodes(node.path)[0];
if (helper.fn === undefined) {
if (this.compileOptions.strict) {
helper.fn = this.container.strict(helper.context, name, loc);
} else {
helper.fn =
helper.context != null
? this.container.lookupProperty(helper.context, name)
: helper.context;
if (helper.fn == null) helper.fn = this.container.hooks.helperMissing;
}
}
return typeof helper.fn === 'function'
? helper.fn.apply(helper.context, helper.params)
: helper.fn;
}
private ambiguousBlockValue(block: hbs.AST.BlockStatement, value: any) {
const name = block.path.parts[0];
const helper = this.setupHelper(block, name);
if (!helper.fn) {
const context = this.scopes[0];
const options = helper.params[helper.params.length - 1];
value = this.container.hooks.blockHelperMissing!.call(context, value, options);
}
return value;
}
private setupHelper(node: ProcessableNodeWithPathParts, helperName: string) {
return {
fn: this.container.lookupProperty(this.container.helpers, helperName),
context: this.scopes[0],
params: [...this.resolveNodes(node.params), this.setupParams(node, helperName)],
};
}
private setupParams(
node: ProcessableNodeWithPathParts,
helperName: string
): Handlebars.HelperOptions {
const options: Handlebars.HelperOptions = {
// @ts-expect-error: Name should be on there, but the offical types doesn't know this
name: helperName,
hash: this.getHash(node),
data: this.runtimeOptions!.data,
};
if (isBlock(node)) {
const generateProgramFunction = (program: hbs.AST.Program) => {
const prog = (nextContext: any, runtimeOptions: ExtendedRuntimeOptions = {}) => {
// inherit data an blockParams from parent program
runtimeOptions = Object.assign({}, runtimeOptions);
runtimeOptions.data = runtimeOptions.data || this.runtimeOptions!.data;
if (runtimeOptions.blockParams) {
runtimeOptions.blockParams = runtimeOptions.blockParams.concat(
this.runtimeOptions!.blockParams
);
}
// stash parent program data
const tmpRuntimeOptions = this.runtimeOptions;
this.runtimeOptions = runtimeOptions;
const shiftContext = nextContext !== this.scopes[0];
if (shiftContext) this.scopes.unshift(nextContext);
this.blockParamValues.unshift(runtimeOptions.blockParams || []);
// execute child program
const result = this.resolveNodes(program).join('');
// unstash parent program data
this.blockParamValues.shift();
if (shiftContext) this.scopes.shift();
this.runtimeOptions = tmpRuntimeOptions;
// return result of child program
return result;
};
prog.blockParams = node.program?.blockParams?.length ?? 0;
return prog;
};
options.fn = node.program ? generateProgramFunction(node.program) : noop;
options.inverse = node.inverse ? generateProgramFunction(node.inverse) : noop;
}
return Object.assign(options, this.defaultHelperOptions);
}
private getHash(statement: { hash?: hbs.AST.Hash }) {
const result: { [key: string]: any } = {};
if (!statement.hash) return result;
for (const { key, value } of statement.hash.pairs) {
result[key] = this.resolveNodes(value)[0];
}
return result;
}
private resolvePath(obj: any, path: hbs.AST.PathExpression, index = 0) {
if (this.compileOptions.strict || this.compileOptions.assumeObjects) {
return this.strictLookup(obj, path);
}
for (; index < path.parts.length; index++) {
if (obj == null) return;
obj = this.container.lookupProperty(obj, path.parts[index]);
}
return obj;
}
private strictLookup(obj: any, path: hbs.AST.PathExpression) {
// @ts-expect-error strict is not a valid property on PathExpression, but we used in the same way it's also used in the original handlebars
const requireTerminal = this.compileOptions.strict && path.strict;
const len = path.parts.length - (requireTerminal ? 1 : 0);
for (let i = 0; i < len; i++) {
obj = this.container.lookupProperty(obj, path.parts[i]);
}
if (requireTerminal) {
return this.container.strict(obj, path.parts[len], path.loc);
} else {
return obj;
}
}
private resolveNodes(nodes: hbs.AST.Node | hbs.AST.Node[]): any[] {
const currentOutput = this.output;
this.output = [];
if (Array.isArray(nodes)) {
this.acceptArray(nodes);
} else {
this.accept(nodes);
}
const result = this.output;
this.output = currentOutput;
return result;
}
}
// ********************************************** //
// *** Utilily Functions *** //
// ********************************************** //
function isBlock(node: hbs.AST.Node): node is hbs.AST.BlockStatement {
return 'program' in node || 'inverse' in node;
}
function noop() {
return '';
}
// liftet from handlebars lib/handlebars/runtime.js
function initData(context: any, data: any) {
if (!data || !('root' in data)) {
data = data ? createFrame(data) : {};
data.root = context;
}
return data;
}
// liftet from handlebars lib/handlebars/compiler/compiler.js
function transformLiteralToPath(node: { path: hbs.AST.PathExpression | hbs.AST.Literal }) {
const pathIsLiteral = 'parts' in node.path === false;
if (pathIsLiteral) {
const literal = node.path;
// @ts-expect-error: Not all `hbs.AST.Literal` sub-types has an `original` property, but that's ok, in that case we just want `undefined`
const original = literal.original;
// Casting to string here to make false and 0 literal values play nicely with the rest
// of the system.
node.path = {
type: 'PathExpression',
data: false,
depth: 0,
parts: [original + ''],
original: original + '',
loc: literal.loc,
};
}
}
function allowUnsafeEval() {
try {
new Function();
return true;
} catch (e) {
return false;
}
}

View file

@ -0,0 +1,481 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('basic context', () => {
it('most basic', () => {
expectTemplate('{{foo}}').withInput({ foo: 'foo' }).toCompileTo('foo');
});
it('escaping', () => {
expectTemplate('\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('{{foo}}');
expectTemplate('content \\{{foo}}').withInput({ foo: 'food' }).toCompileTo('content {{foo}}');
expectTemplate('\\\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('\\food');
expectTemplate('content \\\\{{foo}}').withInput({ foo: 'food' }).toCompileTo('content \\food');
expectTemplate('\\\\ {{foo}}').withInput({ foo: 'food' }).toCompileTo('\\\\ food');
});
it('compiling with a basic context', () => {
expectTemplate('Goodbye\n{{cruel}}\n{{world}}!')
.withInput({
cruel: 'cruel',
world: 'world',
})
.toCompileTo('Goodbye\ncruel\nworld!');
});
it('compiling with a string context', () => {
expectTemplate('{{.}}{{length}}').withInput('bye').toCompileTo('bye3');
});
it('compiling with an undefined context', () => {
expectTemplate('Goodbye\n{{cruel}}\n{{world.bar}}!')
.withInput(undefined)
.toCompileTo('Goodbye\n\n!');
expectTemplate('{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}')
.withInput(undefined)
.toCompileTo('Goodbye');
});
it('comments', () => {
expectTemplate('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!')
.withInput({
cruel: 'cruel',
world: 'world',
})
.toCompileTo('Goodbye\ncruel\nworld!');
expectTemplate(' {{~! comment ~}} blah').toCompileTo('blah');
expectTemplate(' {{~!-- long-comment --~}} blah').toCompileTo('blah');
expectTemplate(' {{! comment ~}} blah').toCompileTo(' blah');
expectTemplate(' {{!-- long-comment --~}} blah').toCompileTo(' blah');
expectTemplate(' {{~! comment}} blah').toCompileTo(' blah');
expectTemplate(' {{~!-- long-comment --}} blah').toCompileTo(' blah');
});
it('boolean', () => {
const string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbye: true,
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye: false,
world: 'world',
})
.toCompileTo('cruel world!');
});
it('zeros', () => {
expectTemplate('num1: {{num1}}, num2: {{num2}}')
.withInput({
num1: 42,
num2: 0,
})
.toCompileTo('num1: 42, num2: 0');
expectTemplate('num: {{.}}').withInput(0).toCompileTo('num: 0');
expectTemplate('num: {{num1/num2}}')
.withInput({ num1: { num2: 0 } })
.toCompileTo('num: 0');
});
it('false', () => {
/* eslint-disable no-new-wrappers */
expectTemplate('val1: {{val1}}, val2: {{val2}}')
.withInput({
val1: false,
val2: new Boolean(false),
})
.toCompileTo('val1: false, val2: false');
expectTemplate('val: {{.}}').withInput(false).toCompileTo('val: false');
expectTemplate('val: {{val1/val2}}')
.withInput({ val1: { val2: false } })
.toCompileTo('val: false');
expectTemplate('val1: {{{val1}}}, val2: {{{val2}}}')
.withInput({
val1: false,
val2: new Boolean(false),
})
.toCompileTo('val1: false, val2: false');
expectTemplate('val: {{{val1/val2}}}')
.withInput({ val1: { val2: false } })
.toCompileTo('val: false');
/* eslint-enable */
});
it('should handle undefined and null', () => {
expectTemplate('{{awesome undefined null}}')
.withInput({
awesome(_undefined: any, _null: any, options: any) {
return (_undefined === undefined) + ' ' + (_null === null) + ' ' + typeof options;
},
})
.toCompileTo('true true object');
expectTemplate('{{undefined}}')
.withInput({
undefined() {
return 'undefined!';
},
})
.toCompileTo('undefined!');
expectTemplate('{{null}}')
.withInput({
null() {
return 'null!';
},
})
.toCompileTo('null!');
});
it('newlines', () => {
expectTemplate("Alan's\nTest").toCompileTo("Alan's\nTest");
expectTemplate("Alan's\rTest").toCompileTo("Alan's\rTest");
});
it('escaping text', () => {
expectTemplate("Awesome's").toCompileTo("Awesome's");
expectTemplate('Awesome\\').toCompileTo('Awesome\\');
expectTemplate('Awesome\\\\ foo').toCompileTo('Awesome\\\\ foo');
expectTemplate('Awesome {{foo}}').withInput({ foo: '\\' }).toCompileTo('Awesome \\');
expectTemplate(" ' ' ").toCompileTo(" ' ' ");
});
it('escaping expressions', () => {
expectTemplate('{{{awesome}}}').withInput({ awesome: "&'\\<>" }).toCompileTo("&'\\<>");
expectTemplate('{{&awesome}}').withInput({ awesome: "&'\\<>" }).toCompileTo("&'\\<>");
expectTemplate('{{awesome}}')
.withInput({ awesome: '&"\'`\\<>' })
.toCompileTo('&amp;&quot;&#x27;&#x60;\\&lt;&gt;');
expectTemplate('{{awesome}}')
.withInput({ awesome: 'Escaped, <b> looks like: &lt;b&gt;' })
.toCompileTo('Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;gt;');
});
it("functions returning safestrings shouldn't be escaped", () => {
expectTemplate('{{awesome}}')
.withInput({
awesome() {
return new Handlebars.SafeString("&'\\<>");
},
})
.toCompileTo("&'\\<>");
});
it('functions', () => {
expectTemplate('{{awesome}}')
.withInput({
awesome() {
return 'Awesome';
},
})
.toCompileTo('Awesome');
expectTemplate('{{awesome}}')
.withInput({
awesome() {
return this.more;
},
more: 'More awesome',
})
.toCompileTo('More awesome');
});
it('functions with context argument', () => {
expectTemplate('{{awesome frank}}')
.withInput({
awesome(context: any) {
return context;
},
frank: 'Frank',
})
.toCompileTo('Frank');
});
it('pathed functions with context argument', () => {
expectTemplate('{{bar.awesome frank}}')
.withInput({
bar: {
awesome(context: any) {
return context;
},
},
frank: 'Frank',
})
.toCompileTo('Frank');
});
it('depthed functions with context argument', () => {
expectTemplate('{{#with frank}}{{../awesome .}}{{/with}}')
.withInput({
awesome(context: any) {
return context;
},
frank: 'Frank',
})
.toCompileTo('Frank');
});
it('block functions with context argument', () => {
expectTemplate('{{#awesome 1}}inner {{.}}{{/awesome}}')
.withInput({
awesome(context: any, options: any) {
return options.fn(context);
},
})
.toCompileTo('inner 1');
});
it('depthed block functions with context argument', () => {
expectTemplate('{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}')
.withInput({
value: true,
awesome(context: any, options: any) {
return options.fn(context);
},
})
.toCompileTo('inner 1');
});
it('block functions without context argument', () => {
expectTemplate('{{#awesome}}inner{{/awesome}}')
.withInput({
awesome(options: any) {
return options.fn(this);
},
})
.toCompileTo('inner');
});
it('pathed block functions without context argument', () => {
expectTemplate('{{#foo.awesome}}inner{{/foo.awesome}}')
.withInput({
foo: {
awesome() {
return this;
},
},
})
.toCompileTo('inner');
});
it('depthed block functions without context argument', () => {
expectTemplate('{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}')
.withInput({
value: true,
awesome() {
return this;
},
})
.toCompileTo('inner');
});
it('paths with hyphens', () => {
expectTemplate('{{foo-bar}}').withInput({ 'foo-bar': 'baz' }).toCompileTo('baz');
expectTemplate('{{foo.foo-bar}}')
.withInput({ foo: { 'foo-bar': 'baz' } })
.toCompileTo('baz');
expectTemplate('{{foo/foo-bar}}')
.withInput({ foo: { 'foo-bar': 'baz' } })
.toCompileTo('baz');
});
it('nested paths', () => {
expectTemplate('Goodbye {{alan/expression}} world!')
.withInput({ alan: { expression: 'beautiful' } })
.toCompileTo('Goodbye beautiful world!');
});
it('nested paths with empty string value', () => {
expectTemplate('Goodbye {{alan/expression}} world!')
.withInput({ alan: { expression: '' } })
.toCompileTo('Goodbye world!');
});
it('literal paths', () => {
expectTemplate('Goodbye {{[@alan]/expression}} world!')
.withInput({ '@alan': { expression: 'beautiful' } })
.toCompileTo('Goodbye beautiful world!');
expectTemplate('Goodbye {{[foo bar]/expression}} world!')
.withInput({ 'foo bar': { expression: 'beautiful' } })
.toCompileTo('Goodbye beautiful world!');
});
it('literal references', () => {
expectTemplate('Goodbye {{[foo bar]}} world!')
.withInput({ 'foo bar': 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
expectTemplate('Goodbye {{"foo bar"}} world!')
.withInput({ 'foo bar': 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
expectTemplate("Goodbye {{'foo bar'}} world!")
.withInput({ 'foo bar': 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
expectTemplate('Goodbye {{"foo[bar"}} world!')
.withInput({ 'foo[bar': 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
expectTemplate('Goodbye {{"foo\'bar"}} world!')
.withInput({ "foo'bar": 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
expectTemplate("Goodbye {{'foo\"bar'}} world!")
.withInput({ 'foo"bar': 'beautiful' })
.toCompileTo('Goodbye beautiful world!');
});
it("that current context path ({{.}}) doesn't hit helpers", () => {
expectTemplate('test: {{.}}')
.withInput(null)
// @ts-expect-error Setting the helper to a string instead of a function doesn't make sense normally, but here it doesn't matter
.withHelpers({ helper: 'awesome' })
.toCompileTo('test: ');
});
it('complex but empty paths', () => {
expectTemplate('{{person/name}}')
.withInput({ person: { name: null } })
.toCompileTo('');
expectTemplate('{{person/name}}').withInput({ person: {} }).toCompileTo('');
});
it('this keyword in paths', () => {
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}')
.withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] })
.toCompileTo('goodbyeGoodbyeGOODBYE');
expectTemplate('{{#hellos}}{{this/text}}{{/hellos}}')
.withInput({
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
})
.toCompileTo('helloHelloHELLO');
});
it('this keyword nested inside path', () => {
expectTemplate('{{#hellos}}{{text/this/foo}}{{/hellos}}').toThrow(
'Invalid path: text/this - 1:13'
);
expectTemplate('{{[this]}}').withInput({ this: 'bar' }).toCompileTo('bar');
expectTemplate('{{text/[this]}}')
.withInput({ text: { this: 'bar' } })
.toCompileTo('bar');
});
it('this keyword in helpers', () => {
const helpers = {
foo(value: any) {
return 'bar ' + value;
},
};
expectTemplate('{{#goodbyes}}{{foo this}}{{/goodbyes}}')
.withInput({ goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] })
.withHelpers(helpers)
.toCompileTo('bar goodbyebar Goodbyebar GOODBYE');
expectTemplate('{{#hellos}}{{foo this/text}}{{/hellos}}')
.withInput({
hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }],
})
.withHelpers(helpers)
.toCompileTo('bar hellobar Hellobar HELLO');
});
it('this keyword nested inside helpers param', () => {
expectTemplate('{{#hellos}}{{foo text/this/foo}}{{/hellos}}').toThrow(
'Invalid path: text/this - 1:17'
);
expectTemplate('{{foo [this]}}')
.withInput({
foo(value: any) {
return value;
},
this: 'bar',
})
.toCompileTo('bar');
expectTemplate('{{foo text/[this]}}')
.withInput({
foo(value: any) {
return value;
},
text: { this: 'bar' },
})
.toCompileTo('bar');
});
it('pass string literals', () => {
expectTemplate('{{"foo"}}').toCompileTo('');
expectTemplate('{{"foo"}}').withInput({ foo: 'bar' }).toCompileTo('bar');
expectTemplate('{{#"foo"}}{{.}}{{/"foo"}}')
.withInput({
foo: ['bar', 'baz'],
})
.toCompileTo('barbaz');
});
it('pass number literals', () => {
expectTemplate('{{12}}').toCompileTo('');
expectTemplate('{{12}}').withInput({ '12': 'bar' }).toCompileTo('bar');
expectTemplate('{{12.34}}').toCompileTo('');
expectTemplate('{{12.34}}').withInput({ '12.34': 'bar' }).toCompileTo('bar');
expectTemplate('{{12.34 1}}')
.withInput({
'12.34'(arg: any) {
return 'bar' + arg;
},
})
.toCompileTo('bar1');
});
it('pass boolean literals', () => {
expectTemplate('{{true}}').toCompileTo('');
expectTemplate('{{true}}').withInput({ '': 'foo' }).toCompileTo('');
expectTemplate('{{false}}').withInput({ false: 'foo' }).toCompileTo('foo');
});
it('should handle literals in subexpression', () => {
expectTemplate('{{foo (false)}}')
.withInput({
false() {
return 'bar';
},
})
.withHelper('foo', function (arg) {
return arg;
})
.toCompileTo('bar');
});
});

View file

@ -0,0 +1,198 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import { expectTemplate } from '../__jest__/test_bench';
describe('blocks', () => {
it('array', () => {
const string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
expectTemplate(string)
.withInput({
goodbyes: [],
world: 'world',
})
.toCompileTo('cruel world!');
});
it('array without data', () => {
expectTemplate('{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE');
});
it('array with @index', () => {
expectTemplate('{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
});
it('empty block', () => {
const string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('cruel world!');
expectTemplate(string)
.withInput({
goodbyes: [],
world: 'world',
})
.toCompileTo('cruel world!');
});
it('block with complex lookup', () => {
expectTemplate('{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}')
.withInput({
name: 'Alan',
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
})
.toCompileTo('goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ');
});
it('multiple blocks with complex lookup', () => {
expectTemplate('{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}')
.withInput({
name: 'Alan',
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
})
.toCompileTo('AlanAlanAlanAlanAlanAlan');
});
it('block with complex lookup using nested context', () => {
expectTemplate('{{#goodbyes}}{{text}} cruel {{foo/../name}}! {{/goodbyes}}').toThrow(Error);
});
it('block with deep nested complex lookup', () => {
expectTemplate(
'{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}'
)
.withInput({
omg: 'OMG!',
outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }],
})
.toCompileTo('Goodbye cruel sad OMG!');
});
it('works with cached blocks', () => {
expectTemplate('{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}')
.withCompileOptions({ data: false })
.withInput({
person: [
{ first: 'Alan', last: 'Johnson' },
{ first: 'Alan', last: 'Johnson' },
],
})
.toCompileTo('Alan JohnsonAlan Johnson');
});
describe('inverted sections', () => {
it('inverted sections with unset value', () => {
expectTemplate(
'{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}'
).toCompileTo('Right On!');
});
it('inverted section with false value', () => {
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}')
.withInput({ goodbyes: false })
.toCompileTo('Right On!');
});
it('inverted section with empty set', () => {
expectTemplate('{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}')
.withInput({ goodbyes: [] })
.toCompileTo('Right On!');
});
it('block inverted sections', () => {
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
.withInput({ none: 'No people' })
.toCompileTo('No people');
});
it('chained inverted sections', () => {
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}')
.withInput({ none: 'No people' })
.toCompileTo('No people');
expectTemplate(
'{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}'
)
.withInput({ none: 'No people' })
.toCompileTo('No people');
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}')
.withInput({ none: 'No people' })
.toCompileTo('No people');
});
it('chained inverted sections with mismatch', () => {
expectTemplate('{{#people}}{{name}}{{else if none}}{{none}}{{/if}}').toThrow(Error);
});
it('block inverted sections with empty arrays', () => {
expectTemplate('{{#people}}{{name}}{{^}}{{none}}{{/people}}')
.withInput({
none: 'No people',
people: [],
})
.toCompileTo('No people');
});
});
describe('standalone sections', () => {
it('block standalone else sections', () => {
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
.withInput({ none: 'No people' })
.toCompileTo('No people\n');
expectTemplate('{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n')
.withInput({ none: 'No people' })
.toCompileTo('No people\n');
expectTemplate('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n')
.withInput({ none: 'No people' })
.toCompileTo('No people\n');
});
it('block standalone chained else sections', () => {
expectTemplate('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n')
.withInput({ none: 'No people' })
.toCompileTo('No people\n');
expectTemplate('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n')
.withInput({ none: 'No people' })
.toCompileTo('No people\n');
});
it('should handle nesting', () => {
expectTemplate('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.')
.withInput({
data: [1, 3, 5],
})
.toCompileTo('1\n3\n5\nOK.');
});
});
});

View file

@ -0,0 +1,649 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
/* eslint-disable max-classes-per-file */
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('builtin helpers', () => {
describe('#if', () => {
it('if', () => {
const string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbye: true,
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye: 'dummy',
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye: false,
world: 'world',
})
.toCompileTo('cruel world!');
expectTemplate(string).withInput({ world: 'world' }).toCompileTo('cruel world!');
expectTemplate(string)
.withInput({
goodbye: ['foo'],
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye: [],
world: 'world',
})
.toCompileTo('cruel world!');
expectTemplate(string)
.withInput({
goodbye: 0,
world: 'world',
})
.toCompileTo('cruel world!');
expectTemplate('{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!')
.withInput({
goodbye: 0,
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
});
it('if with function argument', () => {
const string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbye() {
return true;
},
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye() {
return this.world;
},
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
expectTemplate(string)
.withInput({
goodbye() {
return false;
},
world: 'world',
})
.toCompileTo('cruel world!');
expectTemplate(string)
.withInput({
goodbye() {
return this.foo;
},
world: 'world',
})
.toCompileTo('cruel world!');
});
it('should not change the depth list', () => {
expectTemplate('{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}')
.withInput({
foo: { goodbye: true },
world: 'world',
})
.toCompileTo('GOODBYE cruel world!');
});
});
describe('#with', () => {
it('with', () => {
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
.withInput({
person: {
first: 'Alan',
last: 'Johnson',
},
})
.toCompileTo('Alan Johnson');
});
it('with with function argument', () => {
expectTemplate('{{#with person}}{{first}} {{last}}{{/with}}')
.withInput({
person() {
return {
first: 'Alan',
last: 'Johnson',
};
},
})
.toCompileTo('Alan Johnson');
});
it('with with else', () => {
expectTemplate(
'{{#with person}}Person is present{{else}}Person is not present{{/with}}'
).toCompileTo('Person is not present');
});
it('with provides block parameter', () => {
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
.withInput({
person: {
first: 'Alan',
last: 'Johnson',
},
})
.toCompileTo('Alan Johnson');
});
it('works when data is disabled', () => {
expectTemplate('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}')
.withInput({ person: { first: 'Alan', last: 'Johnson' } })
.withCompileOptions({ data: false })
.toCompileTo('Alan Johnson');
});
});
describe('#each', () => {
it('each', () => {
const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
expectTemplate(string)
.withInput({
goodbyes: [],
world: 'world',
})
.toCompileTo('cruel world!');
});
it('each without data', () => {
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.withRuntimeOptions({ data: false })
.withCompileOptions({ data: false })
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
expectTemplate('{{#each .}}{{.}}{{/each}}')
.withInput({ goodbyes: 'cruel', world: 'world' })
.withRuntimeOptions({ data: false })
.withCompileOptions({ data: false })
.toCompileTo('cruelworld');
});
it('each without context', () => {
expectTemplate('{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!')
.withInput(undefined)
.toCompileTo('cruel !');
});
it('each with an object and @key', () => {
const string = '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
function Clazz(this: any) {
this['<b>#1</b>'] = { text: 'goodbye' };
this[2] = { text: 'GOODBYE' };
}
Clazz.prototype.foo = 'fail';
const hash = { goodbyes: new (Clazz as any)(), world: 'world' };
// Object property iteration order is undefined according to ECMA spec,
// so we need to check both possible orders
// @see http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop
try {
expectTemplate(string)
.withInput(hash)
.toCompileTo('&lt;b&gt;#1&lt;/b&gt;. goodbye! 2. GOODBYE! cruel world!');
} catch (e) {
expectTemplate(string)
.withInput(hash)
.toCompileTo('2. GOODBYE! &lt;b&gt;#1&lt;/b&gt;. goodbye! cruel world!');
}
expectTemplate(string)
.withInput({
goodbyes: {},
world: 'world',
})
.toCompileTo('cruel world!');
});
it('each with @index', () => {
expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
});
it('each with nested @index', () => {
expectTemplate(
'{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!'
)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo(
'0. goodbye! 0 1 2 After 0 1. Goodbye! 0 1 2 After 1 2. GOODBYE! 0 1 2 After 2 cruel world!'
);
});
it('each with block params', () => {
expectTemplate(
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!'
)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }],
world: 'world',
})
.toCompileTo('0. goodbye! 0 0 0 1 After 0 1. Goodbye! 1 0 1 1 After 1 cruel world!');
});
it('each object with @index', () => {
expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
.withInput({
goodbyes: {
a: { text: 'goodbye' },
b: { text: 'Goodbye' },
c: { text: 'GOODBYE' },
},
world: 'world',
})
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
});
it('each with @first', () => {
expectTemplate('{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('goodbye! cruel world!');
});
it('each with nested @first', () => {
expectTemplate(
'{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!');
});
it('each object with @first', () => {
expectTemplate('{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
.withInput({
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
world: 'world',
})
.toCompileTo('goodbye! cruel world!');
});
it('each with @last', () => {
expectTemplate('{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('GOODBYE! cruel world!');
});
it('each object with @last', () => {
expectTemplate('{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!')
.withInput({
goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
world: 'world',
})
.toCompileTo('Goodbye! cruel world!');
});
it('each with nested @last', () => {
expectTemplate(
'{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!'
)
.withInput({
goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
world: 'world',
})
.toCompileTo('(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!');
});
it('each with function argument', () => {
const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbyes() {
return [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }];
},
world: 'world',
})
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
expectTemplate(string)
.withInput({
goodbyes: [],
world: 'world',
})
.toCompileTo('cruel world!');
});
it('each object when last key is an empty string', () => {
expectTemplate('{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!')
.withInput({
goodbyes: {
a: { text: 'goodbye' },
b: { text: 'Goodbye' },
'': { text: 'GOODBYE' },
},
world: 'world',
})
.toCompileTo('0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!');
});
it('data passed to helpers', () => {
expectTemplate('{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}')
.withInput({ letters: ['a', 'b', 'c'] })
.withHelper('detectDataInsideEach', function (options) {
return options.data && options.data.exclaim;
})
.withRuntimeOptions({
data: {
exclaim: '!',
},
})
.toCompileTo('a!b!c!');
});
it('each on implicit context', () => {
expectTemplate('{{#each}}{{text}}! {{/each}}cruel world!').toThrow(Handlebars.Exception);
});
it('each on iterable', () => {
class Iterator {
private arr: any[];
private index: number = 0;
constructor(arr: any[]) {
this.arr = arr;
}
next() {
const value = this.arr[this.index];
const done = this.index === this.arr.length;
if (!done) {
this.index++;
}
return { value, done };
}
}
class Iterable {
private arr: any[];
constructor(arr: any[]) {
this.arr = arr;
}
[Symbol.iterator]() {
return new Iterator(this.arr);
}
}
const string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
expectTemplate(string)
.withInput({
goodbyes: new Iterable([{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }]),
world: 'world',
})
.toCompileTo('goodbye! Goodbye! GOODBYE! cruel world!');
expectTemplate(string)
.withInput({
goodbyes: new Iterable([]),
world: 'world',
})
.toCompileTo('cruel world!');
});
});
describe('#log', function () {
/* eslint-disable no-console */
let $log: typeof console.log;
let $info: typeof console.info;
let $error: typeof console.error;
beforeEach(function () {
$log = console.log;
$info = console.info;
$error = console.error;
global.kbnHandlebarsEnv = Handlebars.create();
});
afterEach(function () {
console.log = $log;
console.info = $info;
console.error = $error;
});
it('should call logger at default level', function () {
let levelArg;
let logArg;
kbnHandlebarsEnv!.log = function (level, arg) {
levelArg = level;
logArg = arg;
};
expectTemplate('{{log blah}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(1).toEqual(levelArg);
expect('whee').toEqual(logArg);
});
it('should call logger at data level', function () {
let levelArg;
let logArg;
kbnHandlebarsEnv!.log = function (level, arg) {
levelArg = level;
logArg = arg;
};
expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' })
.withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true })
.toCompileTo('');
expect('03').toEqual(levelArg);
expect('whee').toEqual(logArg);
});
it('should output to info', function () {
let called;
console.info = function (info) {
expect('whee').toEqual(info);
called = true;
console.info = $info;
console.log = $log;
};
console.log = function (log) {
expect('whee').toEqual(log);
called = true;
console.info = $info;
console.log = $log;
};
expectTemplate('{{log blah}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(true).toEqual(called);
});
it('should log at data level', function () {
let called;
console.error = function (log) {
expect('whee').toEqual(log);
called = true;
console.error = $error;
};
expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' })
.withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true })
.toCompileTo('');
expect(true).toEqual(called);
});
it('should handle missing logger', function () {
let called = false;
// @ts-expect-error
console.error = undefined;
console.log = function (log) {
expect('whee').toEqual(log);
called = true;
console.log = $log;
};
expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' })
.withRuntimeOptions({ data: { level: '03' } })
.withCompileOptions({ data: true })
.toCompileTo('');
expect(true).toEqual(called);
});
it('should handle string log levels', function () {
let called;
console.error = function (log) {
expect('whee').toEqual(log);
called = true;
};
expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' })
.withRuntimeOptions({ data: { level: 'error' } })
.withCompileOptions({ data: true })
.toCompileTo('');
expect(true).toEqual(called);
called = false;
expectTemplate('{{log blah}}')
.withInput({ blah: 'whee' })
.withRuntimeOptions({ data: { level: 'ERROR' } })
.withCompileOptions({ data: true })
.toCompileTo('');
expect(true).toEqual(called);
});
it('should handle hash log levels [1]', function () {
let called;
console.error = function (log) {
expect('whee').toEqual(log);
called = true;
};
expectTemplate('{{log blah level="error"}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(true).toEqual(called);
});
it('should handle hash log levels [2]', function () {
let called = false;
console.info =
console.log =
console.error =
console.debug =
function () {
called = true;
console.info = console.log = console.error = console.debug = $log;
};
expectTemplate('{{log blah level="debug"}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(false).toEqual(called);
});
it('should pass multiple log arguments', function () {
let called;
console.info = console.log = function (log1, log2, log3) {
expect('whee').toEqual(log1);
expect('foo').toEqual(log2);
expect(1).toEqual(log3);
called = true;
console.log = $log;
};
expectTemplate('{{log blah "foo" 1}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(true).toEqual(called);
});
it('should pass zero log arguments', function () {
let called;
console.info = console.log = function () {
expect(arguments.length).toEqual(0);
called = true;
console.log = $log;
};
expectTemplate('{{log}}').withInput({ blah: 'whee' }).toCompileTo('');
expect(called).toEqual(true);
});
/* eslint-enable no-console */
});
describe('#lookup', () => {
it('should lookup arbitrary content', () => {
expectTemplate('{{#each goodbyes}}{{lookup ../data .}}{{/each}}')
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
.toCompileTo('foobar');
});
it('should not fail on undefined value', () => {
expectTemplate('{{#each goodbyes}}{{lookup ../bar .}}{{/each}}')
.withInput({ goodbyes: [0, 1], data: ['foo', 'bar'] })
.toCompileTo('');
});
});
});

View file

@ -0,0 +1,89 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
describe('compiler', () => {
const compileFns = ['compile', 'compileAST'];
if (process.env.AST) compileFns.splice(0, 1);
else if (process.env.EVAL) compileFns.splice(1, 1);
compileFns.forEach((compileName) => {
// @ts-expect-error
const compile = Handlebars[compileName];
describe(`#${compileName}`, () => {
it('should fail with invalid input', () => {
expect(function () {
compile(null);
}).toThrow(
`You must pass a string or Handlebars AST to Handlebars.${compileName}. You passed null`
);
expect(function () {
compile({});
}).toThrow(
`You must pass a string or Handlebars AST to Handlebars.${compileName}. You passed [object Object]`
);
});
it('should include the location in the error (row and column)', () => {
try {
compile(' \n {{#if}}\n{{/def}}')({});
expect(true).toEqual(false);
} catch (err) {
expect(err.message).toEqual("if doesn't match def - 2:5");
if (Object.getOwnPropertyDescriptor(err, 'column')!.writable) {
// In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty,
// its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482)
// Since this was neither working in Handlebars 3 nor in 4.0.5, we only check the column for other browsers.
expect(err.column).toEqual(5);
}
expect(err.lineNumber).toEqual(2);
}
});
it('should include the location as enumerable property', () => {
try {
compile(' \n {{#if}}\n{{/def}}')({});
expect(true).toEqual(false);
} catch (err) {
expect(Object.prototype.propertyIsEnumerable.call(err, 'column')).toEqual(true);
}
});
it('can utilize AST instance', () => {
expect(
compile({
type: 'Program',
body: [{ type: 'ContentStatement', value: 'Hello' }],
})({})
).toEqual('Hello');
});
it('can pass through an empty string', () => {
expect(compile('')({})).toEqual('');
});
it('should not modify the options.data property(GH-1327)', () => {
const options = { data: [{ a: 'foo' }, { a: 'bar' }] };
compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)({});
expect(JSON.stringify(options, null, 2)).toEqual(
JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, null, 2)
);
});
it('should not modify the options.knownHelpers property(GH-1327)', () => {
const options = { knownHelpers: {} };
compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)({});
expect(JSON.stringify(options, null, 2)).toEqual(
JSON.stringify({ knownHelpers: {} }, null, 2)
);
});
});
});
});

View file

@ -0,0 +1,255 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('data', () => {
it('passing in data to a compiled function that expects data - works with helpers', () => {
expectTemplate('{{hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (this: any, options) {
return options.data.adjective + ' ' + this.noun;
})
.withRuntimeOptions({ data: { adjective: 'happy' } })
.withInput({ noun: 'cat' })
.toCompileTo('happy cat');
});
it('data can be looked up via @foo', () => {
expectTemplate('{{@hello}}')
.withRuntimeOptions({ data: { hello: 'hello' } })
.toCompileTo('hello');
});
it('deep @foo triggers automatic top-level data', () => {
global.kbnHandlebarsEnv = Handlebars.create();
const helpers = Handlebars.createFrame(kbnHandlebarsEnv!.helpers);
helpers.let = function (options: Handlebars.HelperOptions) {
const frame = Handlebars.createFrame(options.data);
for (const prop in options.hash) {
if (prop in options.hash) {
frame[prop] = options.hash[prop];
}
}
return options.fn(this, { data: frame });
};
expectTemplate(
'{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}'
)
.withInput({ foo: true })
.withHelpers(helpers)
.toCompileTo('Hello world');
});
it('parameter data can be looked up via @foo', () => {
expectTemplate('{{hello @world}}')
.withRuntimeOptions({ data: { world: 'world' } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.toCompileTo('Hello world');
});
it('hash values can be looked up via @foo', () => {
expectTemplate('{{hello noun=@world}}')
.withRuntimeOptions({ data: { world: 'world' } })
.withHelper('hello', function (options) {
return 'Hello ' + options.hash.noun;
})
.toCompileTo('Hello world');
});
it('nested parameter data can be looked up via @foo.bar', () => {
expectTemplate('{{hello @world.bar}}')
.withRuntimeOptions({ data: { world: { bar: 'world' } } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.toCompileTo('Hello world');
});
it('nested parameter data does not fail with @world.bar', () => {
expectTemplate('{{hello @world.bar}}')
.withRuntimeOptions({ data: { foo: { bar: 'world' } } })
.withHelper('hello', function (noun) {
return 'Hello ' + noun;
})
.toCompileTo('Hello undefined');
});
it('parameter data throws when using complex scope references', () => {
expectTemplate('{{#goodbyes}}{{text}} cruel {{@foo/../name}}! {{/goodbyes}}').toThrow(Error);
});
it('data can be functions', () => {
expectTemplate('{{@hello}}')
.withRuntimeOptions({
data: {
hello() {
return 'hello';
},
},
})
.toCompileTo('hello');
});
it('data can be functions with params', () => {
expectTemplate('{{@hello "hello"}}')
.withRuntimeOptions({
data: {
hello(arg: any) {
return arg;
},
},
})
.toCompileTo('hello');
});
it('data is inherited downstream', () => {
expectTemplate(
'{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}'
)
.withInput({ bar: { baz: 'hello world' } })
.withCompileOptions({ data: true })
.withHelper('let', function (this: any, options) {
const frame = Handlebars.createFrame(options.data);
for (const prop in options.hash) {
if (prop in options.hash) {
frame[prop] = options.hash[prop];
}
}
return options.fn(this, { data: frame });
})
.withRuntimeOptions({ data: {} })
.toCompileTo('2hello world1');
});
it('passing in data to a compiled function that expects data - works with helpers and parameters', () => {
expectTemplate('{{hello world}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (this: any, noun, options) {
return options.data.adjective + ' ' + noun + (this.exclaim ? '!' : '');
})
.withInput({ exclaim: true, world: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.toCompileTo('happy world!');
});
it('passing in data to a compiled function that expects data - works with block helpers', () => {
expectTemplate('{{#hello}}{{world}}{{/hello}}')
.withCompileOptions({
data: true,
})
.withHelper('hello', function (this: any, options) {
return options.fn(this);
})
.withHelper('world', function (this: any, options) {
return options.data.adjective + ' world' + (this.exclaim ? '!' : '');
})
.withInput({ exclaim: true })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.toCompileTo('happy world!');
});
it('passing in data to a compiled function that expects data - works with block helpers that use ..', () => {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn({ exclaim: '?' });
})
.withHelper('world', function (this: any, thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.toCompileTo('happy world?');
});
it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', () => {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
})
.withHelper('world', function (this: any, thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy', accessData: '#win' } })
.toCompileTo('#win happy world?');
});
it('you can override inherited data when invoking a helper', () => {
expectTemplate('{{#hello}}{{world zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn({ exclaim: '?', zomg: 'world' }, { data: { adjective: 'sad' } });
})
.withHelper('world', function (this: any, thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'planet' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.toCompileTo('sad world?');
});
it('you can override inherited data when invoking a helper with depth', () => {
expectTemplate('{{#hello}}{{world ../zomg}}{{/hello}}')
.withCompileOptions({ data: true })
.withHelper('hello', function (options) {
return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
})
.withHelper('world', function (this: any, thing, options) {
return options.data.adjective + ' ' + thing + (this.exclaim || '');
})
.withInput({ exclaim: true, zomg: 'world' })
.withRuntimeOptions({ data: { adjective: 'happy' } })
.toCompileTo('sad world?');
});
describe('@root', () => {
it('the root context can be looked up via @root', () => {
expectTemplate('{{@root.foo}}')
.withInput({ foo: 'hello' })
.withRuntimeOptions({ data: {} })
.toCompileTo('hello');
expectTemplate('{{@root.foo}}').withInput({ foo: 'hello' }).toCompileTo('hello');
});
it('passed root values take priority', () => {
expectTemplate('{{@root.foo}}')
.withInput({ foo: 'should not be used' })
.withRuntimeOptions({ data: { root: { foo: 'hello' } } })
.toCompileTo('hello');
});
});
describe('nesting', () => {
it('the root context can be looked up via @root', () => {
expectTemplate(
'{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
)
.withInput({ foo: 'hello' })
.withHelper('helper', function (this: any, options) {
const frame = Handlebars.createFrame(options.data);
frame.depth = options.data.depth + 1;
return options.fn(this, { data: frame });
})
.withRuntimeOptions({
data: {
depth: 0,
},
})
.toCompileTo('2 1 0');
});
});
});

View file

@ -0,0 +1,954 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
beforeEach(() => {
global.kbnHandlebarsEnv = Handlebars.create();
});
describe('helpers', () => {
it('helper with complex lookup$', () => {
expectTemplate('{{#goodbyes}}{{{link ../prefix}}}{{/goodbyes}}')
.withInput({
prefix: '/root',
goodbyes: [{ text: 'Goodbye', url: 'goodbye' }],
})
.withHelper('link', function (this: any, prefix) {
return '<a href="' + prefix + '/' + this.url + '">' + this.text + '</a>';
})
.toCompileTo('<a href="/root/goodbye">Goodbye</a>');
});
it('helper for raw block gets raw content', () => {
expectTemplate('{{{{raw}}}} {{test}} {{{{/raw}}}}')
.withInput({ test: 'hello' })
.withHelper('raw', function (options) {
return options.fn();
})
.toCompileTo(' {{test}} ');
});
it('helper for raw block gets parameters', () => {
expectTemplate('{{{{raw 1 2 3}}}} {{test}} {{{{/raw}}}}')
.withInput({ test: 'hello' })
.withHelper('raw', function (a, b, c, options) {
const ret = options.fn() + a + b + c;
return ret;
})
.toCompileTo(' {{test}} 123');
});
describe('raw block parsing (with identity helper-function)', () => {
function runWithIdentityHelper(template: string, expected: string) {
expectTemplate(template)
.withHelper('identity', function (options) {
return options.fn();
})
.toCompileTo(expected);
}
it('helper for nested raw block gets raw content', () => {
runWithIdentityHelper(
'{{{{identity}}}} {{{{b}}}} {{{{/b}}}} {{{{/identity}}}}',
' {{{{b}}}} {{{{/b}}}} '
);
});
it('helper for nested raw block works with empty content', () => {
runWithIdentityHelper('{{{{identity}}}}{{{{/identity}}}}', '');
});
it.skip('helper for nested raw block works if nested raw blocks are broken', () => {
// This test was introduced in 4.4.4, but it was not the actual problem that lead to the patch release
// The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3
// If anyone can make this template work without breaking everything else, then go for it,
// but for now, this is just a known bug, that will be documented.
runWithIdentityHelper(
'{{{{identity}}}} {{{{a}}}} {{{{ {{{{/ }}}} }}}} {{{{/identity}}}}',
' {{{{a}}}} {{{{ {{{{/ }}}} }}}} '
);
});
it('helper for nested raw block closes after first matching close', () => {
runWithIdentityHelper(
'{{{{identity}}}}abc{{{{/identity}}}} {{{{identity}}}}abc{{{{/identity}}}}',
'abc abc'
);
});
it('helper for nested raw block throw exception when with missing closing braces', () => {
const string = '{{{{a}}}} {{{{/a';
expectTemplate(string).toThrow();
});
});
it('helper block with identical context', () => {
expectTemplate('{{#goodbyes}}{{name}}{{/goodbyes}}')
.withInput({ name: 'Alan' })
.withHelper('goodbyes', function (this: any, options) {
let out = '';
const byes = ['Goodbye', 'goodbye', 'GOODBYE'];
for (let i = 0, j = byes.length; i < j; i++) {
out += byes[i] + ' ' + options.fn(this) + '! ';
}
return out;
})
.toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! ');
});
it('helper block with complex lookup expression', () => {
expectTemplate('{{#goodbyes}}{{../name}}{{/goodbyes}}')
.withInput({ name: 'Alan' })
.withHelper('goodbyes', function (options) {
let out = '';
const byes = ['Goodbye', 'goodbye', 'GOODBYE'];
for (let i = 0, j = byes.length; i < j; i++) {
out += byes[i] + ' ' + options.fn({}) + '! ';
}
return out;
})
.toCompileTo('Goodbye Alan! goodbye Alan! GOODBYE Alan! ');
});
it('helper with complex lookup and nested template', () => {
expectTemplate('{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}')
.withInput({
prefix: '/root',
goodbyes: [{ text: 'Goodbye', url: 'goodbye' }],
})
.withHelper('link', function (this: any, prefix, options) {
return '<a href="' + prefix + '/' + this.url + '">' + options.fn(this) + '</a>';
})
.toCompileTo('<a href="/root/goodbye">Goodbye</a>');
});
it('helper with complex lookup and nested template in VM+Compiler', () => {
expectTemplate('{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}')
.withInput({
prefix: '/root',
goodbyes: [{ text: 'Goodbye', url: 'goodbye' }],
})
.withHelper('link', function (this: any, prefix, options) {
return '<a href="' + prefix + '/' + this.url + '">' + options.fn(this) + '</a>';
})
.toCompileTo('<a href="/root/goodbye">Goodbye</a>');
});
it('helper returning undefined value', () => {
expectTemplate(' {{nothere}}')
.withHelpers({
nothere() {},
})
.toCompileTo(' ');
expectTemplate(' {{#nothere}}{{/nothere}}')
.withHelpers({
nothere() {},
})
.toCompileTo(' ');
});
it('block helper', () => {
expectTemplate('{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!')
.withInput({ world: 'world' })
.withHelper('goodbyes', function (options) {
return options.fn({ text: 'GOODBYE' });
})
.toCompileTo('GOODBYE! cruel world!');
});
it('block helper staying in the same context', () => {
expectTemplate('{{#form}}<p>{{name}}</p>{{/form}}')
.withInput({ name: 'Yehuda' })
.withHelper('form', function (this: any, options) {
return '<form>' + options.fn(this) + '</form>';
})
.toCompileTo('<form><p>Yehuda</p></form>');
});
it('block helper should have context in this', () => {
function link(this: any, options: Handlebars.HelperOptions) {
return '<a href="/people/' + this.id + '">' + options.fn(this) + '</a>';
}
expectTemplate('<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>')
.withInput({
people: [
{ name: 'Alan', id: 1 },
{ name: 'Yehuda', id: 2 },
],
})
.withHelper('link', link)
.toCompileTo(
'<ul><li><a href="/people/1">Alan</a></li><li><a href="/people/2">Yehuda</a></li></ul>'
);
});
it('block helper for undefined value', () => {
expectTemplate("{{#empty}}shouldn't render{{/empty}}").toCompileTo('');
});
it('block helper passing a new context', () => {
expectTemplate('{{#form yehuda}}<p>{{name}}</p>{{/form}}')
.withInput({ yehuda: { name: 'Yehuda' } })
.withHelper('form', function (context, options) {
return '<form>' + options.fn(context) + '</form>';
})
.toCompileTo('<form><p>Yehuda</p></form>');
});
it('block helper passing a complex path context', () => {
expectTemplate('{{#form yehuda/cat}}<p>{{name}}</p>{{/form}}')
.withInput({ yehuda: { name: 'Yehuda', cat: { name: 'Harold' } } })
.withHelper('form', function (context, options) {
return '<form>' + options.fn(context) + '</form>';
})
.toCompileTo('<form><p>Harold</p></form>');
});
it('nested block helpers', () => {
expectTemplate('{{#form yehuda}}<p>{{name}}</p>{{#link}}Hello{{/link}}{{/form}}')
.withInput({
yehuda: { name: 'Yehuda' },
})
.withHelper('link', function (this: any, options) {
return '<a href="' + this.name + '">' + options.fn(this) + '</a>';
})
.withHelper('form', function (context, options) {
return '<form>' + options.fn(context) + '</form>';
})
.toCompileTo('<form><p>Yehuda</p><a href="Yehuda">Hello</a></form>');
});
it('block helper inverted sections', () => {
const string = "{{#list people}}{{name}}{{^}}<em>Nobody's here</em>{{/list}}";
function list(this: any, context: any, options: Handlebars.HelperOptions) {
if (context.length > 0) {
let out = '<ul>';
for (let i = 0, j = context.length; i < j; i++) {
out += '<li>';
out += options.fn(context[i]);
out += '</li>';
}
out += '</ul>';
return out;
} else {
return '<p>' + options.inverse(this) + '</p>';
}
}
// the meaning here may be kind of hard to catch, but list.not is always called,
// so we should see the output of both
expectTemplate(string)
.withInput({ people: [{ name: 'Alan' }, { name: 'Yehuda' }] })
.withHelpers({ list })
.toCompileTo('<ul><li>Alan</li><li>Yehuda</li></ul>');
expectTemplate(string)
.withInput({ people: [] })
.withHelpers({ list })
.toCompileTo("<p><em>Nobody's here</em></p>");
expectTemplate('{{#list people}}Hello{{^}}{{message}}{{/list}}')
.withInput({
people: [],
message: "Nobody's here",
})
.withHelpers({ list })
.toCompileTo('<p>Nobody&#x27;s here</p>');
});
it('pathed lambas with parameters', () => {
const hash = {
helper: () => 'winning',
};
// @ts-expect-error
hash.hash = hash;
const helpers = {
'./helper': () => 'fail',
};
expectTemplate('{{./helper 1}}').withInput(hash).withHelpers(helpers).toCompileTo('winning');
expectTemplate('{{hash/helper 1}}').withInput(hash).withHelpers(helpers).toCompileTo('winning');
});
describe('helpers hash', () => {
it('providing a helpers hash', () => {
expectTemplate('Goodbye {{cruel}} {{world}}!')
.withInput({ cruel: 'cruel' })
.withHelpers({
world() {
return 'world';
},
})
.toCompileTo('Goodbye cruel world!');
expectTemplate('Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!')
.withInput({ iter: [{ cruel: 'cruel' }] })
.withHelpers({
world() {
return 'world';
},
})
.toCompileTo('Goodbye cruel world!');
});
it('in cases of conflict, helpers win', () => {
expectTemplate('{{{lookup}}}')
.withInput({ lookup: 'Explicit' })
.withHelpers({
lookup() {
return 'helpers';
},
})
.toCompileTo('helpers');
expectTemplate('{{lookup}}')
.withInput({ lookup: 'Explicit' })
.withHelpers({
lookup() {
return 'helpers';
},
})
.toCompileTo('helpers');
});
it('the helpers hash is available is nested contexts', () => {
expectTemplate('{{#outer}}{{#inner}}{{helper}}{{/inner}}{{/outer}}')
.withInput({ outer: { inner: { unused: [] } } })
.withHelpers({
helper() {
return 'helper';
},
})
.toCompileTo('helper');
});
it('the helper hash should augment the global hash', () => {
kbnHandlebarsEnv!.registerHelper('test_helper', function () {
return 'found it!';
});
expectTemplate('{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}')
.withInput({ cruel: 'cruel' })
.withHelpers({
world() {
return 'world!';
},
})
.toCompileTo('found it! Goodbye cruel world!!');
});
});
describe('registration', () => {
it('unregisters', () => {
deleteAllKeys(kbnHandlebarsEnv!.helpers);
kbnHandlebarsEnv!.registerHelper('foo', function () {
return 'fail';
});
expect(kbnHandlebarsEnv!.helpers.foo).toBeDefined();
kbnHandlebarsEnv!.unregisterHelper('foo');
expect(kbnHandlebarsEnv!.helpers.foo).toBeUndefined();
});
it('allows multiple globals', () => {
const ifHelper = kbnHandlebarsEnv!.helpers.if;
deleteAllKeys(kbnHandlebarsEnv!.helpers);
kbnHandlebarsEnv!.registerHelper({
if: ifHelper,
world() {
return 'world!';
},
testHelper() {
return 'found it!';
},
});
expectTemplate('{{testHelper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}')
.withInput({ cruel: 'cruel' })
.toCompileTo('found it! Goodbye cruel world!!');
});
it('fails with multiple and args', () => {
expect(() => {
kbnHandlebarsEnv!.registerHelper(
// @ts-expect-error TypeScript is complaining about the invalid input just as the thrown error
{
world() {
return 'world!';
},
testHelper() {
return 'found it!';
},
},
{}
);
}).toThrow('Arg not supported with multiple helpers');
});
});
it('decimal number literals work', () => {
expectTemplate('Message: {{hello -1.2 1.2}}')
.withHelper('hello', function (times, times2) {
if (typeof times !== 'number') {
times = 'NaN';
}
if (typeof times2 !== 'number') {
times2 = 'NaN';
}
return 'Hello ' + times + ' ' + times2 + ' times';
})
.toCompileTo('Message: Hello -1.2 1.2 times');
});
it('negative number literals work', () => {
expectTemplate('Message: {{hello -12}}')
.withHelper('hello', function (times) {
if (typeof times !== 'number') {
times = 'NaN';
}
return 'Hello ' + times + ' times';
})
.toCompileTo('Message: Hello -12 times');
});
describe('String literal parameters', () => {
it('simple literals work', () => {
expectTemplate('Message: {{hello "world" 12 true false}}')
.withHelper('hello', function (param, times, bool1, bool2) {
if (typeof times !== 'number') {
times = 'NaN';
}
if (typeof bool1 !== 'boolean') {
bool1 = 'NaB';
}
if (typeof bool2 !== 'boolean') {
bool2 = 'NaB';
}
return 'Hello ' + param + ' ' + times + ' times: ' + bool1 + ' ' + bool2;
})
.toCompileTo('Message: Hello world 12 times: true false');
});
it('using a quote in the middle of a parameter raises an error', () => {
expectTemplate('Message: {{hello wo"rld"}}').toThrow(Error);
});
it('escaping a String is possible', () => {
expectTemplate('Message: {{{hello "\\"world\\""}}}')
.withHelper('hello', function (param) {
return 'Hello ' + param;
})
.toCompileTo('Message: Hello "world"');
});
it("it works with ' marks", () => {
expectTemplate('Message: {{{hello "Alan\'s world"}}}')
.withHelper('hello', function (param) {
return 'Hello ' + param;
})
.toCompileTo("Message: Hello Alan's world");
});
});
describe('multiple parameters', () => {
it('simple multi-params work', () => {
expectTemplate('Message: {{goodbye cruel world}}')
.withInput({ cruel: 'cruel', world: 'world' })
.withHelper('goodbye', function (cruel, world) {
return 'Goodbye ' + cruel + ' ' + world;
})
.toCompileTo('Message: Goodbye cruel world');
});
it('block multi-params work', () => {
expectTemplate('Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}')
.withInput({ cruel: 'cruel', world: 'world' })
.withHelper('goodbye', function (cruel, world, options) {
return options.fn({ greeting: 'Goodbye', adj: cruel, noun: world });
})
.toCompileTo('Message: Goodbye cruel world');
});
});
describe('hash', () => {
it('helpers can take an optional hash', () => {
expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" times=12}}')
.withHelper('goodbye', function (options) {
return (
'GOODBYE ' +
options.hash.cruel +
' ' +
options.hash.world +
' ' +
options.hash.times +
' TIMES'
);
})
.toCompileTo('GOODBYE CRUEL WORLD 12 TIMES');
});
it('helpers can take an optional hash with booleans', () => {
function goodbye(options: Handlebars.HelperOptions) {
if (options.hash.print === true) {
return 'GOODBYE ' + options.hash.cruel + ' ' + options.hash.world;
} else if (options.hash.print === false) {
return 'NOT PRINTING';
} else {
return 'THIS SHOULD NOT HAPPEN';
}
}
expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" print=true}}')
.withHelper('goodbye', goodbye)
.toCompileTo('GOODBYE CRUEL WORLD');
expectTemplate('{{goodbye cruel="CRUEL" world="WORLD" print=false}}')
.withHelper('goodbye', goodbye)
.toCompileTo('NOT PRINTING');
});
it('block helpers can take an optional hash', () => {
expectTemplate('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}')
.withHelper('goodbye', function (this: any, options) {
return (
'GOODBYE ' +
options.hash.cruel +
' ' +
options.fn(this) +
' ' +
options.hash.times +
' TIMES'
);
})
.toCompileTo('GOODBYE CRUEL world 12 TIMES');
});
it('block helpers can take an optional hash with single quoted stings', () => {
expectTemplate('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}')
.withHelper('goodbye', function (this: any, options) {
return (
'GOODBYE ' +
options.hash.cruel +
' ' +
options.fn(this) +
' ' +
options.hash.times +
' TIMES'
);
})
.toCompileTo('GOODBYE CRUEL world 12 TIMES');
});
it('block helpers can take an optional hash with booleans', () => {
function goodbye(this: any, options: Handlebars.HelperOptions) {
if (options.hash.print === true) {
return 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this);
} else if (options.hash.print === false) {
return 'NOT PRINTING';
} else {
return 'THIS SHOULD NOT HAPPEN';
}
}
expectTemplate('{{#goodbye cruel="CRUEL" print=true}}world{{/goodbye}}')
.withHelper('goodbye', goodbye)
.toCompileTo('GOODBYE CRUEL world');
expectTemplate('{{#goodbye cruel="CRUEL" print=false}}world{{/goodbye}}')
.withHelper('goodbye', goodbye)
.toCompileTo('NOT PRINTING');
});
});
describe('helperMissing', () => {
it('if a context is not found, helperMissing is used', () => {
expectTemplate('{{hello}} {{link_to world}}').toThrow(/Missing helper: "link_to"/);
});
it('if a context is not found, custom helperMissing is used', () => {
expectTemplate('{{hello}} {{link_to world}}')
.withInput({ hello: 'Hello', world: 'world' })
.withHelper('helperMissing', function (mesg, options) {
if (options.name === 'link_to') {
return new Handlebars.SafeString('<a>' + mesg + '</a>');
}
})
.toCompileTo('Hello <a>world</a>');
});
it('if a value is not found, custom helperMissing is used', () => {
expectTemplate('{{hello}} {{link_to}}')
.withInput({ hello: 'Hello', world: 'world' })
.withHelper('helperMissing', function (options) {
if (options.name === 'link_to') {
return new Handlebars.SafeString('<a>winning</a>');
}
})
.toCompileTo('Hello <a>winning</a>');
});
});
describe('knownHelpers', () => {
it('Known helper should render helper', () => {
expectTemplate('{{hello}}')
.withCompileOptions({
knownHelpers: { hello: true },
})
.withHelper('hello', function () {
return 'foo';
})
.toCompileTo('foo');
});
it('Unknown helper in knownHelpers only mode should be passed as undefined', () => {
expectTemplate('{{typeof hello}}')
.withCompileOptions({
knownHelpers: { typeof: true },
knownHelpersOnly: true,
})
.withHelper('typeof', function (arg) {
return typeof arg;
})
.withHelper('hello', function () {
return 'foo';
})
.toCompileTo('undefined');
});
it('Builtin helpers available in knownHelpers only mode', () => {
expectTemplate('{{#unless foo}}bar{{/unless}}')
.withCompileOptions({
knownHelpersOnly: true,
})
.toCompileTo('bar');
});
it('Field lookup works in knownHelpers only mode', () => {
expectTemplate('{{foo}}')
.withCompileOptions({
knownHelpersOnly: true,
})
.withInput({ foo: 'bar' })
.toCompileTo('bar');
});
it('Conditional blocks work in knownHelpers only mode', () => {
expectTemplate('{{#foo}}bar{{/foo}}')
.withCompileOptions({
knownHelpersOnly: true,
})
.withInput({ foo: 'baz' })
.toCompileTo('bar');
});
it('Invert blocks work in knownHelpers only mode', () => {
expectTemplate('{{^foo}}bar{{/foo}}')
.withCompileOptions({
knownHelpersOnly: true,
})
.withInput({ foo: false })
.toCompileTo('bar');
});
it('Functions are bound to the context in knownHelpers only mode', () => {
expectTemplate('{{foo}}')
.withCompileOptions({
knownHelpersOnly: true,
})
.withInput({
foo() {
return this.bar;
},
bar: 'bar',
})
.toCompileTo('bar');
});
it('Unknown helper call in knownHelpers only mode should throw', () => {
expectTemplate('{{typeof hello}}')
.withCompileOptions({ knownHelpersOnly: true })
.toThrow(Error);
});
});
describe('blockHelperMissing', () => {
it('lambdas are resolved by blockHelperMissing, not handlebars proper', () => {
expectTemplate('{{#truthy}}yep{{/truthy}}')
.withInput({
truthy() {
return true;
},
})
.toCompileTo('yep');
});
it('lambdas resolved by blockHelperMissing are bound to the context', () => {
expectTemplate('{{#truthy}}yep{{/truthy}}')
.withInput({
truthy() {
return this.truthiness();
},
truthiness() {
return false;
},
})
.toCompileTo('');
});
});
describe('name field', () => {
const helpers = {
blockHelperMissing(...args: any[]) {
return 'missing: ' + args[args.length - 1].name;
},
helperMissing(...args: any[]) {
return 'helper missing: ' + args[args.length - 1].name;
},
helper(...args: any[]) {
return 'ran: ' + args[args.length - 1].name;
},
};
it('should include in ambiguous mustache calls', () => {
expectTemplate('{{helper}}').withHelpers(helpers).toCompileTo('ran: helper');
});
it('should include in helper mustache calls', () => {
expectTemplate('{{helper 1}}').withHelpers(helpers).toCompileTo('ran: helper');
});
it('should include in ambiguous block calls', () => {
expectTemplate('{{#helper}}{{/helper}}').withHelpers(helpers).toCompileTo('ran: helper');
});
it('should include in simple block calls', () => {
expectTemplate('{{#./helper}}{{/./helper}}')
.withHelpers(helpers)
.toCompileTo('missing: ./helper');
});
it('should include in helper block calls', () => {
expectTemplate('{{#helper 1}}{{/helper}}').withHelpers(helpers).toCompileTo('ran: helper');
});
it('should include in known helper calls', () => {
expectTemplate('{{helper}}')
.withCompileOptions({
knownHelpers: { helper: true },
knownHelpersOnly: true,
})
.withHelpers(helpers)
.toCompileTo('ran: helper');
});
it('should include full id', () => {
expectTemplate('{{#foo.helper}}{{/foo.helper}}')
.withInput({ foo: {} })
.withHelpers(helpers)
.toCompileTo('missing: foo.helper');
});
it('should include full id if a hash is passed', () => {
expectTemplate('{{#foo.helper bar=baz}}{{/foo.helper}}')
.withInput({ foo: {} })
.withHelpers(helpers)
.toCompileTo('helper missing: foo.helper');
});
});
describe('name conflicts', () => {
it('helpers take precedence over same-named context properties', () => {
expectTemplate('{{goodbye}} {{cruel world}}')
.withHelper('goodbye', function (this: any) {
return this.goodbye.toUpperCase();
})
.withHelper('cruel', function (world) {
return 'cruel ' + world.toUpperCase();
})
.withInput({
goodbye: 'goodbye',
world: 'world',
})
.toCompileTo('GOODBYE cruel WORLD');
});
it('helpers take precedence over same-named context properties$', () => {
expectTemplate('{{#goodbye}} {{cruel world}}{{/goodbye}}')
.withHelper('goodbye', function (this: any, options) {
return this.goodbye.toUpperCase() + options.fn(this);
})
.withHelper('cruel', function (world) {
return 'cruel ' + world.toUpperCase();
})
.withInput({
goodbye: 'goodbye',
world: 'world',
})
.toCompileTo('GOODBYE cruel WORLD');
});
it('Scoped names take precedence over helpers', () => {
expectTemplate('{{this.goodbye}} {{cruel world}} {{cruel this.goodbye}}')
.withHelper('goodbye', function (this: any) {
return this.goodbye.toUpperCase();
})
.withHelper('cruel', function (world) {
return 'cruel ' + world.toUpperCase();
})
.withInput({
goodbye: 'goodbye',
world: 'world',
})
.toCompileTo('goodbye cruel WORLD cruel GOODBYE');
});
it('Scoped names take precedence over block helpers', () => {
expectTemplate('{{#goodbye}} {{cruel world}}{{/goodbye}} {{this.goodbye}}')
.withHelper('goodbye', function (this: any, options) {
return this.goodbye.toUpperCase() + options.fn(this);
})
.withHelper('cruel', function (world) {
return 'cruel ' + world.toUpperCase();
})
.withInput({
goodbye: 'goodbye',
world: 'world',
})
.toCompileTo('GOODBYE cruel WORLD goodbye');
});
});
describe('block params', () => {
it('should take presedence over context values', () => {
expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}')
.withInput({ value: 'foo' })
.withHelper('goodbyes', function (options) {
expect(options.fn.blockParams).toEqual(1);
return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
})
.toCompileTo('1foo');
});
it('should take presedence over helper values', () => {
expectTemplate('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}')
.withHelper('value', function () {
return 'foo';
})
.withHelper('goodbyes', function (options) {
expect(options.fn.blockParams).toEqual(1);
return options.fn({}, { blockParams: [1, 2] });
})
.toCompileTo('1foo');
});
it('should not take presedence over pathed values', () => {
expectTemplate('{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}')
.withInput({ value: 'bar' })
.withHelper('value', function () {
return 'foo';
})
.withHelper('goodbyes', function (this: any, options) {
expect(options.fn.blockParams).toEqual(1);
return options.fn(this, { blockParams: [1, 2] });
})
.toCompileTo('barfoo');
});
it('should take presednece over parent block params', () => {
let value: number;
expectTemplate(
'{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}',
{
beforeEach() {
value = 1;
},
}
)
.withInput({ value: 'foo' })
.withHelper('goodbyes', function (options) {
return options.fn(
{ value: 'bar' },
{
blockParams: options.fn.blockParams === 1 ? [value++, value++] : undefined,
}
);
})
.toCompileTo('13foo');
});
it('should allow block params on chained helpers', () => {
expectTemplate('{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}')
.withInput({ value: 'foo' })
.withHelper('goodbyes', function (options) {
expect(options.fn.blockParams).toEqual(1);
return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
})
.toCompileTo('1foo');
});
});
describe('built-in helpers malformed arguments ', () => {
it('if helper - too few arguments', () => {
expectTemplate('{{#if}}{{/if}}').toThrow(/#if requires exactly one argument/);
});
it('if helper - too many arguments, string', () => {
expectTemplate('{{#if test "string"}}{{/if}}').toThrow(/#if requires exactly one argument/);
});
it('if helper - too many arguments, undefined', () => {
expectTemplate('{{#if test undefined}}{{/if}}').toThrow(/#if requires exactly one argument/);
});
it('if helper - too many arguments, null', () => {
expectTemplate('{{#if test null}}{{/if}}').toThrow(/#if requires exactly one argument/);
});
it('unless helper - too few arguments', () => {
expectTemplate('{{#unless}}{{/unless}}').toThrow(/#unless requires exactly one argument/);
});
it('unless helper - too many arguments', () => {
expectTemplate('{{#unless test null}}{{/unless}}').toThrow(
/#unless requires exactly one argument/
);
});
it('with helper - too few arguments', () => {
expectTemplate('{{#with}}{{/with}}').toThrow(/#with requires exactly one argument/);
});
it('with helper - too many arguments', () => {
expectTemplate('{{#with test "string"}}{{/with}}').toThrow(
/#with requires exactly one argument/
);
});
});
describe('the lookupProperty-option', () => {
it('should be passed to custom helpers', () => {
expectTemplate('{{testHelper}}')
.withHelper('testHelper', function testHelper(this: any, options) {
return options.lookupProperty(this, 'testProperty');
})
.withInput({ testProperty: 'abc' })
.toCompileTo('abc');
});
});
});
function deleteAllKeys(obj: { [key: string]: any }) {
for (const key of Object.keys(obj)) {
delete obj[key];
}
}

View file

@ -0,0 +1,279 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import { expectTemplate } from '../__jest__/test_bench';
describe('Regressions', () => {
it('GH-94: Cannot read property of undefined', () => {
expectTemplate('{{#books}}{{title}}{{author.name}}{{/books}}')
.withInput({
books: [
{
title: 'The origin of species',
author: {
name: 'Charles Darwin',
},
},
{
title: 'Lazarillo de Tormes',
},
],
})
.toCompileTo('The origin of speciesCharles DarwinLazarillo de Tormes');
});
it("GH-150: Inverted sections print when they shouldn't", () => {
const string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
expectTemplate(string).toCompileTo('not set :: ');
expectTemplate(string).withInput({ set: undefined }).toCompileTo('not set :: ');
expectTemplate(string).withInput({ set: false }).toCompileTo('not set :: ');
expectTemplate(string).withInput({ set: true }).toCompileTo(' :: set');
});
it('GH-158: Using array index twice, breaks the template', () => {
expectTemplate('{{arr.[0]}}, {{arr.[1]}}')
.withInput({ arr: [1, 2] })
.toCompileTo('1, 2');
});
it("bug reported by @fat where lambdas weren't being properly resolved", () => {
const string =
'<strong>This is a slightly more complicated {{thing}}.</strong>.\n' +
'{{! Just ignore this business. }}\n' +
'Check this out:\n' +
'{{#hasThings}}\n' +
'<ul>\n' +
'{{#things}}\n' +
'<li class={{className}}>{{word}}</li>\n' +
'{{/things}}</ul>.\n' +
'{{/hasThings}}\n' +
'{{^hasThings}}\n' +
'\n' +
'<small>Nothing to check out...</small>\n' +
'{{/hasThings}}';
const data = {
thing() {
return 'blah';
},
things: [
{ className: 'one', word: '@fat' },
{ className: 'two', word: '@dhg' },
{ className: 'three', word: '@sayrer' },
],
hasThings() {
return true;
},
};
const output =
'<strong>This is a slightly more complicated blah.</strong>.\n' +
'Check this out:\n' +
'<ul>\n' +
'<li class=one>@fat</li>\n' +
'<li class=two>@dhg</li>\n' +
'<li class=three>@sayrer</li>\n' +
'</ul>.\n';
expectTemplate(string).withInput(data).toCompileTo(output);
});
it('GH-408: Multiple loops fail', () => {
expectTemplate('{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}')
.withInput([
{ name: 'John Doe', location: { city: 'Chicago' } },
{ name: 'Jane Doe', location: { city: 'New York' } },
])
.toCompileTo('John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe');
});
it('GS-428: Nested if else rendering', () => {
const succeedingTemplate =
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
const failingTemplate =
'{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
const helpers = {
blk(block: Handlebars.HelperOptions) {
return block.fn('');
},
inverse(block: Handlebars.HelperOptions) {
return block.inverse('');
},
};
expectTemplate(succeedingTemplate).withHelpers(helpers).toCompileTo(' Expected ');
expectTemplate(failingTemplate).withHelpers(helpers).toCompileTo(' Expected ');
});
it('GH-458: Scoped this identifier', () => {
expectTemplate('{{./foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
});
it('GH-375: Unicode line terminators', () => {
expectTemplate('\u2028').toCompileTo('\u2028');
});
it('GH-534: Object prototype aliases', () => {
/* eslint-disable no-extend-native */
// @ts-expect-error
Object.prototype[0xd834] = true;
expectTemplate('{{foo}}').withInput({ foo: 'bar' }).toCompileTo('bar');
// @ts-expect-error
delete Object.prototype[0xd834];
/* eslint-enable no-extend-native */
});
it('GH-437: Matching escaping', () => {
expectTemplate('{{{a}}').toThrow(/Parse error on/);
expectTemplate('{{a}}}').toThrow(/Parse error on/);
});
it('GH-676: Using array in escaping mustache fails', () => {
const data = { arr: [1, 2] };
expectTemplate('{{arr}}').withInput(data).toCompileTo(data.arr.toString());
});
it('Mustache man page', () => {
expectTemplate(
'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}'
)
.withInput({
name: 'Chris',
value: 10000,
taxed_value: 10000 - 10000 * 0.4,
in_ca: true,
})
.toCompileTo('Hello Chris. You have just won $10000! Well, $6000, after taxes.');
});
it('GH-731: zero context rendering', () => {
expectTemplate('{{#foo}} This is {{bar}} ~ {{/foo}}')
.withInput({
foo: 0,
bar: 'OK',
})
.toCompileTo(' This is ~ ');
});
it('GH-820: zero pathed rendering', () => {
expectTemplate('{{foo.bar}}').withInput({ foo: 0 }).toCompileTo('');
});
it('GH-837: undefined values for helpers', () => {
expectTemplate('{{str bar.baz}}')
.withHelpers({
str(value) {
return value + '';
},
})
.toCompileTo('undefined');
});
it('GH-926: Depths and de-dupe', () => {
expectTemplate(
'{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}'
)
.withInput({
name: 'foo',
data: [1],
notData: [1],
})
.toCompileTo('foo');
});
it('GH-1021: Each empty string key', () => {
expectTemplate('{{#each data}}Key: {{@key}}\n{{/each}}')
.withInput({
data: {
'': 'foo',
name: 'Chris',
value: 10000,
},
})
.toCompileTo('Key: \nKey: name\nKey: value\n');
});
it('GH-1065: Sparse arrays', () => {
const array = [];
array[1] = 'foo';
array[3] = 'bar';
expectTemplate('{{#each array}}{{@index}}{{.}}{{/each}}')
.withInput({ array })
.toCompileTo('1foo3bar');
});
it('GH-1093: Undefined helper context', () => {
expectTemplate('{{#each obj}}{{{helper}}}{{.}}{{/each}}')
.withInput({ obj: { foo: undefined, bar: 'bat' } })
.withHelpers({
helper(this: any) {
// It's valid to execute a block against an undefined context, but
// helpers can not do so, so we expect to have an empty object here;
for (const name in this) {
if (Object.prototype.hasOwnProperty.call(this, name)) {
return 'found';
}
}
// And to make IE happy, check for the known string as length is not enumerated.
return this === 'bat' ? 'found' : 'not';
},
})
.toCompileTo('notfoundbat');
});
it('GH-1135 : Context handling within each iteration', () => {
expectTemplate(
'{{#each array}}\n' +
' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' +
' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n' +
'{{/each}}'
)
.withInput({ array: [1], name: 'John' })
.withHelpers({
myif(conditional, options) {
if (conditional) {
return options.fn(this);
} else {
return options.inverse(this);
}
},
})
.toCompileTo(' 1. IF: John--\n' + ' 2. MYIF: John==\n');
});
it('GH-1319: "unless" breaks when "each" value equals "null"', () => {
expectTemplate('{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}')
.withInput({
value: 'parent',
list: [null, 'a'],
})
.toCompileTo('parent=parent parent=parent ');
});
it('should allow hash with protected array names', () => {
expectTemplate('{{helpa length="foo"}}')
.withInput({ array: [1], name: 'John' })
.withHelpers({
helpa(options) {
return options.hash.length;
},
})
.toCompileTo('foo');
});
describe("GH-1639: TypeError: Cannot read property 'apply' of undefined\" when handlebars version > 4.6.0 (undocumented, deprecated usage)", () => {
it('should treat undefined helpers like non-existing helpers', () => {
expectTemplate('{{foo}}')
.withHelper('foo', undefined)
.withInput({ foo: 'bar' })
.toCompileTo('bar');
});
});
});

View file

@ -0,0 +1,132 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('security issues', () => {
describe('GH-1495: Prevent Remote Code Execution via constructor', () => {
it('should not allow constructors to be accessed', () => {
expectTemplate('{{lookup (lookup this "constructor") "name"}}').withInput({}).toCompileTo('');
expectTemplate('{{constructor.name}}').withInput({}).toCompileTo('');
});
it('GH-1603: should not allow constructors to be accessed (lookup via toString)', () => {
expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
.withInput({})
.withHelper('list', function (element) {
return [element];
})
.toCompileTo('');
});
it('should allow the "constructor" property to be accessed if it is an "ownProperty"', () => {
expectTemplate('{{constructor.name}}')
.withInput({ constructor: { name: 'here we go' } })
.toCompileTo('here we go');
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
.withInput({ constructor: { name: 'here we go' } })
.toCompileTo('here we go');
});
it('should allow the "constructor" property to be accessed if it is an "own property"', () => {
expectTemplate('{{lookup (lookup this "constructor") "name"}}')
.withInput({ constructor: { name: 'here we go' } })
.toCompileTo('here we go');
});
});
describe('GH-1558: Prevent explicit call of helperMissing-helpers', () => {
describe('without the option "allowExplicitCallOfHelperMissing"', () => {
it('should throw an exception when calling "{{helperMissing}}" ', () => {
expectTemplate('{{helperMissing}}').toThrow(Error);
});
it('should throw an exception when calling "{{#helperMissing}}{{/helperMissing}}" ', () => {
expectTemplate('{{#helperMissing}}{{/helperMissing}}').toThrow(Error);
});
it('should throw an exception when calling "{{blockHelperMissing "abc" .}}" ', () => {
const functionCalls = [];
expect(() => {
const template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
template({
fn() {
functionCalls.push('called');
},
});
}).toThrow(Error);
expect(functionCalls.length).toEqual(0);
});
it('should throw an exception when calling "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', () => {
expectTemplate('{{#blockHelperMissing .}}{{/blockHelperMissing}}')
.withInput({
fn() {
return 'functionInData';
},
})
.toThrow(Error);
});
});
});
describe('GH-1563', () => {
it('should not allow to access constructor after overriding via __defineGetter__', () => {
// @ts-expect-error
if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
return; // Browser does not support this exploit anyway
}
expectTemplate(
'{{__defineGetter__ "undefined" valueOf }}' +
'{{#with __lookupGetter__ }}' +
'{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
'{{constructor.name}}' +
'{{/with}}'
)
.withInput({})
.toThrow(/Missing helper: "__defineGetter__"/);
});
});
describe('GH-1595: dangerous properties', () => {
const templates = [
'{{constructor}}',
'{{__defineGetter__}}',
'{{__defineSetter__}}',
'{{__lookupGetter__}}',
'{{__proto__}}',
'{{lookup this "constructor"}}',
'{{lookup this "__defineGetter__"}}',
'{{lookup this "__defineSetter__"}}',
'{{lookup this "__lookupGetter__"}}',
'{{lookup this "__proto__"}}',
];
templates.forEach((template) => {
describe('access should be denied to ' + template, () => {
it('by default', () => {
expectTemplate(template).withInput({}).toCompileTo('');
});
});
});
});
describe('escapes template variables', () => {
it('in default mode', () => {
expectTemplate("{{'a\\b'}}").withCompileOptions().withInput({ 'a\\b': 'c' }).toCompileTo('c');
});
it('in strict mode', () => {
expectTemplate("{{'a\\b'}}")
.withCompileOptions({ strict: true })
.withInput({ 'a\\b': 'c' })
.toCompileTo('c');
});
});
});

View file

@ -0,0 +1,164 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import { expectTemplate } from '../__jest__/test_bench';
describe('strict', () => {
describe('strict mode', () => {
it('should error on missing property lookup', () => {
expectTemplate('{{hello}}')
.withCompileOptions({ strict: true })
.toThrow(/"hello" not defined in/);
});
it('should error on missing child', () => {
expectTemplate('{{hello.bar}}')
.withCompileOptions({ strict: true })
.withInput({ hello: { bar: 'foo' } })
.toCompileTo('foo');
expectTemplate('{{hello.bar}}')
.withCompileOptions({ strict: true })
.withInput({ hello: {} })
.toThrow(/"bar" not defined in/);
});
it('should handle explicit undefined', () => {
expectTemplate('{{hello.bar}}')
.withCompileOptions({ strict: true })
.withInput({ hello: { bar: undefined } })
.toCompileTo('');
});
it('should error on missing property lookup in known helpers mode', () => {
expectTemplate('{{hello}}')
.withCompileOptions({
strict: true,
knownHelpersOnly: true,
})
.toThrow(/"hello" not defined in/);
});
it('should error on missing context', () => {
expectTemplate('{{hello}}').withCompileOptions({ strict: true }).toThrow(Error);
});
it('should error on missing data lookup', () => {
const xt = expectTemplate('{{@hello}}').withCompileOptions({
strict: true,
});
xt.toThrow(Error);
xt.withRuntimeOptions({ data: { hello: 'foo' } }).toCompileTo('foo');
});
it('should not run helperMissing for helper calls', () => {
expectTemplate('{{hello foo}}')
.withCompileOptions({ strict: true })
.withInput({ foo: true })
.toThrow(/"hello" not defined in/);
expectTemplate('{{#hello foo}}{{/hello}}')
.withCompileOptions({ strict: true })
.withInput({ foo: true })
.toThrow(/"hello" not defined in/);
});
it('should throw on ambiguous blocks', () => {
expectTemplate('{{#hello}}{{/hello}}')
.withCompileOptions({ strict: true })
.toThrow(/"hello" not defined in/);
expectTemplate('{{^hello}}{{/hello}}')
.withCompileOptions({ strict: true })
.toThrow(/"hello" not defined in/);
expectTemplate('{{#hello.bar}}{{/hello.bar}}')
.withCompileOptions({ strict: true })
.withInput({ hello: {} })
.toThrow(/"bar" not defined in/);
});
it('should allow undefined parameters when passed to helpers', () => {
expectTemplate('{{#unless foo}}success{{/unless}}')
.withCompileOptions({ strict: true })
.toCompileTo('success');
});
it('should allow undefined hash when passed to helpers', () => {
expectTemplate('{{helper value=@foo}}')
.withCompileOptions({
strict: true,
})
.withHelpers({
helper(options) {
expect('value' in options.hash).toEqual(true);
expect(options.hash.value).toBeUndefined();
return 'success';
},
})
.toCompileTo('success');
});
it('should show error location on missing property lookup', () => {
expectTemplate('\n\n\n {{hello}}')
.withCompileOptions({ strict: true })
.toThrow('"hello" not defined in [object Object] - 4:5');
});
it('should error contains correct location properties on missing property lookup', () => {
try {
expectTemplate('\n\n\n {{hello}}')
.withCompileOptions({ strict: true })
.toCompileTo('throw before asserting this');
} catch (error) {
expect(error.lineNumber).toEqual(4);
expect(error.endLineNumber).toEqual(4);
expect(error.column).toEqual(5);
expect(error.endColumn).toEqual(10);
}
});
});
describe('assume objects', () => {
it('should ignore missing property', () => {
expectTemplate('{{hello}}').withCompileOptions({ assumeObjects: true }).toCompileTo('');
});
it('should ignore missing child', () => {
expectTemplate('{{hello.bar}}')
.withCompileOptions({ assumeObjects: true })
.withInput({ hello: {} })
.toCompileTo('');
});
it('should error on missing object', () => {
expectTemplate('{{hello.bar}}').withCompileOptions({ assumeObjects: true }).toThrow(Error);
});
it('should error on missing context', () => {
expectTemplate('{{hello}}')
.withCompileOptions({ assumeObjects: true })
.withInput(undefined)
.toThrow(Error);
});
it('should error on missing data lookup', () => {
expectTemplate('{{@hello.bar}}')
.withCompileOptions({ assumeObjects: true })
.withInput(undefined)
.toThrow(Error);
});
it('should execute blockHelperMissing', () => {
expectTemplate('{{^hello}}foo{{/hello}}')
.withCompileOptions({ assumeObjects: true })
.toCompileTo('foo');
});
});
});

View file

@ -0,0 +1,214 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('subexpressions', () => {
it('arg-less helper', () => {
expectTemplate('{{foo (bar)}}!')
.withHelpers({
foo(val) {
return val + val;
},
bar() {
return 'LOL';
},
})
.toCompileTo('LOLLOL!');
});
it('helper w args', () => {
expectTemplate('{{blog (equal a b)}}')
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('mixed paths and helpers', () => {
expectTemplate('{{blog baz.bat (equal a b) baz.bar}}')
.withInput({ bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } })
.withHelpers({
blog(val, that, theOther) {
return 'val is ' + val + ', ' + that + ' and ' + theOther;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is foo!, true and bar!');
});
it('supports much nesting', () => {
expectTemplate('{{blog (equal (equal true true) true)}}')
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('GH-800 : Complex subexpressions', () => {
const context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
const helpers = {
dash(a: any, b: any) {
return a + '-' + b;
},
concat(a: any, b: any) {
return a + b;
},
};
expectTemplate("{{dash 'abc' (concat a b)}}")
.withInput(context)
.withHelpers(helpers)
.toCompileTo('abc-ab');
expectTemplate('{{dash d (concat a b)}}')
.withInput(context)
.withHelpers(helpers)
.toCompileTo('d-ab');
expectTemplate('{{dash c.c (concat a b)}}')
.withInput(context)
.withHelpers(helpers)
.toCompileTo('c-ab');
expectTemplate('{{dash (concat a b) c.c}}')
.withInput(context)
.withHelpers(helpers)
.toCompileTo('ab-c');
expectTemplate('{{dash (concat a e.e) c.c}}')
.withInput(context)
.withHelpers(helpers)
.toCompileTo('ae-c');
});
it('provides each nested helper invocation its own options hash', () => {
let lastOptions: Handlebars.HelperOptions;
const helpers = {
equal(x: any, y: any, options: Handlebars.HelperOptions) {
if (!options || options === lastOptions) {
throw new Error('options hash was reused');
}
lastOptions = options;
return x === y;
},
};
expectTemplate('{{equal (equal true true) true}}').withHelpers(helpers).toCompileTo('true');
});
it('with hashes', () => {
expectTemplate("{{blog (equal (equal true true) true fun='yes')}}")
.withInput({ bar: 'LOL' })
.withHelpers({
blog(val) {
return 'val is ' + val;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('as hashes', () => {
expectTemplate("{{blog fun=(equal (blog fun=1) 'val is 1')}}")
.withHelpers({
blog(options) {
return 'val is ' + options.hash.fun;
},
equal(x, y) {
return x === y;
},
})
.toCompileTo('val is true');
});
it('multiple subexpressions in a hash', () => {
expectTemplate('{{input aria-label=(t "Name") placeholder=(t "Example User")}}')
.withHelpers({
input(options) {
const hash = options.hash;
const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
return new Handlebars.SafeString(
'<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />'
);
},
t(defaultString) {
return new Handlebars.SafeString(defaultString);
},
})
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
});
it('multiple subexpressions in a hash with context', () => {
expectTemplate('{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}')
.withInput({
item: {
field: 'Name',
placeholder: 'Example User',
},
})
.withHelpers({
input(options) {
const hash = options.hash;
const ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
const placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
return new Handlebars.SafeString(
'<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />'
);
},
t(defaultString) {
return new Handlebars.SafeString(defaultString);
},
})
.toCompileTo('<input aria-label="Name" placeholder="Example User" />');
});
it('subexpression functions on the context', () => {
expectTemplate('{{foo (bar)}}!')
.withInput({
bar() {
return 'LOL';
},
})
.withHelpers({
foo(val) {
return val + val;
},
})
.toCompileTo('LOLLOL!');
});
it("subexpressions can't just be property lookups", () => {
expectTemplate('{{foo (bar)}}!')
.withInput({
bar: 'LOL',
})
.withHelpers({
foo(val) {
return val + val;
},
})
.toThrow();
});
});

View file

@ -0,0 +1,24 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import Handlebars from '..';
import { expectTemplate } from '../__jest__/test_bench';
describe('utils', function () {
describe('#SafeString', function () {
it('constructing a safestring from a string and checking its type', function () {
const safe = new Handlebars.SafeString('testing 1, 2, 3');
expect(safe).toBeInstanceOf(Handlebars.SafeString);
expect(safe.toString()).toEqual('testing 1, 2, 3');
});
it('it should not escape SafeString properties', function () {
const name = new Handlebars.SafeString('<em>Sean O&#x27;Malley</em>');
expectTemplate('{{name}}').withInput({ name }).toCompileTo('<em>Sean O&#x27;Malley</em>');
});
});
});

View file

@ -0,0 +1,80 @@
/*
* This file is forked from the handlebars project (https://github.com/handlebars-lang/handlebars.js),
* and may include modifications made by Elasticsearch B.V.
* Elasticsearch B.V. licenses this file to you under the MIT License.
* See `packages/kbn-handlebars/LICENSE` for more information.
*/
import { expectTemplate } from '../__jest__/test_bench';
describe('whitespace control', () => {
it('should strip whitespace around mustache calls', () => {
const hash = { foo: 'bar<' };
expectTemplate(' {{~foo~}} ').withInput(hash).toCompileTo('bar&lt;');
expectTemplate(' {{~foo}} ').withInput(hash).toCompileTo('bar&lt; ');
expectTemplate(' {{foo~}} ').withInput(hash).toCompileTo(' bar&lt;');
expectTemplate(' {{~&foo~}} ').withInput(hash).toCompileTo('bar<');
expectTemplate(' {{~{foo}~}} ').withInput(hash).toCompileTo('bar<');
expectTemplate('1\n{{foo~}} \n\n 23\n{{bar}}4').toCompileTo('1\n23\n4');
});
describe('blocks', () => {
it('should strip whitespace around simple block calls', () => {
const hash = { foo: 'bar<' };
expectTemplate(' {{~#if foo~}} bar {{~/if~}} ').withInput(hash).toCompileTo('bar');
expectTemplate(' {{#if foo~}} bar {{/if~}} ').withInput(hash).toCompileTo(' bar ');
expectTemplate(' {{~#if foo}} bar {{~/if}} ').withInput(hash).toCompileTo(' bar ');
expectTemplate(' {{#if foo}} bar {{/if}} ').withInput(hash).toCompileTo(' bar ');
expectTemplate(' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ')
.withInput(hash)
.toCompileTo('bar');
expectTemplate(' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ')
.withInput(hash)
.toCompileTo(' abara ');
});
it('should strip whitespace around inverse block calls', () => {
expectTemplate(' {{~^if foo~}} bar {{~/if~}} ').toCompileTo('bar');
expectTemplate(' {{^if foo~}} bar {{/if~}} ').toCompileTo(' bar ');
expectTemplate(' {{~^if foo}} bar {{~/if}} ').toCompileTo(' bar ');
expectTemplate(' {{^if foo}} bar {{/if}} ').toCompileTo(' bar ');
expectTemplate(' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ').toCompileTo('bar');
});
it('should strip whitespace around complex block calls', () => {
const hash = { foo: 'bar<' };
expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').withInput(hash).toCompileTo('bar');
expectTemplate('{{#if foo~}} bar {{^~}} baz {{/if}}').withInput(hash).toCompileTo('bar ');
expectTemplate('{{#if foo}} bar {{~^~}} baz {{~/if}}').withInput(hash).toCompileTo(' bar');
expectTemplate('{{#if foo}} bar {{^~}} baz {{/if}}').withInput(hash).toCompileTo(' bar ');
expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').withInput(hash).toCompileTo('bar');
expectTemplate('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n')
.withInput(hash)
.toCompileTo('bar');
expectTemplate('\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n')
.withInput(hash)
.toCompileTo('bar<');
expectTemplate('{{#if foo~}} bar {{~^~}} baz {{~/if}}').toCompileTo('baz');
expectTemplate('{{#if foo}} bar {{~^~}} baz {{/if}}').toCompileTo('baz ');
expectTemplate('{{#if foo~}} bar {{~^}} baz {{~/if}}').toCompileTo(' baz');
expectTemplate('{{#if foo~}} bar {{~^}} baz {{/if}}').toCompileTo(' baz ');
expectTemplate('{{#if foo~}} bar {{~else~}} baz {{~/if}}').toCompileTo('baz');
expectTemplate('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n').toCompileTo(
'baz'
);
});
});
it('should only strip whitespace once', () => {
expectTemplate(' {{~foo~}} {{foo}} {{foo}} ')
.withInput({ foo: 'bar' })
.toCompileTo('barbar bar ');
});
});

View file

@ -0,0 +1,19 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"outDir": "./target_types",
"rootDir": "src",
"sourceMap": true,
"sourceRoot": "../../../../packages/kbn-handlebars/src",
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*.ts"
]
}

View file

@ -39,6 +39,13 @@ const getDirectiveValueValidator = ({ allowNone, allowNonce }: DirectiveValidati
const configSchema = schema.object(
{
disableUnsafeEval: schema.conditional(
// Default disableUnsafeEval to false if it's not a distributable release
schema.contextRef('dist'),
true,
schema.boolean({ defaultValue: false }),
schema.boolean({ defaultValue: true })
),
script_src: schema.arrayOf(schema.string(), {
defaultValue: [],
validate: getDirectiveValidator({ allowNone: false, allowNonce: false }),

View file

@ -0,0 +1,25 @@
/*
* 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 { schema } from '@kbn/config-schema';
import { config } from './config';
const origSchema = config.schema;
export const mockConfig = {
create(defaultDisableUnsafeEval: boolean) {
// @ts-expect-error: Property 'extends' does not exist on type??
config.schema = config.schema.extends({
disableUnsafeEval: schema.boolean({ defaultValue: defaultDisableUnsafeEval }),
});
return config;
},
reset() {
config.schema = origSchema;
},
};

View file

@ -8,6 +8,7 @@
import { CspConfig } from './csp_config';
import { config as cspConfig, CspConfigType } from './config';
import { mockConfig } from './csp_config.test.mocks';
// CSP rules aren't strictly additive, so any change can potentially expand or
// restrict the policy in a way we consider a breaking change. For that reason,
@ -33,7 +34,7 @@ describe('CspConfig', () => {
expect(CspConfig.DEFAULT).toMatchInlineSnapshot(`
CspConfig {
"disableEmbedding": false,
"header": "script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"header": "script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"strict": true,
"warnLegacyBrowsers": true,
}
@ -64,7 +65,7 @@ describe('CspConfig', () => {
worker_src: ['foo', 'bar'],
});
expect(config.header).toEqual(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self' foo bar; style-src 'unsafe-inline' 'self'`
`script-src 'self'; worker-src blob: 'self' foo bar; style-src 'unsafe-inline' 'self'`
);
});
@ -75,7 +76,7 @@ describe('CspConfig', () => {
});
expect(config.header).toEqual(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self' foo bar`
`script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self' foo bar`
);
});
@ -86,7 +87,7 @@ describe('CspConfig', () => {
});
expect(config.header).toEqual(
`script-src 'unsafe-eval' 'self' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
`script-src 'self' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
});
@ -98,7 +99,7 @@ describe('CspConfig', () => {
style_src: ['style', 'dolly'],
});
expect(config.header).toEqual(
`script-src 'unsafe-eval' 'self' script foo; worker-src blob: 'self' worker bar; style-src 'unsafe-inline' 'self' style dolly`
`script-src 'self' script foo; worker-src blob: 'self' worker bar; style-src 'unsafe-inline' 'self' style dolly`
);
});
@ -110,10 +111,68 @@ describe('CspConfig', () => {
style_src: ['style'],
});
expect(config.header).toEqual(
`script-src 'unsafe-eval' 'self' script; worker-src blob: 'self' worker; style-src 'unsafe-inline' 'self' style`
`script-src 'self' script; worker-src blob: 'self' worker; style-src 'unsafe-inline' 'self' style`
);
});
describe('disableUnsafeEval', () => {
test('when "disableUnsafeEval" is set to `true`, the `unsafe-eval` CSP should not be set', () => {
const config = new CspConfig({
...defaultConfig,
disableUnsafeEval: true,
script_src: ['foo', 'bar'],
});
expect(config.header).toEqual(
`script-src 'self' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
});
test('when "disableUnsafeEval" is set to `false`, the `unsafe-eval` CSP should be set', () => {
const config = new CspConfig({
...defaultConfig,
disableUnsafeEval: false,
script_src: ['foo', 'bar'],
});
expect(config.header).toEqual(
`script-src 'self' 'unsafe-eval' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
});
test('when "disableUnsafeEval" is not set, and the default value is "false", the `unsafe-eval` CSP should be set', () => {
// The default value for `disableUnsafeEval` depends on whether Kibana is a distributable or not. To test both scenarios, we mock the config.
const mockedConfig = mockConfig.create(false).schema.validate({});
const config = new CspConfig({
...mockedConfig,
script_src: ['foo', 'bar'],
});
expect(config.header).toEqual(
`script-src 'self' 'unsafe-eval' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
mockConfig.reset();
});
test('when "disableUnsafeEval" is not set, and the default value is "true", the `unsafe-eval` CSP should not be set', () => {
// The default value for `disableUnsafeEval` depends on whether Kibana is a distributable or not. To test both scenarios, we mock the config.
const mockedConfig = mockConfig.create(true).schema.validate({});
const config = new CspConfig({
...mockedConfig,
script_src: ['foo', 'bar'],
});
expect(config.header).toEqual(
`script-src 'self' foo bar; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
mockConfig.reset();
});
});
describe('allows "disableEmbedding" to be set', () => {
const disableEmbedding = true;
@ -122,7 +181,7 @@ describe('CspConfig', () => {
expect(config.disableEmbedding).toEqual(disableEmbedding);
expect(config.disableEmbedding).not.toEqual(CspConfig.DEFAULT.disableEmbedding);
expect(config.header).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; frame-ancestors 'self'"`
`"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; frame-ancestors 'self'"`
);
});
@ -135,7 +194,7 @@ describe('CspConfig', () => {
expect(config.disableEmbedding).toEqual(disableEmbedding);
expect(config.disableEmbedding).not.toEqual(CspConfig.DEFAULT.disableEmbedding);
expect(config.header).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; frame-ancestors 'self'"`
`"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; frame-ancestors 'self'"`
);
});
});

View file

@ -78,7 +78,7 @@ describe('CspDirectives', () => {
const config = cspConfig.schema.validate({});
const directives = CspDirectives.fromConfig(config);
expect(directives.getCspHeader()).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'"`
`"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'"`
);
});
@ -91,7 +91,7 @@ describe('CspDirectives', () => {
const directives = CspDirectives.fromConfig(config);
expect(directives.getCspHeader()).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self' baz; worker-src blob: 'self' foo; style-src 'unsafe-inline' 'self' bar dolly"`
`"script-src 'self' baz; worker-src blob: 'self' foo; style-src 'unsafe-inline' 'self' bar dolly"`
);
});
@ -108,7 +108,7 @@ describe('CspDirectives', () => {
});
const directives = CspDirectives.fromConfig(config);
expect(directives.getCspHeader()).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; connect-src 'self' connect-src; default-src 'self' default-src; font-src 'self' font-src; frame-src 'self' frame-src; img-src 'self' img-src; frame-ancestors 'self' frame-ancestors; report-uri report-uri; report-to report-to"`
`"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'; connect-src 'self' connect-src; default-src 'self' default-src; font-src 'self' font-src; frame-src 'self' frame-src; img-src 'self' img-src; frame-ancestors 'self' frame-ancestors; report-uri report-uri; report-to report-to"`
);
});
@ -118,7 +118,7 @@ describe('CspDirectives', () => {
});
const directives = CspDirectives.fromConfig(config);
expect(directives.getCspHeader()).toMatchInlineSnapshot(
`"script-src 'unsafe-eval' 'self' 'unsafe-hashes'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'"`
`"script-src 'self' 'unsafe-hashes'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'"`
);
});
});

View file

@ -25,7 +25,7 @@ export type CspDirectiveName =
* The default directives rules that are always applied
*/
export const defaultRules: Partial<Record<CspDirectiveName, string[]>> = {
'script-src': [`'unsafe-eval'`, `'self'`],
'script-src': [`'self'`],
'worker-src': [`blob:`, `'self'`],
'style-src': [`'unsafe-inline'`, `'self'`],
};
@ -94,6 +94,9 @@ const parseConfigDirectives = (cspConfig: CspConfigType): Map<CspDirectiveName,
if (cspConfig.script_src?.length) {
map.set('script-src', cspConfig.script_src);
}
if (cspConfig.disableUnsafeEval !== true) {
map.set('script-src', ["'unsafe-eval'", ...(map.get('script-src') ?? [])]);
}
if (cspConfig.worker_src?.length) {
map.set('worker-src', cspConfig.worker_src);
}

View file

@ -101,7 +101,7 @@ describe('HttpResources service', () => {
headers: {
'x-kibana': '42',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});
@ -147,7 +147,7 @@ describe('HttpResources service', () => {
headers: {
'x-kibana': '42',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});
@ -167,7 +167,7 @@ describe('HttpResources service', () => {
headers: {
'content-type': 'text/html',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});
@ -196,7 +196,7 @@ describe('HttpResources service', () => {
'content-type': 'text/html',
'x-kibana': '42',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});
@ -216,7 +216,7 @@ describe('HttpResources service', () => {
headers: {
'content-type': 'text/javascript',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});
@ -245,7 +245,7 @@ describe('HttpResources service', () => {
'content-type': 'text/javascript',
'x-kibana': '42',
'content-security-policy':
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
"script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'",
},
});
});

View file

@ -11,11 +11,20 @@ import * as kbnTestServer from '../../../test_helpers/kbn_server';
describe('http resources service', () => {
describe('register', () => {
applyTestsWithDisableUnsafeEvalSetTo(true);
applyTestsWithDisableUnsafeEvalSetTo(false);
});
});
function applyTestsWithDisableUnsafeEvalSetTo(disableUnsafeEval: boolean) {
describe(`with disableUnsafeEval=${disableUnsafeEval}`, () => {
let root: ReturnType<typeof kbnTestServer.createRoot>;
const defaultCspRules =
"script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'";
const defaultCspRules = disableUnsafeEval
? `script-src 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
: `script-src 'self' 'unsafe-eval'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`;
beforeEach(async () => {
root = kbnTestServer.createRoot({
csp: { disableUnsafeEval },
plugins: { initialize: false },
elasticsearch: { skipStartupConnectionCheck: true },
});
@ -191,4 +200,4 @@ describe('http resources service', () => {
});
});
});
});
}

View file

@ -27,6 +27,7 @@ kibana_vars=(
console.proxyFilter
csp.strict
csp.warnLegacyBrowsers
csp.disableUnsafeEval
csp.script_src
csp.worker_src
csp.style_src

View file

@ -59,6 +59,10 @@ export const IGNORE_FILE_GLOBS = [
// filename must match upstream filenames from lodash
'packages/elastic-safer-lodash-set/**/*',
// filename must match upstream filenames from handlebars
'packages/kbn-handlebars/src/upstream/**/*',
'packages/kbn-handlebars/.patches/**/*',
'x-pack/plugins/maps/server/fonts/**/*',
// Bazel default files

View file

@ -24,6 +24,7 @@ describe('csp collector', () => {
function updateCsp(config: Partial<ICspConfig>) {
httpMock.csp = new CspConfig({
...CspConfig.DEFAULT,
disableUnsafeEval: false,
style_src: [],
worker_src: [],
script_src: [],

View file

@ -7,25 +7,18 @@
*/
import { encode, RisonValue } from 'rison-node';
import {
create as createHandlebars,
compile as compileHandlebars,
HelperDelegate,
HelperOptions,
} from 'handlebars';
import Handlebars, { ExtendedCompileOptions, compileFnName } from '@kbn/handlebars';
import { i18n } from '@kbn/i18n';
import { emptyLabel } from '../../../../common/empty_label';
type CompileOptions = Parameters<typeof compileHandlebars>[1];
const handlebars = createHandlebars();
const handlebars = Handlebars.create();
function createSerializationHelper(
fnName: string,
serializeFn: (value: unknown) => string
): HelperDelegate {
): Handlebars.HelperDelegate {
return (...args) => {
const { hash } = args.slice(-1)[0] as HelperOptions;
const { hash } = args.slice(-1)[0] as Handlebars.HelperOptions;
const hasHash = Object.keys(hash).length > 0;
const hasValues = args.length > 1;
if (hasHash && hasValues) {
@ -60,12 +53,12 @@ export function replaceVars(
str: string,
args: Record<string, unknown> = {},
vars: Record<string, unknown> = {},
compileOptions: Partial<CompileOptions> = {}
compileOptions: Partial<ExtendedCompileOptions> = {}
) {
try {
/** we need add '[]' for emptyLabel because this value contains special characters.
* @see (https://handlebarsjs.com/guide/expressions.html#literal-segments) **/
const template = handlebars.compile(str.split(emptyLabel).join(`[${emptyLabel}]`), {
const template = handlebars[compileFnName](str.split(emptyLabel).join(`[${emptyLabel}]`), {
strict: true,
knownHelpersOnly: true,
knownHelpers: {

View file

@ -7,7 +7,7 @@
*/
import { isNumber } from 'lodash';
import handlebars from 'handlebars';
import handlebars, { compileFnName } from '@kbn/handlebars';
import { isEmptyValue, DISPLAY_EMPTY_VALUE } from '../../../../common/last_value_utils';
import { inputFormats, outputFormats, isDuration } from './durations';
import { getFieldFormats } from '../../../services';
@ -16,7 +16,7 @@ export const createTickFormatter = (format = '0,0.[00]', template, getConfig = n
const fieldFormats = getFieldFormats();
if (!template) template = '{{value}}';
const render = handlebars.compile(template, { noEscape: true, knownHelpersOnly: true });
const render = handlebars[compileFnName](template, { noEscape: true, knownHelpersOnly: true });
let formatter;
if (isDuration(format)) {

View file

@ -1,36 +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 expect from '@kbn/expect';
export default function ({ getService }) {
const supertest = getService('supertest');
describe('csp smoke test', () => {
it('app response sends content security policy headers', async () => {
const response = await supertest.get('/app/kibana');
expect(response.headers).to.have.property('content-security-policy');
const header = response.headers['content-security-policy'];
const parsed = new Map(
header.split(';').map((rule) => {
const parts = rule.trim().split(' ');
const key = parts.splice(0, 1)[0];
return [key, parts];
})
);
const entries = Array.from(parsed.entries());
expect(entries).to.eql([
['script-src', ["'unsafe-eval'", "'self'"]],
['worker-src', ['blob:', "'self'"]],
['style-src', ["'unsafe-inline'", "'self'"]],
]);
});
});
}

View file

@ -9,6 +9,5 @@
export default function ({ loadTestFile }) {
describe('general', () => {
loadTestFile(require.resolve('./cookies'));
loadTestFile(require.resolve('./csp'));
});
}

View file

@ -43,6 +43,7 @@ export default function () {
// Needed for async search functional tests to introduce a delay
`--data.search.aggs.shardDelay.enabled=true`,
`--security.showInsecureClusterWarning=false`,
'--csp.disableUnsafeEval=true',
'--telemetry.banner=false',
'--telemetry.optIn=false',
// These are *very* important to have them pointing to staging

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { compileFnName } from '@kbn/handlebars';
import {
Datatable,
Render,
@ -64,7 +65,7 @@ export function markdown(): ExpressionFunctionDefinition<
// @ts-expect-error untyped local
const { Handlebars } = await import('../../../common/lib/handlebars');
const compileFunctions = args.content.map((str) =>
Handlebars.compile(String(str), { knownHelpersOnly: true })
Handlebars[compileFnName](String(str), { knownHelpersOnly: true })
);
const ctx = {
columns: [],

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import Hbars from 'handlebars/dist/handlebars';
import Hbars from '@kbn/handlebars';
import { evaluate } from '@kbn/tinymath';
import { pivotObjectArray } from './pivot_object_array';

View file

@ -26,6 +26,7 @@ import type {
UnauthorizedErrorHandler,
UnauthorizedErrorHandlerToolkit,
} from '@kbn/core/server';
import { CspConfig } from '@kbn/core/server';
import {
coreMock,
elasticsearchServiceMock,
@ -743,7 +744,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/login?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2Fapp%2Fsome',
},
@ -768,7 +769,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/logout?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2Fapp%2Fsome',
},
@ -795,7 +796,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/login?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2F',
},
@ -841,7 +842,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/login?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2Fapp%2Fsome',
},
@ -866,7 +867,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/logout?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2Fapp%2Fsome',
},
@ -893,7 +894,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: '<div/>',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
Refresh:
'0;url=/mock-server-basepath/login?msg=UNAUTHENTICATED&next=%2Fmock-server-basepath%2F',
},
@ -938,7 +939,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: 'rendered-view',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
},
});
@ -970,7 +971,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: 'rendered-view',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
},
});
@ -1005,7 +1006,7 @@ describe('AuthenticationService', () => {
expect(mockOnPreResponseToolkit.render).toHaveBeenCalledWith({
body: 'rendered-view',
headers: {
'Content-Security-Policy': `script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`,
'Content-Security-Policy': CspConfig.DEFAULT.header,
},
});

View file

@ -255,7 +255,9 @@ const browserConsoleStep = {
package_version: '1.0.0-beta.14',
journey: { name: 'inline', id: 'inline' },
payload: {
text: "Refused to execute inline script because it violates the following Content Security Policy directive: \"script-src 'unsafe-eval' 'self'\". Either the 'unsafe-inline' keyword, a hash ('sha256-P5polb1UreUSOe5V/Pv7tc+yeZuJXiOi/3fqhGsU7BE='), or a nonce ('nonce-...') is required to enable inline execution.\n",
text: expect.stringMatching(
'Refused to execute inline script because it violates the following Content Security Policy directive:'
),
type: 'error',
},
index: 755,

View file

@ -5,21 +5,21 @@
* 2.0.
*/
import { create as createHandlebars, HelperDelegate, HelperOptions } from 'handlebars';
import Handlebars from '@kbn/handlebars';
import { encode, RisonValue } from 'rison-node';
import dateMath from '@kbn/datemath';
import moment, { Moment } from 'moment';
import numeral from '@elastic/numeral';
import { url } from '@kbn/kibana-utils-plugin/public';
const handlebars = createHandlebars();
const handlebars = Handlebars.create();
function createSerializationHelper(
fnName: string,
serializeFn: (value: unknown) => string
): HelperDelegate {
): Handlebars.HelperDelegate {
return (...args) => {
const { hash } = args.slice(-1)[0] as HelperOptions;
const { hash } = args.slice(-1)[0] as Handlebars.HelperOptions;
const hasHash = Object.keys(hash).length > 0;
const hasValues = args.length > 1;
if (hasHash && hasValues) {

View file

@ -10,13 +10,12 @@ export async function compile(
context: object,
doEncode: boolean = true
): Promise<string> {
const handlebarsTemplate = (await import('./handlebars').then((m) => m.handlebars)).compile(
urlTemplate,
{
strict: true,
noEscape: true,
}
);
const { handlebars } = await import('./handlebars');
const { compileFnName } = await import('@kbn/handlebars');
const handlebarsTemplate = handlebars[compileFnName](urlTemplate, {
strict: true,
noEscape: true,
});
let processedUrl: string = handlebarsTemplate(context);

View file

@ -117,9 +117,7 @@ export default function ({ getService }: FtrProviderContext) {
.expect(401);
expect(unauthenticatedResponse.headers['set-cookie']).to.be(undefined);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});
});

View file

@ -97,9 +97,7 @@ export default function ({ getService }: FtrProviderContext) {
// If browser and Kibana can successfully negotiate this HTML won't rendered, but if not
// users will see a proper `Unauthenticated` page.
expect(spnegoResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(spnegoResponse.headers['content-security-policy']).to.be.a('string');
expect(spnegoResponse.text).to.contain('We couldn&#x27;t log you in');
});

View file

@ -425,9 +425,7 @@ export default function ({ getService }: FtrProviderContext) {
})
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.headers.refresh).to.be(
`0;url=/logout?msg=UNAUTHENTICATED&next=%2F`
);
@ -442,9 +440,7 @@ export default function ({ getService }: FtrProviderContext) {
})
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.headers.refresh).to.be(
`0;url=/login?msg=UNAUTHENTICATED&next=%2F`
);
@ -709,9 +705,7 @@ export default function ({ getService }: FtrProviderContext) {
.set('Cookie', handshakeCookie.cookieString())
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.headers.refresh).to.be(
`0;url=/logout?msg=UNAUTHENTICATED&next=%2F`
);
@ -723,9 +717,7 @@ export default function ({ getService }: FtrProviderContext) {
.ca(CA_CERT)
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.headers.refresh).to.be(
`0;url=/login?msg=UNAUTHENTICATED&next=%2F`
);

View file

@ -175,9 +175,7 @@ export default function ({ getService }: FtrProviderContext) {
.get(`/api/security/oidc/callback?code=thisisthecode&state=${stateAndNonce.state}`)
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});
@ -187,9 +185,7 @@ export default function ({ getService }: FtrProviderContext) {
.set('Cookie', handshakeCookie.cookieString())
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});

View file

@ -68,9 +68,7 @@ export default function ({ getService }: FtrProviderContext) {
expect(response.headers['cache-control']).to.be(
'private, no-cache, no-store, must-revalidate'
);
expect(response.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(response.headers['content-security-policy']).to.be.a('string');
// Check that script that forwards URL fragment worked correctly.
expect(dom.window.location.href).to.be(
@ -90,9 +88,7 @@ export default function ({ getService }: FtrProviderContext) {
)
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});
@ -109,9 +105,7 @@ export default function ({ getService }: FtrProviderContext) {
.set('Cookie', handshakeCookie.cookieString())
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});

View file

@ -72,9 +72,7 @@ export default function ({ getService }: FtrProviderContext) {
.pfx(UNTRUSTED_CLIENT_CERT)
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});

View file

@ -188,9 +188,7 @@ export default function ({ getService }: FtrProviderContext) {
.send({ SAMLResponse: await createSAMLResponse({ inResponseTo: samlRequestId }) })
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});
@ -237,9 +235,7 @@ export default function ({ getService }: FtrProviderContext) {
})
.expect(401);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be(
`script-src 'unsafe-eval' 'self'; worker-src blob: 'self'; style-src 'unsafe-inline' 'self'`
);
expect(unauthenticatedResponse.headers['content-security-policy']).to.be.a('string');
expect(unauthenticatedResponse.text).to.contain('We couldn&#x27;t log you in');
});
});

View file

@ -3056,6 +3056,10 @@
version "0.0.0"
uid ""
"@kbn/handlebars@link:bazel-bin/packages/kbn-handlebars":
version "0.0.0"
uid ""
"@kbn/i18n-react@link:bazel-bin/packages/kbn-i18n-react":
version "0.0.0"
uid ""
@ -6270,6 +6274,10 @@
version "0.0.0"
uid ""
"@types/kbn__handlebars@link:bazel-bin/packages/kbn-handlebars/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__i18n-react@link:bazel-bin/packages/kbn-i18n-react/npm_module_types":
version "0.0.0"
uid ""