diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md
new file mode 100644
index 0000000000000..a0516702af7af
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.md
@@ -0,0 +1,234 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md)
+
+## kibana-plugin-server package
+
+The Kibana Core APIs for server-side plugins.
+
+A plugin requires a `kibana.json` file at it's root directory that follows [the manfiest schema](./kibana-plugin-server.pluginmanifest.md) to define static plugin information required to load the plugin.
+
+A plugin's `server/index` file must contain a named import, `plugin`, that implements [PluginInitializer](./kibana-plugin-server.plugininitializer.md) which returns an object that implements [Plugin](./kibana-plugin-server.plugin.md).
+
+The plugin integrates with the core system via lifecycle events: `setup`, `start`, and `stop`. In each lifecycle method, the plugin will receive the corresponding core services available (either [CoreSetup](./kibana-plugin-server.coresetup.md) or [CoreStart](./kibana-plugin-server.corestart.md)) and any interfaces returned by dependency plugins' lifecycle method. Anything returned by the plugin's lifecycle method will be exposed to downstream dependencies when their corresponding lifecycle methods are invoked.
+
+## Classes
+
+| Class | Description |
+| --- | --- |
+| [BasePath](./kibana-plugin-server.basepath.md) | Access or manipulate the Kibana base path |
+| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
+| [CspConfig](./kibana-plugin-server.cspconfig.md) | CSP configuration for use in Kibana. |
+| [ElasticsearchErrorHelpers](./kibana-plugin-server.elasticsearcherrorhelpers.md) | Helpers for working with errors returned from the Elasticsearch service.Since the internal data of errors are subject to change, consumers of the Elasticsearch service should always use these helpers to classify errors instead of checking error internals such as body.error.header[WWW-Authenticate]
|
+| [KibanaRequest](./kibana-plugin-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. |
+| [RouteValidationError](./kibana-plugin-server.routevalidationerror.md) | Error to return when the validation is not successful. |
+| [SavedObjectsClient](./kibana-plugin-server.savedobjectsclient.md) | |
+| [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | |
+| [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) | |
+| [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient
but exposes additional callAsCurrentUser
method that doesn't use credentials of the Kibana internal user (as callAsInternalUser
does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). |
+
+## Enumerations
+
+| Enumeration | Description |
+| --- | --- |
+| [AuthResultType](./kibana-plugin-server.authresulttype.md) | |
+| [AuthStatus](./kibana-plugin-server.authstatus.md) | Status indicating an outcome of the authentication. |
+
+## Interfaces
+
+| Interface | Description |
+| --- | --- |
+| [APICaller](./kibana-plugin-server.apicaller.md) | |
+| [AssistanceAPIResponse](./kibana-plugin-server.assistanceapiresponse.md) | |
+| [AssistantAPIClientParams](./kibana-plugin-server.assistantapiclientparams.md) | |
+| [Authenticated](./kibana-plugin-server.authenticated.md) | |
+| [AuthResultParams](./kibana-plugin-server.authresultparams.md) | Result of an incoming request authentication. |
+| [AuthToolkit](./kibana-plugin-server.authtoolkit.md) | A tool set defining an outcome of Auth interceptor for incoming request. |
+| [CallAPIOptions](./kibana-plugin-server.callapioptions.md) | The set of options that defines how API call should be made and result be processed. |
+| [Capabilities](./kibana-plugin-server.capabilities.md) | The read-only set of capabilities available for the current UI session. Capabilities are simple key-value pairs of (string, boolean), where the string denotes the capability ID, and the boolean is a flag indicating if the capability is enabled or disabled. |
+| [CapabilitiesSetup](./kibana-plugin-server.capabilitiessetup.md) | APIs to manage the [Capabilities](./kibana-plugin-server.capabilities.md) that will be used by the application.Plugins relying on capabilities to toggle some of their features should register them during the setup phase using the registerProvider
method.Plugins having the responsibility to restrict capabilities depending on a given context should register their capabilities switcher using the registerSwitcher
method.Refers to the methods documentation for complete description and examples. |
+| [CapabilitiesStart](./kibana-plugin-server.capabilitiesstart.md) | APIs to access the application [Capabilities](./kibana-plugin-server.capabilities.md). |
+| [ConfigDeprecationFactory](./kibana-plugin-server.configdeprecationfactory.md) | Provides helpers to generates the most commonly used [ConfigDeprecation](./kibana-plugin-server.configdeprecation.md) when invoking a [ConfigDeprecationProvider](./kibana-plugin-server.configdeprecationprovider.md).See methods documentation for more detailed examples. |
+| [ContextSetup](./kibana-plugin-server.contextsetup.md) | An object that handles registration of context providers and configuring handlers with context. |
+| [CoreSetup](./kibana-plugin-server.coresetup.md) | Context passed to the plugins setup
method. |
+| [CoreStart](./kibana-plugin-server.corestart.md) | Context passed to the plugins start
method. |
+| [CustomHttpResponseOptions](./kibana-plugin-server.customhttpresponseoptions.md) | HTTP response parameters for a response with adjustable status code. |
+| [DeprecationAPIClientParams](./kibana-plugin-server.deprecationapiclientparams.md) | |
+| [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) | |
+| [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) | |
+| [DeprecationSettings](./kibana-plugin-server.deprecationsettings.md) | UiSettings deprecation field options. |
+| [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) | Small container object used to expose information about discovered plugins that may or may not have been started. |
+| [ElasticsearchError](./kibana-plugin-server.elasticsearcherror.md) | |
+| [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) | |
+| [EnvironmentMode](./kibana-plugin-server.environmentmode.md) | |
+| [ErrorHttpResponseOptions](./kibana-plugin-server.errorhttpresponseoptions.md) | HTTP response parameters |
+| [FakeRequest](./kibana-plugin-server.fakerequest.md) | Fake request object created manually by Kibana plugins. |
+| [HttpResponseOptions](./kibana-plugin-server.httpresponseoptions.md) | HTTP response parameters |
+| [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | Kibana HTTP Service provides own abstraction for work with HTTP stack. Plugins don't have direct access to hapi
server and its primitives anymore. Moreover, plugins shouldn't rely on the fact that HTTP Service uses one or another library under the hood. This gives the platform flexibility to upgrade or changing our internal HTTP stack without breaking plugins. If the HTTP Service lacks functionality you need, we are happy to discuss and support your needs. |
+| [HttpServiceStart](./kibana-plugin-server.httpservicestart.md) | |
+| [IContextContainer](./kibana-plugin-server.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
+| [ICspConfig](./kibana-plugin-server.icspconfig.md) | CSP configuration for use in Kibana. |
+| [IKibanaResponse](./kibana-plugin-server.ikibanaresponse.md) | A response data object, expected to returned as a result of [RequestHandler](./kibana-plugin-server.requesthandler.md) execution |
+| [IKibanaSocket](./kibana-plugin-server.ikibanasocket.md) | A tiny abstraction for TCP socket. |
+| [ImageValidation](./kibana-plugin-server.imagevalidation.md) | |
+| [IndexSettingsDeprecationInfo](./kibana-plugin-server.indexsettingsdeprecationinfo.md) | |
+| [IRenderOptions](./kibana-plugin-server.irenderoptions.md) | |
+| [IRouter](./kibana-plugin-server.irouter.md) | Registers route handlers for specified resource path and method. See [RouteConfig](./kibana-plugin-server.routeconfig.md) and [RequestHandler](./kibana-plugin-server.requesthandler.md) for more information about arguments to route registrations. |
+| [IScopedRenderingClient](./kibana-plugin-server.iscopedrenderingclient.md) | |
+| [IUiSettingsClient](./kibana-plugin-server.iuisettingsclient.md) | Server-side client that provides access to the advanced settings stored in elasticsearch. The settings provide control over the behavior of the Kibana application. For example, a user can specify how to display numeric or date fields. Users can adjust the settings via Management UI. |
+| [KibanaRequestEvents](./kibana-plugin-server.kibanarequestevents.md) | Request events. |
+| [KibanaRequestRoute](./kibana-plugin-server.kibanarequestroute.md) | Request specific route information exposed to a handler. |
+| [LegacyRequest](./kibana-plugin-server.legacyrequest.md) | |
+| [LegacyServiceSetupDeps](./kibana-plugin-server.legacyservicesetupdeps.md) | |
+| [LegacyServiceStartDeps](./kibana-plugin-server.legacyservicestartdeps.md) | |
+| [Logger](./kibana-plugin-server.logger.md) | Logger exposes all the necessary methods to log any type of information and this is the interface used by the logging consumers including plugins. |
+| [LoggerFactory](./kibana-plugin-server.loggerfactory.md) | The single purpose of LoggerFactory
interface is to define a way to retrieve a context-based logger instance. |
+| [LogMeta](./kibana-plugin-server.logmeta.md) | Contextual metadata |
+| [OnPostAuthToolkit](./kibana-plugin-server.onpostauthtoolkit.md) | A tool set defining an outcome of OnPostAuth interceptor for incoming request. |
+| [OnPreAuthToolkit](./kibana-plugin-server.onpreauthtoolkit.md) | A tool set defining an outcome of OnPreAuth interceptor for incoming request. |
+| [OnPreResponseExtensions](./kibana-plugin-server.onpreresponseextensions.md) | Additional data to extend a response. |
+| [OnPreResponseInfo](./kibana-plugin-server.onpreresponseinfo.md) | Response status code. |
+| [OnPreResponseToolkit](./kibana-plugin-server.onpreresponsetoolkit.md) | A tool set defining an outcome of OnPreAuth interceptor for incoming request. |
+| [PackageInfo](./kibana-plugin-server.packageinfo.md) | |
+| [Plugin](./kibana-plugin-server.plugin.md) | The interface that should be returned by a PluginInitializer
. |
+| [PluginConfigDescriptor](./kibana-plugin-server.pluginconfigdescriptor.md) | Describes a plugin configuration properties. |
+| [PluginInitializerContext](./kibana-plugin-server.plugininitializercontext.md) | Context that's available to plugins during initialization stage. |
+| [PluginManifest](./kibana-plugin-server.pluginmanifest.md) | Describes the set of required and optional properties plugin can define in its mandatory JSON manifest file. |
+| [PluginsServiceSetup](./kibana-plugin-server.pluginsservicesetup.md) | |
+| [PluginsServiceStart](./kibana-plugin-server.pluginsservicestart.md) | |
+| [RequestHandlerContext](./kibana-plugin-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.Provides the following clients: - [rendering](./kibana-plugin-server.iscopedrenderingclient.md) - Rendering client which uses the data of the incoming request - [savedObjects.client](./kibana-plugin-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [elasticsearch.dataClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request |
+| [RouteConfig](./kibana-plugin-server.routeconfig.md) | Route specific configuration. |
+| [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) | Additional route options. |
+| [RouteConfigOptionsBody](./kibana-plugin-server.routeconfigoptionsbody.md) | Additional body options for a route |
+| [RouteValidationResultFactory](./kibana-plugin-server.routevalidationresultfactory.md) | Validation result factory to be used in the custom validation function to return the valid data or validation errorsSee [RouteValidationFunction](./kibana-plugin-server.routevalidationfunction.md). |
+| [RouteValidatorConfig](./kibana-plugin-server.routevalidatorconfig.md) | The configuration object to the RouteValidator class. Set params
, query
and/or body
to specify the validation logic to follow for that property. |
+| [RouteValidatorOptions](./kibana-plugin-server.routevalidatoroptions.md) | Additional options for the RouteValidator class to modify its default behaviour. |
+| [SavedObject](./kibana-plugin-server.savedobject.md) | |
+| [SavedObjectAttributes](./kibana-plugin-server.savedobjectattributes.md) | The data for a Saved Object is stored as an object in the attributes
property. |
+| [SavedObjectReference](./kibana-plugin-server.savedobjectreference.md) | A reference to another saved object. |
+| [SavedObjectsBaseOptions](./kibana-plugin-server.savedobjectsbaseoptions.md) | |
+| [SavedObjectsBulkCreateObject](./kibana-plugin-server.savedobjectsbulkcreateobject.md) | |
+| [SavedObjectsBulkGetObject](./kibana-plugin-server.savedobjectsbulkgetobject.md) | |
+| [SavedObjectsBulkResponse](./kibana-plugin-server.savedobjectsbulkresponse.md) | |
+| [SavedObjectsBulkUpdateObject](./kibana-plugin-server.savedobjectsbulkupdateobject.md) | |
+| [SavedObjectsBulkUpdateOptions](./kibana-plugin-server.savedobjectsbulkupdateoptions.md) | |
+| [SavedObjectsBulkUpdateResponse](./kibana-plugin-server.savedobjectsbulkupdateresponse.md) | |
+| [SavedObjectsClientProviderOptions](./kibana-plugin-server.savedobjectsclientprovideroptions.md) | Options to control the creation of the Saved Objects Client. |
+| [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) | Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. |
+| [SavedObjectsComplexFieldMapping](./kibana-plugin-server.savedobjectscomplexfieldmapping.md) | |
+| [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md) | |
+| [SavedObjectsCreateOptions](./kibana-plugin-server.savedobjectscreateoptions.md) | |
+| [SavedObjectsDeleteByNamespaceOptions](./kibana-plugin-server.savedobjectsdeletebynamespaceoptions.md) | |
+| [SavedObjectsDeleteOptions](./kibana-plugin-server.savedobjectsdeleteoptions.md) | |
+| [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) | Options controlling the export operation. |
+| [SavedObjectsExportResultDetails](./kibana-plugin-server.savedobjectsexportresultdetails.md) | Structure of the export result details entry |
+| [SavedObjectsFindOptions](./kibana-plugin-server.savedobjectsfindoptions.md) | |
+| [SavedObjectsFindResponse](./kibana-plugin-server.savedobjectsfindresponse.md) | Return type of the Saved Objects find()
method.\*Note\*: this type is different between the Public and Server Saved Objects clients. |
+| [SavedObjectsImportConflictError](./kibana-plugin-server.savedobjectsimportconflicterror.md) | Represents a failure to import due to a conflict. |
+| [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) | Represents a failure to import. |
+| [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) | Represents a failure to import due to missing references. |
+| [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) | Options to control the import operation. |
+| [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) | The response describing the result of an import. |
+| [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) | Describes a retry operation for importing a saved object. |
+| [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) | Represents a failure to import due to an unknown reason. |
+| [SavedObjectsImportUnsupportedTypeError](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md) | Represents a failure to import due to having an unsupported saved object type. |
+| [SavedObjectsIncrementCounterOptions](./kibana-plugin-server.savedobjectsincrementcounteroptions.md) | |
+| [SavedObjectsMappingProperties](./kibana-plugin-server.savedobjectsmappingproperties.md) | Describe the fields of a [saved object type](./kibana-plugin-server.savedobjectstypemappingdefinition.md). |
+| [SavedObjectsMigrationLogger](./kibana-plugin-server.savedobjectsmigrationlogger.md) | |
+| [SavedObjectsMigrationVersion](./kibana-plugin-server.savedobjectsmigrationversion.md) | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. |
+| [SavedObjectsRawDoc](./kibana-plugin-server.savedobjectsrawdoc.md) | A raw document as represented directly in the saved object index. |
+| [SavedObjectsRepositoryFactory](./kibana-plugin-server.savedobjectsrepositoryfactory.md) | Factory provided when invoking a [client factory provider](./kibana-plugin-server.savedobjectsclientfactoryprovider.md) See [SavedObjectsServiceSetup.setClientFactoryProvider](./kibana-plugin-server.savedobjectsservicesetup.setclientfactoryprovider.md) |
+| [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) | Options to control the "resolve import" operation. |
+| [SavedObjectsServiceSetup](./kibana-plugin-server.savedobjectsservicesetup.md) | Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for creating and registering Saved Object client wrappers. |
+| [SavedObjectsServiceStart](./kibana-plugin-server.savedobjectsservicestart.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceStart API provides a scoped Saved Objects client for interacting with Saved Objects. |
+| [SavedObjectsTypeMappingDefinition](./kibana-plugin-server.savedobjectstypemappingdefinition.md) | Describe a saved object type mapping. |
+| [SavedObjectsTypeMappingDefinitions](./kibana-plugin-server.savedobjectstypemappingdefinitions.md) | A map of [saved object type mappings](./kibana-plugin-server.savedobjectstypemappingdefinition.md) |
+| [SavedObjectsUpdateOptions](./kibana-plugin-server.savedobjectsupdateoptions.md) | |
+| [SavedObjectsUpdateResponse](./kibana-plugin-server.savedobjectsupdateresponse.md) | |
+| [SessionCookieValidationResult](./kibana-plugin-server.sessioncookievalidationresult.md) | Return type from a function to validate cookie contents. |
+| [SessionStorage](./kibana-plugin-server.sessionstorage.md) | Provides an interface to store and retrieve data across requests. |
+| [SessionStorageCookieOptions](./kibana-plugin-server.sessionstoragecookieoptions.md) | Configuration used to create HTTP session storage based on top of cookie mechanism. |
+| [SessionStorageFactory](./kibana-plugin-server.sessionstoragefactory.md) | SessionStorage factory to bind one to an incoming request |
+| [StringValidationRegex](./kibana-plugin-server.stringvalidationregex.md) | StringValidation with regex object |
+| [StringValidationRegexString](./kibana-plugin-server.stringvalidationregexstring.md) | StringValidation as regex string |
+| [UiSettingsParams](./kibana-plugin-server.uisettingsparams.md) | UiSettings parameters defined by the plugins. |
+| [UiSettingsServiceSetup](./kibana-plugin-server.uisettingsservicesetup.md) | |
+| [UiSettingsServiceStart](./kibana-plugin-server.uisettingsservicestart.md) | |
+| [UserProvidedValues](./kibana-plugin-server.userprovidedvalues.md) | Describes the values explicitly set by user. |
+| [UuidServiceSetup](./kibana-plugin-server.uuidservicesetup.md) | APIs to access the application's instance uuid. |
+
+## Variables
+
+| Variable | Description |
+| --- | --- |
+| [kibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) | Set of helpers used to create KibanaResponse
to form HTTP response on an incoming request. Should be returned as a result of [RequestHandler](./kibana-plugin-server.requesthandler.md) execution. |
+| [validBodyOutput](./kibana-plugin-server.validbodyoutput.md) | The set of valid body.output |
+
+## Type Aliases
+
+| Type Alias | Description |
+| --- | --- |
+| [AuthenticationHandler](./kibana-plugin-server.authenticationhandler.md) | See [AuthToolkit](./kibana-plugin-server.authtoolkit.md). |
+| [AuthHeaders](./kibana-plugin-server.authheaders.md) | Auth Headers map |
+| [AuthResult](./kibana-plugin-server.authresult.md) | |
+| [CapabilitiesProvider](./kibana-plugin-server.capabilitiesprovider.md) | See [CapabilitiesSetup](./kibana-plugin-server.capabilitiessetup.md) |
+| [CapabilitiesSwitcher](./kibana-plugin-server.capabilitiesswitcher.md) | See [CapabilitiesSetup](./kibana-plugin-server.capabilitiessetup.md) |
+| [ConfigDeprecation](./kibana-plugin-server.configdeprecation.md) | Configuration deprecation returned from [ConfigDeprecationProvider](./kibana-plugin-server.configdeprecationprovider.md) that handles a single deprecation from the configuration. |
+| [ConfigDeprecationLogger](./kibana-plugin-server.configdeprecationlogger.md) | Logger interface used when invoking a [ConfigDeprecation](./kibana-plugin-server.configdeprecation.md) |
+| [ConfigDeprecationProvider](./kibana-plugin-server.configdeprecationprovider.md) | A provider that should returns a list of [ConfigDeprecation](./kibana-plugin-server.configdeprecation.md).See [ConfigDeprecationFactory](./kibana-plugin-server.configdeprecationfactory.md) for more usage examples. |
+| [ConfigPath](./kibana-plugin-server.configpath.md) | |
+| [ElasticsearchClientConfig](./kibana-plugin-server.elasticsearchclientconfig.md) | |
+| [GetAuthHeaders](./kibana-plugin-server.getauthheaders.md) | Get headers to authenticate a user against Elasticsearch. |
+| [GetAuthState](./kibana-plugin-server.getauthstate.md) | Get authentication state for a request. Returned by auth
interceptor. |
+| [HandlerContextType](./kibana-plugin-server.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md) to represent the type of the context. |
+| [HandlerFunction](./kibana-plugin-server.handlerfunction.md) | A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-server.icontextcontainer.md) |
+| [HandlerParameters](./kibana-plugin-server.handlerparameters.md) | Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-server.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-server.handlercontexttype.md). |
+| [Headers](./kibana-plugin-server.headers.md) | Http request headers to read. |
+| [HttpResponsePayload](./kibana-plugin-server.httpresponsepayload.md) | Data send to the client as a response payload. |
+| [IBasePath](./kibana-plugin-server.ibasepath.md) | Access or manipulate the Kibana base path[BasePath](./kibana-plugin-server.basepath.md) |
+| [IClusterClient](./kibana-plugin-server.iclusterclient.md) | Represents an Elasticsearch cluster API client created by the platform. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
+| [IContextProvider](./kibana-plugin-server.icontextprovider.md) | A function that returns a context value for a specific key of given context type. |
+| [ICustomClusterClient](./kibana-plugin-server.icustomclusterclient.md) | Represents an Elasticsearch cluster API client created by a plugin. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)
).See [ClusterClient](./kibana-plugin-server.clusterclient.md). |
+| [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Return authentication status for a request. |
+| [ISavedObjectsRepository](./kibana-plugin-server.isavedobjectsrepository.md) | See [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) |
+| [IScopedClusterClient](./kibana-plugin-server.iscopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient
but exposes additional callAsCurrentUser
method that doesn't use credentials of the Kibana internal user (as callAsInternalUser
does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). |
+| [KibanaRequestRouteOptions](./kibana-plugin-server.kibanarequestrouteoptions.md) | Route options: If 'GET' or 'OPTIONS' method, body options won't be returned. |
+| [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. |
+| [KnownHeaders](./kibana-plugin-server.knownheaders.md) | Set of well-known HTTP headers. |
+| [LifecycleResponseFactory](./kibana-plugin-server.lifecycleresponsefactory.md) | Creates an object containing redirection or error response with error details, HTTP headers, and other data transmitted to the client. |
+| [MIGRATION\_ASSISTANCE\_INDEX\_ACTION](./kibana-plugin-server.migration_assistance_index_action.md) | |
+| [MIGRATION\_DEPRECATION\_LEVEL](./kibana-plugin-server.migration_deprecation_level.md) | |
+| [MutatingOperationRefreshSetting](./kibana-plugin-server.mutatingoperationrefreshsetting.md) | Elasticsearch Refresh setting for mutating operation |
+| [OnPostAuthHandler](./kibana-plugin-server.onpostauthhandler.md) | See [OnPostAuthToolkit](./kibana-plugin-server.onpostauthtoolkit.md). |
+| [OnPreAuthHandler](./kibana-plugin-server.onpreauthhandler.md) | See [OnPreAuthToolkit](./kibana-plugin-server.onpreauthtoolkit.md). |
+| [OnPreResponseHandler](./kibana-plugin-server.onpreresponsehandler.md) | See [OnPreAuthToolkit](./kibana-plugin-server.onpreauthtoolkit.md). |
+| [PluginConfigSchema](./kibana-plugin-server.pluginconfigschema.md) | Dedicated type for plugin configuration schema. |
+| [PluginInitializer](./kibana-plugin-server.plugininitializer.md) | The plugin
export at the root of a plugin's server
directory should conform to this interface. |
+| [PluginName](./kibana-plugin-server.pluginname.md) | Dedicated type for plugin name/id that is supposed to make Map/Set/Arrays that use it as a key or value more obvious. |
+| [PluginOpaqueId](./kibana-plugin-server.pluginopaqueid.md) | |
+| [RecursiveReadonly](./kibana-plugin-server.recursivereadonly.md) | |
+| [RedirectResponseOptions](./kibana-plugin-server.redirectresponseoptions.md) | HTTP response parameters for redirection response |
+| [RequestHandler](./kibana-plugin-server.requesthandler.md) | A function executed when route path matched requested resource path. Request handler is expected to return a result of one of [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) functions. |
+| [RequestHandlerContextContainer](./kibana-plugin-server.requesthandlercontextcontainer.md) | An object that handles registration of http request context providers. |
+| [RequestHandlerContextProvider](./kibana-plugin-server.requesthandlercontextprovider.md) | Context provider for request handler. Extends request context object with provided functionality or data. |
+| [ResponseError](./kibana-plugin-server.responseerror.md) | Error message and optional data send to the client in case of error. |
+| [ResponseErrorAttributes](./kibana-plugin-server.responseerrorattributes.md) | Additional data to provide error details. |
+| [ResponseHeaders](./kibana-plugin-server.responseheaders.md) | Http response headers to set. |
+| [RouteContentType](./kibana-plugin-server.routecontenttype.md) | The set of supported parseable Content-Types |
+| [RouteMethod](./kibana-plugin-server.routemethod.md) | The set of common HTTP methods supported by Kibana routing. |
+| [RouteRegistrar](./kibana-plugin-server.routeregistrar.md) | Route handler common definition |
+| [RouteValidationFunction](./kibana-plugin-server.routevalidationfunction.md) | The custom validation function if @kbn/config-schema is not a valid solution for your specific plugin requirements. |
+| [RouteValidationSpec](./kibana-plugin-server.routevalidationspec.md) | Allowed property validation options: either @kbn/config-schema validations or custom validation functionsSee [RouteValidationFunction](./kibana-plugin-server.routevalidationfunction.md) for custom validation. |
+| [RouteValidatorFullConfig](./kibana-plugin-server.routevalidatorfullconfig.md) | Route validations config and options merged into one object |
+| [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | Type definition for a Saved Object attribute value |
+| [SavedObjectAttributeSingle](./kibana-plugin-server.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) |
+| [SavedObjectsClientContract](./kibana-plugin-server.savedobjectsclientcontract.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing plugin state.\#\# SavedObjectsClient errorsSince the SavedObjectsClient has its hands in everything we are a little paranoid about the way we present errors back to to application code. Ideally, all errors will be either:1. Caused by bad implementation (ie. undefined is not a function) and as such unpredictable 2. An error that has been classified and decorated appropriately by the decorators in [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md)Type 1 errors are inevitable, but since all expected/handle-able errors should be Type 2 the isXYZError()
helpers exposed at SavedObjectsErrorHelpers
should be used to understand and manage error responses from the SavedObjectsClient
.Type 2 errors are decorated versions of the source error, so if the elasticsearch client threw an error it will be decorated based on its type. That means that rather than looking for error.body.error.type
or doing substring checks on error.body.error.reason
, just use the helpers to understand the meaning of the error:\`\`\`js if (SavedObjectsErrorHelpers.isNotFoundError(error)) { // handle 404 }if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) { // 401 handling should be automatic, but in case you wanted to know }// always rethrow the error unless you handle it throw error; \`\`\`\#\#\# 404s from missing indexFrom the perspective of application code and APIs the SavedObjectsClient is a black box that persists objects. One of the internal details that users have no control over is that we use an elasticsearch index for persistance and that index might be missing.At the time of writing we are in the process of transitioning away from the operating assumption that the SavedObjects index is always available. Part of this transition is handling errors resulting from an index missing. These used to trigger a 500 error in most cases, and in others cause 404s with different error messages.From my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The object the request/call was targeting could not be found. This is why \#14141 takes special care to ensure that 404 errors are generic and don't distinguish between index missing or document missing.\#\#\# 503s from missing indexUnlike all other methods, create requests are supposed to succeed even when the Kibana index does not exist because it will be automatically created by elasticsearch. When that is not the case it is because Elasticsearch's action.auto_create_index
setting prevents it from being created automatically so we throw a special 503 with the intention of informing the user that their Elasticsearch settings need to be updated.See [SavedObjectsClient](./kibana-plugin-server.savedobjectsclient.md) See [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) |
+| [SavedObjectsClientFactory](./kibana-plugin-server.savedobjectsclientfactory.md) | Describes the factory used to create instances of the Saved Objects Client. |
+| [SavedObjectsClientFactoryProvider](./kibana-plugin-server.savedobjectsclientfactoryprovider.md) | Provider to invoke to retrieve a [SavedObjectsClientFactory](./kibana-plugin-server.savedobjectsclientfactory.md). |
+| [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | Describes the factory used to create instances of Saved Objects Client Wrappers. |
+| [SavedObjectsFieldMapping](./kibana-plugin-server.savedobjectsfieldmapping.md) | Describe a [saved object type mapping](./kibana-plugin-server.savedobjectstypemappingdefinition.md) field. |
+| [ScopeableRequest](./kibana-plugin-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.See [KibanaRequest](./kibana-plugin-server.kibanarequest.md). |
+| [SharedGlobalConfig](./kibana-plugin-server.sharedglobalconfig.md) | |
+| [StringValidation](./kibana-plugin-server.stringvalidation.md) | Allows regex objects or a regex string |
+| [UiSettingsType](./kibana-plugin-server.uisettingstype.md) | UI element type to represent the settings. |
+
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.dynamic.md b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.dynamic.md
new file mode 100644
index 0000000000000..44e548c611b02
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.dynamic.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-server.savedobjectscomplexfieldmapping.md) > [dynamic](./kibana-plugin-server.savedobjectscomplexfieldmapping.dynamic.md)
+
+## SavedObjectsComplexFieldMapping.dynamic property
+
+Signature:
+
+```typescript
+dynamic?: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.md b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.md
new file mode 100644
index 0000000000000..fb1ad5e9270a6
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.md
@@ -0,0 +1,21 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-server.savedobjectscomplexfieldmapping.md)
+
+## SavedObjectsComplexFieldMapping interface
+
+
+Signature:
+
+```typescript
+export interface SavedObjectsComplexFieldMapping
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [dynamic](./kibana-plugin-server.savedobjectscomplexfieldmapping.dynamic.md) | string
| |
+| [properties](./kibana-plugin-server.savedobjectscomplexfieldmapping.properties.md) | SavedObjectsMappingProperties
| |
+| [type](./kibana-plugin-server.savedobjectscomplexfieldmapping.type.md) | string
| |
+
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.properties.md b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.properties.md
new file mode 100644
index 0000000000000..7ceb0f8ee43c5
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.properties.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-server.savedobjectscomplexfieldmapping.md) > [properties](./kibana-plugin-server.savedobjectscomplexfieldmapping.properties.md)
+
+## SavedObjectsComplexFieldMapping.properties property
+
+Signature:
+
+```typescript
+properties: SavedObjectsMappingProperties;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.type.md
new file mode 100644
index 0000000000000..ef0db5123c927
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscomplexfieldmapping.type.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsComplexFieldMapping](./kibana-plugin-server.savedobjectscomplexfieldmapping.md) > [type](./kibana-plugin-server.savedobjectscomplexfieldmapping.type.md)
+
+## SavedObjectsComplexFieldMapping.type property
+
+Signature:
+
+```typescript
+type?: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.enabled.md b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.enabled.md
new file mode 100644
index 0000000000000..b7e4203977763
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.enabled.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md) > [enabled](./kibana-plugin-server.savedobjectscorefieldmapping.enabled.md)
+
+## SavedObjectsCoreFieldMapping.enabled property
+
+Signature:
+
+```typescript
+enabled?: boolean;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.fields.md b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.fields.md
new file mode 100644
index 0000000000000..880ef36cd73fc
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.fields.md
@@ -0,0 +1,15 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md) > [fields](./kibana-plugin-server.savedobjectscorefieldmapping.fields.md)
+
+## SavedObjectsCoreFieldMapping.fields property
+
+Signature:
+
+```typescript
+fields?: {
+ [subfield: string]: {
+ type: string;
+ };
+ };
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.index.md b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.index.md
new file mode 100644
index 0000000000000..31ff5a1d51948
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.index.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md) > [index](./kibana-plugin-server.savedobjectscorefieldmapping.index.md)
+
+## SavedObjectsCoreFieldMapping.index property
+
+Signature:
+
+```typescript
+index?: boolean;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.md b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.md
new file mode 100644
index 0000000000000..b3a010467a689
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.md
@@ -0,0 +1,22 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md)
+
+## SavedObjectsCoreFieldMapping interface
+
+
+Signature:
+
+```typescript
+export interface SavedObjectsCoreFieldMapping
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [enabled](./kibana-plugin-server.savedobjectscorefieldmapping.enabled.md) | boolean
| |
+| [fields](./kibana-plugin-server.savedobjectscorefieldmapping.fields.md) | {
[subfield: string]: {
type: string;
};
}
| |
+| [index](./kibana-plugin-server.savedobjectscorefieldmapping.index.md) | boolean
| |
+| [type](./kibana-plugin-server.savedobjectscorefieldmapping.type.md) | string
| |
+
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.type.md
new file mode 100644
index 0000000000000..8071217af861f
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectscorefieldmapping.type.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsCoreFieldMapping](./kibana-plugin-server.savedobjectscorefieldmapping.md) > [type](./kibana-plugin-server.savedobjectscorefieldmapping.type.md)
+
+## SavedObjectsCoreFieldMapping.type property
+
+Signature:
+
+```typescript
+type: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsfieldmapping.md b/docs/development/core/server/kibana-plugin-server.savedobjectsfieldmapping.md
new file mode 100644
index 0000000000000..1c18e237901bd
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectsfieldmapping.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsFieldMapping](./kibana-plugin-server.savedobjectsfieldmapping.md)
+
+## SavedObjectsFieldMapping type
+
+Describe a [saved object type mapping](./kibana-plugin-server.savedobjectstypemappingdefinition.md) field.
+
+Signature:
+
+```typescript
+export declare type SavedObjectsFieldMapping = SavedObjectsCoreFieldMapping | SavedObjectsComplexFieldMapping;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsmappingproperties.md b/docs/development/core/server/kibana-plugin-server.savedobjectsmappingproperties.md
new file mode 100644
index 0000000000000..23c5a83afc1f8
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectsmappingproperties.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsMappingProperties](./kibana-plugin-server.savedobjectsmappingproperties.md)
+
+## SavedObjectsMappingProperties interface
+
+Describe the fields of a [saved object type](./kibana-plugin-server.savedobjectstypemappingdefinition.md).
+
+Signature:
+
+```typescript
+export interface SavedObjectsMappingProperties
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md
index 64fb1f4a5f638..01a8ba9d733d4 100644
--- a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md
@@ -20,14 +20,25 @@ When plugins access the Saved Objects client, a new client is created using the
## Example
+
+```ts
import { SavedObjectsClient, CoreSetup } from 'src/core/server';
-export class Plugin() { setup: (core: CoreSetup) => { core.savedObjects.setClientFactory(({ request: KibanaRequest }) => { return new SavedObjectsClient(core.savedObjects.scopedRepository(request)); }) } }
+export class Plugin() {
+ setup: (core: CoreSetup) => {
+ core.savedObjects.setClientFactory(({ request: KibanaRequest }) => {
+ return new SavedObjectsClient(core.savedObjects.scopedRepository(request));
+ })
+ }
+}
+
+```
## Properties
| Property | Type | Description |
| --- | --- | --- |
| [addClientWrapper](./kibana-plugin-server.savedobjectsservicesetup.addclientwrapper.md) | (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void
| Add a [client wrapper factory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) with the given priority. |
+| [registerMappings](./kibana-plugin-server.savedobjectsservicesetup.registermappings.md) | (mappings: SavedObjectsTypeMappingDefinitions) => void
| Register [saved object type mappings](./kibana-plugin-server.savedobjectstypemappingdefinitions.md) |
| [setClientFactoryProvider](./kibana-plugin-server.savedobjectsservicesetup.setclientfactoryprovider.md) | (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void
| Set the default [factory provider](./kibana-plugin-server.savedobjectsclientfactoryprovider.md) for creating Saved Objects clients. Only one provider can be set, subsequent calls to this method will fail. |
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registermappings.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registermappings.md
new file mode 100644
index 0000000000000..e524a5f8207fd
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registermappings.md
@@ -0,0 +1,49 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsServiceSetup](./kibana-plugin-server.savedobjectsservicesetup.md) > [registerMappings](./kibana-plugin-server.savedobjectsservicesetup.registermappings.md)
+
+## SavedObjectsServiceSetup.registerMappings property
+
+Register [saved object type mappings](./kibana-plugin-server.savedobjectstypemappingdefinitions.md)
+
+Signature:
+
+```typescript
+registerMappings: (mappings: SavedObjectsTypeMappingDefinitions) => void;
+```
+
+## Remarks
+
+It's possible to directly use an imported json mappings file to call this API. However, as typescript ensure type validation of the mappings, it's strongly encouraged to use a typescript definition instead.
+
+## Example
+
+
+```ts
+// my-plugin/server/mappings.ts
+import { SavedObjectsTypeMappingDefinitions } from 'src/core/server';
+
+export const mappings: SavedObjectsTypeMappingDefinitions = {
+ 'my-type': {
+ properties: {
+ afield: {
+ type: "text"
+ }
+ }
+ }
+}
+
+```
+
+```ts
+// my-plugin/server/plugin.ts
+import { mappings } from './mappings';
+
+export class MyPlugin implements Plugin {
+ setup({ savedObjects }) {
+ savedObjects.registerMappings(mappings);
+ }
+}
+
+```
+
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.md b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.md
new file mode 100644
index 0000000000000..99983d3a9f02b
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.md
@@ -0,0 +1,45 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsTypeMappingDefinition](./kibana-plugin-server.savedobjectstypemappingdefinition.md)
+
+## SavedObjectsTypeMappingDefinition interface
+
+Describe a saved object type mapping.
+
+Signature:
+
+```typescript
+export interface SavedObjectsTypeMappingDefinition
+```
+
+## Example
+
+
+```ts
+const typeDefinition: SavedObjectsTypeMappingDefinition = {
+ properties: {
+ enabled: {
+ type: "boolean"
+ },
+ sendUsageFrom: {
+ ignore_above: 256,
+ type: "keyword"
+ },
+ lastReported: {
+ type: "date"
+ },
+ lastVersionChecked: {
+ ignore_above: 256,
+ type: "keyword"
+ },
+ }
+}
+
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [properties](./kibana-plugin-server.savedobjectstypemappingdefinition.properties.md) | SavedObjectsMappingProperties
| |
+
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.properties.md b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.properties.md
new file mode 100644
index 0000000000000..555870c3fdd7d
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinition.properties.md
@@ -0,0 +1,11 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsTypeMappingDefinition](./kibana-plugin-server.savedobjectstypemappingdefinition.md) > [properties](./kibana-plugin-server.savedobjectstypemappingdefinition.properties.md)
+
+## SavedObjectsTypeMappingDefinition.properties property
+
+Signature:
+
+```typescript
+properties: SavedObjectsMappingProperties;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinitions.md b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinitions.md
new file mode 100644
index 0000000000000..5a0cd32aa25eb
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.savedobjectstypemappingdefinitions.md
@@ -0,0 +1,45 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsTypeMappingDefinitions](./kibana-plugin-server.savedobjectstypemappingdefinitions.md)
+
+## SavedObjectsTypeMappingDefinitions interface
+
+A map of [saved object type mappings](./kibana-plugin-server.savedobjectstypemappingdefinition.md)
+
+Signature:
+
+```typescript
+export interface SavedObjectsTypeMappingDefinitions
+```
+
+## Example
+
+
+```ts
+const mappings: SavedObjectsTypeMappingDefinitions = {
+ someType: {
+ properties: {
+ enabled: {
+ type: "boolean"
+ },
+ field: {
+ type: "keyword"
+ },
+ },
+ },
+ anotherType: {
+ properties: {
+ enabled: {
+ type: "boolean"
+ },
+ lastReported: {
+ type: "date"
+ },
+ },
+ },
+
+}
+
+```
+ This is the format for a `mappings.json` savedObject mapping file.
+
diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md
index 087888922ac9b..0b1478b10f2a6 100644
--- a/src/core/MIGRATION.md
+++ b/src/core/MIGRATION.md
@@ -56,6 +56,8 @@
- [On the server side](#on-the-server-side)
- [On the client side](#on-the-client-side)
- [Updates an application navlink at runtime](#updates-an-app-navlink-at-runtime)
+ - [Migrate my plugin's savedObjects definitions](#migrate-saved-object-definitions)
+ - [Mappings](#migrate-saved-object-mappings)
Make no mistake, it is going to take a lot of work to move certain plugins to the new platform. Our target is to migrate the entire repo over to the new platform throughout 7.x and to remove the legacy plugin system no later than 8.0, and this is only possible if teams start on the effort now.
@@ -1205,6 +1207,7 @@ In server code, `core` can be accessed from either `server.newPlatform` or `kbnS
| `request.getSavedObjectsClient` | [`context.core.savedObjects.client`](/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md) | |
| `request.getUiSettingsService` | [`context.uiSettings.client`](/docs/development/core/server/kibana-plugin-server.iuisettingsclient.md) | |
| `kibana.Plugin.deprecations` | [Handle plugin configuration deprecations](#handle-plugin-config-deprecations) and [`PluginConfigDescriptor.deprecations`](docs/development/core/server/kibana-plugin-server.pluginconfigdescriptor.md) | Deprecations from New Platform are not applied to legacy configuration |
+| `kibana.Plugin.mappings` | [Migrate my plugin's savedObjects definitions](#migrate-saved-object-definitions) and [`SavedObjectServices.registerMappings`](docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registermappings.md) | Deprecations from New Platform are not applied to legacy configuration |
_See also: [Server's CoreSetup API Docs](/docs/development/core/server/kibana-plugin-server.coresetup.md)_
@@ -1654,4 +1657,105 @@ export class MyPlugin implements Plugin {
tooltip: 'Application disabled',
})
}
+```
+
+### Migrate my plugin's savedObjects definitions
+
+Legacy plugins were using the `uiExports` in their plugin definition to define their saved object mappings, schema and migrations.
+
+```js
+import mappings from './mappings.json';
+import { migrations } from './migrations';
+
+new kibana.Plugin({
+ init(server){
+ // [...]
+ },
+ uiExports: {
+ mappings,
+ migrations,
+ savedObjectSchemas: {
+ 'sample-data-telemetry': {
+ isNamespaceAgnostic: true,
+ },
+ 'kql-telemetry': {
+ isNamespaceAgnostic: true,
+ },
+ },
+ },
+})
+```
+
+In the new platform, all these registration are to be performed programmatically during your plugin's `setup` phase,
+using the core `savedObjects` service APIs.
+
+#### Mappings
+
+For mapping, `savedObjects.registerMappings` should be used. It expects a mappings definition in the exact same
+format they were in legacy.
+
+```js
+import mappings from './mappings.json';
+
+new kibana.Plugin({
+ uiExports: {
+ mappings,
+ },
+})
+```
+
+Would become:
+
+```typescript
+import mappings from './mappings.json';
+
+export class MyPlugin implements Plugin {
+ setup({ savedObjects }) {
+ savedObjects.registerMappings(mappings as SavedObjectsTypeMappingDefinitions);
+ }
+```
+
+Note: in new platform, there are now proper typescript types for the saved objects mappings. It's strongly
+advised to convert your json mapping file to typescript to ensure correct typings:
+
+```json
+// my-plugin/server/mappings.json
+{
+ "my-type": {
+ "properties": {
+ "afield": {
+ "type": "text"
+ }
+ }
+ }
+}
+```
+
+should be converted to a ts file
+
+```typescript
+// my-plugin/server/mappings.ts
+import { SavedObjectsTypeMappingDefinitions } from 'src/core/server';
+
+export const mappings: SavedObjectsTypeMappingDefinitions = {
+ 'my-type': {
+ properties: {
+ afield: {
+ type: "text"
+ }
+ }
+ }
+}
+```
+
+The usage would then become:
+
+```typescript
+import { mappings } from './mappings';
+
+export class MyPlugin implements Plugin {
+ setup({ savedObjects }) {
+ savedObjects.registerMappings(mappings);
+ }
+}
```
\ No newline at end of file
diff --git a/src/core/server/index.ts b/src/core/server/index.ts
index 91f38c9f2ddbe..dcce06e932d32 100644
--- a/src/core/server/index.ts
+++ b/src/core/server/index.ts
@@ -210,6 +210,12 @@ export {
SavedObjectsRepository,
SavedObjectsDeleteByNamespaceOptions,
SavedObjectsIncrementCounterOptions,
+ SavedObjectsComplexFieldMapping,
+ SavedObjectsCoreFieldMapping,
+ SavedObjectsFieldMapping,
+ SavedObjectsTypeMappingDefinitions,
+ SavedObjectsTypeMappingDefinition,
+ SavedObjectsMappingProperties,
} from './saved_objects';
export {
diff --git a/src/core/server/legacy/legacy_service.mock.ts b/src/core/server/legacy/legacy_service.mock.ts
index 495141cdcb58d..bd62c061ac27b 100644
--- a/src/core/server/legacy/legacy_service.mock.ts
+++ b/src/core/server/legacy/legacy_service.mock.ts
@@ -24,7 +24,12 @@ type LegacyServiceMock = jest.Mocked & { legacyId
const createDiscoverPluginsMock = (): LegacyServiceDiscoverPlugins => ({
pluginSpecs: [],
- uiExports: {} as any,
+ uiExports: {
+ savedObjectSchemas: {},
+ savedObjectMappings: [],
+ savedObjectMigrations: {},
+ savedObjectValidations: {},
+ },
navLinks: [],
pluginExtendedConfig: {
get: jest.fn(),
diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts
index 0cb717e3832aa..fb731e81df2d0 100644
--- a/src/core/server/legacy/legacy_service.ts
+++ b/src/core/server/legacy/legacy_service.ts
@@ -292,6 +292,7 @@ export class LegacyService implements CoreService {
savedObjects: {
setClientFactoryProvider: setupDeps.core.savedObjects.setClientFactoryProvider,
addClientWrapper: setupDeps.core.savedObjects.addClientWrapper,
+ registerMappings: setupDeps.core.savedObjects.registerMappings.bind(null, 'legacy'),
},
uiSettings: {
register: setupDeps.core.uiSettings.register,
diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts
index c0a8973d98a54..f67099b08ef60 100644
--- a/src/core/server/mocks.ts
+++ b/src/core/server/mocks.ts
@@ -107,12 +107,20 @@ function createCoreSetupMock() {
const uiSettingsMock = {
register: uiSettingsServiceMock.createSetupContract().register,
};
+
+ const savedObjectsService = savedObjectsServiceMock.createSetupContract();
+ const savedObjectMock: jest.Mocked = {
+ addClientWrapper: savedObjectsService.addClientWrapper,
+ setClientFactoryProvider: savedObjectsService.setClientFactoryProvider,
+ registerMappings: jest.fn(),
+ };
+
const mock: CoreSetupMockType = {
capabilities: capabilitiesServiceMock.createSetupContract(),
context: contextServiceMock.createSetupContract(),
elasticsearch: elasticsearchServiceMock.createSetup(),
http: httpMock,
- savedObjects: savedObjectsServiceMock.createSetupContract(),
+ savedObjects: savedObjectMock,
uiSettings: uiSettingsMock,
uuid: uuidServiceMock.createSetupContract(),
getStartServices: jest
diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts
index 99cd4eda7374c..cf2c9f109f1a6 100644
--- a/src/core/server/plugins/plugin_context.ts
+++ b/src/core/server/plugins/plugin_context.ts
@@ -167,6 +167,7 @@ export function createPluginSetupContext(
savedObjects: {
setClientFactoryProvider: deps.savedObjects.setClientFactoryProvider,
addClientWrapper: deps.savedObjects.addClientWrapper,
+ registerMappings: deps.savedObjects.registerMappings.bind(null, plugin.name),
},
uiSettings: {
register: deps.uiSettings.register,
diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts
index 181025d73817d..c2b08c7d2d159 100644
--- a/src/core/server/saved_objects/index.ts
+++ b/src/core/server/saved_objects/index.ts
@@ -50,4 +50,13 @@ export {
SavedObjectsDeleteByNamespaceOptions,
} from './service/lib/repository';
+export {
+ SavedObjectsCoreFieldMapping,
+ SavedObjectsComplexFieldMapping,
+ SavedObjectsFieldMapping,
+ SavedObjectsMappingProperties,
+ SavedObjectsTypeMappingDefinition,
+ SavedObjectsTypeMappingDefinitions,
+} from './mappings';
+
export { config } from './saved_objects_config';
diff --git a/src/core/server/saved_objects/mappings/index.ts b/src/core/server/saved_objects/mappings/index.ts
index 15b0736ca5f1f..62d65ce9e2270 100644
--- a/src/core/server/saved_objects/mappings/index.ts
+++ b/src/core/server/saved_objects/mappings/index.ts
@@ -18,9 +18,13 @@
*/
export { getTypes, getProperty, getRootProperties, getRootPropertiesObjects } from './lib';
export {
- FieldMapping,
- MappingMeta,
- MappingProperties,
+ SavedObjectsComplexFieldMapping,
+ SavedObjectsCoreFieldMapping,
+ SavedObjectsTypeMapping,
+ SavedObjectsTypeMappingDefinition,
+ SavedObjectsTypeMappingDefinitions,
+ SavedObjectsMappingProperties,
+ SavedObjectsFieldMapping,
+ IndexMappingMeta,
IndexMapping,
- SavedObjectsMapping,
} from './types';
diff --git a/src/core/server/saved_objects/mappings/lib/get_property.test.ts b/src/core/server/saved_objects/mappings/lib/get_property.test.ts
index a85697ddd08b8..a271cf3826e5d 100644
--- a/src/core/server/saved_objects/mappings/lib/get_property.test.ts
+++ b/src/core/server/saved_objects/mappings/lib/get_property.test.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { FieldMapping, IndexMapping } from '../types';
+import { SavedObjectsFieldMapping, IndexMapping } from '../types';
import { getProperty } from './get_property';
const MAPPINGS = {
@@ -47,7 +47,7 @@ const MAPPINGS = {
},
};
-function runTest(key: string | string[], mapping: IndexMapping | FieldMapping) {
+function runTest(key: string | string[], mapping: IndexMapping | SavedObjectsFieldMapping) {
expect(typeof key === 'string' || Array.isArray(key)).toBeTruthy();
expect(typeof mapping).toBe('object');
diff --git a/src/core/server/saved_objects/mappings/lib/get_property.ts b/src/core/server/saved_objects/mappings/lib/get_property.ts
index 4e9ff10fc5d47..a31c9fe0c3ba1 100644
--- a/src/core/server/saved_objects/mappings/lib/get_property.ts
+++ b/src/core/server/saved_objects/mappings/lib/get_property.ts
@@ -18,15 +18,15 @@
*/
import toPath from 'lodash/internal/toPath';
-import { CoreFieldMapping, FieldMapping, IndexMapping } from '../types';
+import { SavedObjectsCoreFieldMapping, SavedObjectsFieldMapping, IndexMapping } from '../types';
function getPropertyMappingFromObjectMapping(
- mapping: IndexMapping | FieldMapping,
+ mapping: IndexMapping | SavedObjectsFieldMapping,
path: string[]
-): FieldMapping | undefined {
+): SavedObjectsFieldMapping | undefined {
const props =
(mapping && (mapping as IndexMapping).properties) ||
- (mapping && (mapping as CoreFieldMapping).fields);
+ (mapping && (mapping as SavedObjectsCoreFieldMapping).fields);
if (!props) {
return undefined;
@@ -39,6 +39,9 @@ function getPropertyMappingFromObjectMapping(
}
}
-export function getProperty(mappings: IndexMapping | FieldMapping, path: string | string[]) {
+export function getProperty(
+ mappings: IndexMapping | SavedObjectsFieldMapping,
+ path: string | string[]
+) {
return getPropertyMappingFromObjectMapping(mappings, toPath(path));
}
diff --git a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts
index 61e4d752445c4..81ba1d8235561 100644
--- a/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts
+++ b/src/core/server/saved_objects/mappings/lib/get_root_properties_objects.ts
@@ -17,7 +17,11 @@
* under the License.
*/
-import { ComplexFieldMapping, IndexMapping, MappingProperties } from '../types';
+import {
+ SavedObjectsComplexFieldMapping,
+ IndexMapping,
+ SavedObjectsMappingProperties,
+} from '../types';
import { getRootProperties } from './get_root_properties';
/**
@@ -43,10 +47,10 @@ export function getRootPropertiesObjects(mappings: IndexMapping) {
// we consider the existence of the properties or type of object to designate that this is an object datatype
if (
!blacklist.includes(key) &&
- ((value as ComplexFieldMapping).properties || value.type === 'object')
+ ((value as SavedObjectsComplexFieldMapping).properties || value.type === 'object')
) {
acc[key] = value;
}
return acc;
- }, {} as MappingProperties);
+ }, {} as SavedObjectsMappingProperties);
}
diff --git a/src/core/server/saved_objects/mappings/types.ts b/src/core/server/saved_objects/mappings/types.ts
index 8bb1a69d2eb13..cb3f86c91eefa 100644
--- a/src/core/server/saved_objects/mappings/types.ts
+++ b/src/core/server/saved_objects/mappings/types.ts
@@ -17,47 +17,141 @@
* under the License.
*/
-// FieldMapping isn't 1:1 with the options available,
-// modify as needed.
-export interface CoreFieldMapping {
+/**
+ * Internal representation of a saved object type mapping definition.
+ *
+ * @internal
+ */
+export interface SavedObjectsTypeMapping {
+ pluginId: string;
type: string;
- fields?: {
- [subfield: string]: {
- type: string;
- };
- };
+ definition: SavedObjectsTypeMappingDefinition;
}
-// FieldMapping isn't 1:1 with the options available,
-// modify as needed.
-export interface ComplexFieldMapping {
- dynamic?: string;
- type?: string;
- properties: MappingProperties;
+/**
+ * Describe a saved object type mapping.
+ *
+ * @example
+ * ```ts
+ * const typeDefinition: SavedObjectsTypeMappingDefinition = {
+ * properties: {
+ * enabled: {
+ * type: "boolean"
+ * },
+ * sendUsageFrom: {
+ * ignore_above: 256,
+ * type: "keyword"
+ * },
+ * lastReported: {
+ * type: "date"
+ * },
+ * lastVersionChecked: {
+ * ignore_above: 256,
+ * type: "keyword"
+ * },
+ * }
+ * }
+ * ```
+ *
+ * @public
+ */
+export interface SavedObjectsTypeMappingDefinition {
+ properties: SavedObjectsMappingProperties;
}
-export type FieldMapping = CoreFieldMapping | ComplexFieldMapping;
+/**
+ * A map of {@link SavedObjectsTypeMappingDefinition | saved object type mappings}
+ *
+ * @example
+ * ```ts
+ * const mappings: SavedObjectsTypeMappingDefinitions = {
+ * someType: {
+ * properties: {
+ * enabled: {
+ * type: "boolean"
+ * },
+ * field: {
+ * type: "keyword"
+ * },
+ * },
+ * },
+ * anotherType: {
+ * properties: {
+ * enabled: {
+ * type: "boolean"
+ * },
+ * lastReported: {
+ * type: "date"
+ * },
+ * },
+ * },
-export interface MappingProperties {
- [field: string]: FieldMapping;
+ * }
+ * ```
+ * @remark This is the format for a `mappings.json` savedObject mapping file.
+ *
+ * @public
+ */
+export interface SavedObjectsTypeMappingDefinitions {
+ [type: string]: SavedObjectsTypeMappingDefinition;
}
-export interface SavedObjectsMapping {
- pluginId: string;
- properties: MappingProperties;
+/**
+ * Describe the fields of a {@link SavedObjectsTypeMappingDefinition | saved object type}.
+ *
+ * @public
+ */
+export interface SavedObjectsMappingProperties {
+ [field: string]: SavedObjectsFieldMapping;
}
-export interface MappingMeta {
+/**
+ * Describe a {@link SavedObjectsTypeMappingDefinition | saved object type mapping} field.
+ *
+ * @public
+ */
+export type SavedObjectsFieldMapping =
+ | SavedObjectsCoreFieldMapping
+ | SavedObjectsComplexFieldMapping;
+
+// INDEX MAPPING
+
+// IndexMapping isn't 1:1 with the options available,
+// modify as needed.
+/** @internal */
+export interface IndexMapping {
+ dynamic?: string;
+ properties: SavedObjectsMappingProperties;
+ _meta?: IndexMappingMeta;
+}
+
+/** @internal */
+export interface IndexMappingMeta {
// A dictionary of key -> md5 hash (e.g. 'dashboard': '24234qdfa3aefa3wa')
// with each key being a root-level mapping property, and each value being
// the md5 hash of that mapping's value when the index was created.
migrationMappingPropertyHashes?: { [k: string]: string };
}
-// IndexMapping isn't 1:1 with the options available,
+// FieldMapping isn't 1:1 with the options available,
// modify as needed.
-export interface IndexMapping {
+/** @public */
+export interface SavedObjectsCoreFieldMapping {
+ type: string;
+ index?: boolean;
+ enabled?: boolean;
+ fields?: {
+ [subfield: string]: {
+ type: string;
+ };
+ };
+}
+
+// FieldMapping isn't 1:1 with the options available,
+// modify as needed.
+/** @public */
+export interface SavedObjectsComplexFieldMapping {
dynamic?: string;
- properties: MappingProperties;
- _meta?: MappingMeta;
+ type?: string;
+ properties: SavedObjectsMappingProperties;
}
diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
index 71f589f24369a..821a10353f8ec 100644
--- a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
+++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts
@@ -27,21 +27,19 @@ describe('buildActiveMappings', () => {
bbb: { type: 'long' },
};
- expect(buildActiveMappings({ properties })).toMatchSnapshot();
+ expect(buildActiveMappings(properties)).toMatchSnapshot();
});
test('disallows duplicate mappings', () => {
const properties = { type: { type: 'long' } };
- expect(() => buildActiveMappings({ properties })).toThrow(
- /Cannot redefine core mapping \"type\"/
- );
+ expect(() => buildActiveMappings(properties)).toThrow(/Cannot redefine core mapping \"type\"/);
});
test('disallows mappings with leading underscore', () => {
const properties = { _hm: { type: 'keyword' } };
- expect(() => buildActiveMappings({ properties })).toThrow(
+ expect(() => buildActiveMappings(properties)).toThrow(
/Invalid mapping \"_hm\"\. Mappings cannot start with _/
);
});
@@ -53,7 +51,7 @@ describe('buildActiveMappings', () => {
ccc: { fields: { b: { type: 'text' }, a: { type: 'text' } }, type: 'keyword' },
};
- const mappings = buildActiveMappings({ properties });
+ const mappings = buildActiveMappings(properties);
const hashes = mappings._meta!.migrationMappingPropertyHashes!;
expect(hashes.aaa).toBeDefined();
diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts
index 2cf640cceea83..3afe8aae119d9 100644
--- a/src/core/server/saved_objects/migrations/core/build_active_mappings.ts
+++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.ts
@@ -22,31 +22,31 @@
*/
import crypto from 'crypto';
-import _ from 'lodash';
-import { IndexMapping, MappingProperties } from './../../mappings';
+import { cloneDeep, mapValues } from 'lodash';
+import {
+ IndexMapping,
+ SavedObjectsMappingProperties,
+ SavedObjectsTypeMappingDefinitions,
+} from './../../mappings';
/**
* Creates an index mapping with the core properties required by saved object
* indices, as well as the specified additional properties.
*
- * @param {Opts} opts
- * @prop {MappingDefinition} properties - The mapping's properties
- * @returns {IndexMapping}
+ * @param typeDefinitions - the type definitions to build mapping from.
*/
-export function buildActiveMappings({
- properties,
-}: {
- properties: MappingProperties;
-}): IndexMapping {
+export function buildActiveMappings(
+ typeDefinitions: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties
+): IndexMapping {
const mapping = defaultMapping();
- properties = validateAndMerge(mapping.properties, properties);
+ const mergedProperties = validateAndMerge(mapping.properties, typeDefinitions);
- return _.cloneDeep({
+ return cloneDeep({
...mapping,
- properties,
+ properties: mergedProperties,
_meta: {
- migrationMappingPropertyHashes: md5Values(properties),
+ migrationMappingPropertyHashes: md5Values(mergedProperties),
},
});
}
@@ -113,7 +113,7 @@ function canonicalStringify(obj: any): string {
// Convert an object's values to md5 hash strings
function md5Values(obj: any) {
- return _.mapValues(obj, md5Object);
+ return mapValues(obj, md5Object);
}
// If something exists in actual, but is missing in expected, we don't
@@ -171,12 +171,14 @@ function defaultMapping(): IndexMapping {
};
}
-function validateAndMerge(dest: MappingProperties, source: MappingProperties) {
+function validateAndMerge(
+ dest: SavedObjectsMappingProperties,
+ source: SavedObjectsTypeMappingDefinitions | SavedObjectsMappingProperties
+) {
Object.keys(source).forEach(k => {
if (k.startsWith('_')) {
throw new Error(`Invalid mapping "${k}". Mappings cannot start with _.`);
}
-
if (dest.hasOwnProperty(k)) {
throw new Error(`Cannot redefine core mapping "${k}".`);
}
diff --git a/src/core/server/saved_objects/migrations/core/build_index_map.ts b/src/core/server/saved_objects/migrations/core/build_index_map.ts
index 914447563cc77..4fc0a230adacf 100644
--- a/src/core/server/saved_objects/migrations/core/build_index_map.ts
+++ b/src/core/server/saved_objects/migrations/core/build_index_map.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { MappingProperties } from '../../mappings';
+import { SavedObjectsTypeMappingDefinitions } from '../../mappings';
import { SavedObjectsSchema } from '../../schema';
import { LegacyConfig } from '../../../legacy';
@@ -25,12 +25,12 @@ export interface CreateIndexMapOptions {
config: LegacyConfig;
kibanaIndexName: string;
schema: SavedObjectsSchema;
- indexMap: MappingProperties;
+ indexMap: SavedObjectsTypeMappingDefinitions;
}
export interface IndexMap {
[index: string]: {
- typeMappings: MappingProperties;
+ typeMappings: SavedObjectsTypeMappingDefinitions;
script?: string;
};
}
diff --git a/src/core/server/saved_objects/migrations/core/migration_context.ts b/src/core/server/saved_objects/migrations/core/migration_context.ts
index d4e97ee6c5747..3a6145f5d9623 100644
--- a/src/core/server/saved_objects/migrations/core/migration_context.ts
+++ b/src/core/server/saved_objects/migrations/core/migration_context.ts
@@ -26,7 +26,7 @@
import { Logger } from 'src/core/server/logging';
import { SavedObjectsSerializer } from '../../serialization';
-import { MappingProperties } from '../../mappings';
+import { SavedObjectsTypeMappingDefinitions } from '../../mappings';
import { buildActiveMappings } from './build_active_mappings';
import { CallCluster } from './call_cluster';
import { VersionedTransformer } from './document_migrator';
@@ -40,7 +40,7 @@ export interface MigrationOpts {
callCluster: CallCluster;
index: string;
log: Logger;
- mappingProperties: MappingProperties;
+ mappingProperties: SavedObjectsTypeMappingDefinitions;
documentMigrator: VersionedTransformer;
serializer: SavedObjectsSerializer;
convertToAliasScript?: string;
@@ -107,9 +107,9 @@ function createSourceContext(source: FullIndexInfo, alias: string) {
function createDestContext(
source: FullIndexInfo,
alias: string,
- mappingProperties: MappingProperties
+ mappingProperties: SavedObjectsTypeMappingDefinitions
): FullIndexInfo {
- const activeMappings = buildActiveMappings({ properties: mappingProperties });
+ const activeMappings = buildActiveMappings(mappingProperties);
return {
aliases: {},
@@ -133,6 +133,5 @@ function createDestContext(
function nextIndexName(indexName: string, alias: string) {
const indexSuffix = (indexName.match(/[\d]+$/) || [])[0];
const indexNum = parseInt(indexSuffix, 10) || 0;
-
return `${alias}_${indexNum + 1}`;
}
diff --git a/src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap b/src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap
index 792b2063fc86d..37a73b11bbc48 100644
--- a/src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap
+++ b/src/core/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap
@@ -4,8 +4,8 @@ exports[`KibanaMigrator getActiveMappings returns full index mappings w/ core pr
Object {
"_meta": Object {
"migrationMappingPropertyHashes": Object {
- "amap": "625b32086eb1d1203564cf85062dd22e",
- "bmap": "625b32086eb1d1203564cf85062dd22e",
+ "amap": "510f1f0adb69830cf8a1c5ce2923ed82",
+ "bmap": "510f1f0adb69830cf8a1c5ce2923ed82",
"config": "87aca8fdb053154f11383fce3dbf3edf",
"migrationVersion": "4a1746014a75ade3a714e1db5763276f",
"namespace": "2f4316de49999235636386fe51dc06c1",
@@ -17,10 +17,18 @@ Object {
"dynamic": "strict",
"properties": Object {
"amap": Object {
- "type": "text",
+ "properties": Object {
+ "field": Object {
+ "type": "text",
+ },
+ },
},
"bmap": Object {
- "type": "text",
+ "properties": Object {
+ "field": Object {
+ "type": "text",
+ },
+ },
},
"config": Object {
"dynamic": "true",
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts
index c1021018538d5..9f0501d22c67d 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts
@@ -19,17 +19,16 @@
import { KibanaMigrator } from './kibana_migrator';
import { buildActiveMappings } from '../core';
-import { SavedObjectsMapping } from '../../mappings';
-const { mergeProperties } = jest.requireActual('./kibana_migrator');
+import { SavedObjectsTypeMapping } from '../../mappings';
+const { mergeTypes } = jest.requireActual('./kibana_migrator');
const defaultSavedObjectMappings = [
{
pluginId: 'testplugin',
- properties: {
- testtype: {
- properties: {
- name: { type: 'keyword' },
- },
+ type: 'testtype',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
},
},
@@ -39,7 +38,7 @@ const createMigrator = (
{
savedObjectMappings,
}: {
- savedObjectMappings: SavedObjectsMapping[];
+ savedObjectMappings: SavedObjectsTypeMapping[];
} = { savedObjectMappings: defaultSavedObjectMappings }
) => {
const mockMigrator: jest.Mocked> = {
@@ -49,7 +48,7 @@ const createMigrator = (
};
mockMigrator.getActiveMappings.mockReturnValue(
- buildActiveMappings({ properties: mergeProperties(savedObjectMappings) })
+ buildActiveMappings(mergeTypes(savedObjectMappings))
);
mockMigrator.migrateDocument.mockImplementation(doc => doc);
return mockMigrator;
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
index b89abc596ad18..7d69687accd07 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts
@@ -17,7 +17,6 @@
* under the License.
*/
-import _ from 'lodash';
import { KibanaMigratorOptions, KibanaMigrator } from './kibana_migrator';
import { loggingServiceMock } from '../../../logging/logging_service.mock';
import { SavedObjectsSchema } from '../../schema';
@@ -29,11 +28,17 @@ describe('KibanaMigrator', () => {
options.savedObjectMappings = [
{
pluginId: 'aaa',
- properties: { amap: { type: 'text' } },
+ type: 'amap',
+ definition: {
+ properties: { field: { type: 'text' } },
+ },
},
{
pluginId: 'bbb',
- properties: { bmap: { type: 'text' } },
+ type: 'bmap',
+ definition: {
+ properties: { field: { type: 'text' } },
+ },
},
];
const mappings = new KibanaMigrator(options).getActiveMappings();
@@ -45,11 +50,17 @@ describe('KibanaMigrator', () => {
options.savedObjectMappings = [
{
pluginId: 'aaa',
- properties: { amap: { type: 'text' } },
+ type: 'amap',
+ definition: {
+ properties: { field: { type: 'text' } },
+ },
},
{
pluginId: 'bbb',
- properties: { amap: { type: 'long' } },
+ type: 'amap',
+ definition: {
+ properties: { field: { type: 'long' } },
+ },
},
];
expect(() => new KibanaMigrator(options).getActiveMappings()).toThrow(
@@ -94,21 +105,19 @@ function mockOptions({ configValues }: { configValues?: any } = {}): KibanaMigra
savedObjectMappings: [
{
pluginId: 'testtype',
- properties: {
- testtype: {
- properties: {
- name: { type: 'keyword' },
- },
+ type: 'testtype',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
},
},
{
pluginId: 'testtype2',
- properties: {
- testtype2: {
- properties: {
- name: { type: 'keyword' },
- },
+ type: 'testtype2',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
},
},
diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
index c35e8dd90b5b1..6d842e55d2354 100644
--- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
+++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts
@@ -24,7 +24,11 @@
import { Logger } from 'src/core/server/logging';
import { KibanaConfigType } from 'src/core/server/kibana_config';
-import { MappingProperties, SavedObjectsMapping, IndexMapping } from '../../mappings';
+import {
+ SavedObjectsTypeMapping,
+ IndexMapping,
+ SavedObjectsTypeMappingDefinitions,
+} from '../../mappings';
import { SavedObjectsSchema } from '../../schema';
import { RawSavedObjectDoc, SavedObjectsSerializer } from '../../serialization';
import { docValidator, PropertyValidators } from '../../validation';
@@ -45,7 +49,7 @@ export interface KibanaMigratorOptions {
kibanaConfig: KibanaConfigType;
kibanaVersion: string;
logger: Logger;
- savedObjectMappings: SavedObjectsMapping[];
+ savedObjectMappings: SavedObjectsTypeMapping[];
savedObjectMigrations: MigrationDefinition;
savedObjectSchemas: SavedObjectsSchema;
savedObjectValidations: PropertyValidators;
@@ -63,7 +67,7 @@ export class KibanaMigrator {
private readonly documentMigrator: VersionedTransformer;
private readonly kibanaConfig: KibanaConfigType;
private readonly log: Logger;
- private readonly mappingProperties: MappingProperties;
+ private readonly mappingProperties: SavedObjectsTypeMappingDefinitions;
private readonly schema: SavedObjectsSchema;
private readonly serializer: SavedObjectsSerializer;
private migrationResult?: Promise>;
@@ -89,7 +93,7 @@ export class KibanaMigrator {
this.savedObjectsConfig = savedObjectsConfig;
this.schema = savedObjectSchemas;
this.serializer = new SavedObjectsSerializer(this.schema);
- this.mappingProperties = mergeProperties(savedObjectMappings || []);
+ this.mappingProperties = mergeTypes(savedObjectMappings || []);
this.log = logger;
this.documentMigrator = new DocumentMigrator({
kibanaVersion,
@@ -159,7 +163,7 @@ export class KibanaMigrator {
*
*/
public getActiveMappings(): IndexMapping {
- return buildActiveMappings({ properties: this.mappingProperties });
+ return buildActiveMappings(this.mappingProperties);
}
/**
@@ -177,12 +181,17 @@ export class KibanaMigrator {
* Merges savedObjectMappings properties into a single object, verifying that
* no mappings are redefined.
*/
-export function mergeProperties(mappings: SavedObjectsMapping[]): MappingProperties {
- return mappings.reduce((acc, { pluginId, properties }) => {
- const duplicate = Object.keys(properties).find(k => acc.hasOwnProperty(k));
+export function mergeTypes(
+ mappings: SavedObjectsTypeMapping[]
+): SavedObjectsTypeMappingDefinitions {
+ return mappings.reduce((acc, { pluginId, type, definition }) => {
+ const duplicate = acc.hasOwnProperty(type);
if (duplicate) {
- throw new Error(`Plugin ${pluginId} is attempting to redefine mapping "${duplicate}".`);
+ throw new Error(`Plugin ${pluginId} is attempting to redefine mapping "${type}".`);
}
- return Object.assign(acc, properties);
+ return {
+ ...acc,
+ [type]: definition,
+ };
}, {});
}
diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts
index a15d1f5b864b7..084316a1f102b 100644
--- a/src/core/server/saved_objects/saved_objects_service.mock.ts
+++ b/src/core/server/saved_objects/saved_objects_service.mock.ts
@@ -49,6 +49,7 @@ const createSetupContractMock = () => {
const setupContract: jest.Mocked = {
setClientFactoryProvider: jest.fn(),
addClientWrapper: jest.fn(),
+ registerMappings: jest.fn(),
};
return setupContract;
};
diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts
index 6668d57045a95..8f526d2ec73d6 100644
--- a/src/core/server/saved_objects/saved_objects_service.test.ts
+++ b/src/core/server/saved_objects/saved_objects_service.test.ts
@@ -105,6 +105,118 @@ describe('SavedObjectsService', () => {
);
});
});
+
+ describe('#registerMappings', () => {
+ it('registers the mappings and uses them to create the migrator', async () => {
+ const coreContext = mockCoreContext.create();
+ const soService = new SavedObjectsService(coreContext);
+ const setup = await soService.setup(createSetupDeps());
+
+ setup.registerMappings('pluginA', {
+ firstA: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ secondA: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ });
+ setup.registerMappings('pluginB', {
+ firstB: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ });
+
+ await soService.start({});
+
+ expect(KibanaMigratorMock.mock.calls[0][0].savedObjectMappings).toEqual([
+ {
+ pluginId: 'pluginA',
+ type: 'firstA',
+ definition: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ {
+ pluginId: 'pluginA',
+ type: 'secondA',
+ definition: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ {
+ pluginId: 'pluginB',
+ type: 'firstB',
+ definition: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ ]);
+ });
+
+ it('merges legacy mappings and mappings registered using the service', async () => {
+ const coreContext = mockCoreContext.create();
+ const soService = new SavedObjectsService(coreContext);
+ const setupDeps = createSetupDeps();
+
+ setupDeps.legacyPlugins.uiExports.savedObjectMappings = [
+ {
+ pluginId: 'legacyPlugin',
+ properties: {
+ legacyType: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ },
+ ];
+
+ const setup = await soService.setup(setupDeps);
+
+ setup.registerMappings('pluginA', {
+ typeA: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ });
+
+ await soService.start({});
+
+ expect(KibanaMigratorMock.mock.calls[0][0].savedObjectMappings).toEqual([
+ {
+ pluginId: 'legacyPlugin',
+ type: 'legacyType',
+ definition: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ {
+ pluginId: 'pluginA',
+ type: 'typeA',
+ definition: {
+ properties: {
+ field: { type: 'text' },
+ },
+ },
+ },
+ ]);
+ });
+ });
});
describe('#start()', () => {
diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts
index b08033a19242b..e1019117c65d2 100644
--- a/src/core/server/saved_objects/saved_objects_service.ts
+++ b/src/core/server/saved_objects/saved_objects_service.ts
@@ -27,6 +27,7 @@ import {
SavedObjectsClientProviderOptions,
} from './';
import { KibanaMigrator, IKibanaMigrator } from './migrations';
+import { SavedObjectsTypeMappingDefinitions } from './mappings';
import { CoreContext } from '../core_context';
import { LegacyServiceDiscoverPlugins } from '../legacy';
import { InternalElasticsearchServiceSetup, APICaller } from '../elasticsearch';
@@ -41,10 +42,11 @@ import {
SavedObjectsClientWrapperFactory,
} from './service/lib/scoped_client_provider';
import { Logger } from '../logging';
-import { SavedObjectsMapping } from './mappings';
+import { SavedObjectsTypeMapping } from './mappings';
import { MigrationDefinition } from './migrations/core/document_migrator';
import { SavedObjectsSchemaDefinition } from './schema';
import { PropertyValidators } from './validation';
+import { convertLegacyMappings } from './utils';
/**
* Saved Objects is Kibana's data persistence mechanism allowing plugins to
@@ -70,6 +72,7 @@ import { PropertyValidators } from './validation';
* constructor.
*
* @example
+ * ```ts
* import { SavedObjectsClient, CoreSetup } from 'src/core/server';
*
* export class Plugin() {
@@ -79,6 +82,7 @@ import { PropertyValidators } from './validation';
* })
* }
* }
+ * ```
*
* @public
*/
@@ -97,12 +101,52 @@ export interface SavedObjectsServiceSetup {
id: string,
factory: SavedObjectsClientWrapperFactory
) => void;
+
+ /**
+ * Register {@link SavedObjectsTypeMappingDefinitions | saved object type mappings}
+ *
+ * @example
+ *
+ * ```ts
+ * // my-plugin/server/mappings.ts
+ * import { SavedObjectsTypeMappingDefinitions } from 'src/core/server';
+ *
+ * export const mappings: SavedObjectsTypeMappingDefinitions = {
+ * 'my-type': {
+ * properties: {
+ * afield: {
+ * type: "text"
+ * }
+ * }
+ * }
+ * }
+ * ```
+ *
+ * ```ts
+ * // my-plugin/server/plugin.ts
+ * import { mappings } from './mappings';
+ *
+ * export class MyPlugin implements Plugin {
+ * setup({ savedObjects }) {
+ * savedObjects.registerMappings(mappings);
+ * }
+ * }
+ * ```
+ *
+ * @remarks
+ * It's possible to directly use an imported json mappings file to call this API. However, as typescript
+ * ensure type validation of the mappings, it's strongly encouraged to use a typescript definition instead.
+ */
+ registerMappings: (mappings: SavedObjectsTypeMappingDefinitions) => void;
}
/**
* @internal
*/
-export type InternalSavedObjectsServiceSetup = SavedObjectsServiceSetup;
+export interface InternalSavedObjectsServiceSetup
+ extends Omit {
+ registerMappings: (pluginId: string, mappings: SavedObjectsTypeMappingDefinitions) => void;
+}
/**
* Saved Objects is Kibana's data persisentence mechanism allowing plugins to
@@ -207,7 +251,7 @@ export class SavedObjectsService
private clientFactoryProvider?: SavedObjectsClientFactoryProvider;
private clientFactoryWrappers: WrappedClientFactoryWrapper[] = [];
- private mappings: SavedObjectsMapping[] = [];
+ private mappings: SavedObjectsTypeMapping[] = [];
private migrations: MigrationDefinition = {};
private schemas: SavedObjectsSchemaDefinition = {};
private validations: PropertyValidators = {};
@@ -223,11 +267,12 @@ export class SavedObjectsService
const {
savedObjectSchemas: savedObjectsSchemasDefinition,
- savedObjectMappings,
+ savedObjectMappings: legacyMappings,
savedObjectMigrations,
savedObjectValidations,
} = setupDeps.legacyPlugins.uiExports;
- this.mappings = savedObjectMappings;
+
+ this.mappings = convertLegacyMappings(legacyMappings || []);
this.migrations = savedObjectMigrations;
this.schemas = savedObjectsSchemasDefinition;
this.validations = savedObjectValidations;
@@ -246,6 +291,15 @@ export class SavedObjectsService
factory,
});
},
+ registerMappings: (pluginId, mappings) => {
+ this.mappings.push(
+ ...Object.entries(mappings).map(([type, definition]) => ({
+ pluginId,
+ type,
+ definition,
+ }))
+ );
+ },
};
}
diff --git a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts
index b3ea056484760..be221e4bdfce9 100644
--- a/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts
+++ b/src/core/server/saved_objects/service/lib/repository_create_repository.test.ts
@@ -35,25 +35,33 @@ describe('SavedObjectsRepository#createRepository', () => {
const mappings = [
{
pluginId: 'testplugin',
- properties: {
- nsAgnosticType: {
- properties: {
- name: { type: 'keyword' },
- },
+ type: 'nsAgnosticType',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
- nsType: {
- properties: {
- name: { type: 'keyword' },
- },
+ },
+ },
+ {
+ pluginId: 'testplugin',
+ type: 'nsType',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
- hiddenType: {
- properties: {
- name: { type: 'keyword' },
- },
+ },
+ },
+ {
+ pluginId: 'testplugin',
+ type: 'hiddenType',
+ definition: {
+ properties: {
+ name: { type: 'keyword' },
},
},
},
];
+
const migrator = mockKibanaMigrator.create({ savedObjectMappings: mappings });
const RepositoryConstructor = (SavedObjectsRepository as unknown) as jest.Mock<
SavedObjectsRepository
diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts
index a3fe2b937635b..787755bdda285 100644
--- a/src/core/server/saved_objects/types.ts
+++ b/src/core/server/saved_objects/types.ts
@@ -18,7 +18,7 @@
*/
import { SavedObjectsClient } from './service/saved_objects_client';
-import { SavedObjectsMapping } from './mappings';
+import { SavedObjectsTypeMappingDefinitions } from './mappings';
import { MigrationDefinition } from './migrations/core/document_migrator';
import { SavedObjectsSchemaDefinition } from './schema';
import { PropertyValidators } from './validation';
@@ -213,8 +213,17 @@ export type SavedObjectsClientContract = Pick {
+ it('converts the legacy uiExport mappings to core format', () => {
+ const legacyMappings: SavedObjectsLegacyMapping[] = [
+ {
+ pluginId: 'pluginA',
+ properties: {
+ typeA: {
+ properties: {
+ fieldA: { type: 'text' },
+ },
+ },
+ typeB: {
+ properties: {
+ fieldB: { type: 'text' },
+ },
+ },
+ },
+ },
+ {
+ pluginId: 'pluginB',
+ properties: {
+ typeC: {
+ properties: {
+ fieldC: { type: 'text' },
+ },
+ },
+ },
+ },
+ ];
+ expect(convertLegacyMappings(legacyMappings)).toMatchInlineSnapshot(`
+ Array [
+ Object {
+ "definition": Object {
+ "properties": Object {
+ "fieldA": Object {
+ "type": "text",
+ },
+ },
+ },
+ "pluginId": "pluginA",
+ "type": "typeA",
+ },
+ Object {
+ "definition": Object {
+ "properties": Object {
+ "fieldB": Object {
+ "type": "text",
+ },
+ },
+ },
+ "pluginId": "pluginA",
+ "type": "typeB",
+ },
+ Object {
+ "definition": Object {
+ "properties": Object {
+ "fieldC": Object {
+ "type": "text",
+ },
+ },
+ },
+ "pluginId": "pluginB",
+ "type": "typeC",
+ },
+ ]
+ `);
+ });
+});
diff --git a/src/core/server/saved_objects/utils.ts b/src/core/server/saved_objects/utils.ts
new file mode 100644
index 0000000000000..5da7c6d73522b
--- /dev/null
+++ b/src/core/server/saved_objects/utils.ts
@@ -0,0 +1,36 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { SavedObjectsLegacyMapping } from './types';
+import { SavedObjectsTypeMapping } from './mappings';
+
+export const convertLegacyMappings = (
+ legacyMappings: SavedObjectsLegacyMapping[]
+): SavedObjectsTypeMapping[] => {
+ return legacyMappings.reduce((mappings, { pluginId, properties }) => {
+ return [
+ ...mappings,
+ ...Object.entries(properties).map(([type, definition]) => ({
+ pluginId,
+ type,
+ definition,
+ })),
+ ];
+ }, [] as SavedObjectsTypeMapping[]);
+};
diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md
index a179e1f35a937..93f861a6eecd5 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -1519,6 +1519,32 @@ export interface SavedObjectsClientWrapperOptions {
request: KibanaRequest;
}
+// @public (undocumented)
+export interface SavedObjectsComplexFieldMapping {
+ // (undocumented)
+ dynamic?: string;
+ // (undocumented)
+ properties: SavedObjectsMappingProperties;
+ // (undocumented)
+ type?: string;
+}
+
+// @public (undocumented)
+export interface SavedObjectsCoreFieldMapping {
+ // (undocumented)
+ enabled?: boolean;
+ // (undocumented)
+ fields?: {
+ [subfield: string]: {
+ type: string;
+ };
+ };
+ // (undocumented)
+ index?: boolean;
+ // (undocumented)
+ type: string;
+}
+
// @public (undocumented)
export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions {
id?: string;
@@ -1614,6 +1640,9 @@ export interface SavedObjectsExportResultDetails {
}>;
}
+// @public
+export type SavedObjectsFieldMapping = SavedObjectsCoreFieldMapping | SavedObjectsComplexFieldMapping;
+
// @public (undocumented)
export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions {
// (undocumented)
@@ -1778,6 +1807,12 @@ export interface SavedObjectsLegacyService {
types: string[];
}
+// @public
+export interface SavedObjectsMappingProperties {
+ // (undocumented)
+ [field: string]: SavedObjectsFieldMapping;
+}
+
// @public (undocumented)
export interface SavedObjectsMigrationLogger {
// (undocumented)
@@ -1885,6 +1920,7 @@ export class SavedObjectsSerializer {
// @public
export interface SavedObjectsServiceSetup {
addClientWrapper: (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void;
+ registerMappings: (mappings: SavedObjectsTypeMappingDefinitions) => void;
setClientFactoryProvider: (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void;
}
@@ -1895,6 +1931,18 @@ export interface SavedObjectsServiceStart {
getScopedClient: (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract;
}
+// @public
+export interface SavedObjectsTypeMappingDefinition {
+ // (undocumented)
+ properties: SavedObjectsMappingProperties;
+}
+
+// @public
+export interface SavedObjectsTypeMappingDefinitions {
+ // (undocumented)
+ [type: string]: SavedObjectsTypeMappingDefinition;
+}
+
// @public (undocumented)
export interface SavedObjectsUpdateOptions extends SavedObjectsBaseOptions {
references?: SavedObjectReference[];
diff --git a/src/es_archiver/lib/indices/kibana_index.js b/src/es_archiver/lib/indices/kibana_index.js
index 744132bdcef69..202e7c4ea9590 100644
--- a/src/es_archiver/lib/indices/kibana_index.js
+++ b/src/es_archiver/lib/indices/kibana_index.js
@@ -26,6 +26,7 @@ import { toArray } from 'rxjs/operators';
import { deleteIndex } from './delete_index';
import { collectUiExports } from '../../../legacy/ui/ui_exports';
import { KibanaMigrator } from '../../../core/server/saved_objects/migrations';
+import { convertLegacyMappings } from '../../../core/server/saved_objects/utils';
import { SavedObjectsSchema } from '../../../core/server/saved_objects';
import { findPluginSpecs } from '../../../legacy/plugin_discovery';
@@ -103,7 +104,7 @@ export async function migrateKibanaIndex({ client, log, kibanaPluginIds }) {
},
version: kibanaVersion,
savedObjectSchemas: new SavedObjectsSchema(uiExports.savedObjectSchemas),
- savedObjectMappings: uiExports.savedObjectMappings,
+ savedObjectMappings: convertLegacyMappings(uiExports.savedObjectMappings),
savedObjectMigrations: uiExports.savedObjectMigrations,
savedObjectValidations: uiExports.savedObjectValidations,
callCluster: (path, ...args) => _.get(client, path).call(client, ...args),
diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.test.js b/src/legacy/server/saved_objects/saved_objects_mixin.test.js
index 691878cf66d27..a78dca6bd4fb5 100644
--- a/src/legacy/server/saved_objects/saved_objects_mixin.test.js
+++ b/src/legacy/server/saved_objects/saved_objects_mixin.test.js
@@ -22,6 +22,8 @@ import { savedObjectsMixin } from './saved_objects_mixin';
import { mockKibanaMigrator } from '../../../core/server/saved_objects/migrations/kibana/kibana_migrator.mock';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { savedObjectsClientProviderMock } from '../../../core/server/saved_objects/service/lib/scoped_client_provider.mock';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { convertLegacyMappings } from '../../../core/server/saved_objects/utils';
const savedObjectMappings = [
{
@@ -61,7 +63,9 @@ const savedObjectMappings = [
},
];
-const migrator = mockKibanaMigrator.create({ savedObjectMappings });
+const migrator = mockKibanaMigrator.create({
+ savedObjectMappings: convertLegacyMappings(savedObjectMappings),
+});
describe('Saved Objects Mixin', () => {
let mockKbnServer;